From 2b6dd0e8309a96d0b731e5e4d9876e554bd88707 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Tue, 3 May 2011 00:57:02 +0200 Subject: [PATCH] Fix issue 406. Incorrect boundary algorithm and additional check of indexing multipolygon --- .../src/net/osmand/data/Boundary.java | 35 +++++-------------- .../osmand/data/preparation/IndexCreator.java | 6 ++-- .../preparation/IndexVectorMapCreator.java | 32 +++++++++++++++++ 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/DataExtractionOSM/src/net/osmand/data/Boundary.java b/DataExtractionOSM/src/net/osmand/data/Boundary.java index 7ee0b6428b..42789936a2 100644 --- a/DataExtractionOSM/src/net/osmand/data/Boundary.java +++ b/DataExtractionOSM/src/net/osmand/data/Boundary.java @@ -15,7 +15,7 @@ public class Boundary { private String adminLevel; - // ? ready rings + // not necessary ready rings private List outerWays = new ArrayList(); private List innerWays = new ArrayList(); @@ -44,6 +44,7 @@ public class Boundary { return intersections % 2 == 1; } + // Try to intersect with ray from left to right private boolean ray_intersect(Node node, Node node2, double latitude, double longitude) { // a node below Node a = node.getLatitude() < node2.getLatitude() ? node : node2; @@ -60,19 +61,14 @@ public class Boundary { } else if(longitude < Math.min(a.getLongitude(), b.getLongitude())){ return false; } else { - double mR; - if(a.getLongitude() != b.getLongitude()){ - mR = (b.getLatitude() - a.getLatitude()) / (b.getLongitude() - a.getLongitude()); - } else { - mR = Double.POSITIVE_INFINITY; + if(a.getLongitude() == b.getLongitude()) { + // the node on the boundary !!! + return true; } - double mB; - if(a.getLongitude() != b.getLongitude()){ - mB = (latitude - a.getLatitude()) / (longitude - a.getLongitude()); - } else { - mB = Double.POSITIVE_INFINITY; - } - if(mB >= mR){ + // that tested on all cases (left/right) + double mR = (b.getLatitude() - a.getLatitude()) / (b.getLongitude() - a.getLongitude()); + double mB = (latitude - a.getLatitude()) / (longitude - a.getLongitude()); + if(mB <= mR){ return true; } else { return false; @@ -81,19 +77,6 @@ public class Boundary { } } - public void initializeWay(Way w) { - for (int i = 0; i < outerWays.size(); i++) { - if (outerWays.get(i).getId() == w.getId()) { - outerWays.set(i, w); - } - } - for (int i = 0; i < innerWays.size(); i++) { - if (innerWays.get(i).getId() == w.getId()) { - innerWays.set(i, w); - } - } - } - public LatLon getCenterPoint(){ List points = new ArrayList(); for(Way w : outerWays){ diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java index 81484d9d48..43a8c884d9 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java @@ -596,10 +596,10 @@ public class IndexCreator { creator.recreateOnlyBinaryFile = false; creator.deleteDatabaseIndexes = true; -// creator.generateIndexes(new File("/home/victor/projects/OsmAnd/download/384/spain.osm.pbf"), -// new ConsoleProgressImplementation(1), null, MapZooms.getDefault(), null); - creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/osm-maps/minsk_around.osm"), + creator.generateIndexes(new File("/home/victor/projects/OsmAnd/download/406/map.osm"), new ConsoleProgressImplementation(1), null, MapZooms.getDefault(), null); +// creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/osm-maps/minsk_around.osm"), +// new ConsoleProgressImplementation(1), null, MapZooms.getDefault(), null); diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java index ec1e9e85e3..02a157f7cc 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexVectorMapCreator.java @@ -12,6 +12,7 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; @@ -21,6 +22,7 @@ import java.util.Set; import net.osmand.Algoritms; import net.osmand.IProgress; import net.osmand.binary.BinaryMapIndexWriter; +import net.osmand.data.Boundary; import net.osmand.data.MapAlgorithms; import net.osmand.osm.Entity; import net.osmand.osm.LatLon; @@ -130,6 +132,13 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator { } } } + + Node nodeOut = checkOuterWaysEncloseInnerWays(completedRings, entities); + if(nodeOut != null){ + log.warn("Map bug: Multipoligon contains 'inner' way point outside of 'outer' border.\n" + //$NON-NLS-1$ + "Multipolygon id : " + e.getId() + ", inner node out id : " + nodeOut.getId()); //$NON-NLS-1$ + return; + } for (List l : completedRings) { boolean innerType = "inner".equals(entities.get(l.get(0))); //$NON-NLS-1$ @@ -157,6 +166,29 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator { + private Node checkOuterWaysEncloseInnerWays(List> completedRings, Map entities) { + List innerWays = new ArrayList(); + Boundary outerBoundary = new Boundary(); + for(List ring : completedRings){ + boolean innerType = "inner".equals(entities.get(ring.get(0))); //$NON-NLS-1$ + if(!innerType){ + outerBoundary.getOuterWays().addAll(ring); + } else { + innerWays.addAll(ring); + } + } + + for(Way innerWay : innerWays){ + for(Node node : innerWay.getNodes()){ + if(!outerBoundary.containsPoint(node.getLatitude(), node.getLongitude())){ + return node; + } + } + } + return null; + } + + private void indexHighwayRestrictions(Entity e, OsmDbAccessorContext ctx) throws SQLException { if (e instanceof Relation && "restriction".equals(e.getTag(OSMTagKey.TYPE))) { //$NON-NLS-1$ String val = e.getTag("restriction"); //$NON-NLS-1$