Ticket #17483: 17483.diff

File 17483.diff, 9.7 KB (added by j2tracey@…, 6 years ago)

patch

  • src/org/openstreetmap/josm/plugins/utilsplugin2/selection/NodeWayUtils.java

     
    3939        // Hide default constructor for utilities classes
    4040    }
    4141
     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
    4254    /**
    4355     * Find the neighbours of node n on the way w and put them in given collection
    4456     * @param w way on which the search goes
     
    5567
    5668        // add previous element
    5769        if (idx > 0) {
    58             nodes.add(nodeList.get(idx - 1));
     70            filteredAdd(nodes, nodeList.get(idx - 1));
    5971        }
    6072        // add next element
    6173        if (idx < nodeList.size() - 1) {
    62             nodes.add(nodeList.get(idx + 1));
     74            filteredAdd(nodes, nodeList.get(idx + 1));
    6375        }
    6476        if (w.isClosed()) {
    6577            // cyclic neighbours detection
    6678            if (idx == 0) {
    67                 nodes.add(nodeList.get(nodeList.size() - 2));
     79                filteredAdd(nodes, nodeList.get(nodeList.size() - 2));
    6880            }
    6981            if (idx == nodeList.size() - 1) {
    70                 nodes.add(nodeList.get(1));
     82                filteredAdd(nodes, nodeList.get(1));
    7183            }
    7284        }
    7385    }
     
    8395        List<Node> nodes = w.getNodes();
    8496        boolean flag = ways.contains(w);
    8597        for (Node n: nodes) {
    86             ways.addAll(n.getParentWays());
     98            filteredAddAll(ways, n.getParentWays());
    8799        }
    88100        if (!flag) ways.remove(w);
    89101        return ways.size() - s;
     
    97109     */
    98110    static int addWaysConnectedToNode(Node n, Set<Way> ways) {
    99111        int s = ways.size();
    100         ways.addAll(n.getParentWays());
     112        filteredAddAll(ways, n.getParentWays());
    101113        return ways.size() - s;
    102114    }
    103115
     
    106118     * @param ways collection of ways to search
    107119     * @param w way to check intersections
    108120     * @param newWays set to place the ways we found
     121     * @param excludeWays set of excluded ways
    109122     * @return number of ways possibly added added to newWays
    110123     */
    111124    static int addWaysIntersectingWay(Collection<Way> ways, Way w, Set<Way> newWays, Set<Way> excludeWays) {
     
    112125        List<Pair<Node, Node>> nodePairs = w.getNodePairs(false);
    113126        int count = 0;
    114127        for (Way anyway: ways) {
     128            if (anyway.isDisabled()) continue;
    115129            if (Objects.equals(anyway, w)) continue;
    116130            if (newWays.contains(anyway) || excludeWays.contains(anyway)) continue;
    117131
     
    132146    }
    133147
    134148    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);
    154151    }
    155152
    156153    /**
     
    161158     * @return number of ways added to newWays
    162159     */
    163160    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);
    164164        int count = 0;
    165165        for (Way w : initWays) {
    166             count += addWaysIntersectingWay(allWays, w, newWays);
     166            count += addWaysIntersectingWay(filteredWays, w, newWays);
    167167        }
    168168        return count;
    169169    }
     
    195195        foundWays.addAll(initWays);
    196196        newWays.addAll(initWays);
    197197        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);
    198202
    199203        int level = 0, c;
    200204        do {
     
    201205            c = 0;
    202206            newFoundWays = new HashSet<>();
    203207            for (Way w : foundWays) {
    204                 c += addWaysIntersectingWay(allWays, w, newFoundWays, newWays);
     208                c += addWaysIntersectingWay(filteredWays, w, newFoundWays);
    205209            }
    206210            foundWays = newFoundWays;
    207211            newWays.addAll(newFoundWays);
     
    212216                        ).setIcon(JOptionPane.WARNING_MESSAGE).show();
    213217                return;
    214218            }
    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);
    216226    }
    217227
    218228    public static void addWaysConnectedToWaysRecursively(Collection<Way> initWays, Set<Way> newWays) {
     
    232242                        ).setIcon(JOptionPane.WARNING_MESSAGE).show();
    233243                return;
    234244            }
    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);
    236252    }
    237253
    238254    static void addMiddle(Set<Node> selectedNodes, Set<Node> newNodes) {
     
    255271                if (w.isClosed()) {
    256272                    if ((i2-i1)*2 <= n) { // i1 ... i2
    257273                        for (int i = i1+1; i != i2; i++) {
    258                             newNodes.add(nodes.get(i));
     274                            filteredAdd(newNodes, nodes.get(i));
    259275                        }
    260276                    } else { // i2 ... n-1 0 1 ... i1
    261277                        for (int i = i2+1; i != i1; i = (i+1) % n) {
    262                             newNodes.add(nodes.get(i));
     278                            filteredAdd(newNodes, nodes.get(i));
    263279                        }
    264280                    }
    265281                } else {
    266282                    for (int i = i1+1; i < i2; i++) {
    267                         newNodes.add(nodes.get(i));
     283                        filteredAdd(newNodes, nodes.get(i));
    268284                    }
    269285                }
    270286            }
     
    330346            if (Objects.equals(firstWay, nextWay)) {
    331347                //we came to starting way, but not not the right end
    332348                if (Objects.equals(otherEnd, firstWay.firstNode())) return false;
    333                 newWays.addAll(newestWays);
     349                filteredAddAll(newWays, newestWays);
    334350                return true; // correct loop found
    335351            }
    336352            if (newestWays.contains(nextWay)) {
     
    361377        for (Node n : searchNodes) {
    362378            //if (Geometry.nodeInsidePolygon(n, polyNodes)) {
    363379            if (NodeWayUtils.isPointInsidePolygon(n.getEastNorth(), polyPoints)) {
     380                // can't filter nodes here, would prevent selecting ways that have filtered nodes
    364381                newestNodes.add(n);
    365382            }
    366383        }
     
    368385        List<Way> searchWays = data.searchWays(box);
    369386        for (Way w : searchWays) {
    370387            if (newestNodes.containsAll(w.getNodes())) {
    371                 newestWays.add(w);
     388                filteredAdd(newestWays, w);
    372389            }
    373390        }
    374391        for (Way w : newestWays) {
     
    376393            // do not select nodes of already selected ways
    377394        }
    378395
    379         newNodes.addAll(newestNodes);
    380         newWays.addAll(newestWays);
     396        filteredAddAll(newNodes, newestNodes);
     397        newWays.addAll(newestWays); // already filtered
    381398    }
    382399
    383400    static void addAllInsideWay(DataSet data, Way way, Set<Way> newWays, Set<Node> newNodes) {
     
    391408        for (Node n : searchNodes) {
    392409            //if (Geometry.nodeInsidePolygon(n, polyNodes)) {
    393410            if (NodeWayUtils.isPointInsidePolygon(n.getEastNorth(), polyPoints)) {
     411                // can't filter nodes here, would prevent selecting ways that have filtered nodes
    394412                newestNodes.add(n);
    395413            }
    396414        }
     
    398416        List<Way> searchWays = data.searchWays(box);
    399417        for (Way w : searchWays) {
    400418            if (newestNodes.containsAll(w.getNodes())) {
    401                 newestWays.add(w);
     419                filteredAdd(newestWays, w);
    402420            }
    403421        }
    404422
    405         newNodes.addAll(newestNodes);
    406         newWays.addAll(newestWays);
     423        filteredAddAll(newNodes, newestNodes);
     424        newWays.addAll(newestWays); // already filtered
    407425    }
    408426
    409427    public static boolean isPointInsidePolygon(EastNorth point, Iterable<EastNorth> polygonPoints) {