Ticket #15170: simplifyway2.patch

File simplifyway2.patch, 4.8 KB (added by shinigami, 7 years ago)
  • src/org/openstreetmap/josm/actions/SimplifyWayAction.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
     
    77
    88import java.awt.event.ActionEvent;
    99import java.awt.event.KeyEvent;
    10 import java.util.ArrayList;
    11 import java.util.Arrays;
    12 import java.util.Collection;
    13 import java.util.Collections;
    14 import java.util.HashSet;
    15 import java.util.LinkedList;
    16 import java.util.List;
    17 import java.util.Set;
     10import java.util.*;
    1811
    1912import javax.swing.JOptionPane;
    2013import javax.swing.SwingUtilities;
     
    134127     *
    135128     * @param way the way to be simplified
    136129     * @param node the node to check
    137      * @return true if <code>node</code> is a required node which can't be removed
     130     * @param hist precounted frequencies of nodes in way
     131         * @return true if <code>node</code> is a required node which can't be removed
    138132     * in order to simplify the way.
    139133     */
    140     protected static boolean isRequiredNode(Way way, Node node) {
    141         int frequency = Collections.frequency(way.getNodes(), node);
     134    protected static boolean isRequiredNode(Way way, Node node, Map<Node, Integer> hist) {
     135
     136                // node is more than once in given way
     137        int frequency = hist.get(node);
    142138        if ((way.getNode(0) == node) && (way.getNode(way.getNodesCount()-1) == node)) {
    143139            frequency = frequency - 1; // closed way closing node counted only once
    144140        }
    145         boolean isRequired = frequency > 1;
    146         if (!isRequired) {
    147             List<OsmPrimitive> parents = new LinkedList<>();
    148             parents.addAll(node.getReferrers());
    149             parents.remove(way);
    150             isRequired = !parents.isEmpty();
    151         }
    152         if (!isRequired) {
    153             isRequired = node.isTagged();
    154         }
    155         return isRequired;
     141        if (frequency > 1){
     142                return true;
     143                }
     144
     145                // other referrers than given way
     146                List<OsmPrimitive> parents = new LinkedList<>();
     147                parents.addAll(node.getReferrers());
     148                parents.remove(way);
     149                if (!parents.isEmpty()){
     150                        return true;
     151                }
     152
     153                // has tags??
     154        return node.isTagged();
    156155    }
    157156
    158157    /**
     
    177176    public static SequenceCommand simplifyWay(Way w, double threshold) {
    178177        int lower = 0;
    179178        int i = 0;
     179
    180180        List<Node> newNodes = new ArrayList<>(w.getNodesCount());
     181                Map<Node, Integer> hist = makeHistogram(w.getNodes());
     182
    181183        while (i < w.getNodesCount()) {
    182             if (isRequiredNode(w, w.getNode(i))) {
     184            if (isRequiredNode(w, w.getNode(i), hist)) {
    183185                // copy a required node to the list of new nodes. Simplify not possible
    184186                newNodes.add(w.getNode(i));
    185187                i++;
     
    188190            }
    189191            i++;
    190192            // find the longest sequence of not required nodes ...
    191             while (i < w.getNodesCount() && !isRequiredNode(w, w.getNode(i))) {
     193            while (i < w.getNodesCount() && !isRequiredNode(w, w.getNode(i), hist)) {
    192194                i++;
    193195            }
    194196            // ... and simplify them
     
    198200        }
    199201
    200202        // Closed way, check if the first node could also be simplified ...
    201         if (newNodes.size() > 3 && newNodes.get(0) == newNodes.get(newNodes.size() - 1) && !isRequiredNode(w, newNodes.get(0))) {
     203        if (newNodes.size() > 3 && newNodes.get(0) == newNodes.get(newNodes.size() - 1) && !isRequiredNode(w, newNodes.get(0), hist)) {
    202204            final List<Node> l1 = Arrays.asList(newNodes.get(newNodes.size() - 2), newNodes.get(0), newNodes.get(1));
    203205            final List<Node> l2 = new ArrayList<>(3);
    204206            buildSimplifiedNodeList(l1, 0, 2, threshold, l2);
     
    208210            }
    209211        }
    210212
    211         Set<Node> delNodes = new HashSet<>();
    212         delNodes.addAll(w.getNodes());
    213         delNodes.removeAll(newNodes);
     213                Set<Node> delNodes = new HashSet<>(w.getNodes());
     214                for (Node n : newNodes) {
     215                        delNodes.remove(n);
     216                }
    214217
    215218        if (delNodes.isEmpty()) return null;
    216219
     
    224227                trn("Simplify Way (remove {0} node)", "Simplify Way (remove {0} nodes)", delNodes.size(), delNodes.size()), cmds);
    225228    }
    226229
    227     /**
     230        private static Map<Node, Integer> makeHistogram(List<Node> nodes) {
     231        Map<Node, Integer> h = new HashMap<>(nodes.size());
     232                for (Node node : nodes) {
     233                        Integer c = h.get(node);
     234                        if (c == null){
     235                                h.put(node, 1);
     236                        }
     237                        else {
     238                                h.put(node, c + 1);
     239                        }
     240                }
     241                return h;
     242        }
     243
     244        /**
    228245     * Builds the simplified list of nodes for a way segment given by a lower index <code>from</code>
    229246     * and an upper index <code>to</code>
    230247     *