IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
|
|
|
|
| 7 | 7 | |
| 8 | 8 | import java.awt.event.ActionEvent; |
| 9 | 9 | import 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; |
| | 10 | import java.util.*; |
| 18 | 11 | |
| 19 | 12 | import javax.swing.JOptionPane; |
| 20 | 13 | import javax.swing.SwingUtilities; |
| … |
… |
|
| 134 | 127 | * |
| 135 | 128 | * @param way the way to be simplified |
| 136 | 129 | * @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 |
| 138 | 132 | * in order to simplify the way. |
| 139 | 133 | */ |
| 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); |
| 142 | 138 | if ((way.getNode(0) == node) && (way.getNode(way.getNodesCount()-1) == node)) { |
| 143 | 139 | frequency = frequency - 1; // closed way closing node counted only once |
| 144 | 140 | } |
| 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(); |
| 156 | 155 | } |
| 157 | 156 | |
| 158 | 157 | /** |
| … |
… |
|
| 177 | 176 | public static SequenceCommand simplifyWay(Way w, double threshold) { |
| 178 | 177 | int lower = 0; |
| 179 | 178 | int i = 0; |
| | 179 | |
| 180 | 180 | List<Node> newNodes = new ArrayList<>(w.getNodesCount()); |
| | 181 | Map<Node, Integer> hist = makeHistogram(w.getNodes()); |
| | 182 | |
| 181 | 183 | while (i < w.getNodesCount()) { |
| 182 | | if (isRequiredNode(w, w.getNode(i))) { |
| | 184 | if (isRequiredNode(w, w.getNode(i), hist)) { |
| 183 | 185 | // copy a required node to the list of new nodes. Simplify not possible |
| 184 | 186 | newNodes.add(w.getNode(i)); |
| 185 | 187 | i++; |
| … |
… |
|
| 188 | 190 | } |
| 189 | 191 | i++; |
| 190 | 192 | // 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)) { |
| 192 | 194 | i++; |
| 193 | 195 | } |
| 194 | 196 | // ... and simplify them |
| … |
… |
|
| 198 | 200 | } |
| 199 | 201 | |
| 200 | 202 | // 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)) { |
| 202 | 204 | final List<Node> l1 = Arrays.asList(newNodes.get(newNodes.size() - 2), newNodes.get(0), newNodes.get(1)); |
| 203 | 205 | final List<Node> l2 = new ArrayList<>(3); |
| 204 | 206 | buildSimplifiedNodeList(l1, 0, 2, threshold, l2); |
| … |
… |
|
| 208 | 210 | } |
| 209 | 211 | } |
| 210 | 212 | |
| 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 | } |
| 214 | 217 | |
| 215 | 218 | if (delNodes.isEmpty()) return null; |
| 216 | 219 | |
| … |
… |
|
| 224 | 227 | trn("Simplify Way (remove {0} node)", "Simplify Way (remove {0} nodes)", delNodes.size(), delNodes.size()), cmds); |
| 225 | 228 | } |
| 226 | 229 | |
| 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 | /** |
| 228 | 245 | * Builds the simplified list of nodes for a way segment given by a lower index <code>from</code> |
| 229 | 246 | * and an upper index <code>to</code> |
| 230 | 247 | * |