Slightly change multipolygons impl
This commit is contained in:
parent
a7d0e8be6a
commit
8277d39a31
2 changed files with 35 additions and 96 deletions
|
@ -104,34 +104,24 @@ public class Multipolygon {
|
||||||
* @param longitude lon to check
|
* @param longitude lon to check
|
||||||
* @return true if this multipolygon is correct and contains the point
|
* @return true if this multipolygon is correct and contains the point
|
||||||
*/
|
*/
|
||||||
public boolean containsPoint(double latitude, double longitude){
|
public boolean containsPoint(double latitude, double longitude) {
|
||||||
|
boolean outerContain = false;
|
||||||
|
|
||||||
TreeSet<Ring> outers = new TreeSet<Ring>();
|
|
||||||
TreeSet<Ring> inners = new TreeSet<Ring>();
|
|
||||||
|
|
||||||
for (Ring outer : getOuterRings()) {
|
for (Ring outer : getOuterRings()) {
|
||||||
if (outer.containsPoint(latitude, longitude)) {
|
if (outer.containsPoint(latitude, longitude)) {
|
||||||
outers.add(outer);
|
outerContain = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!outerContain) {
|
||||||
for(Ring inner : getInnerRings()) {
|
return false;
|
||||||
|
}
|
||||||
|
for (Ring inner : getInnerRings()) {
|
||||||
if (inner.containsPoint(latitude, longitude)) {
|
if (inner.containsPoint(latitude, longitude)) {
|
||||||
inners.add(inner);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(outers.size() == 0) return false;
|
return true;
|
||||||
if(inners.size() == 0) return true;
|
|
||||||
|
|
||||||
Ring smallestOuter = outers.first();
|
|
||||||
Ring smallestInner = inners.first();
|
|
||||||
|
|
||||||
// if the smallest outer is in the smallest inner, the multiPolygon contains the point
|
|
||||||
|
|
||||||
return smallestOuter.isIn(smallestInner);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,11 +169,8 @@ public class Multipolygon {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public int countOuterPolygons() {
|
public int countOuterPolygons() {
|
||||||
|
|
||||||
groupInRings();
|
groupInRings();
|
||||||
return zeroSizeIfNull(getOuterRings());
|
return zeroSizeIfNull(getOuterRings());
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -285,14 +272,6 @@ public class Multipolygon {
|
||||||
return MapUtils.getWeightCenterForNodes(points);
|
return MapUtils.getWeightCenterForNodes(points);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* check if a cache has been created
|
|
||||||
* @return true if the cache exists
|
|
||||||
*/
|
|
||||||
public boolean hasCache() {
|
|
||||||
return outerRings != null && innerRings != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the cache <br />
|
* Create the cache <br />
|
||||||
* The cache has to be null before it will be created
|
* The cache has to be null before it will be created
|
||||||
|
@ -315,10 +294,10 @@ public class Multipolygon {
|
||||||
|
|
||||||
//make a clone of the inners set
|
//make a clone of the inners set
|
||||||
// this set will be changed through execution of the method
|
// this set will be changed through execution of the method
|
||||||
SortedSet<Ring> inners = new TreeSet<Ring>(getInnerRings());
|
ArrayList<Ring> inners = new ArrayList<Ring>(getInnerRings());
|
||||||
|
|
||||||
// get the set of outer rings in a variable. This set will not be changed
|
// get the set of outer rings in a variable. This set will not be changed
|
||||||
SortedSet<Ring> outers = new TreeSet<Ring>(getOuterRings());
|
ArrayList<Ring> outers = new ArrayList<Ring>(getOuterRings());
|
||||||
ArrayList<Multipolygon> multipolygons = new ArrayList<Multipolygon>();
|
ArrayList<Multipolygon> multipolygons = new ArrayList<Multipolygon>();
|
||||||
|
|
||||||
// loop; start with the smallest outer ring
|
// loop; start with the smallest outer ring
|
||||||
|
@ -329,7 +308,7 @@ public class Multipolygon {
|
||||||
m.addOuterWays(outer.getWays());
|
m.addOuterWays(outer.getWays());
|
||||||
|
|
||||||
// Search the inners inside this outer ring
|
// Search the inners inside this outer ring
|
||||||
SortedSet<Ring> innersInsideOuter = new TreeSet<Ring>();
|
ArrayList<Ring> innersInsideOuter = new ArrayList<Ring>();
|
||||||
for (Ring inner : inners) {
|
for (Ring inner : inners) {
|
||||||
if (inner.isIn(outer)) {
|
if (inner.isIn(outer)) {
|
||||||
innersInsideOuter.add(inner);
|
innersInsideOuter.add(inner);
|
||||||
|
|
|
@ -17,12 +17,12 @@ import net.osmand.osm.Way;
|
||||||
* @author sander
|
* @author sander
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Ring implements Comparable<Ring>{
|
public class Ring {
|
||||||
/**
|
/**
|
||||||
* This is a list of the ways added by the user
|
* This is a list of the ways added by the user
|
||||||
* The order can be changed with methods from this class
|
* The order can be changed with methods from this class
|
||||||
*/
|
*/
|
||||||
private ArrayList<Way> ways;
|
private final ArrayList<Way> ways;
|
||||||
/**
|
/**
|
||||||
* This is the closure of the ways added by the user
|
* This is the closure of the ways added by the user
|
||||||
* So simple two-node ways are added to close the ring
|
* So simple two-node ways are added to close the ring
|
||||||
|
@ -40,17 +40,10 @@ public class Ring implements Comparable<Ring>{
|
||||||
* Construct a Ring with a list of ways
|
* Construct a Ring with a list of ways
|
||||||
* @param ways the ways that make up the Ring
|
* @param ways the ways that make up the Ring
|
||||||
*/
|
*/
|
||||||
public Ring(List<Way> ways) {
|
private Ring(List<Way> ways) {
|
||||||
this.ways = new ArrayList<Way>();
|
this.ways = new ArrayList<Way>(ways);
|
||||||
this.ways.addAll(ways);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct an empty Ring
|
|
||||||
*/
|
|
||||||
public Ring() {
|
|
||||||
this.ways = new ArrayList<Way>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the ways added to the Ring.
|
* Get the ways added to the Ring.
|
||||||
|
@ -61,19 +54,6 @@ public class Ring implements Comparable<Ring>{
|
||||||
public List<Way> getWays() {
|
public List<Way> getWays() {
|
||||||
return ways;
|
return ways;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a way to the Ring
|
|
||||||
* @param w the way to add
|
|
||||||
*/
|
|
||||||
public void addWay(Way w) {
|
|
||||||
// Reset the cache
|
|
||||||
closedWays = null;
|
|
||||||
closedBorder = null;
|
|
||||||
// Add the way
|
|
||||||
ways.add(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the closed ways that make up the Ring
|
* Get the closed ways that make up the Ring
|
||||||
* This method will sort the ways, so it is CPU intensive
|
* This method will sort the ways, so it is CPU intensive
|
||||||
|
@ -178,38 +158,30 @@ public class Ring implements Comparable<Ring>{
|
||||||
closedWays = new ArrayList<Way>();
|
closedWays = new ArrayList<Way>();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ArrayList<ArrayList<Way>> multiLines = createMultiLines(ways);
|
closedWays = new ArrayList<Way>(ways);
|
||||||
|
|
||||||
// TODO try to close rings which consist out of multiple segments.
|
long[] endNodes = getMultiLineEndNodes(ways);
|
||||||
// This is a data fault, but it could be solved a bit by OsmAnd
|
|
||||||
if (multiLines.size() != 1) return;
|
|
||||||
|
|
||||||
ArrayList<Way> multiLine = multiLines.get(0);
|
|
||||||
|
|
||||||
closedWays = multiLine;
|
|
||||||
|
|
||||||
long[] endNodes = getMultiLineEndNodes(multiLine);
|
|
||||||
if (endNodes[0] != endNodes[1]) {
|
if (endNodes[0] != endNodes[1]) {
|
||||||
if(multiLine.get(0).getNodes() == null) {
|
if(ways.get(0).getNodes() == null) {
|
||||||
Way w = new Way(0L);
|
Way w = new Way(0L);
|
||||||
w.addNode(endNodes[0]);
|
w.addNode(endNodes[0]);
|
||||||
w.addNode(endNodes[1]);
|
w.addNode(endNodes[1]);
|
||||||
closedWays.add(w);
|
closedWays.add(w);
|
||||||
} else {
|
} else {
|
||||||
Node n1 = null, n2 = null;
|
Node n1 = null, n2 = null;
|
||||||
if (multiLine.get(0).getFirstNodeId() == endNodes[0]) {
|
if (ways.get(0).getFirstNodeId() == endNodes[0]) {
|
||||||
n1 = multiLine.get(0).getNodes().get(0);
|
n1 = ways.get(0).getNodes().get(0);
|
||||||
} else {
|
} else {
|
||||||
int index = multiLine.get(0).getNodes().size() - 1;
|
int index = ways.get(0).getNodes().size() - 1;
|
||||||
n1 = multiLine.get(0).getNodes().get(index);
|
n1 = ways.get(0).getNodes().get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int lastML = multiLine.size() - 1;
|
int lastML = ways.size() - 1;
|
||||||
if (multiLine.get(lastML).getFirstNodeId() == endNodes[0]) {
|
if (ways.get(lastML).getFirstNodeId() == endNodes[0]) {
|
||||||
n2 = multiLine.get(lastML).getNodes().get(0);
|
n2 = ways.get(lastML).getNodes().get(0);
|
||||||
} else {
|
} else {
|
||||||
int index = multiLine.get(lastML).getNodes().size() - 1;
|
int index = ways.get(lastML).getNodes().size() - 1;
|
||||||
n2 = multiLine.get(lastML).getNodes().get(index);
|
n2 = ways.get(lastML).getNodes().get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Way w = new Way(0L);
|
Way w = new Way(0L);
|
||||||
|
@ -524,18 +496,6 @@ public class Ring implements Comparable<Ring>{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
/**
|
|
||||||
* @return -1 if this Ring is inside r <br />
|
|
||||||
* 1 if r is inside this Ring <br />
|
|
||||||
* 0 otherwise (Rings are next to each other, Rings intersect or Rings are malformed)
|
|
||||||
*/
|
|
||||||
public int compareTo(Ring r) {
|
|
||||||
if (this.isIn(r)) return -1;
|
|
||||||
if (r.isIn(this)) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this Ring is not complete
|
* If this Ring is not complete
|
||||||
* (some ways are not initialized
|
* (some ways are not initialized
|
||||||
|
|
Loading…
Reference in a new issue