Fix issue 406. Incorrect boundary algorithm and additional check of indexing multipolygon
This commit is contained in:
parent
c3f2194237
commit
2b6dd0e830
3 changed files with 44 additions and 29 deletions
|
@ -15,7 +15,7 @@ public class Boundary {
|
||||||
private String adminLevel;
|
private String adminLevel;
|
||||||
|
|
||||||
|
|
||||||
// ? ready rings
|
// not necessary ready rings
|
||||||
private List<Way> outerWays = new ArrayList<Way>();
|
private List<Way> outerWays = new ArrayList<Way>();
|
||||||
private List<Way> innerWays = new ArrayList<Way>();
|
private List<Way> innerWays = new ArrayList<Way>();
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ public class Boundary {
|
||||||
return intersections % 2 == 1;
|
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) {
|
private boolean ray_intersect(Node node, Node node2, double latitude, double longitude) {
|
||||||
// a node below
|
// a node below
|
||||||
Node a = node.getLatitude() < node2.getLatitude() ? node : node2;
|
Node a = node.getLatitude() < node2.getLatitude() ? node : node2;
|
||||||
|
@ -60,19 +61,14 @@ public class Boundary {
|
||||||
} else if(longitude < Math.min(a.getLongitude(), b.getLongitude())){
|
} else if(longitude < Math.min(a.getLongitude(), b.getLongitude())){
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
double mR;
|
if(a.getLongitude() == b.getLongitude()) {
|
||||||
if(a.getLongitude() != b.getLongitude()){
|
// the node on the boundary !!!
|
||||||
mR = (b.getLatitude() - a.getLatitude()) / (b.getLongitude() - a.getLongitude());
|
return true;
|
||||||
} else {
|
|
||||||
mR = Double.POSITIVE_INFINITY;
|
|
||||||
}
|
}
|
||||||
double mB;
|
// that tested on all cases (left/right)
|
||||||
if(a.getLongitude() != b.getLongitude()){
|
double mR = (b.getLatitude() - a.getLatitude()) / (b.getLongitude() - a.getLongitude());
|
||||||
mB = (latitude - a.getLatitude()) / (longitude - a.getLongitude());
|
double mB = (latitude - a.getLatitude()) / (longitude - a.getLongitude());
|
||||||
} else {
|
if(mB <= mR){
|
||||||
mB = Double.POSITIVE_INFINITY;
|
|
||||||
}
|
|
||||||
if(mB >= mR){
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
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(){
|
public LatLon getCenterPoint(){
|
||||||
List<Node> points = new ArrayList<Node>();
|
List<Node> points = new ArrayList<Node>();
|
||||||
for(Way w : outerWays){
|
for(Way w : outerWays){
|
||||||
|
|
|
@ -596,10 +596,10 @@ public class IndexCreator {
|
||||||
creator.recreateOnlyBinaryFile = false;
|
creator.recreateOnlyBinaryFile = false;
|
||||||
creator.deleteDatabaseIndexes = true;
|
creator.deleteDatabaseIndexes = true;
|
||||||
|
|
||||||
// creator.generateIndexes(new File("/home/victor/projects/OsmAnd/download/384/spain.osm.pbf"),
|
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);
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.sql.Statement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -21,6 +22,7 @@ import java.util.Set;
|
||||||
import net.osmand.Algoritms;
|
import net.osmand.Algoritms;
|
||||||
import net.osmand.IProgress;
|
import net.osmand.IProgress;
|
||||||
import net.osmand.binary.BinaryMapIndexWriter;
|
import net.osmand.binary.BinaryMapIndexWriter;
|
||||||
|
import net.osmand.data.Boundary;
|
||||||
import net.osmand.data.MapAlgorithms;
|
import net.osmand.data.MapAlgorithms;
|
||||||
import net.osmand.osm.Entity;
|
import net.osmand.osm.Entity;
|
||||||
import net.osmand.osm.LatLon;
|
import net.osmand.osm.LatLon;
|
||||||
|
@ -131,6 +133,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) {
|
for (List<Way> l : completedRings) {
|
||||||
boolean innerType = "inner".equals(entities.get(l.get(0))); //$NON-NLS-1$
|
boolean innerType = "inner".equals(entities.get(l.get(0))); //$NON-NLS-1$
|
||||||
boolean clockwise = MapSwingAlgorithms.isClockwiseWay(l);
|
boolean clockwise = MapSwingAlgorithms.isClockwiseWay(l);
|
||||||
|
@ -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 {
|
private void indexHighwayRestrictions(Entity e, OsmDbAccessorContext ctx) throws SQLException {
|
||||||
if (e instanceof Relation && "restriction".equals(e.getTag(OSMTagKey.TYPE))) { //$NON-NLS-1$
|
if (e instanceof Relation && "restriction".equals(e.getTag(OSMTagKey.TYPE))) { //$NON-NLS-1$
|
||||||
String val = e.getTag("restriction"); //$NON-NLS-1$
|
String val = e.getTag("restriction"); //$NON-NLS-1$
|
||||||
|
|
Loading…
Reference in a new issue