Run
This commit is contained in:
parent
ed71b91423
commit
f790c30271
1 changed files with 33 additions and 7 deletions
|
@ -2,7 +2,12 @@ package net.osmand.data;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
@ -29,6 +34,7 @@ public class Multipolygon {
|
||||||
* cache with the ways grouped per Ring
|
* cache with the ways grouped per Ring
|
||||||
*/
|
*/
|
||||||
private List<Ring> innerRings, outerRings;
|
private List<Ring> innerRings, outerRings;
|
||||||
|
private Map<Ring, Set<Ring>> cacheContainedInnerInOuter = new LinkedHashMap<Ring, Set<Ring>>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ways added by the user
|
* ways added by the user
|
||||||
|
@ -113,15 +119,14 @@ public class Multipolygon {
|
||||||
public boolean containsPoint(double latitude, double longitude) {
|
public boolean containsPoint(double latitude, double longitude) {
|
||||||
// fast check
|
// fast check
|
||||||
updateCacheOfRings();
|
updateCacheOfRings();
|
||||||
if(maxLat + 1 < latitude || minLat - 1 > latitude ||
|
if(maxLat + 0.3 < latitude || minLat - 0.3 > latitude ||
|
||||||
maxLon + 1 < longitude || minLon - 1 > longitude) {
|
maxLon + 0.3 < longitude || minLon - 0.3 > longitude) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ring containedInOuter = null;
|
Ring containedInOuter = null;
|
||||||
// use a sortedset to get the smallest outer containing the point
|
// use a sortedset to get the smallest outer containing the point
|
||||||
SortedSet<Ring> outers = new TreeSet<Ring> (getOuterRings());
|
for (Ring outer : outerRings) {
|
||||||
for (Ring outer : outers) {
|
|
||||||
if (outer.containsPoint(latitude, longitude)) {
|
if (outer.containsPoint(latitude, longitude)) {
|
||||||
containedInOuter = outer;
|
containedInOuter = outer;
|
||||||
break;
|
break;
|
||||||
|
@ -133,9 +138,8 @@ public class Multipolygon {
|
||||||
}
|
}
|
||||||
|
|
||||||
//use a sortedSet to get the smallest inner Ring
|
//use a sortedSet to get the smallest inner Ring
|
||||||
SortedSet<Ring> inners = new TreeSet<Ring> (getInnerRings());
|
|
||||||
Ring containedInInner = null;
|
Ring containedInInner = null;
|
||||||
for (Ring inner : inners) {
|
for (Ring inner : innerRings) {
|
||||||
if (inner.containsPoint(latitude, longitude)) {
|
if (inner.containsPoint(latitude, longitude)) {
|
||||||
containedInInner = inner;
|
containedInInner = inner;
|
||||||
break;
|
break;
|
||||||
|
@ -143,9 +147,17 @@ public class Multipolygon {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (containedInInner == null) return true;
|
if (containedInInner == null) return true;
|
||||||
|
if (outerRings.size() == 1) {
|
||||||
|
// return immediately false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// if it is both, in an inner and in an outer, check if the inner is indeed the smallest one
|
// if it is both, in an inner and in an outer, check if the inner is indeed the smallest one
|
||||||
return !containedInInner.isIn(containedInOuter);
|
Set<Ring> s = cacheContainedInnerInOuter.get(containedInInner);
|
||||||
|
if(s == null) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
return !s.contains(containedInOuter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -315,9 +327,23 @@ public class Multipolygon {
|
||||||
minLon = (float) Math.min(minLon, n.getLongitude());
|
minLon = (float) Math.min(minLon, n.getLongitude());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// keep sorted
|
||||||
|
Collections.sort(outerRings);
|
||||||
}
|
}
|
||||||
if (innerRings == null) {
|
if (innerRings == null) {
|
||||||
innerRings = Ring.combineToRings(getInnerWays());
|
innerRings = Ring.combineToRings(getInnerWays());
|
||||||
|
for(Ring inner : innerRings) {
|
||||||
|
HashSet<Ring> outContainingRings = new HashSet<Ring>();
|
||||||
|
for(Ring out : outerRings) {
|
||||||
|
if(inner.isIn(out)) {
|
||||||
|
outContainingRings.add(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cacheContainedInnerInOuter.put(inner, outContainingRings);
|
||||||
|
|
||||||
|
}
|
||||||
|
// keep sorted
|
||||||
|
Collections.sort(innerRings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue