Changeset 14970 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2019-04-07T19:03:21+02:00 (6 years ago)
Author:
GerdP
Message:

see #16102: Drastically improve performance for SimplifyWayAction when used with very complex ways.
For a kml file produced by brouter with ~50000 points the import took > 50 seconds, now it is done in 1.5 seconds.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/SimplifyWayAction.java

    r14654 r14970  
    134134     * @param way the way to be simplified
    135135     * @param node the node to check
     136     * @param multipleUseNodes set of nodes which is used more than once in the way
    136137     * @return true if <code>node</code> is a required node which can't be removed
    137138     * in order to simplify the way.
    138139     */
    139     protected static boolean isRequiredNode(Way way, Node node) {
     140    protected static boolean isRequiredNode(Way way, Node node, Set<Node> multipleUseNodes) {
    140141        boolean isRequired = node.isTagged();
    141         if (!isRequired) {
     142        if (!isRequired && multipleUseNodes.contains(node)) {
    142143            int frequency = Collections.frequency(way.getNodes(), node);
    143144            if ((way.getNode(0) == node) && (way.getNode(way.getNodesCount()-1) == node)) {
     
    164165    public final SequenceCommand simplifyWay(Way w) {
    165166        return simplifyWay(w, Config.getPref().getDouble("simplify-way.max-error", 3.0));
     167    }
     168
     169    /**
     170     * Calculate a set of nodes which occurs more than once in the way
     171     * @param w the way
     172     * @return a set of nodes which occurs more than once in the way
     173     */
     174    private static Set<Node> getMultiUseNodes(Way w) {
     175        Set<Node> multipleUseNodes = new HashSet<>();
     176        Set<Node> allNodes = new HashSet<>();
     177        for (Node n : w.getNodes()) {
     178            if (!allNodes.add(n))
     179                multipleUseNodes.add(n);
     180        }
     181        return multipleUseNodes;
    166182    }
    167183
     
    177193        int lower = 0;
    178194        int i = 0;
     195
     196        Set<Node> multipleUseNodes = getMultiUseNodes(w);
    179197        List<Node> newNodes = new ArrayList<>(w.getNodesCount());
    180198        while (i < w.getNodesCount()) {
    181             if (isRequiredNode(w, w.getNode(i))) {
     199            if (isRequiredNode(w, w.getNode(i), multipleUseNodes)) {
    182200                // copy a required node to the list of new nodes. Simplify not possible
    183201                newNodes.add(w.getNode(i));
     
    188206            i++;
    189207            // find the longest sequence of not required nodes ...
    190             while (i < w.getNodesCount() && !isRequiredNode(w, w.getNode(i))) {
     208            while (i < w.getNodesCount() && !isRequiredNode(w, w.getNode(i), multipleUseNodes)) {
    191209                i++;
    192210            }
     
    198216
    199217        // Closed way, check if the first node could also be simplified ...
    200         if (newNodes.size() > 3 && newNodes.get(0) == newNodes.get(newNodes.size() - 1) && !isRequiredNode(w, newNodes.get(0))) {
     218        if (newNodes.size() > 3 && newNodes.get(0) == newNodes.get(newNodes.size() - 1) && !isRequiredNode(w, newNodes.get(0), multipleUseNodes)) {
    201219            final List<Node> l1 = Arrays.asList(newNodes.get(newNodes.size() - 2), newNodes.get(0), newNodes.get(1));
    202220            final List<Node> l2 = new ArrayList<>(3);
Note: See TracChangeset for help on using the changeset viewer.