Changeset 23819 in osm for applications/editors/josm/plugins/multipoly
- Timestamp:
- 2010-10-25T09:02:22+02:00 (14 years ago)
- Location:
- applications/editors/josm/plugins/multipoly/src/multipoly
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/multipoly/src/multipoly/GeometryFunctions.java
r23771 r23819 15 15 */ 16 16 public class GeometryFunctions { 17 public enum Intersection {INSIDE, OUTSIDE, CROSSING, EQUAL} 18 19 /** 20 * Finds the intersection of two lines of inifinite length. 21 * @return EastNorth null if no intersection was found, the coordinates of the intersection otherwise 22 */ 23 public static EastNorth getLineLineIntersection(EastNorth p1, EastNorth p2, EastNorth p3, EastNorth p4) { 24 25 // Convert line from (point, point) form to ax+by=c 26 double a1 = p2.getY() - p1.getY(); 27 double b1 = p1.getX() - p2.getX(); 28 double c1 = p2.getX() * p1.getY() - p1.getX() * p2.getY(); 29 30 double a2 = p4.getY() - p3.getY(); 31 double b2 = p3.getX() - p4.getX(); 32 double c2 = p4.getX() * p3.getY() - p3.getX() * p4.getY(); 33 34 // Solve the equations 35 double det = a1 * b2 - a2 * b1; 36 if (det == 0) 37 return null; // Lines are parallel 38 39 return new EastNorth((b1 * c2 - b2 * c1) / det, (a2 * c1 - a1 * c2) / det); 40 } 41 42 public static boolean segmentsParralel(EastNorth p1, EastNorth p2, EastNorth p3, EastNorth p4) { 43 44 // Convert line from (point, point) form to ax+by=c 45 double a1 = p2.getY() - p1.getY(); 46 double b1 = p1.getX() - p2.getX(); 47 48 double a2 = p4.getY() - p3.getY(); 49 double b2 = p3.getX() - p4.getX(); 50 51 // Solve the equations 52 double det = a1 * b2 - a2 * b1; 53 return Math.abs(det) < 1e-13; 54 } 55 56 /** 57 * Calcualtes closest point to a line segment. 58 * @param segmentP1 59 * @param segmentP2 60 * @param point 61 * @return segmentP1 if it is the closest point, segmentP2 if it is the closest point, 62 * a new point if closest point is between segmentP1 and segmentP2. 63 */ 64 public static EastNorth closestPointToSegment(EastNorth segmentP1, EastNorth segmentP2, EastNorth point) { 65 66 double ldx = segmentP2.getX() - segmentP1.getX(); 67 double ldy = segmentP2.getY() - segmentP1.getY(); 68 69 if (ldx == 0 && ldy == 0) //segment zero length 70 return segmentP1; 71 72 double pdx = point.getX() - segmentP1.getX(); 73 double pdy = point.getY() - segmentP1.getY(); 74 75 double offset = (pdx * ldx + pdy * ldy) / (ldx * ldx + ldy * ldy); 76 77 if (offset <= 0) 78 return segmentP1; 79 else if (offset >= 1) 80 return segmentP2; 81 else 82 return new EastNorth(segmentP1.getX() + ldx * offset, segmentP1.getY() + ldy * offset); 83 84 } 85 86 /** 87 * This method tests if secondNode is clockwise to first node. 88 * @param commonNode starting point for both vectors 89 * @param firstNode first vector end node 90 * @param secondNode second vector end node 91 * @return true if first vector is clockwise before second vector. 92 */ 93 94 public static boolean angleIsClockwise(EastNorth commonNode, EastNorth firstNode, EastNorth secondNode) { 95 double dy1 = (firstNode.getY() - commonNode.getY()); 96 double dy2 = (secondNode.getY() - commonNode.getY()); 97 double dx1 = (firstNode.getX() - commonNode.getX()); 98 double dx2 = (secondNode.getX() - commonNode.getX()); 99 100 return dy1 * dx2 - dx1 * dy2 > 0; 101 } 102 103 104 /** 105 * Tests if two polygons instersect. 106 * @param first 107 * @param second 108 * @return Inside if second is inside first, Outside, if second is outside first, Crossing, if they cross. 109 */ 110 public static Intersection polygonIntersection(List<Node> outside, List<Node> inside) { 111 Set<Node> outsideNodes = new HashSet<Node>(outside); 112 113 boolean nodesInside = false; 114 boolean nodesOutside = false; 115 116 for (Node insideNode : inside) { 117 if (!outsideNodes.contains(insideNode)) { 118 if (nodeInsidePolygon(insideNode, outside)) { 119 nodesInside = true; 120 } 121 else { 122 nodesOutside = true; 123 } 124 } 125 } 126 127 if (nodesInside) { 128 if (nodesOutside){ 129 return Intersection.CROSSING; 130 } 131 else { 132 return Intersection.INSIDE; 133 } 134 } 135 else { 136 if (nodesOutside){ 137 return Intersection.OUTSIDE; 138 } 139 else { 140 return Intersection.EQUAL; 141 } 142 } 143 } 144 145 /** 146 * Tests if point is inside a polygon. The polygon can be self-intersecting. In such case the contains function works in xor-like manner. 147 * @param polygonNodes list of nodes from polygon path. 148 * @param point the point to test 149 * @return true if the point is inside polygon. 150 */ 151 public static boolean nodeInsidePolygon(Node point, List<Node> polygonNodes) { 152 if (polygonNodes.size() < 2) 153 return false; 154 155 boolean inside = false; 156 Node p1, p2; 157 158 //iterate each side of the polygon, start with the last segment 159 Node oldPoint = polygonNodes.get(polygonNodes.size() - 1); 160 161 for (Node newPoint : polygonNodes) { 162 //skip duplicate points 163 if (newPoint.equals(oldPoint)) { 164 continue; 165 } 166 167 //order points so p1.lat <= p2.lat; 168 if (newPoint.getEastNorth().getY() > oldPoint.getEastNorth().getY()) { 169 p1 = oldPoint; 170 p2 = newPoint; 171 } else { 172 p1 = newPoint; 173 p2 = oldPoint; 174 } 175 176 //test if the line is crossed and if so invert the inside flag. 177 if ((newPoint.getEastNorth().getY() < point.getEastNorth().getY()) == (point.getEastNorth().getY() <= oldPoint.getEastNorth().getY()) 178 && (point.getEastNorth().getX() - p1.getEastNorth().getX()) * (p2.getEastNorth().getY() - p1.getEastNorth().getY()) 179 < (p2.getEastNorth().getX() - p1.getEastNorth().getX()) * (point.getEastNorth().getY() - p1.getEastNorth().getY())) 180 { 181 inside = !inside; 182 } 183 184 oldPoint = newPoint; 185 } 186 187 return inside; 188 } 17 public enum PolygonIntersection {FIRST_INSIDE_SECOND, SECOND_INSIDE_FIRST, OUTSIDE, CROSSING} 18 19 /** 20 * Finds the intersection of two lines of infinite length. 21 * @return EastNorth null if no intersection was found, the coordinates of the intersection otherwise 22 */ 23 public static EastNorth getLineLineIntersection(EastNorth p1, EastNorth p2, EastNorth p3, EastNorth p4) { 24 25 // Convert line from (point, point) form to ax+by=c 26 double a1 = p2.getY() - p1.getY(); 27 double b1 = p1.getX() - p2.getX(); 28 double c1 = p2.getX() * p1.getY() - p1.getX() * p2.getY(); 29 30 double a2 = p4.getY() - p3.getY(); 31 double b2 = p3.getX() - p4.getX(); 32 double c2 = p4.getX() * p3.getY() - p3.getX() * p4.getY(); 33 34 // Solve the equations 35 double det = a1 * b2 - a2 * b1; 36 if (det == 0) 37 return null; // Lines are parallel 38 39 return new EastNorth((b1 * c2 - b2 * c1) / det, (a2 * c1 - a1 * c2) / det); 40 } 41 42 public static boolean segmentsParralel(EastNorth p1, EastNorth p2, EastNorth p3, EastNorth p4) { 43 44 // Convert line from (point, point) form to ax+by=c 45 double a1 = p2.getY() - p1.getY(); 46 double b1 = p1.getX() - p2.getX(); 47 48 double a2 = p4.getY() - p3.getY(); 49 double b2 = p3.getX() - p4.getX(); 50 51 // Solve the equations 52 double det = a1 * b2 - a2 * b1; 53 return Math.abs(det) < 1e-13; 54 } 55 56 /** 57 * Calculates closest point to a line segment. 58 * @param segmentP1 59 * @param segmentP2 60 * @param point 61 * @return segmentP1 if it is the closest point, segmentP2 if it is the closest point, 62 * a new point if closest point is between segmentP1 and segmentP2. 63 */ 64 public static EastNorth closestPointToSegment(EastNorth segmentP1, EastNorth segmentP2, EastNorth point) { 65 66 double ldx = segmentP2.getX() - segmentP1.getX(); 67 double ldy = segmentP2.getY() - segmentP1.getY(); 68 69 if (ldx == 0 && ldy == 0) //segment zero length 70 return segmentP1; 71 72 double pdx = point.getX() - segmentP1.getX(); 73 double pdy = point.getY() - segmentP1.getY(); 74 75 double offset = (pdx * ldx + pdy * ldy) / (ldx * ldx + ldy * ldy); 76 77 if (offset <= 0) 78 return segmentP1; 79 else if (offset >= 1) 80 return segmentP2; 81 else 82 return new EastNorth(segmentP1.getX() + ldx * offset, segmentP1.getY() + ldy * offset); 83 84 } 85 86 /** 87 * This method tests if secondNode is clockwise to first node. 88 * @param commonNode starting point for both vectors 89 * @param firstNode first vector end node 90 * @param secondNode second vector end node 91 * @return true if first vector is clockwise before second vector. 92 */ 93 94 public static boolean angleIsClockwise(EastNorth commonNode, EastNorth firstNode, EastNorth secondNode) { 95 double dy1 = (firstNode.getY() - commonNode.getY()); 96 double dy2 = (secondNode.getY() - commonNode.getY()); 97 double dx1 = (firstNode.getX() - commonNode.getX()); 98 double dx2 = (secondNode.getX() - commonNode.getX()); 99 100 return dy1 * dx2 - dx1 * dy2 > 0; 101 } 102 103 104 /** 105 * Tests if two polygons intersect. 106 * @param first 107 * @param second 108 * @return intersection kind 109 * TODO: test segments, not only points 110 * TODO: is O(N*M), should use sweep for better performance. 111 */ 112 public static PolygonIntersection polygonIntersection(List<Node> first, List<Node> second) { 113 Set<Node> firstSet = new HashSet<Node>(first); 114 Set<Node> secondSet = new HashSet<Node>(second); 115 116 int nodesInsideSecond = 0; 117 int nodesOutsideSecond = 0; 118 int nodesInsideFirst = 0; 119 int nodesOutsideFirst = 0; 120 121 for (Node insideNode : first) { 122 if (secondSet.contains(insideNode)) { 123 continue; 124 //ignore touching nodes. 125 } 126 127 if (nodeInsidePolygon(insideNode, second)) { 128 nodesInsideSecond ++; 129 } 130 else { 131 nodesOutsideSecond ++; 132 } 133 } 134 135 for (Node insideNode : second) { 136 if (firstSet.contains(insideNode)) { 137 continue; 138 //ignore touching nodes. 139 } 140 141 if (nodeInsidePolygon(insideNode, first)) { 142 nodesInsideFirst ++; 143 } 144 else { 145 nodesOutsideFirst ++; 146 } 147 } 148 149 if (nodesInsideFirst == 0) { 150 if (nodesInsideSecond == 0){ 151 if (nodesOutsideFirst + nodesInsideSecond > 0) { 152 return PolygonIntersection.OUTSIDE; 153 } 154 else { 155 //all nodes common 156 return PolygonIntersection.CROSSING; 157 } 158 } 159 else 160 { 161 return PolygonIntersection.FIRST_INSIDE_SECOND; 162 } 163 } 164 else 165 { 166 if (nodesInsideSecond == 0) { 167 return PolygonIntersection.SECOND_INSIDE_FIRST; 168 } 169 else 170 { 171 return PolygonIntersection.CROSSING; 172 } 173 } 174 } 175 176 /** 177 * Tests if point is inside a polygon. The polygon can be self-intersecting. In such case the contains function works in xor-like manner. 178 * @param polygonNodes list of nodes from polygon path. 179 * @param point the point to test 180 * @return true if the point is inside polygon. 181 */ 182 public static boolean nodeInsidePolygon(Node point, List<Node> polygonNodes) { 183 if (polygonNodes.size() < 2) 184 return false; 185 186 boolean inside = false; 187 Node p1, p2; 188 189 //iterate each side of the polygon, start with the last segment 190 Node oldPoint = polygonNodes.get(polygonNodes.size() - 1); 191 192 for (Node newPoint : polygonNodes) { 193 //skip duplicate points 194 if (newPoint.equals(oldPoint)) { 195 continue; 196 } 197 198 //order points so p1.lat <= p2.lat; 199 if (newPoint.getEastNorth().getY() > oldPoint.getEastNorth().getY()) { 200 p1 = oldPoint; 201 p2 = newPoint; 202 } else { 203 p1 = newPoint; 204 p2 = oldPoint; 205 } 206 207 //test if the line is crossed and if so invert the inside flag. 208 if ((newPoint.getEastNorth().getY() < point.getEastNorth().getY()) == (point.getEastNorth().getY() <= oldPoint.getEastNorth().getY()) 209 && (point.getEastNorth().getX() - p1.getEastNorth().getX()) * (p2.getEastNorth().getY() - p1.getEastNorth().getY()) 210 < (p2.getEastNorth().getX() - p1.getEastNorth().getX()) * (point.getEastNorth().getY() - p1.getEastNorth().getY())) 211 { 212 inside = !inside; 213 } 214 215 oldPoint = newPoint; 216 } 217 218 return inside; 219 } 189 220 190 221 -
applications/editors/josm/plugins/multipoly/src/multipoly/Multipolygon.java
r23773 r23819 10 10 import java.util.Set; 11 11 12 import multipoly.GeometryFunctions. Intersection;12 import multipoly.GeometryFunctions.PolygonIntersection; 13 13 14 14 import org.openstreetmap.josm.data.osm.Node; … … 16 16 import org.openstreetmap.josm.tools.MultiMap; 17 17 18 public class Multipolygon { 19 20 /** 21 * Represents one polygon that consists of multiple ways. 18 public class Multipolygon { 19 20 /** 21 * Represents one polygon that consists of multiple ways. 22 22 * @author Viesturs 23 23 * 24 24 */ 25 25 public static class JoinedPolygon { 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 public final int level; //nesting level , even for outer, odd for inner polygons. 81 82 83 84 85 86 87 88 89 90 91 92 26 public final List<Way> ways; 27 public final List<Boolean> reversed; 28 public final List<Node> nodes; 29 30 public JoinedPolygon(List<Way> ways, List<Boolean> reversed) { 31 this.ways = ways; 32 this.reversed = reversed; 33 this.nodes = this.getNodes(); 34 } 35 36 /** 37 * Creates a polygon form single way. 38 * @param way 39 */ 40 public JoinedPolygon(Way way) { 41 this.ways = Collections.singletonList(way); 42 this.reversed = Collections.singletonList(Boolean.FALSE); 43 this.nodes = this.getNodes(); 44 } 45 46 47 /** 48 * Builds a list of nodes for this polygon. First node is not duplicated as last node. 49 * @return 50 */ 51 private List<Node> getNodes() { 52 List<Node> nodes = new ArrayList<Node>(); 53 54 for(int waypos = 0; waypos < this.ways.size(); waypos ++) { 55 Way way = this.ways.get(waypos); 56 boolean reversed = this.reversed.get(waypos).booleanValue(); 57 58 if (!reversed){ 59 for (int pos = 0; pos < way.getNodesCount() - 1; pos++) { 60 nodes.add(way.getNode(pos)); 61 } 62 } 63 else { 64 for (int pos = way.getNodesCount() - 1; pos > 0; pos--) { 65 nodes.add(way.getNode(pos)); 66 } 67 } 68 } 69 70 return nodes; 71 } 72 } 73 74 75 /** 76 * Helper storage class for finding findOuterWays 77 * @author viesturs 78 */ 79 static class PolygonLevel { 80 public final int level; //nesting level , even for outer, odd for inner polygons. 81 public final JoinedPolygon outerWay; 82 83 public List<JoinedPolygon> innerWays; 84 85 public PolygonLevel(JoinedPolygon _pol, int _level) { 86 this.outerWay = _pol; 87 this.level = _level; 88 this.innerWays = new ArrayList<JoinedPolygon>(); 89 } 90 } 91 92 93 93 public List<JoinedPolygon> outerWays; 94 94 public List<JoinedPolygon> innerWays; 95 96 95 96 97 97 public Multipolygon(List<JoinedPolygon> outerWays, List<JoinedPolygon> innerWays){ 98 98 this.outerWays = outerWays; 99 99 this.innerWays = innerWays; 100 100 } 101 101 102 102 public Multipolygon(){ 103 103 this.outerWays = new ArrayList<JoinedPolygon>(0); 104 104 this.innerWays = new ArrayList<JoinedPolygon>(0); 105 105 } 106 106 107 107 /** 108 108 * Splits ways into inner and outer JoinedWays. Sets innerWays and outerWays to the result. … … 111 111 */ 112 112 public String makeFromWays(Collection<Way> ways){ 113 List<JoinedPolygon> joinedWays = new ArrayList<JoinedPolygon>(); 114 113 List<JoinedPolygon> joinedWays = new ArrayList<JoinedPolygon>(); 114 115 115 //collect ways connecting to each node. 116 116 MultiMap<Node, Way> nodesWithConnectedWays = new MultiMap<Node, Way>(); 117 117 Set<Way> usedWays = new HashSet<Way>(); 118 118 119 119 for(Way w: ways) { 120 120 if (w.getNodesCount() < 2) { 121 121 return tr("Cannot add a way with only {0} nodes.", w.getNodesCount()); 122 122 } 123 123 124 124 if (w.isClosed()) { 125 125 //closed way, add as is. … … 133 133 } 134 134 } 135 135 136 136 //process unclosed ways 137 137 for(Way startWay: ways) { … … 139 139 continue; 140 140 } 141 141 142 142 Node startNode = startWay.firstNode(); 143 143 List<Way> collectedWays = new ArrayList<Way>(); … … 145 145 Way curWay = startWay; 146 146 Node prevNode = startNode; 147 147 148 148 //find polygon ways 149 149 while (true) { 150 boolean curWayReverse = prevNode == curWay.lastNode(); 151 Node nextNode = (curWayReverse) ? curWay.firstNode(): curWay.lastNode(); 150 boolean curWayReverse = prevNode == curWay.lastNode(); 151 Node nextNode = (curWayReverse) ? curWay.firstNode(): curWay.lastNode(); 152 152 153 153 //add cur way to the list 154 154 collectedWays.add(curWay); 155 155 collectedWaysReverse.add(Boolean.valueOf(curWayReverse)); 156 156 157 157 if (nextNode == startNode) { 158 158 //way finished 159 159 break; 160 160 } 161 161 162 162 //find next way 163 163 Collection<Way> adjacentWays = nodesWithConnectedWays.get(nextNode); 164 164 165 165 if (adjacentWays.size() != 2) { 166 166 return tr("Each node must connect exactly 2 ways"); 167 167 } 168 168 169 169 Way nextWay = null; 170 170 for(Way way: adjacentWays){ 171 171 if (way != curWay){ 172 nextWay = way; 173 } 174 } 175 172 nextWay = way; 173 } 174 } 175 176 176 //move to the next way 177 curWay = nextWay; 177 curWay = nextWay; 178 178 prevNode = nextNode; 179 179 } 180 181 usedWays.addAll(collectedWays); 182 joinedWays.add(new JoinedPolygon(collectedWays, collectedWaysReverse)); 183 } 184 180 181 usedWays.addAll(collectedWays); 182 joinedWays.add(new JoinedPolygon(collectedWays, collectedWaysReverse)); 183 } 184 185 185 //analyze witch way is inside witch outside. 186 186 return makeFromPolygons(joinedWays); … … 193 193 */ 194 194 private String makeFromPolygons(List<JoinedPolygon> polygons) { 195 196 197 198 199 195 List<PolygonLevel> list = findOuterWaysRecursive(0, polygons); 196 197 if (list == null){ 198 return tr("There is an intersection between ways."); 199 } 200 200 201 201 this.outerWays = new ArrayList<JoinedPolygon>(0); 202 202 this.innerWays = new ArrayList<JoinedPolygon>(0); 203 204 //take every other level 205 for (PolygonLevel pol : list) { 206 if (pol.level % 2 == 0) { 207 this.outerWays.add(pol.outerWay); 208 } 209 else { 210 this.innerWays.add(pol.outerWay); 211 } 212 } 213 214 return null; 215 } 216 217 /** 218 * Collects outer way and corresponding inner ways from all boundaries. 219 * @param boundaryWays 220 * @return the outermostWay, or null if intersection found. 221 */ 222 private List<PolygonLevel> findOuterWaysRecursive(int level, Collection<JoinedPolygon> boundaryWays) { 223 224 //TODO: bad performance for deep nesting... 225 List<PolygonLevel> result = new ArrayList<PolygonLevel>(); 226 227 for (JoinedPolygon outerWay : boundaryWays) { 228 229 boolean outerGood = true; 230 List<JoinedPolygon> innerCandidates = new ArrayList<JoinedPolygon>(); 231 232 for (JoinedPolygon innerWay : boundaryWays) { 233 if (innerWay == outerWay) { 234 continue; 235 } 236 237 Intersection innerInside = GeometryFunctions.polygonIntersection(outerWay.nodes, innerWay.nodes); 238 Intersection outerInside = GeometryFunctions.polygonIntersection(innerWay.nodes, outerWay.nodes); 239 240 if (outerInside == Intersection.INSIDE) { 241 outerGood = false; // outer is inside another polygon 242 break; 243 } else if (innerInside == Intersection.INSIDE) { 244 innerCandidates.add(innerWay); 245 } 246 else if (innerInside == Intersection.CROSSING) 247 { 248 //ways intersect 249 return null; 250 } 251 } 252 253 if (!outerGood) { 254 continue; 255 } 256 257 //add new outer polygon 258 PolygonLevel pol = new PolygonLevel(outerWay, level); 259 260 //process inner ways 261 if (innerCandidates.size() > 0) { 262 List<PolygonLevel> innerList = this.findOuterWaysRecursive(level + 1, innerCandidates); 263 if (innerList == null) { 264 return null; //intersection found 265 } 266 267 result.addAll(innerList); 268 269 for (PolygonLevel pl : innerList) { 270 if (pl.level == level + 1) { 271 pol.innerWays.add(pl.outerWay); 272 } 273 } 274 } 275 276 result.add(pol); 277 } 278 279 return result; 280 } 281 282 283 203 204 //take every other level 205 for (PolygonLevel pol : list) { 206 if (pol.level % 2 == 0) { 207 this.outerWays.add(pol.outerWay); 208 } 209 else { 210 this.innerWays.add(pol.outerWay); 211 } 212 } 213 214 return null; 215 } 216 217 /** 218 * Collects outer way and corresponding inner ways from all boundaries. 219 * @param boundaryWays 220 * @return the outermostWay, or null if intersection found. 221 */ 222 private List<PolygonLevel> findOuterWaysRecursive(int level, Collection<JoinedPolygon> boundaryWays) { 223 224 //TODO: bad performance for deep nesting... 225 List<PolygonLevel> result = new ArrayList<PolygonLevel>(); 226 227 for (JoinedPolygon outerWay : boundaryWays) { 228 229 boolean outerGood = true; 230 List<JoinedPolygon> innerCandidates = new ArrayList<JoinedPolygon>(); 231 232 for (JoinedPolygon innerWay : boundaryWays) { 233 if (innerWay == outerWay) { 234 continue; 235 } 236 237 PolygonIntersection intersection = GeometryFunctions.polygonIntersection(outerWay.nodes, innerWay.nodes); 238 239 if (intersection == PolygonIntersection.FIRST_INSIDE_SECOND) { 240 outerGood = false; // outer is inside another polygon 241 break; 242 } else if (intersection == PolygonIntersection.SECOND_INSIDE_FIRST) { 243 innerCandidates.add(innerWay); 244 } 245 else if (intersection == PolygonIntersection.CROSSING) 246 { 247 //ways intersect 248 return null; 249 } 250 } 251 252 if (!outerGood) { 253 continue; 254 } 255 256 //add new outer polygon 257 PolygonLevel pol = new PolygonLevel(outerWay, level); 258 259 //process inner ways 260 if (innerCandidates.size() > 0) { 261 List<PolygonLevel> innerList = this.findOuterWaysRecursive(level + 1, innerCandidates); 262 if (innerList == null) { 263 return null; //intersection found 264 } 265 266 result.addAll(innerList); 267 268 for (PolygonLevel pl : innerList) { 269 if (pl.level == level + 1) { 270 pol.innerWays.add(pl.outerWay); 271 } 272 } 273 } 274 275 result.add(pol); 276 } 277 278 return result; 279 } 280 281 282 284 283 }
Note:
See TracChangeset
for help on using the changeset viewer.