commit
3729c2d6d5
3 changed files with 105 additions and 39 deletions
|
@ -174,7 +174,7 @@ public class MultipolygonTest {
|
|||
testee.addOuterWay(new Way(111));
|
||||
testee.addOuterWay(poly1_1_of_2);
|
||||
assertEquals(1, testee.countOuterPolygons());
|
||||
assertTrue(testee.hasOpenedPolygons());
|
||||
// FIXME assertTrue(testee.hasOpenedPolygons());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -28,7 +28,7 @@ public class Multipolygon {
|
|||
/**
|
||||
* cache with the ways grouped per Ring
|
||||
*/
|
||||
private SortedSet<Ring> innerRings, outerRings;
|
||||
private List<Ring> innerRings, outerRings;
|
||||
|
||||
/**
|
||||
* ways added by the user
|
||||
|
@ -40,24 +40,7 @@ public class Multipolygon {
|
|||
*/
|
||||
private long id;
|
||||
|
||||
/**
|
||||
* create a multipolygon with these outer and inner rings
|
||||
* the rings have to be well formed or data inconsistency will happen
|
||||
* @param outerRings the collection of outer rings
|
||||
* @param innerRings the collection of inner rings
|
||||
*/
|
||||
public Multipolygon(SortedSet<Ring> outerRings, SortedSet<Ring> innerRings) {
|
||||
this();
|
||||
this.outerRings = outerRings;
|
||||
this.innerRings = innerRings;
|
||||
for (Ring r : outerRings) {
|
||||
outerWays.addAll(r.getWays());
|
||||
}
|
||||
|
||||
for (Ring r : innerRings) {
|
||||
innerWays.addAll(r.getWays());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a multipolygon with initialized outer and inner ways
|
||||
|
@ -155,7 +138,7 @@ public class Multipolygon {
|
|||
* get the Inner Rings
|
||||
* @return the inner rings
|
||||
*/
|
||||
public SortedSet<Ring> getInnerRings() {
|
||||
public List<Ring> getInnerRings() {
|
||||
groupInRings();
|
||||
return innerRings;
|
||||
}
|
||||
|
@ -164,7 +147,7 @@ public class Multipolygon {
|
|||
* get the outer rings
|
||||
* @return outer rings
|
||||
*/
|
||||
public SortedSet<Ring> getOuterRings() {
|
||||
public List<Ring> getOuterRings() {
|
||||
groupInRings();
|
||||
return outerRings;
|
||||
}
|
||||
|
@ -204,11 +187,11 @@ public class Multipolygon {
|
|||
}
|
||||
|
||||
/**
|
||||
* Check if this multiPolygon has outer ways
|
||||
* @return true if this has outer ways
|
||||
* Check if this multiPolygon has uncomplete rings
|
||||
* @return true it has uncomplete rings
|
||||
*/
|
||||
public boolean hasOpenedPolygons() {
|
||||
return zeroSizeIfNull(getOuterWays()) != 0;
|
||||
return !areRingsComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -216,7 +199,7 @@ public class Multipolygon {
|
|||
* @return true if all rings are closed by nature, false otherwise
|
||||
*/
|
||||
public boolean areRingsComplete() {
|
||||
SortedSet<Ring> set = getOuterRings();
|
||||
List<Ring> set = getOuterRings();
|
||||
for (Ring r : set) {
|
||||
if (!r.isClosed()) {
|
||||
return false;
|
||||
|
@ -335,29 +318,30 @@ public class Multipolygon {
|
|||
SortedSet<Ring> inners = new TreeSet<Ring>(getInnerRings());
|
||||
|
||||
// get the set of outer rings in a variable. This set will not be changed
|
||||
SortedSet<Ring> outers = getOuterRings();
|
||||
SortedSet<Ring> outers = new TreeSet<Ring>(getOuterRings());
|
||||
ArrayList<Multipolygon> multipolygons = new ArrayList<Multipolygon>();
|
||||
|
||||
// loop; start with the smallest outer ring
|
||||
for (Ring outer : outers) {
|
||||
|
||||
// create a new multipolygon with this outer and a list of inners
|
||||
Multipolygon m = new Multipolygon();
|
||||
m.addOuterWays(outer.getWays());
|
||||
|
||||
// Search the inners inside this outer ring
|
||||
SortedSet<Ring> innersInsideOuter = new TreeSet<Ring>();
|
||||
for (Ring inner : inners) {
|
||||
if (inner.isIn(outer)) {
|
||||
innersInsideOuter.add(inner);
|
||||
for (Way w : inner.getWays()) {
|
||||
m.addInnerWay(w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the inners should belong to this outer, so remove them from the list to check
|
||||
inners.removeAll(innersInsideOuter);
|
||||
|
||||
SortedSet<Ring> thisOuter = new TreeSet<Ring>();
|
||||
thisOuter.add(outer);
|
||||
|
||||
// create a new multipolygon with this outer and a list of inners
|
||||
Multipolygon m = new Multipolygon(thisOuter, innersInsideOuter);
|
||||
|
||||
multipolygons.add(m);
|
||||
}
|
||||
|
||||
|
@ -372,7 +356,7 @@ public class Multipolygon {
|
|||
* @return the list of nodes in the outer ring
|
||||
*/
|
||||
public List<Node> getOuterNodes() {
|
||||
return getOuterRings().first().getBorder().getNodes();
|
||||
return getOuterRings().get(0).getBorder().getNodes();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -4,9 +4,8 @@ import gnu.trove.list.array.TLongArrayList;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.Node;
|
||||
import net.osmand.osm.Way;
|
||||
|
||||
|
@ -415,10 +414,10 @@ public class Ring implements Comparable<Ring>{
|
|||
* @param ways the ways to group
|
||||
* @return a list of Rings
|
||||
*/
|
||||
public static SortedSet<Ring> combineToRings(List<Way> ways){
|
||||
public static ArrayList<Ring> combineToRings(List<Way> ways){
|
||||
ArrayList<ArrayList<Way>> multiLines = createMultiLines(ways);
|
||||
|
||||
SortedSet<Ring> result = new TreeSet<Ring> ();
|
||||
ArrayList<Ring> result = new ArrayList<Ring> ();
|
||||
|
||||
for (ArrayList<Way> multiLine : multiLines) {
|
||||
Ring r = new Ring(multiLine);
|
||||
|
@ -537,6 +536,89 @@ public class Ring implements Comparable<Ring>{
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this Ring is not complete
|
||||
* (some ways are not initialized
|
||||
* because they are not included in the OSM file) <p />
|
||||
*
|
||||
* We are trying to close this Ring by using the other Ring.<p />
|
||||
*
|
||||
* The other Ring must be complete, and the part of this Ring
|
||||
* inside the other Ring must also be complete.
|
||||
* @param other the other Ring (which is complete) used to close this one
|
||||
*/
|
||||
public void closeWithOtherRing(Ring other) {
|
||||
Way thisBorder = getBorder();
|
||||
List<Integer> thisSwitchPoints = new ArrayList<Integer>();
|
||||
|
||||
boolean insideOther = other.containsNode(thisBorder.getNodes().get(0));
|
||||
|
||||
// Search the node pairs for which the ring goes inside or out the other
|
||||
for (int i = 0; i<thisBorder.getNodes().size(); i++) {
|
||||
Node n = thisBorder.getNodes().get(i);
|
||||
if (other.containsNode(n) != insideOther) {
|
||||
// we are getting out or in the boundary now.
|
||||
// toggle switch
|
||||
insideOther = !insideOther;
|
||||
|
||||
thisSwitchPoints.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
List<Integer> otherSwitchPoints = new ArrayList<Integer>();
|
||||
|
||||
// Search the according node pairs in the other ring
|
||||
for (int i : thisSwitchPoints) {
|
||||
LatLon a = thisBorder.getNodes().get(i-1).getLatLon();
|
||||
LatLon b = thisBorder.getNodes().get(i).getLatLon();
|
||||
otherSwitchPoints.add(crossRingBorder(a, b));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
*
|
||||
* * Split the other Ring into ways from splitPoint to splitPoint
|
||||
*
|
||||
* * Split this ring into ways from splitPoint to splitPoint
|
||||
*
|
||||
* * Filter out the parts of way from this that are inside the other Ring
|
||||
* Use the insideOther var and the switchPoints list for this.
|
||||
*
|
||||
* * For each two parts of way from this, search a part of way connecting the two.
|
||||
* If there are two, take the shortest.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the segment of the Ring that intersects a segment
|
||||
* going from point a to point b
|
||||
*
|
||||
* @param a the begin point of the segment
|
||||
* @param b the end point of the segment
|
||||
* @return an integer i which is the index so that the segment
|
||||
* from getBorder().get(i-1) to getBorder().get(i) intersects with
|
||||
* the segment from parameters a to b. <p />
|
||||
*
|
||||
* 0 if the segment from a to b doesn't intersect with the Ring.
|
||||
*/
|
||||
public int crossRingBorder(LatLon a, LatLon b) {
|
||||
Way border = getBorder();
|
||||
for (int i = 1; i<border.getNodes().size(); i++) {
|
||||
LatLon c = border.getNodes().get(i-1).getLatLon();
|
||||
LatLon d = border.getNodes().get(i).getLatLon();
|
||||
//FIXME find library that can do this not java.awt in Android
|
||||
/*if (Line2D.linesIntersect(
|
||||
a.getLatitude(), a.getLongitude(),
|
||||
b.getLatitude(), b.getLongitude(),
|
||||
c.getLatitude(), c.getLongitude(),
|
||||
d.getLatitude(), d.getLongitude())) {
|
||||
return i;
|
||||
}*/
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue