Fix issue 406. Incorrect boundary algorithm and additional check of indexing multipolygon

This commit is contained in:
Victor Shcherb 2011-05-03 00:57:02 +02:00
parent c3f2194237
commit 2b6dd0e830
3 changed files with 44 additions and 29 deletions

View file

@ -15,7 +15,7 @@ public class Boundary {
private String adminLevel;
// ? ready rings
// not necessary ready rings
private List<Way> outerWays = new ArrayList<Way>();
private List<Way> innerWays = new ArrayList<Way>();
@ -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<Node> points = new ArrayList<Node>();
for(Way w : outerWays){

View file

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

View file

@ -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<Way> 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<List<Way>> completedRings, Map<Entity, String> entities) {
List<Way> innerWays = new ArrayList<Way>();
Boundary outerBoundary = new Boundary();
for(List<Way> 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$