Ticket #17483: 17483.diff
File 17483.diff, 9.7 KB (added by , 6 years ago) |
---|
-
src/org/openstreetmap/josm/plugins/utilsplugin2/selection/NodeWayUtils.java
39 39 // Hide default constructor for utilities classes 40 40 } 41 41 42 private static <T extends OsmPrimitive> void filteredAdd(Collection<T> collection, T element) { 43 if (!element.isDisabled()) { 44 collection.add(element); 45 } 46 } 47 48 private static <T extends OsmPrimitive> void filteredAddAll(Collection<T> out, Collection<T> in) { 49 for (T element: in) { 50 filteredAdd(out, element); 51 } 52 } 53 42 54 /** 43 55 * Find the neighbours of node n on the way w and put them in given collection 44 56 * @param w way on which the search goes … … 55 67 56 68 // add previous element 57 69 if (idx > 0) { 58 nodes.add(nodeList.get(idx - 1));70 filteredAdd(nodes, nodeList.get(idx - 1)); 59 71 } 60 72 // add next element 61 73 if (idx < nodeList.size() - 1) { 62 nodes.add(nodeList.get(idx + 1));74 filteredAdd(nodes, nodeList.get(idx + 1)); 63 75 } 64 76 if (w.isClosed()) { 65 77 // cyclic neighbours detection 66 78 if (idx == 0) { 67 nodes.add(nodeList.get(nodeList.size() - 2));79 filteredAdd(nodes, nodeList.get(nodeList.size() - 2)); 68 80 } 69 81 if (idx == nodeList.size() - 1) { 70 nodes.add(nodeList.get(1));82 filteredAdd(nodes, nodeList.get(1)); 71 83 } 72 84 } 73 85 } … … 83 95 List<Node> nodes = w.getNodes(); 84 96 boolean flag = ways.contains(w); 85 97 for (Node n: nodes) { 86 ways.addAll(n.getParentWays());98 filteredAddAll(ways, n.getParentWays()); 87 99 } 88 100 if (!flag) ways.remove(w); 89 101 return ways.size() - s; … … 97 109 */ 98 110 static int addWaysConnectedToNode(Node n, Set<Way> ways) { 99 111 int s = ways.size(); 100 ways.addAll(n.getParentWays());112 filteredAddAll(ways, n.getParentWays()); 101 113 return ways.size() - s; 102 114 } 103 115 … … 106 118 * @param ways collection of ways to search 107 119 * @param w way to check intersections 108 120 * @param newWays set to place the ways we found 121 * @param excludeWays set of excluded ways 109 122 * @return number of ways possibly added added to newWays 110 123 */ 111 124 static int addWaysIntersectingWay(Collection<Way> ways, Way w, Set<Way> newWays, Set<Way> excludeWays) { … … 112 125 List<Pair<Node, Node>> nodePairs = w.getNodePairs(false); 113 126 int count = 0; 114 127 for (Way anyway: ways) { 128 if (anyway.isDisabled()) continue; 115 129 if (Objects.equals(anyway, w)) continue; 116 130 if (newWays.contains(anyway) || excludeWays.contains(anyway)) continue; 117 131 … … 132 146 } 133 147 134 148 static int addWaysIntersectingWay(Collection<Way> ways, Way w, Set<Way> newWays) { 135 List<Pair<Node, Node>> nodePairs = w.getNodePairs(false); 136 int count = 0; 137 for (Way anyway: ways) { 138 if (Objects.equals(anyway, w)) continue; 139 if (newWays.contains(anyway)) continue; 140 List<Pair<Node, Node>> nodePairs2 = anyway.getNodePairs(false); 141 loop: for (Pair<Node, Node> p1 : nodePairs) { 142 for (Pair<Node, Node> p2 : nodePairs2) { 143 if (null != Geometry.getSegmentSegmentIntersection( 144 p1.a.getEastNorth(), p1.b.getEastNorth(), 145 p2.a.getEastNorth(), p2.b.getEastNorth())) { 146 newWays.add(anyway); 147 count++; 148 break loop; 149 } 150 } 151 } 152 } 153 return count; 149 Set<Way> excludeWays = new HashSet<Way>(); 150 return addWaysIntersectingWay(ways, w, newWays, excludeWays); 154 151 } 155 152 156 153 /** … … 161 158 * @return number of ways added to newWays 162 159 */ 163 160 public static int addWaysIntersectingWays(Collection<Way> allWays, Collection<Way> initWays, Set<Way> newWays) { 161 // performance improvement - filter everything ahead of time 162 Set<Way> filteredWays = new HashSet<>(); 163 filteredAddAll(filteredWays, allWays); 164 164 int count = 0; 165 165 for (Way w : initWays) { 166 count += addWaysIntersectingWay( allWays, w, newWays);166 count += addWaysIntersectingWay(filteredWays, w, newWays); 167 167 } 168 168 return count; 169 169 } … … 195 195 foundWays.addAll(initWays); 196 196 newWays.addAll(initWays); 197 197 Set<Way> newFoundWays; 198 // performance improvement - apply filters ahead of time 199 Set<Way> filteredWays = new HashSet<>(); 200 filteredAddAll(filteredWays, allWays); 201 filteredWays.removeAll(initWays); 198 202 199 203 int level = 0, c; 200 204 do { … … 201 205 c = 0; 202 206 newFoundWays = new HashSet<>(); 203 207 for (Way w : foundWays) { 204 c += addWaysIntersectingWay( allWays, w, newFoundWays, newWays);208 c += addWaysIntersectingWay(filteredWays, w, newFoundWays); 205 209 } 206 210 foundWays = newFoundWays; 207 211 newWays.addAll(newFoundWays); … … 212 216 ).setIcon(JOptionPane.WARNING_MESSAGE).show(); 213 217 return; 214 218 } 215 } while (c > 0 && level < maxLevel); 219 if (level >= maxLevel) { 220 new Notification( 221 tr("Reached max recursion depth: {0}", level) 222 ).setIcon(JOptionPane.WARNING_MESSAGE).show(); 223 return; 224 } 225 } while (c > 0); 216 226 } 217 227 218 228 public static void addWaysConnectedToWaysRecursively(Collection<Way> initWays, Set<Way> newWays) { … … 232 242 ).setIcon(JOptionPane.WARNING_MESSAGE).show(); 233 243 return; 234 244 } 235 } while (c > 0 && level < maxLevel); 245 if (level >= maxLevel) { 246 new Notification( 247 tr("Reached max recursion depth: {0}", level) 248 ).setIcon(JOptionPane.WARNING_MESSAGE).show(); 249 return; 250 } 251 } while (c > 0); 236 252 } 237 253 238 254 static void addMiddle(Set<Node> selectedNodes, Set<Node> newNodes) { … … 255 271 if (w.isClosed()) { 256 272 if ((i2-i1)*2 <= n) { // i1 ... i2 257 273 for (int i = i1+1; i != i2; i++) { 258 newNodes.add(nodes.get(i));274 filteredAdd(newNodes, nodes.get(i)); 259 275 } 260 276 } else { // i2 ... n-1 0 1 ... i1 261 277 for (int i = i2+1; i != i1; i = (i+1) % n) { 262 newNodes.add(nodes.get(i));278 filteredAdd(newNodes, nodes.get(i)); 263 279 } 264 280 } 265 281 } else { 266 282 for (int i = i1+1; i < i2; i++) { 267 newNodes.add(nodes.get(i));283 filteredAdd(newNodes, nodes.get(i)); 268 284 } 269 285 } 270 286 } … … 330 346 if (Objects.equals(firstWay, nextWay)) { 331 347 //we came to starting way, but not not the right end 332 348 if (Objects.equals(otherEnd, firstWay.firstNode())) return false; 333 newWays.addAll(newestWays);349 filteredAddAll(newWays, newestWays); 334 350 return true; // correct loop found 335 351 } 336 352 if (newestWays.contains(nextWay)) { … … 361 377 for (Node n : searchNodes) { 362 378 //if (Geometry.nodeInsidePolygon(n, polyNodes)) { 363 379 if (NodeWayUtils.isPointInsidePolygon(n.getEastNorth(), polyPoints)) { 380 // can't filter nodes here, would prevent selecting ways that have filtered nodes 364 381 newestNodes.add(n); 365 382 } 366 383 } … … 368 385 List<Way> searchWays = data.searchWays(box); 369 386 for (Way w : searchWays) { 370 387 if (newestNodes.containsAll(w.getNodes())) { 371 newestWays.add(w);388 filteredAdd(newestWays, w); 372 389 } 373 390 } 374 391 for (Way w : newestWays) { … … 376 393 // do not select nodes of already selected ways 377 394 } 378 395 379 newNodes.addAll(newestNodes);380 newWays.addAll(newestWays); 396 filteredAddAll(newNodes, newestNodes); 397 newWays.addAll(newestWays); // already filtered 381 398 } 382 399 383 400 static void addAllInsideWay(DataSet data, Way way, Set<Way> newWays, Set<Node> newNodes) { … … 391 408 for (Node n : searchNodes) { 392 409 //if (Geometry.nodeInsidePolygon(n, polyNodes)) { 393 410 if (NodeWayUtils.isPointInsidePolygon(n.getEastNorth(), polyPoints)) { 411 // can't filter nodes here, would prevent selecting ways that have filtered nodes 394 412 newestNodes.add(n); 395 413 } 396 414 } … … 398 416 List<Way> searchWays = data.searchWays(box); 399 417 for (Way w : searchWays) { 400 418 if (newestNodes.containsAll(w.getNodes())) { 401 newestWays.add(w);419 filteredAdd(newestWays, w); 402 420 } 403 421 } 404 422 405 newNodes.addAll(newestNodes);406 newWays.addAll(newestWays); 423 filteredAddAll(newNodes, newestNodes); 424 newWays.addAll(newestWays); // already filtered 407 425 } 408 426 409 427 public static boolean isPointInsidePolygon(EastNorth point, Iterable<EastNorth> polygonPoints) {