Slightly change multipolygons impl

This commit is contained in:
Victor Shcherb 2012-09-14 23:01:58 +02:00
parent a7d0e8be6a
commit 8277d39a31
2 changed files with 35 additions and 96 deletions

View file

@ -105,33 +105,23 @@ public class Multipolygon {
* @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) {
return false;
}
for (Ring inner : getInnerRings()) { 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);

View file

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