Ticket #18368: 18368.patch

File 18368.patch, 2.3 KB (added by GerdP, 4 years ago)
  • src/org/openstreetmap/josm/data/osm/NodeGraph.java

     
    44import java.util.ArrayList;
    55import java.util.Collection;
    66import java.util.Collections;
     7import java.util.HashMap;
    78import java.util.LinkedHashMap;
    89import java.util.LinkedHashSet;
    910import java.util.LinkedList;
    1011import java.util.List;
    1112import java.util.Map;
     13import java.util.Map.Entry;
    1214import java.util.Optional;
    1315import java.util.Set;
    1416import java.util.Stack;
     17import java.util.TreeMap;
    1518
    1619import org.openstreetmap.josm.tools.Pair;
    1720
     
    239242        return nodes;
    240243    }
    241244
    242     protected boolean isSpanningWay(Stack<NodePair> way) {
     245    protected boolean isSpanningWay(Collection<NodePair> way) {
    243246        return numUndirectedEges == way.size();
    244247    }
    245248
     
    296299        // In the worst case this loops over all nodes which is very slow for large ways.
    297300        //
    298301        Set<Node> nodes = getTerminalNodes();
     302        nodes = nodes.isEmpty() ? getMostFrequentVisitedNodes() : nodes;
    299303        nodes = nodes.isEmpty() ? getNodes() : nodes;
    300         for (Node n: nodes) {
     304        for (Node n:nodes) {
    301305            List<Node> path = buildSpanningPath(n);
    302306            if (!path.isEmpty())
    303307                return path;
     
    304308        }
    305309        return null;
    306310    }
     311
     312    /**
     313     * @return a set of those nodes which appear most often in the edges.
     314     */
     315    private Set<Node> getMostFrequentVisitedNodes() {
     316        if (edges.isEmpty())
     317            return Collections.emptyNavigableSet();
     318        Map<Node, Integer> counters = new HashMap<>();
     319        for (NodePair pair : edges) {
     320            Integer c = counters.get(pair.getA());
     321            counters.put(pair.getA(), c == null ? 1 : c + 1);
     322            c = counters.get(pair.getB());
     323            counters.put(pair.getB(), c == null ? 1 : c + 1);
     324        }
     325        TreeMap<Integer, Set<Node>> sorted = new TreeMap<>();
     326        for (Entry<Node, Integer> e : counters.entrySet()) {
     327            sorted.computeIfAbsent(e.getValue(), LinkedHashSet::new).add(e.getKey());
     328        }
     329        return sorted.lastEntry().getValue();
     330    }
     331
    307332}