refactor relation members

git-svn-id: https://osmand.googlecode.com/svn/trunk@264 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-06-30 14:33:13 +00:00
parent 29be5c3b16
commit 26eb8107f1
11 changed files with 279 additions and 104 deletions

View file

@ -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) (?)

View 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;
} }

View file

@ -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) {
continue;
}
map.clear(); map.clear();
Collection<Long> ids = e instanceof Way ? ((Way) e).getNodeIds() : ((Relation) e).getMemberIds(); Collection<EntityId> ids = e instanceof Way ? ((Way) e).getEntityIds() : ((Relation) e).getMemberIds();
for (Long i : ids) { for (EntityId i : ids) {
if (!storage.getRegisteredEntities().containsKey(i)) { if (!storage.getRegisteredEntities().containsKey(i)) {
pselect.setLong(1, i); if (i.getType() == EntityType.NODE) {
if (pselect.execute()) { pselectNode.setLong(1, i.getId());
ResultSet rs = pselect.getResultSet(); 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) {
pselectWay.setLong(1, i.getId());
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));
} }
if(storage.getRegisteredEntities().containsKey(i)){ // 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();
}
}
}
if (storage.getRegisteredEntities().containsKey(i)) {
map.put(i, storage.getRegisteredEntities().get(i)); map.put(i, storage.getRegisteredEntities().get(i));
} }
} }
e.initializeLinks(map); 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));
} }
} }
} }

View file

@ -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);
/** /**

View file

@ -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
} }

View file

@ -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));
} }

View file

@ -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);
}
} }
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;

View file

@ -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");
} }
} }