refactor relation members
git-svn-id: https://osmand.googlecode.com/svn/trunk@264 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
29be5c3b16
commit
26eb8107f1
11 changed files with 279 additions and 104 deletions
|
@ -21,9 +21,13 @@ public class ToDoConstants {
|
||||||
// 50. Invent opening hours editor in order to edit POI hours better on device
|
// 50. Invent opening hours editor in order to edit POI hours better on device
|
||||||
// GOT by Olga
|
// GOT by Olga
|
||||||
|
|
||||||
|
// TODO sort hamlets by distance
|
||||||
// 60. Audio guidance for routing
|
// 60. Audio guidance for routing
|
||||||
// 61. Provide route information for YOURS (calclate turns/angle/expected time).
|
// 61. Provide route information for YOURS (calclate turns/angle/expected time).
|
||||||
// Fix some missing turns in CloudMade (for secondary roads wo name). Add them (if dist to prev/next turn > 150m) [dacha]
|
// Fix some missing turns in CloudMade (for secondary roads wo name). Add them (if dist to prev/next turn > 150m) [dacha]
|
||||||
|
// 33. Build transport locations. Create transport index (transport-stops) (investigate)
|
||||||
|
// DONE: Load transport routes in swing.
|
||||||
|
// IDEA TO HAVE :
|
||||||
|
|
||||||
|
|
||||||
// 43. Enable poi filter by name
|
// 43. Enable poi filter by name
|
||||||
|
@ -32,9 +36,6 @@ public class ToDoConstants {
|
||||||
// That setting should rule all activities that use internet. It should ask whenever internet is used
|
// That setting should rule all activities that use internet. It should ask whenever internet is used
|
||||||
// (would you like to use internet for that operation - if using internet is not checked).
|
// (would you like to use internet for that operation - if using internet is not checked).
|
||||||
// Internet using now for : edit POI osm, show osm bugs layer, download tiles.
|
// Internet using now for : edit POI osm, show osm bugs layer, download tiles.
|
||||||
// 33. Build transport locations. Create transport index (transport-stops) (investigate)
|
|
||||||
// DONE: Load transport routes in swing.
|
|
||||||
// IDEA TO HAVE :
|
|
||||||
|
|
||||||
// 40. Support simple vector road rendering (require new index file) (?)
|
// 40. Support simple vector road rendering (require new index file) (?)
|
||||||
// 63. Support simple offline routing(require new index file) (?)
|
// 63. Support simple offline routing(require new index file) (?)
|
||||||
|
|
|
@ -5,6 +5,8 @@ import java.text.Collator;
|
||||||
import com.osmand.osm.Entity;
|
import com.osmand.osm.Entity;
|
||||||
import com.osmand.osm.LatLon;
|
import com.osmand.osm.LatLon;
|
||||||
import com.osmand.osm.MapUtils;
|
import com.osmand.osm.MapUtils;
|
||||||
|
import com.osmand.osm.Entity.EntityId;
|
||||||
|
import com.osmand.osm.Entity.EntityType;
|
||||||
import com.osmand.osm.OSMSettings.OSMTagKey;
|
import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||||
|
|
||||||
public abstract class MapObject implements Comparable<MapObject> {
|
public abstract class MapObject implements Comparable<MapObject> {
|
||||||
|
@ -13,6 +15,7 @@ public abstract class MapObject implements Comparable<MapObject> {
|
||||||
protected String enName = null;
|
protected String enName = null;
|
||||||
protected LatLon location = null;
|
protected LatLon location = null;
|
||||||
protected Long id = null;
|
protected Long id = null;
|
||||||
|
protected EntityType type = null;
|
||||||
|
|
||||||
public MapObject(){}
|
public MapObject(){}
|
||||||
|
|
||||||
|
@ -23,6 +26,7 @@ public abstract class MapObject implements Comparable<MapObject> {
|
||||||
|
|
||||||
public void setEntity(Entity e){
|
public void setEntity(Entity e){
|
||||||
this.id = e.getId();
|
this.id = e.getId();
|
||||||
|
this.type = EntityType.valueOf(e);
|
||||||
if(this.name == null){
|
if(this.name == null){
|
||||||
this.name = e.getTag(OSMTagKey.NAME);
|
this.name = e.getTag(OSMTagKey.NAME);
|
||||||
}
|
}
|
||||||
|
@ -34,6 +38,14 @@ public abstract class MapObject implements Comparable<MapObject> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityId getEntityId(){
|
||||||
|
EntityType t = type;
|
||||||
|
if(t == null){
|
||||||
|
t = EntityType.NODE;
|
||||||
|
}
|
||||||
|
return new EntityId(t, id);
|
||||||
|
}
|
||||||
|
|
||||||
public void setId(Long id) {
|
public void setId(Long id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,8 @@ import com.osmand.osm.Node;
|
||||||
import com.osmand.osm.OSMSettings;
|
import com.osmand.osm.OSMSettings;
|
||||||
import com.osmand.osm.Relation;
|
import com.osmand.osm.Relation;
|
||||||
import com.osmand.osm.Way;
|
import com.osmand.osm.Way;
|
||||||
|
import com.osmand.osm.Entity.EntityId;
|
||||||
|
import com.osmand.osm.Entity.EntityType;
|
||||||
import com.osmand.osm.OSMSettings.OSMTagKey;
|
import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||||
import com.osmand.osm.io.IOsmStorageFilter;
|
import com.osmand.osm.io.IOsmStorageFilter;
|
||||||
import com.osmand.osm.io.OsmBaseStorage;
|
import com.osmand.osm.io.OsmBaseStorage;
|
||||||
|
@ -120,11 +122,18 @@ public class DataExtraction {
|
||||||
ArrayList<Entity> amenities = new ArrayList<Entity>();
|
ArrayList<Entity> amenities = new ArrayList<Entity>();
|
||||||
ArrayList<Way> ways = new ArrayList<Way>();
|
ArrayList<Way> ways = new ArrayList<Way>();
|
||||||
ArrayList<Relation> transport = new ArrayList<Relation>();
|
ArrayList<Relation> transport = new ArrayList<Relation>();
|
||||||
Map<Long, String> postalCodes = new LinkedHashMap<Long, String>();
|
Map<EntityId, String> postalCodes = new LinkedHashMap<EntityId, String>();
|
||||||
|
|
||||||
|
|
||||||
int currentCount = 0;
|
|
||||||
private Connection conn;
|
private Connection conn;
|
||||||
private PreparedStatement prep;
|
|
||||||
|
private boolean preloadRelationAndWaysIntoDB = false;
|
||||||
|
int currentCountNode = 0;
|
||||||
|
private PreparedStatement prepNode;
|
||||||
|
int currentRelationsCount = 0;
|
||||||
|
private PreparedStatement prepRelations;
|
||||||
|
int currentWaysCount = 0;
|
||||||
|
private PreparedStatement prepWays;
|
||||||
|
|
||||||
|
|
||||||
public DataExtractionOsmFilter() {
|
public DataExtractionOsmFilter() {
|
||||||
|
@ -146,7 +155,7 @@ public class DataExtraction {
|
||||||
return transport;
|
return transport;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Long, String> getPostalCodes() {
|
public Map<EntityId, String> getPostalCodes() {
|
||||||
return postalCodes;
|
return postalCodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,45 +180,97 @@ public class DataExtraction {
|
||||||
stat.executeUpdate("drop table if exists node;");
|
stat.executeUpdate("drop table if exists node;");
|
||||||
stat.executeUpdate("create table node (id long, latitude double, longitude double);");
|
stat.executeUpdate("create table node (id long, latitude double, longitude double);");
|
||||||
stat.executeUpdate("create index IdIndex ON node (id);");
|
stat.executeUpdate("create index IdIndex ON node (id);");
|
||||||
|
stat.executeUpdate("drop table if exists ways;");
|
||||||
|
stat.executeUpdate("create table ways (id long, node long);");
|
||||||
|
stat.executeUpdate("create index IdWIndex ON ways (id);");
|
||||||
|
stat.executeUpdate("drop table if exists relations;");
|
||||||
|
stat.executeUpdate("create table relations (id long, member long, type byte, role text);");
|
||||||
|
stat.executeUpdate("create index IdRIndex ON relations (id);");
|
||||||
stat.close();
|
stat.close();
|
||||||
|
|
||||||
prep = conn.prepareStatement("insert into node values (?, ?, ?);");
|
prepNode = conn.prepareStatement("insert into node values (?, ?, ?);");
|
||||||
|
prepWays = conn.prepareStatement("insert into ways values (?, ?);");
|
||||||
|
prepRelations = conn.prepareStatement("insert into relations values (?, ?, ?, ?);");
|
||||||
|
preloadRelationAndWaysIntoDB = indexTransport;
|
||||||
conn.setAutoCommit(false);
|
conn.setAutoCommit(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void correlateData(OsmBaseStorage storage, IProgress progress) throws SQLException {
|
public void correlateData(OsmBaseStorage storage, IProgress progress) throws SQLException {
|
||||||
if (currentCount > 0) {
|
if (currentCountNode > 0) {
|
||||||
prep.executeBatch();
|
prepNode.executeBatch();
|
||||||
}
|
}
|
||||||
prep.close();
|
prepNode.close();
|
||||||
|
if (currentWaysCount > 0) {
|
||||||
|
prepWays.executeBatch();
|
||||||
|
}
|
||||||
|
prepWays.close();
|
||||||
|
if (currentRelationsCount > 0) {
|
||||||
|
prepRelations.executeBatch();
|
||||||
|
}
|
||||||
|
prepRelations.close();
|
||||||
conn.setAutoCommit(true);
|
conn.setAutoCommit(true);
|
||||||
final PreparedStatement pselect = conn.prepareStatement("select * from node where id = ?");
|
|
||||||
Map<Long, Entity> map = new LinkedHashMap<Long, Entity>();
|
final PreparedStatement pselectNode = conn.prepareStatement("select * from node where id = ?");
|
||||||
|
final PreparedStatement pselectWay = conn.prepareStatement("select * from ways where id = ?");
|
||||||
|
final PreparedStatement pselectRelation = conn.prepareStatement("select * from relations where id = ?");
|
||||||
|
|
||||||
|
Map<EntityId, Entity> map = new LinkedHashMap<EntityId, Entity>();
|
||||||
progress.startTask("Correlating data...", storage.getRegisteredEntities().size());
|
progress.startTask("Correlating data...", storage.getRegisteredEntities().size());
|
||||||
Collection<Entity> values = new ArrayList<Entity>(storage.getRegisteredEntities().values());
|
ArrayList<Entity> values = new ArrayList<Entity>(storage.getRegisteredEntities().values());
|
||||||
for (Entity e : values) {
|
for (int ind = 0; ind < values.size(); ind++) {
|
||||||
|
Entity e = values.get(ind);
|
||||||
progress.progress(1);
|
progress.progress(1);
|
||||||
if (e instanceof Way || e instanceof Relation) {
|
if (e instanceof Node) {
|
||||||
map.clear();
|
continue;
|
||||||
Collection<Long> ids = e instanceof Way ? ((Way) e).getNodeIds() : ((Relation) e).getMemberIds();
|
}
|
||||||
for (Long i : ids) {
|
map.clear();
|
||||||
if (!storage.getRegisteredEntities().containsKey(i)) {
|
Collection<EntityId> ids = e instanceof Way ? ((Way) e).getEntityIds() : ((Relation) e).getMemberIds();
|
||||||
pselect.setLong(1, i);
|
for (EntityId i : ids) {
|
||||||
if (pselect.execute()) {
|
if (!storage.getRegisteredEntities().containsKey(i)) {
|
||||||
ResultSet rs = pselect.getResultSet();
|
if (i.getType() == EntityType.NODE) {
|
||||||
|
pselectNode.setLong(1, i.getId());
|
||||||
|
if (pselectNode.execute()) {
|
||||||
|
ResultSet rs = pselectNode.getResultSet();
|
||||||
if (rs.next()) {
|
if (rs.next()) {
|
||||||
storage.getRegisteredEntities().put(i, new Node(rs.getDouble(2), rs.getDouble(3), rs.getLong(1)));
|
storage.getRegisteredEntities().put(i, new Node(rs.getDouble(2), rs.getDouble(3), rs.getLong(1)));
|
||||||
}
|
}
|
||||||
rs.close();
|
rs.close();
|
||||||
}
|
}
|
||||||
}
|
} else if (i.getType() == EntityType.WAY) {
|
||||||
if(storage.getRegisteredEntities().containsKey(i)){
|
pselectWay.setLong(1, i.getId());
|
||||||
map.put(i, storage.getRegisteredEntities().get(i));
|
if (pselectWay.execute()) {
|
||||||
|
ResultSet rs = pselectWay.getResultSet();
|
||||||
|
Way way = new Way(i.getId());
|
||||||
|
storage.getRegisteredEntities().put(i, way);
|
||||||
|
while (rs.next()) {
|
||||||
|
way.addNode(rs.getLong(2));
|
||||||
|
}
|
||||||
|
// add way to load referred nodes
|
||||||
|
values.add(way);
|
||||||
|
rs.close();
|
||||||
|
}
|
||||||
|
} else if (i.getType() == EntityType.RELATION) {
|
||||||
|
pselectRelation.setLong(1, i.getId());
|
||||||
|
if (pselectRelation.execute()) {
|
||||||
|
ResultSet rs = pselectNode.getResultSet();
|
||||||
|
Relation rel = new Relation(i.getId());
|
||||||
|
storage.getRegisteredEntities().put(i, rel);
|
||||||
|
while (rs.next()) {
|
||||||
|
rel.addMember(rs.getLong(1), EntityType.values()[rs.getByte(2)], rs.getString(3));
|
||||||
|
}
|
||||||
|
// do not load relation members recursively ? It is not needed for transport, address, poi before
|
||||||
|
rs.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e.initializeLinks(map);
|
if (storage.getRegisteredEntities().containsKey(i)) {
|
||||||
|
map.put(i, storage.getRegisteredEntities().get(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
e.initializeLinks(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pselectNode.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
|
@ -250,7 +311,7 @@ public class DataExtraction {
|
||||||
if(e instanceof Relation){
|
if(e instanceof Relation){
|
||||||
if(e.getTag(OSMTagKey.POSTAL_CODE) != null){
|
if(e.getTag(OSMTagKey.POSTAL_CODE) != null){
|
||||||
String tag = e.getTag(OSMTagKey.POSTAL_CODE);
|
String tag = e.getTag(OSMTagKey.POSTAL_CODE);
|
||||||
for(Long l : ((Relation)e).getMemberIds()){
|
for(EntityId l : ((Relation)e).getMemberIds()){
|
||||||
postalCodes.put(l, tag);
|
postalCodes.put(l, tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,25 +323,48 @@ public class DataExtraction {
|
||||||
transport.add((Relation) e);
|
transport.add((Relation) e);
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
if(e instanceof Way){
|
|
||||||
processed = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// put all nodes into temporary db to get only required nodes after loading all data
|
// put all nodes into temporary db to get only required nodes after loading all data
|
||||||
try {
|
try {
|
||||||
if (e instanceof Node) {
|
if (e instanceof Node) {
|
||||||
currentCount++;
|
currentCountNode++;
|
||||||
prep.setLong(1, e.getId());
|
prepNode.setLong(1, e.getId());
|
||||||
prep.setDouble(2, ((Node) e).getLatitude());
|
prepNode.setDouble(2, ((Node) e).getLatitude());
|
||||||
prep.setDouble(3, ((Node) e).getLongitude());
|
prepNode.setDouble(3, ((Node) e).getLongitude());
|
||||||
prep.addBatch();
|
prepNode.addBatch();
|
||||||
if (currentCount >= BATCH_SIZE) {
|
if (currentCountNode >= BATCH_SIZE) {
|
||||||
prep.executeBatch();
|
prepNode.executeBatch();
|
||||||
currentCount = 0;
|
currentCountNode = 0;
|
||||||
|
}
|
||||||
|
} else if(preloadRelationAndWaysIntoDB) {
|
||||||
|
if (e instanceof Way) {
|
||||||
|
for(Long i : ((Way)e).getNodeIds()){
|
||||||
|
currentWaysCount ++;
|
||||||
|
prepWays.setLong(1, e.getId());
|
||||||
|
prepWays.setLong(2, i);
|
||||||
|
prepWays.addBatch();
|
||||||
|
}
|
||||||
|
if (currentWaysCount >= BATCH_SIZE) {
|
||||||
|
prepWays.executeBatch();
|
||||||
|
currentWaysCount = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(Entry<EntityId,String> i : ((Relation)e).getMembersMap().entrySet()){
|
||||||
|
currentRelationsCount ++;
|
||||||
|
prepRelations.setLong(1, e.getId());
|
||||||
|
prepRelations.setLong(2, i.getKey().getId());
|
||||||
|
prepRelations.setLong(3, i.getKey().getType().ordinal());
|
||||||
|
prepRelations.setString(4, i.getValue());
|
||||||
|
prepWays.addBatch();
|
||||||
|
}
|
||||||
|
if (currentRelationsCount >= BATCH_SIZE) {
|
||||||
|
prepRelations.executeBatch();
|
||||||
|
currentRelationsCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
log.error("Could not save node", ex);
|
log.error("Could not save in db", ex);
|
||||||
}
|
}
|
||||||
return processed || loadAllObjects;
|
return processed || loadAllObjects;
|
||||||
}
|
}
|
||||||
|
@ -289,8 +373,6 @@ public class DataExtraction {
|
||||||
|
|
||||||
|
|
||||||
public Region readCountry(String path, IProgress progress, IOsmStorageFilter addFilter) throws IOException, SAXException, SQLException{
|
public Region readCountry(String path, IProgress progress, IOsmStorageFilter addFilter) throws IOException, SAXException, SQLException{
|
||||||
|
|
||||||
|
|
||||||
File f = new File(path);
|
File f = new File(path);
|
||||||
InputStream stream = new FileInputStream(f);
|
InputStream stream = new FileInputStream(f);
|
||||||
InputStream streamFile = stream;
|
InputStream streamFile = stream;
|
||||||
|
@ -319,13 +401,13 @@ public class DataExtraction {
|
||||||
final ArrayList<Entity> amenities = filter.getAmenities();
|
final ArrayList<Entity> amenities = filter.getAmenities();
|
||||||
final ArrayList<Way> ways = filter.getWays();
|
final ArrayList<Way> ways = filter.getWays();
|
||||||
final ArrayList<Relation> transport = filter.getTransport();
|
final ArrayList<Relation> transport = filter.getTransport();
|
||||||
Map<Long, String> postalCodes = filter.getPostalCodes();
|
Map<EntityId, String> postalCodes = filter.getPostalCodes();
|
||||||
storage.getFilters().add(filter);
|
storage.getFilters().add(filter);
|
||||||
// 0. Loading osm file
|
// 0. Loading osm file
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 0.1 init database to store temporary data
|
// 0.1 init database to store temporary data
|
||||||
filter.initDatabase();
|
filter.initDatabase();
|
||||||
|
|
||||||
// 0.2 parsing osm itself
|
// 0.2 parsing osm itself
|
||||||
progress.setGeneralProgress("[40 of 100]");
|
progress.setGeneralProgress("[40 of 100]");
|
||||||
storage.parseOSM(stream, progress, streamFile, parseEntityInfo);
|
storage.parseOSM(stream, progress, streamFile, parseEntityInfo);
|
||||||
|
@ -428,7 +510,7 @@ public class DataExtraction {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void readingBuildings(IProgress progress, final ArrayList<Entity> buildings, Region country, Map<Long, String> postalCodes) {
|
private void readingBuildings(IProgress progress, final ArrayList<Entity> buildings, Region country, Map<EntityId, String> postalCodes) {
|
||||||
// found buildings (index addresses)
|
// found buildings (index addresses)
|
||||||
progress.startTask("Indexing buildings...", buildings.size());
|
progress.startTask("Indexing buildings...", buildings.size());
|
||||||
for(Entity b : buildings){
|
for(Entity b : buildings){
|
||||||
|
@ -448,8 +530,9 @@ public class DataExtraction {
|
||||||
}
|
}
|
||||||
if (city != null) {
|
if (city != null) {
|
||||||
Building building = city.registerBuilding(b);
|
Building building = city.registerBuilding(b);
|
||||||
if(postalCodes.containsKey(building.getId()) ){
|
EntityId i = building.getEntityId();
|
||||||
building.setPostcode(postalCodes.get(building.getId()));
|
if(postalCodes.containsKey(i) ){
|
||||||
|
building.setPostcode(postalCodes.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,73 @@ import java.util.Map;
|
||||||
import com.osmand.osm.OSMSettings.OSMTagKey;
|
import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||||
|
|
||||||
public abstract class Entity {
|
public abstract class Entity {
|
||||||
|
public enum EntityType {
|
||||||
|
NODE,
|
||||||
|
WAY,
|
||||||
|
RELATION;
|
||||||
|
|
||||||
|
public static EntityType valueOf(Entity e){
|
||||||
|
if(e instanceof Node){
|
||||||
|
return NODE;
|
||||||
|
} else if(e instanceof Way){
|
||||||
|
return WAY;
|
||||||
|
} else if(e instanceof Relation){
|
||||||
|
return RELATION;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EntityId {
|
||||||
|
private final EntityType type;
|
||||||
|
private final Long id;
|
||||||
|
|
||||||
|
public EntityId(EntityType type, Long id){
|
||||||
|
this.type = type;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
||||||
|
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
EntityId other = (EntityId) obj;
|
||||||
|
if (id == null) {
|
||||||
|
if (other.id != null)
|
||||||
|
return false;
|
||||||
|
} else if (!id.equals(other.id))
|
||||||
|
return false;
|
||||||
|
if (type == null) {
|
||||||
|
if (other.type != null)
|
||||||
|
return false;
|
||||||
|
} else if (!type.equals(other.type))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// lazy initializing
|
// lazy initializing
|
||||||
private Map<String, String> tags = null;
|
private Map<String, String> tags = null;
|
||||||
private final long id;
|
private final long id;
|
||||||
|
@ -57,7 +124,7 @@ public abstract class Entity {
|
||||||
return tags.keySet();
|
return tags.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void initializeLinks(Map<Long, Entity> entities);
|
public abstract void initializeLinks(Map<EntityId, Entity> entities);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class Node extends Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeLinks(Map<Long, Entity> entities) {
|
public void initializeLinks(Map<EntityId, Entity> entities) {
|
||||||
// nothing to initialize
|
// nothing to initialize
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,23 +10,24 @@ import java.util.Map;
|
||||||
public class Relation extends Entity {
|
public class Relation extends Entity {
|
||||||
|
|
||||||
// lazyLoading
|
// lazyLoading
|
||||||
Map<Long, String> members = null;
|
Map<EntityId, String> members = null;
|
||||||
Map<Entity, String> memberEntities = null;
|
Map<Entity, String> memberEntities = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Relation(long id) {
|
public Relation(long id) {
|
||||||
super(id);
|
super(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMember(Long id, String role){
|
public void addMember(Long id, EntityType type, String role){
|
||||||
if(members == null){
|
if(members == null){
|
||||||
members = new LinkedHashMap<Long, String>();
|
members = new LinkedHashMap<EntityId, String>();
|
||||||
}
|
}
|
||||||
members.put(id, role);
|
members.put(new EntityId(type, id), role);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String removeMember(Long id){
|
public String removeMember(EntityType e, Long id){
|
||||||
if(members == null){
|
if(members == null){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -41,26 +42,26 @@ public class Relation extends Entity {
|
||||||
return members.get(id);
|
return members.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Long> getMemberIds() {
|
public Collection<EntityId> getMemberIds() {
|
||||||
return getMemberIds(null);
|
return getMemberIds(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Long, String> getMembersMap() {
|
public Map<EntityId, String> getMembersMap() {
|
||||||
if(members == null){
|
if(members == null){
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
return Collections.unmodifiableMap(members);
|
return Collections.unmodifiableMap(members);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Long> getMemberIds(String role) {
|
public Collection<EntityId> getMemberIds(String role) {
|
||||||
if (members == null) {
|
if (members == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
if (role == null) {
|
if (role == null) {
|
||||||
return members.keySet();
|
return members.keySet();
|
||||||
}
|
}
|
||||||
List<Long> l = new ArrayList<Long>();
|
List<EntityId> l = new ArrayList<EntityId>();
|
||||||
for (Long m : members.keySet()) {
|
for (EntityId m : members.keySet()) {
|
||||||
if (role.equals(members.get(m))) {
|
if (role.equals(members.get(m))) {
|
||||||
l.add(m);
|
l.add(m);
|
||||||
}
|
}
|
||||||
|
@ -89,14 +90,14 @@ public class Relation extends Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeLinks(Map<Long, Entity> entities){
|
public void initializeLinks(Map<EntityId, Entity> entities){
|
||||||
if (members != null) {
|
if (members != null) {
|
||||||
if(memberEntities == null){
|
if(memberEntities == null){
|
||||||
memberEntities = new LinkedHashMap<Entity, String>();
|
memberEntities = new LinkedHashMap<Entity, String>();
|
||||||
} else {
|
} else {
|
||||||
memberEntities.clear();
|
memberEntities.clear();
|
||||||
}
|
}
|
||||||
for(Long l : members.keySet()){
|
for(EntityId l : members.keySet()){
|
||||||
if(l != null && entities.get(l) != null){
|
if(l != null && entities.get(l) != null){
|
||||||
memberEntities.put(entities.get(l), members.get(l));
|
memberEntities.put(entities.get(l), members.get(l));
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,17 @@ public class Way extends Entity {
|
||||||
return nodeIds;
|
return nodeIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<EntityId> getEntityIds(){
|
||||||
|
if(nodeIds == null){
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<EntityId> ls = new ArrayList<EntityId>();
|
||||||
|
for(Long l : nodeIds){
|
||||||
|
ls.add(new EntityId(EntityType.NODE, l));
|
||||||
|
}
|
||||||
|
return ls;
|
||||||
|
}
|
||||||
|
|
||||||
public List<Node> getNodes() {
|
public List<Node> getNodes() {
|
||||||
if(nodes == null){
|
if(nodes == null){
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
@ -55,7 +66,7 @@ public class Way extends Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initializeLinks(Map<Long, Entity> entities) {
|
public void initializeLinks(Map<EntityId, Entity> entities) {
|
||||||
if (nodeIds != null) {
|
if (nodeIds != null) {
|
||||||
if(nodes == null){
|
if(nodes == null){
|
||||||
nodes = new ArrayList<Node>();
|
nodes = new ArrayList<Node>();
|
||||||
|
@ -63,11 +74,7 @@ public class Way extends Entity {
|
||||||
nodes.clear();
|
nodes.clear();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < nodeIds.size(); i++) {
|
for (int i = 0; i < nodeIds.size(); i++) {
|
||||||
if(entities.get(nodeIds.get(i)) instanceof Node){
|
nodes.add((Node) entities.get(new EntityId(EntityType.NODE,nodeIds.get(i))));
|
||||||
nodes.add((Node) entities.get(nodeIds.get(i)));
|
|
||||||
} else {
|
|
||||||
nodes.add(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ import com.osmand.osm.EntityInfo;
|
||||||
import com.osmand.osm.Node;
|
import com.osmand.osm.Node;
|
||||||
import com.osmand.osm.Relation;
|
import com.osmand.osm.Relation;
|
||||||
import com.osmand.osm.Way;
|
import com.osmand.osm.Way;
|
||||||
|
import com.osmand.osm.Entity.EntityId;
|
||||||
|
import com.osmand.osm.Entity.EntityType;
|
||||||
|
|
||||||
public class OsmBaseStorage extends DefaultHandler {
|
public class OsmBaseStorage extends DefaultHandler {
|
||||||
|
|
||||||
|
@ -56,8 +58,8 @@ public class OsmBaseStorage extends DefaultHandler {
|
||||||
|
|
||||||
protected boolean parseStarted;
|
protected boolean parseStarted;
|
||||||
|
|
||||||
protected Map<Long, Entity> entities = new LinkedHashMap<Long, Entity>();
|
protected Map<EntityId, Entity> entities = new LinkedHashMap<EntityId, Entity>();
|
||||||
protected Map<Long, EntityInfo> entityInfo = new LinkedHashMap<Long, EntityInfo>();
|
protected Map<EntityId, EntityInfo> entityInfo = new LinkedHashMap<EntityId, EntityInfo>();
|
||||||
|
|
||||||
// this is used to show feedback to user
|
// this is used to show feedback to user
|
||||||
protected int progressEntity = 0;
|
protected int progressEntity = 0;
|
||||||
|
@ -216,7 +218,8 @@ public class OsmBaseStorage extends DefaultHandler {
|
||||||
} else if (ELEM_MEMBER.equals(name)) {
|
} else if (ELEM_MEMBER.equals(name)) {
|
||||||
Long id = parseId(attributes, ATTR_REF, -1);
|
Long id = parseId(attributes, ATTR_REF, -1);
|
||||||
if(id != -1 && currentParsedEntity instanceof Relation){
|
if(id != -1 && currentParsedEntity instanceof Relation){
|
||||||
((Relation)currentParsedEntity).addMember(id, attributes.getValue(ATTR_ROLE));
|
EntityType type = EntityType.valueOf(attributes.getValue(ATTR_TYPE).toUpperCase());
|
||||||
|
((Relation)currentParsedEntity).addMember(id, type, attributes.getValue(ATTR_ROLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -228,12 +231,21 @@ public class OsmBaseStorage extends DefaultHandler {
|
||||||
@Override
|
@Override
|
||||||
public void endElement(String uri, String localName, String name) throws SAXException {
|
public void endElement(String uri, String localName, String name) throws SAXException {
|
||||||
name = saxParser.isNamespaceAware() ? localName : name;
|
name = saxParser.isNamespaceAware() ? localName : name;
|
||||||
if (ELEM_NODE.equals(name) || ELEM_WAY.equals(name) || ELEM_RELATION.equals(name)) {
|
EntityType type = null;
|
||||||
|
if (ELEM_NODE.equals(name)){
|
||||||
|
type = EntityType.NODE;
|
||||||
|
} else if (ELEM_WAY.equals(name)){
|
||||||
|
type = EntityType.WAY;
|
||||||
|
} else if (ELEM_RELATION.equals(name)){
|
||||||
|
type = EntityType.RELATION;
|
||||||
|
}
|
||||||
|
if (type != null) {
|
||||||
if(currentParsedEntity != null){
|
if(currentParsedEntity != null){
|
||||||
if(acceptEntityToLoad(currentParsedEntity)){
|
if(acceptEntityToLoad(currentParsedEntity)){
|
||||||
Entity oldEntity = entities.put(currentParsedEntity.getId(), currentParsedEntity);
|
EntityId entityId = new EntityId(type, currentParsedEntity.getId());
|
||||||
|
Entity oldEntity = entities.put(entityId, currentParsedEntity);
|
||||||
if(parseEntityInfo && currentParsedEntityInfo != null){
|
if(parseEntityInfo && currentParsedEntityInfo != null){
|
||||||
entityInfo.put(currentParsedEntity.getId(), currentParsedEntityInfo);
|
entityInfo.put(entityId, currentParsedEntityInfo);
|
||||||
}
|
}
|
||||||
if(!supressWarnings && oldEntity!= null){
|
if(!supressWarnings && oldEntity!= null){
|
||||||
throw new UnsupportedOperationException("Entity with id=" + oldEntity.getId() +" is duplicated in osm map"); //$NON-NLS-1$ //$NON-NLS-2$
|
throw new UnsupportedOperationException("Entity with id=" + oldEntity.getId() +" is duplicated in osm map"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
@ -263,11 +275,11 @@ public class OsmBaseStorage extends DefaultHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Long, EntityInfo> getRegisteredEntityInfo() {
|
public Map<EntityId, EntityInfo> getRegisteredEntityInfo() {
|
||||||
return entityInfo;
|
return entityInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Long, Entity> getRegisteredEntities() {
|
public Map<EntityId, Entity> getRegisteredEntities() {
|
||||||
return entities;
|
return entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.osmand.osm.Entity;
|
||||||
import com.osmand.osm.Node;
|
import com.osmand.osm.Node;
|
||||||
import com.osmand.osm.Relation;
|
import com.osmand.osm.Relation;
|
||||||
import com.osmand.osm.Way;
|
import com.osmand.osm.Way;
|
||||||
|
import com.osmand.osm.Entity.EntityId;
|
||||||
|
|
||||||
public class OsmBoundsFilter implements IOsmStorageFilter {
|
public class OsmBoundsFilter implements IOsmStorageFilter {
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ public class OsmBoundsFilter implements IOsmStorageFilter {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(entity instanceof Relation){
|
if(entity instanceof Relation){
|
||||||
for(Long l : ((Relation) entity).getMemberIds()){
|
for(EntityId l : ((Relation) entity).getMemberIds()){
|
||||||
if(storage.getRegisteredEntities().containsKey(l)){
|
if(storage.getRegisteredEntities().containsKey(l)){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import com.osmand.osm.EntityInfo;
|
||||||
import com.osmand.osm.Node;
|
import com.osmand.osm.Node;
|
||||||
import com.osmand.osm.Relation;
|
import com.osmand.osm.Relation;
|
||||||
import com.osmand.osm.Way;
|
import com.osmand.osm.Way;
|
||||||
|
import com.osmand.osm.Entity.EntityId;
|
||||||
import com.sun.org.apache.xerces.internal.impl.PropertyManager;
|
import com.sun.org.apache.xerces.internal.impl.PropertyManager;
|
||||||
import com.sun.xml.internal.stream.writers.XMLStreamWriterImpl;
|
import com.sun.xml.internal.stream.writers.XMLStreamWriterImpl;
|
||||||
|
|
||||||
|
@ -54,9 +55,9 @@ public class OsmStorageWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void saveStorage(OutputStream output, OsmBaseStorage storage, Collection<Long> interestedObjects, boolean includeLinks) throws XMLStreamException, IOException {
|
public void saveStorage(OutputStream output, OsmBaseStorage storage, Collection<EntityId> interestedObjects, boolean includeLinks) throws XMLStreamException, IOException {
|
||||||
Map<Long, Entity> entities = storage.getRegisteredEntities();
|
Map<EntityId, Entity> entities = storage.getRegisteredEntities();
|
||||||
Map<Long, EntityInfo> entityInfo = storage.getRegisteredEntityInfo();
|
Map<EntityId, EntityInfo> entityInfo = storage.getRegisteredEntityInfo();
|
||||||
PropertyManager propertyManager = new PropertyManager(PropertyManager.CONTEXT_WRITER);
|
PropertyManager propertyManager = new PropertyManager(PropertyManager.CONTEXT_WRITER);
|
||||||
// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
// transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||||
// String indent = "{http://xml.apache.org/xslt}indent-amount";
|
// String indent = "{http://xml.apache.org/xslt}indent-amount";
|
||||||
|
@ -69,16 +70,16 @@ public class OsmStorageWriter {
|
||||||
if(interestedObjects == null){
|
if(interestedObjects == null){
|
||||||
interestedObjects = entities.keySet();
|
interestedObjects = entities.keySet();
|
||||||
}
|
}
|
||||||
Stack<Long> toResolve = new Stack<Long>();
|
Stack<EntityId> toResolve = new Stack<EntityId>();
|
||||||
toResolve.addAll(interestedObjects);
|
toResolve.addAll(interestedObjects);
|
||||||
while(!toResolve.isEmpty()){
|
while(!toResolve.isEmpty()){
|
||||||
Long l = toResolve.pop();
|
EntityId l = toResolve.pop();
|
||||||
if(entities.get(l) instanceof Node){
|
if(entities.get(l) instanceof Node){
|
||||||
nodes.add((Node) entities.get(l));
|
nodes.add((Node) entities.get(l));
|
||||||
} else if(entities.get(l) instanceof Way){
|
} else if(entities.get(l) instanceof Way){
|
||||||
ways.add((Way) entities.get(l));
|
ways.add((Way) entities.get(l));
|
||||||
if(includeLinks){
|
if(includeLinks){
|
||||||
toResolve.addAll(((Way)entities.get(l)).getNodeIds());
|
toResolve.addAll(((Way)entities.get(l)).getEntityIds());
|
||||||
}
|
}
|
||||||
} else if(entities.get(l) instanceof Relation){
|
} else if(entities.get(l) instanceof Relation){
|
||||||
relations.add((Relation) entities.get(l));
|
relations.add((Relation) entities.get(l));
|
||||||
|
@ -120,15 +121,15 @@ public class OsmStorageWriter {
|
||||||
writeStartElement(streamWriter, ELEM_RELATION, INDENT);
|
writeStartElement(streamWriter, ELEM_RELATION, INDENT);
|
||||||
streamWriter.writeAttribute(ATTR_ID, r.getId()+"");
|
streamWriter.writeAttribute(ATTR_ID, r.getId()+"");
|
||||||
writeEntityAttributes(streamWriter, r, entityInfo.get(r.getId()));
|
writeEntityAttributes(streamWriter, r, entityInfo.get(r.getId()));
|
||||||
for(Entry<Long, String> e : r.getMembersMap().entrySet()){
|
for(Entry<EntityId, String> e : r.getMembersMap().entrySet()){
|
||||||
writeStartElement(streamWriter, ELEM_MEMBER, INDENT2);
|
writeStartElement(streamWriter, ELEM_MEMBER, INDENT2);
|
||||||
streamWriter.writeAttribute(ATTR_REF, e.getKey()+"");
|
streamWriter.writeAttribute(ATTR_REF, e.getKey().getId()+"");
|
||||||
String s = e.getValue();
|
String s = e.getValue();
|
||||||
if(s == null){
|
if(s == null){
|
||||||
s = "";
|
s = "";
|
||||||
}
|
}
|
||||||
streamWriter.writeAttribute(ATTR_ROLE, s);
|
streamWriter.writeAttribute(ATTR_ROLE, s);
|
||||||
streamWriter.writeAttribute(ATTR_TYPE, getEntityType(entities, e.getKey()));
|
streamWriter.writeAttribute(ATTR_TYPE, e.getKey().getType().toString().toLowerCase());
|
||||||
writeEndElement(streamWriter, INDENT2);
|
writeEndElement(streamWriter, INDENT2);
|
||||||
}
|
}
|
||||||
writeTags(streamWriter, r);
|
writeTags(streamWriter, r);
|
||||||
|
@ -170,18 +171,6 @@ public class OsmStorageWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getEntityType(Map<Long, Entity> entities , Long id){
|
|
||||||
Entity e = entities.get(id);
|
|
||||||
if(e instanceof Way){
|
|
||||||
return "way";
|
|
||||||
} else if(e instanceof Relation){
|
|
||||||
return "relation";
|
|
||||||
}
|
|
||||||
return "node";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean couldBeWrited(MapObject e){
|
public boolean couldBeWrited(MapObject e){
|
||||||
if(!Algoritms.isEmpty(e.getName()) && e.getLocation() != null){
|
if(!Algoritms.isEmpty(e.getName()) && e.getLocation() != null){
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -39,6 +39,8 @@ import com.osmand.osm.MapUtils;
|
||||||
import com.osmand.osm.Node;
|
import com.osmand.osm.Node;
|
||||||
import com.osmand.osm.Relation;
|
import com.osmand.osm.Relation;
|
||||||
import com.osmand.osm.Way;
|
import com.osmand.osm.Way;
|
||||||
|
import com.osmand.osm.Entity.EntityId;
|
||||||
|
import com.osmand.osm.Entity.EntityType;
|
||||||
import com.osmand.osm.OSMSettings.OSMTagKey;
|
import com.osmand.osm.OSMSettings.OSMTagKey;
|
||||||
import com.osmand.osm.io.IOsmStorageFilter;
|
import com.osmand.osm.io.IOsmStorageFilter;
|
||||||
import com.osmand.osm.io.OsmBaseStorage;
|
import com.osmand.osm.io.OsmBaseStorage;
|
||||||
|
@ -351,7 +353,7 @@ public class MinskTransReader {
|
||||||
relation.putTag("type", "route");
|
relation.putTag("type", "route");
|
||||||
relation.putTag("generated", "yes");
|
relation.putTag("generated", "yes");
|
||||||
checkedRoutes.put(s, relation);
|
checkedRoutes.put(s, relation);
|
||||||
storage.getRegisteredEntities().put(relation.getId(), relation);
|
storage.getRegisteredEntities().put(new EntityId(EntityType.RELATION, relation.getId()), relation);
|
||||||
System.out.println("[ADD] Registered new route " + s);
|
System.out.println("[ADD] Registered new route " + s);
|
||||||
}
|
}
|
||||||
Relation relation = checkedRoutes.get(s);
|
Relation relation = checkedRoutes.get(s);
|
||||||
|
@ -372,19 +374,19 @@ public class MinskTransReader {
|
||||||
throw new IllegalArgumentException("Something wrong check " + st.stopId);
|
throw new IllegalArgumentException("Something wrong check " + st.stopId);
|
||||||
}
|
}
|
||||||
node.putTag("generated", "yes");
|
node.putTag("generated", "yes");
|
||||||
storage.getRegisteredEntities().put(node.getId(), node);
|
storage.getRegisteredEntities().put(new EntityId(EntityType.NODE, node.getId()), node);
|
||||||
System.out.println("[ADD] Added new bus_stop : " + node.getId() + " " + st.name + " minsktrans_stop_id " + st.stopId);
|
System.out.println("[ADD] Added new bus_stop : " + node.getId() + " " + st.name + " minsktrans_stop_id " + st.stopId);
|
||||||
correlated.put(stop, node);
|
correlated.put(stop, node);
|
||||||
}
|
}
|
||||||
if (i == 0 || i == r.routeStops.size() - 1) {
|
if (i == 0 || i == r.routeStops.size() - 1) {
|
||||||
if (direct) {
|
if (direct) {
|
||||||
relation.addMember(correlated.get(stop).getId(), "stop");
|
relation.addMember(correlated.get(stop).getId(), EntityType.NODE, "stop");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (direct) {
|
if (direct) {
|
||||||
relation.addMember(correlated.get(stop).getId(), "forward:stop");
|
relation.addMember(correlated.get(stop).getId(), EntityType.NODE, "forward:stop");
|
||||||
} else {
|
} else {
|
||||||
relation.addMember(correlated.get(stop).getId(), "backward:stop");
|
relation.addMember(correlated.get(stop).getId(), EntityType.NODE, "backward:stop");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue