Refactoring IndexCreator (2)
This commit is contained in:
parent
a45a479be2
commit
bcbee2496c
8 changed files with 779 additions and 647 deletions
76
DataExtractionOSM/src/net/osmand/data/MapAlgorithms.java
Normal file
76
DataExtractionOSM/src/net/osmand/data/MapAlgorithms.java
Normal file
|
@ -0,0 +1,76 @@
|
|||
package net.osmand.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.osmand.osm.MapUtils;
|
||||
import net.osmand.osm.Node;
|
||||
import net.osmand.osm.Way;
|
||||
|
||||
public class MapAlgorithms {
|
||||
|
||||
public static void simplifyDouglasPeucker(List<Node> n, int zoom, int epsilon, Way w){
|
||||
ArrayList<Integer> l = new ArrayList<Integer>();
|
||||
int first = 0;
|
||||
while(first < n.size()){
|
||||
if(n.get(first) != null){
|
||||
break;
|
||||
}
|
||||
first++;
|
||||
}
|
||||
int last = n.size() - 1;
|
||||
while (last >= 0) {
|
||||
if (n.get(last) != null) {
|
||||
break;
|
||||
}
|
||||
last--;
|
||||
}
|
||||
if(last - first < 1){
|
||||
return;
|
||||
}
|
||||
boolean cycle = n.get(first).getId() == n.get(last).getId();
|
||||
simplifyDouglasPeucker(n, zoom, epsilon, l, first, cycle ? last - 1: last);
|
||||
w.addNode(n.get(first));
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
w.addNode(n.get(l.get(i)));
|
||||
}
|
||||
if (cycle) {
|
||||
w.addNode(n.get(first));
|
||||
}
|
||||
}
|
||||
|
||||
private static void simplifyDouglasPeucker(List<Node> n, int zoom, int epsilon, List<Integer> ints, int start, int end){
|
||||
double dmax = -1;
|
||||
int index = -1;
|
||||
for (int i = start + 1; i <= end - 1; i++) {
|
||||
if(n.get(i) == null){
|
||||
continue;
|
||||
}
|
||||
double d = orthogonalDistance(zoom, n.get(start), n.get(end), n.get(i));// calculate distance from line
|
||||
if (d > dmax) {
|
||||
dmax = d;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
if(dmax >= epsilon){
|
||||
simplifyDouglasPeucker(n, zoom, epsilon, ints, start, index);
|
||||
simplifyDouglasPeucker(n, zoom, epsilon, ints, index, end);
|
||||
} else {
|
||||
ints.add(end);
|
||||
}
|
||||
}
|
||||
|
||||
private static double orthogonalDistance(int zoom, Node nodeLineStart, Node nodeLineEnd, Node node) {
|
||||
double x1 = MapUtils.getTileNumberX(zoom, nodeLineStart.getLongitude());
|
||||
double y1 = MapUtils.getTileNumberY(zoom, nodeLineStart.getLatitude());
|
||||
double x2 = MapUtils.getTileNumberX(zoom, nodeLineEnd.getLongitude());
|
||||
double y2 = MapUtils.getTileNumberY(zoom, nodeLineEnd.getLatitude());
|
||||
double x = MapUtils.getTileNumberX(zoom, node.getLongitude());
|
||||
double y = MapUtils.getTileNumberY(zoom, node.getLatitude());
|
||||
double A = x - x1;
|
||||
double B = y - y1;
|
||||
double C = x2 - x1;
|
||||
double D = y2 - y1;
|
||||
return Math.abs(A * D - C * B) / Math.sqrt(C * C + D * D);
|
||||
}
|
||||
}
|
|
@ -38,41 +38,6 @@ public class DataIndexWriter {
|
|||
private static final int BATCH_SIZE = 1000;
|
||||
|
||||
|
||||
public static void insertAmenityIntoPoi(PreparedStatement prep, Map<PreparedStatement, Integer> map, Amenity amenity, int batchSize) throws SQLException {
|
||||
assert IndexConstants.POI_TABLE != null : "use constants here to show table usage "; //$NON-NLS-1$
|
||||
|
||||
prep.setLong(1, amenity.getId());
|
||||
prep.setInt(2, MapUtils.get31TileNumberX(amenity.getLocation().getLongitude()));
|
||||
prep.setInt(3, MapUtils.get31TileNumberY(amenity.getLocation().getLatitude()));
|
||||
prep.setString(4, amenity.getEnName());
|
||||
prep.setString(5, amenity.getName());
|
||||
prep.setString(6, AmenityType.valueToString(amenity.getType()));
|
||||
prep.setString(7, amenity.getSubType());
|
||||
prep.setString(8, amenity.getOpeningHours());
|
||||
prep.setString(9, amenity.getSite());
|
||||
prep.setString(10, amenity.getPhone());
|
||||
addBatch(map, prep, batchSize);
|
||||
}
|
||||
|
||||
public static PreparedStatement createStatementAmenityInsert(Connection conn) throws SQLException{
|
||||
return conn.prepareStatement("INSERT INTO " + IndexConstants.POI_TABLE + "(id, x, y, name_en, name, type, subtype, opening_hours, site, phone) " + //$NON-NLS-1$//$NON-NLS-2$
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
}
|
||||
|
||||
public static void createPoiIndexStructure(Connection conn, DBDialect dialect) throws SQLException{
|
||||
Statement stat = conn.createStatement();
|
||||
stat.executeUpdate("create table " + IndexConstants.POI_TABLE + //$NON-NLS-1$
|
||||
"(id bigint, x int, y int, name_en varchar(255), name varchar(255), " +
|
||||
"type varchar(255), subtype varchar(255), opening_hours varchar(255), phone varchar(255), site varchar(255)," +
|
||||
"primary key(id, type, subtype))");
|
||||
stat.executeUpdate("create index poi_loc on poi (x, y, type, subtype)");
|
||||
stat.executeUpdate("create index poi_id on poi (id, type, subtype)");
|
||||
if(dialect == DBDialect.SQLITE){
|
||||
stat.execute("PRAGMA user_version = " + IndexConstants.POI_TABLE_VERSION); //$NON-NLS-1$
|
||||
}
|
||||
stat.close();
|
||||
}
|
||||
|
||||
|
||||
public static PreparedStatement getStreetNodeInsertPreparedStatement(Connection conn) throws SQLException {
|
||||
assert IndexConstants.STREET_NODE_TABLE != null : "use constants here to show table usage "; //$NON-NLS-1$
|
||||
|
@ -349,7 +314,7 @@ public class DataIndexWriter {
|
|||
}
|
||||
}
|
||||
}
|
||||
private static void addBatch(Map<PreparedStatement, Integer> count, PreparedStatement p) throws SQLException {
|
||||
public static void addBatch(Map<PreparedStatement, Integer> count, PreparedStatement p) throws SQLException {
|
||||
addBatch(count, p, BATCH_SIZE, true);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,144 @@
|
|||
package net.osmand.data.preparation;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.AmenityType;
|
||||
import net.osmand.data.index.DataIndexWriter;
|
||||
import net.osmand.data.index.IndexConstants;
|
||||
import net.osmand.osm.Entity;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import net.osmand.osm.OSMSettings.OSMTagKey;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class IndexPoiCreator {
|
||||
|
||||
private static final int BATCH_SIZE = 1000;
|
||||
private static final Log log = LogFactory.getLog(IndexPoiCreator.class);
|
||||
private final IndexCreator creator;
|
||||
|
||||
private Connection poiConnection;
|
||||
private File poiIndexFile;
|
||||
private PreparedStatement poiPreparedStatement;
|
||||
|
||||
private List<Amenity> tempAmenityList = new ArrayList<Amenity>();
|
||||
|
||||
public IndexPoiCreator(IndexCreator creator){
|
||||
this.creator = creator;
|
||||
}
|
||||
|
||||
public void iterateEntity(Entity e, Map<PreparedStatement, Integer> pStatements) throws SQLException{
|
||||
tempAmenityList.clear();
|
||||
tempAmenityList = Amenity.parseAmenities(e, tempAmenityList);
|
||||
if (!tempAmenityList.isEmpty() && poiPreparedStatement != null) {
|
||||
// load data for way (location etc...)
|
||||
creator.loadEntityData(e, false);
|
||||
for (Amenity a : tempAmenityList) {
|
||||
checkEntity(e);
|
||||
a.setEntity(e);
|
||||
if (a.getLocation() != null) {
|
||||
// do not convert english name
|
||||
// convertEnglishName(a);
|
||||
insertAmenityIntoPoi(pStatements, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void commitAndClosePoiFile(Long lastModifiedDate) throws SQLException {
|
||||
if (poiConnection != null) {
|
||||
poiConnection.commit();
|
||||
poiConnection.close();
|
||||
poiConnection = null;
|
||||
if (lastModifiedDate != null) {
|
||||
poiIndexFile.setLastModified(lastModifiedDate);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void insertAmenityIntoPoi( Map<PreparedStatement, Integer> map, Amenity amenity) throws SQLException {
|
||||
assert IndexConstants.POI_TABLE != null : "use constants here to show table usage "; //$NON-NLS-1$
|
||||
|
||||
poiPreparedStatement.setLong(1, amenity.getId());
|
||||
poiPreparedStatement.setInt(2, MapUtils.get31TileNumberX(amenity.getLocation().getLongitude()));
|
||||
poiPreparedStatement.setInt(3, MapUtils.get31TileNumberY(amenity.getLocation().getLatitude()));
|
||||
poiPreparedStatement.setString(4, amenity.getEnName());
|
||||
poiPreparedStatement.setString(5, amenity.getName());
|
||||
poiPreparedStatement.setString(6, AmenityType.valueToString(amenity.getType()));
|
||||
poiPreparedStatement.setString(7, amenity.getSubType());
|
||||
poiPreparedStatement.setString(8, amenity.getOpeningHours());
|
||||
poiPreparedStatement.setString(9, amenity.getSite());
|
||||
poiPreparedStatement.setString(10, amenity.getPhone());
|
||||
DataIndexWriter.addBatch(map, poiPreparedStatement, BATCH_SIZE);
|
||||
}
|
||||
|
||||
public void checkEntity(Entity e){
|
||||
String name = e.getTag(OSMTagKey.NAME);
|
||||
if (name == null){
|
||||
String msg = "";
|
||||
Collection<String> keys = e.getTagKeySet();
|
||||
int cnt = 0;
|
||||
for (Iterator iter = keys.iterator(); iter.hasNext();) {
|
||||
String key = (String) iter.next();
|
||||
if (key.startsWith("name:") && key.length() <= 8) {
|
||||
// ignore specialties like name:botanical
|
||||
if (cnt == 0)
|
||||
msg += "Entity misses default name tag, but it has localized name tag(s):\n";
|
||||
msg += key + "=" + e.getTag(key) + "\n";
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
if (cnt > 0) {
|
||||
msg += "Consider adding the name tag at " + e.getOsmUrl();
|
||||
log.warn(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void createDatabaseStructure(File poiIndexFile, Map<PreparedStatement, Integer> pStatements) throws SQLException {
|
||||
this.poiIndexFile = poiIndexFile;
|
||||
// to save space
|
||||
if (poiIndexFile.exists()) {
|
||||
Algoritms.removeAllFiles(poiIndexFile);
|
||||
}
|
||||
poiIndexFile.getParentFile().mkdirs();
|
||||
// creating nodes db to fast access for all nodes
|
||||
poiConnection = creator.getDatabaseConnection(poiIndexFile.getAbsolutePath(), DBDialect.SQLITE);
|
||||
createPoiIndexStructure(poiConnection);
|
||||
poiPreparedStatement = createStatementAmenityInsert(poiConnection);
|
||||
pStatements.put(poiPreparedStatement, 0);
|
||||
poiConnection.setAutoCommit(false);
|
||||
}
|
||||
|
||||
public void createPoiIndexStructure(Connection conn) throws SQLException{
|
||||
Statement stat = conn.createStatement();
|
||||
stat.executeUpdate("create table " + IndexConstants.POI_TABLE + //$NON-NLS-1$
|
||||
"(id bigint, x int, y int, name_en varchar(255), name varchar(255), " +
|
||||
"type varchar(255), subtype varchar(255), opening_hours varchar(255), phone varchar(255), site varchar(255)," +
|
||||
"primary key(id, type, subtype))");
|
||||
stat.executeUpdate("create index poi_loc on poi (x, y, type, subtype)");
|
||||
stat.executeUpdate("create index poi_id on poi (id, type, subtype)");
|
||||
stat.execute("PRAGMA user_version = " + IndexConstants.POI_TABLE_VERSION); //$NON-NLS-1$
|
||||
stat.close();
|
||||
}
|
||||
|
||||
public PreparedStatement createStatementAmenityInsert(Connection conn) throws SQLException{
|
||||
return conn.prepareStatement("INSERT INTO " + IndexConstants.POI_TABLE + "(id, x, y, name_en, name, type, subtype, opening_hours, site, phone) " + //$NON-NLS-1$//$NON-NLS-2$
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
}
|
||||
|
||||
}
|
|
@ -17,18 +17,6 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import rtree.Element;
|
||||
import rtree.IllegalValueException;
|
||||
import rtree.LeafElement;
|
||||
import rtree.NonLeafElement;
|
||||
import rtree.RTree;
|
||||
import rtree.RTreeException;
|
||||
import rtree.RTreeInsertException;
|
||||
import rtree.Rect;
|
||||
|
||||
import net.osmand.binary.BinaryMapIndexWriter;
|
||||
import net.osmand.data.TransportRoute;
|
||||
import net.osmand.data.TransportStop;
|
||||
|
@ -42,6 +30,18 @@ import net.osmand.osm.Way;
|
|||
import net.osmand.osm.OSMSettings.OSMTagKey;
|
||||
import net.sf.junidecode.Junidecode;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import rtree.Element;
|
||||
import rtree.IllegalValueException;
|
||||
import rtree.LeafElement;
|
||||
import rtree.NonLeafElement;
|
||||
import rtree.RTree;
|
||||
import rtree.RTreeException;
|
||||
import rtree.RTreeInsertException;
|
||||
import rtree.Rect;
|
||||
|
||||
public class IndexTransportCreator {
|
||||
|
||||
private final IndexCreator creator;
|
||||
|
@ -119,9 +119,15 @@ public class IndexTransportCreator {
|
|||
}
|
||||
|
||||
|
||||
public void insertTransportIntoIndex(TransportRoute route, Map<PreparedStatement, Integer> pStatements) throws SQLException {
|
||||
insertTransportIntoIndex(transRouteStat, transRouteStopsStat, transStopsStat, transportStopsTree,
|
||||
visitedStops, route, pStatements, BATCH_SIZE);
|
||||
public void visitEntityMainStep(Entity e, OsmDbAccessorContext ctx, Map<PreparedStatement, Integer> pStatements) throws SQLException {
|
||||
if (e instanceof Relation && e.getTag(OSMTagKey.ROUTE) != null) {
|
||||
ctx.loadEntityData(e, true);
|
||||
TransportRoute route = indexTransportRoute((Relation) e);
|
||||
if (route != null) {
|
||||
insertTransportIntoIndex(transRouteStat, transRouteStopsStat, transStopsStat, transportStopsTree,
|
||||
visitedStops, route, pStatements, BATCH_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void insertTransportIntoIndex(PreparedStatement prepRoute, PreparedStatement prepRouteStops,
|
||||
|
@ -136,7 +142,7 @@ public class IndexTransportCreator {
|
|||
prepRoute.setString(5, route.getName());
|
||||
prepRoute.setString(6, route.getEnName());
|
||||
prepRoute.setInt(7, route.getAvgBothDistance());
|
||||
addBatch(statements, prepRoute);
|
||||
DataIndexWriter.addBatch(statements, prepRoute);
|
||||
|
||||
writeRouteStops(transportStopsTree, prepRouteStops, prepStops, statements, writtenStops, route, route.getForwardStops(), true);
|
||||
writeRouteStops(transportStopsTree, prepRouteStops, prepStops, statements, writtenStops, route, route.getBackwardStops(), false);
|
||||
|
@ -166,7 +172,7 @@ public class IndexTransportCreator {
|
|||
prepStops.setString(5, s.getEnName());
|
||||
int x = (int) MapUtils.getTileNumberX(24, s.getLocation().getLongitude());
|
||||
int y = (int) MapUtils.getTileNumberY(24, s.getLocation().getLatitude());
|
||||
addBatch(count, prepStops);
|
||||
DataIndexWriter.addBatch(count, prepStops);
|
||||
try {
|
||||
transportStopsTree.insert(new LeafElement(new Rect(x, y, x, y), s.getId()));
|
||||
} catch (RTreeInsertException e) {
|
||||
|
@ -180,7 +186,7 @@ public class IndexTransportCreator {
|
|||
prepRouteStops.setLong(2, s.getId());
|
||||
prepRouteStops.setInt(3, direction ? 1 : 0);
|
||||
prepRouteStops.setInt(4, i++);
|
||||
addBatch(count, prepRouteStops);
|
||||
DataIndexWriter.addBatch(count, prepRouteStops);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,6 +332,21 @@ public class IndexTransportCreator {
|
|||
}
|
||||
|
||||
|
||||
public void commitAndCloseFiles(String rtreeStopsFileName, String rtreeStopsPackFileName, boolean deleteDatabaseIndexes) throws IOException {
|
||||
// delete transport rtree files
|
||||
if (transportStopsTree != null) {
|
||||
transportStopsTree.getFileHdr().getFile().close();
|
||||
File f = new File(rtreeStopsFileName);
|
||||
if (f.exists() && deleteDatabaseIndexes) {
|
||||
f.delete();
|
||||
}
|
||||
f = new File(rtreeStopsPackFileName);
|
||||
if (f.exists() && deleteDatabaseIndexes) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void writeBinaryTransportTree(rtree.Node parent, RTree r, BinaryMapIndexWriter writer,
|
||||
PreparedStatement selectTransportStop, PreparedStatement selectTransportRouteStop,
|
||||
|
@ -474,29 +495,4 @@ public class IndexTransportCreator {
|
|||
return r;
|
||||
}
|
||||
|
||||
private static void addBatch(Map<PreparedStatement, Integer> count, PreparedStatement p) throws SQLException {
|
||||
addBatch(count, p, BATCH_SIZE, true);
|
||||
}
|
||||
|
||||
public static void addBatch(Map<PreparedStatement, Integer> count, PreparedStatement p, boolean commit) throws SQLException{
|
||||
addBatch(count, p, BATCH_SIZE, commit);
|
||||
}
|
||||
|
||||
public static void addBatch(Map<PreparedStatement, Integer> count, PreparedStatement p, int batchSize) throws SQLException{
|
||||
addBatch(count, p, batchSize, true);
|
||||
}
|
||||
|
||||
public static void addBatch(Map<PreparedStatement, Integer> count, PreparedStatement p, int batchSize, boolean commit) throws SQLException{
|
||||
p.addBatch();
|
||||
if(count.get(p) >= batchSize){
|
||||
p.executeBatch();
|
||||
if(commit){
|
||||
p.getConnection().commit();
|
||||
}
|
||||
count.put(p, 0);
|
||||
} else {
|
||||
count.put(p, count.get(p) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
package net.osmand.data.preparation;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.osmand.IProgress;
|
||||
import net.osmand.osm.Entity;
|
||||
import net.osmand.osm.Node;
|
||||
import net.osmand.osm.Relation;
|
||||
import net.osmand.osm.Way;
|
||||
import net.osmand.osm.Entity.EntityId;
|
||||
import net.osmand.osm.Entity.EntityType;
|
||||
|
||||
public class OsmDbAccessor implements OsmDbAccessorContext {
|
||||
private final IndexCreator indexCreator;
|
||||
|
||||
private PreparedStatement pselectNode;
|
||||
private PreparedStatement pselectWay;
|
||||
private PreparedStatement pselectRelation;
|
||||
private PreparedStatement pselectTags;
|
||||
private Connection dbConn;
|
||||
|
||||
public interface OsmDbVisitor {
|
||||
public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException;
|
||||
}
|
||||
|
||||
public OsmDbAccessor(IndexCreator indexCreator){
|
||||
this.indexCreator = indexCreator;
|
||||
}
|
||||
|
||||
public void initDatabase(Connection dbConn) throws SQLException {
|
||||
this.dbConn = dbConn;
|
||||
pselectNode = dbConn.prepareStatement("select n.latitude, n.longitude, t.skeys, t.value from node n left join tags t on n.id = t.id and t.type = 0 where n.id = ?"); //$NON-NLS-1$
|
||||
pselectWay = dbConn.prepareStatement("select w.node, w.ord, t.skeys, t.value, n.latitude, n.longitude " + //$NON-NLS-1$
|
||||
"from ways w left join tags t on w.id = t.id and t.type = 1 and w.ord = 0 inner join node n on w.node = n.id " + //$NON-NLS-1$
|
||||
"where w.id = ? order by w.ord"); //$NON-NLS-1$
|
||||
pselectRelation = dbConn.prepareStatement("select r.member, r.type, r.role, r.ord, t.skeys, t.value " + //$NON-NLS-1$
|
||||
"from relations r left join tags t on r.id = t.id and t.type = 2 and r.ord = 0 " + //$NON-NLS-1$
|
||||
"where r.id = ? order by r.ord"); //$NON-NLS-1$
|
||||
pselectTags = dbConn.prepareStatement("select skeys, value from tags where id = ? and type = ?"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public void loadEntityData(Entity e, boolean loadTags) throws SQLException {
|
||||
if (e instanceof Node || (e instanceof Way && !((Way) e).getNodes().isEmpty())) {
|
||||
// do not load tags for nodes inside way
|
||||
return;
|
||||
}
|
||||
Map<EntityId, Entity> map = new LinkedHashMap<EntityId, Entity>();
|
||||
if (e instanceof Relation && ((Relation) e).getMemberIds().isEmpty()) {
|
||||
pselectRelation.setLong(1, e.getId());
|
||||
if (pselectRelation.execute()) {
|
||||
ResultSet rs = pselectRelation.getResultSet();
|
||||
boolean first = true;
|
||||
while (rs.next()) {
|
||||
int ord = rs.getInt(4);
|
||||
if (ord > 0 || first) {
|
||||
first = false;
|
||||
((Relation) e).addMember(rs.getLong(1), EntityType.values()[rs.getInt(2)], rs.getString(3));
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
} else if (e instanceof Way && ((Way) e).getEntityIds().isEmpty()) {
|
||||
pselectWay.setLong(1, e.getId());
|
||||
if (pselectWay.execute()) {
|
||||
ResultSet rs = pselectWay.getResultSet();
|
||||
boolean first = true;
|
||||
while (rs.next()) {
|
||||
int ord = rs.getInt(2);
|
||||
if (ord > 0 || first) {
|
||||
first = false;
|
||||
((Way) e).addNode(new Node(rs.getDouble(5), rs.getDouble(6), rs.getLong(1)));
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
Collection<EntityId> ids = e instanceof Relation ? ((Relation) e).getMemberIds() : ((Way) e).getEntityIds();
|
||||
|
||||
for (EntityId i : ids) {
|
||||
// pselectNode = dbConn.prepareStatement("select n.latitude, n.longitude, t.skeys, t.value from node n left join tags t on n.id = t.id and t.type = 0 where n.id = ?");
|
||||
if (i.getType() == EntityType.NODE) {
|
||||
pselectNode.setLong(1, i.getId());
|
||||
if (pselectNode.execute()) {
|
||||
ResultSet rs = pselectNode.getResultSet();
|
||||
Node n = null;
|
||||
while (rs.next()) {
|
||||
if (n == null) {
|
||||
n = new Node(rs.getDouble(1), rs.getDouble(2), i.getId());
|
||||
}
|
||||
if (rs.getObject(3) != null) {
|
||||
n.putTag(rs.getString(3), rs.getString(4));
|
||||
}
|
||||
}
|
||||
map.put(i, n);
|
||||
rs.close();
|
||||
}
|
||||
} else if (i.getType() == EntityType.WAY) {
|
||||
// pselectWay = dbConn.prepareStatement("select w.node, w.ord, t.skeys, t.value, n.latitude, n.longitude " +
|
||||
// "from ways w left join tags t on w.id = t.id and t.type = 1 and w.ord = 0 inner join node n on w.node = n.id " +
|
||||
// "where w.id = ? order by w.ord");
|
||||
pselectWay.setLong(1, i.getId());
|
||||
if (pselectWay.execute()) {
|
||||
ResultSet rs = pselectWay.getResultSet();
|
||||
Way way = new Way(i.getId());
|
||||
map.put(i, way);
|
||||
boolean first = true;
|
||||
while (rs.next()) {
|
||||
int ord = rs.getInt(2);
|
||||
if (ord > 0 || first) {
|
||||
first = false;
|
||||
way.addNode(new Node(rs.getDouble(5), rs.getDouble(6), rs.getLong(1)));
|
||||
}
|
||||
if (ord == 0 && rs.getObject(3) != null) {
|
||||
way.putTag(rs.getString(3), rs.getString(4));
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
} else if (i.getType() == EntityType.RELATION) {
|
||||
pselectRelation.setLong(1, i.getId());
|
||||
// pselectRelation = dbConn.prepareStatement("select r.member, r.type, r.role, r.ord, t.skeys, t.value" +
|
||||
// "from relations r left join tags t on r.id = t.id and t.type = 2 and r.ord = 0 " +
|
||||
// "where r.id = ? order by r.ord");
|
||||
if (pselectRelation.execute()) {
|
||||
ResultSet rs = pselectRelation.getResultSet();
|
||||
Relation rel = new Relation(i.getId());
|
||||
map.put(i, rel);
|
||||
boolean first = true;
|
||||
while (rs.next()) {
|
||||
int ord = rs.getInt(4);
|
||||
if (ord > 0 || first) {
|
||||
first = false;
|
||||
rel.addMember(rs.getLong(1), EntityType.values()[rs.getInt(2)], rs.getString(3));
|
||||
}
|
||||
if (ord == 0 && rs.getObject(5) != null) {
|
||||
rel.putTag(rs.getString(5), rs.getString(6));
|
||||
}
|
||||
}
|
||||
// do not load relation members recursively ? It is not needed for transport, address, poi before
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.initializeLinks(map);
|
||||
}
|
||||
|
||||
|
||||
public int iterateOverEntities(IProgress progress, EntityType type, int allCount,
|
||||
OsmDbVisitor visitor) throws SQLException {
|
||||
Statement statement = dbConn.createStatement();
|
||||
String select;
|
||||
int count = 0;
|
||||
|
||||
// stat.executeUpdate("create table tags (id "+longType+", type smallint, skeys varchar(255), value varchar(255))");
|
||||
// stat.executeUpdate("create table ways (id "+longType+", node "+longType+", ord smallint)");
|
||||
// stat.executeUpdate("create table relations (id "+longType+", member "+longType+", type smallint, role varchar(255), ord smallint)");
|
||||
if (type == EntityType.NODE) {
|
||||
// filter out all nodes without tags
|
||||
select = "select n.id, n.latitude, n.longitude, t.skeys, t.value from node n inner join tags t on n.id = t.id and t.type = 0 order by n.id"; //$NON-NLS-1$
|
||||
} else if (type == EntityType.WAY) {
|
||||
select = "select w.id, w.node, w.ord, t.skeys, t.value, n.latitude, n.longitude " + //$NON-NLS-1$
|
||||
"from ways w left join tags t on w.id = t.id and t.type = 1 and w.ord = 0 inner join node n on w.node = n.id " + //$NON-NLS-1$
|
||||
"order by w.id, w.ord"; //$NON-NLS-1$
|
||||
} else {
|
||||
select = "select r.id, t.skeys, t.value from relations r inner join tags t on t.id = r.id and t.type = 2 and r.ord = 0"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
ResultSet rs = statement.executeQuery(select);
|
||||
Entity prevEntity = null;
|
||||
|
||||
long prevId = -1;
|
||||
while (rs.next()) {
|
||||
long curId = rs.getLong(1);
|
||||
boolean newEntity = curId != prevId;
|
||||
Entity e = prevEntity;
|
||||
if (type == EntityType.NODE) {
|
||||
if (newEntity) {
|
||||
e = new Node(rs.getDouble(2), rs.getDouble(3), curId);
|
||||
}
|
||||
e.putTag(rs.getString(4), rs.getString(5));
|
||||
} else if (type == EntityType.WAY) {
|
||||
if (newEntity) {
|
||||
e = new Way(curId);
|
||||
}
|
||||
int ord = rs.getInt(3);
|
||||
if (ord == 0 && rs.getObject(4) != null) {
|
||||
e.putTag(rs.getString(4), rs.getString(5));
|
||||
}
|
||||
if (newEntity || ord > 0) {
|
||||
((Way) e).addNode(new Node(rs.getDouble(6), rs.getDouble(7), rs.getLong(2)));
|
||||
}
|
||||
} else {
|
||||
if (newEntity) {
|
||||
e = new Relation(curId);
|
||||
}
|
||||
e.putTag(rs.getString(2), rs.getString(3));
|
||||
}
|
||||
if (newEntity) {
|
||||
count++;
|
||||
if (progress != null) {
|
||||
progress.progress(1);
|
||||
}
|
||||
if (prevEntity != null) {
|
||||
visitor.iterateEntity(prevEntity, this);
|
||||
}
|
||||
prevEntity = e;
|
||||
}
|
||||
prevId = curId;
|
||||
}
|
||||
if (prevEntity != null) {
|
||||
count++;
|
||||
visitor.iterateEntity(prevEntity, this);
|
||||
}
|
||||
rs.close();
|
||||
return count;
|
||||
}
|
||||
|
||||
public void loadEntityTags(EntityType type, Entity e) throws SQLException {
|
||||
pselectTags.setLong(1, e.getId());
|
||||
pselectTags.setByte(2, (byte) type.ordinal());
|
||||
ResultSet rsTags = pselectTags.executeQuery();
|
||||
while (rsTags.next()) {
|
||||
e.putTag(rsTags.getString(1), rsTags.getString(2));
|
||||
}
|
||||
rsTags.close();
|
||||
}
|
||||
|
||||
public void closeReadingConnection() throws SQLException {
|
||||
if (pselectNode != null) {
|
||||
pselectNode.close();
|
||||
}
|
||||
if (pselectWay != null) {
|
||||
pselectWay.close();
|
||||
}
|
||||
if (pselectRelation != null) {
|
||||
pselectRelation.close();
|
||||
}
|
||||
if (pselectTags != null) {
|
||||
pselectTags.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package net.osmand.data.preparation;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import net.osmand.osm.Entity;
|
||||
import net.osmand.osm.Entity.EntityType;
|
||||
|
||||
public interface OsmDbAccessorContext {
|
||||
|
||||
public void loadEntityTags(EntityType type, Entity e) throws SQLException;
|
||||
|
||||
public void loadEntityData(Entity e, boolean loadTags) throws SQLException;
|
||||
}
|
|
@ -2,8 +2,12 @@ package net.osmand.data.preparation;
|
|||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.osmand.osm.Entity;
|
||||
|
@ -43,6 +47,7 @@ public class OsmDbCreator implements IOsmStorageFilter {
|
|||
private Connection dbConn;
|
||||
private final IndexCreator indexCreator;
|
||||
|
||||
|
||||
public OsmDbCreator(IndexCreator indexCreator) {
|
||||
this.indexCreator = indexCreator;
|
||||
}
|
||||
|
@ -177,4 +182,5 @@ public class OsmDbCreator implements IOsmStorageFilter {
|
|||
return allWays;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue