Changeset 15574 in josm for trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java
- Timestamp:
- 2019-12-09T09:47:20+01:00 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java
r15555 r15574 32 32 import org.openstreetmap.josm.data.osm.TagCollection; 33 33 import org.openstreetmap.josm.data.osm.Way; 34 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon; 35 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.JoinedWay; 34 36 import org.openstreetmap.josm.data.preferences.BooleanProperty; 37 import org.openstreetmap.josm.data.validation.Test; 38 import org.openstreetmap.josm.data.validation.tests.OverlappingWays; 39 import org.openstreetmap.josm.data.validation.tests.SelfIntersectingWay; 35 40 import org.openstreetmap.josm.gui.ExtendedDialog; 36 41 import org.openstreetmap.josm.gui.MainApplication; … … 123 128 124 129 // try to build a new way which includes all the combined ways 125 NodeGraph graph = NodeGraph.createNearlyUndirectedGraphFromNodeWays(ways); 126 List<Node> path = graph.buildSpanningPathNoRemove(); 127 if (path == null) { 130 List<Node> path = tryJoin(ways); 131 if (path.isEmpty()) { 128 132 warnCombiningImpossible(); 129 133 return null; … … 137 141 List<Way> reversedWays = new LinkedList<>(); 138 142 List<Way> unreversedWays = new LinkedList<>(); 139 for (Way w: ways) { 140 // Treat zero or one-node ways as unreversed as Combine action action is a good way to fix them (see #8971) 141 if (w.getNodesCount() < 2 || (path.indexOf(w.getNode(0)) + 1) == path.lastIndexOf(w.getNode(1))) { 142 unreversedWays.add(w); 143 } else { 144 reversedWays.add(w); 145 } 146 } 143 detectReversedWays(ways, path, reversedWays, unreversedWays); 147 144 // reverse path if all ways have been reversed 148 145 if (unreversedWays.isEmpty()) { … … 164 161 } 165 162 // if there are still reversed ways with direction-dependent tags, reverse their tags 166 if (!reversedWays.isEmpty() && PROP_REVERSE_WAY.get()) {163 if (!reversedWays.isEmpty() && Boolean.TRUE.equals(PROP_REVERSE_WAY.get())) { 167 164 List<Way> unreversedTagWays = new ArrayList<>(ways); 168 165 unreversedTagWays.removeAll(reversedWays); … … 211 208 212 209 return new Pair<>(targetWay, sequenceCommand); 210 } 211 212 protected static void detectReversedWays(Collection<Way> ways, List<Node> path, List<Way> reversedWays, 213 List<Way> unreversedWays) { 214 for (Way w: ways) { 215 // Treat zero or one-node ways as unreversed as Combine action action is a good way to fix them (see #8971) 216 if (w.getNodesCount() < 2) { 217 unreversedWays.add(w); 218 } else { 219 boolean foundStartSegment = false; 220 int last = path.lastIndexOf(w.getNode(0)); 221 222 for (int i = path.indexOf(w.getNode(0)); i <= last; i++) { 223 if (path.get(i) == w.getNode(0) && i + 1 < path.size() && w.getNode(1) == path.get(i + 1)) { 224 foundStartSegment = true; 225 break; 226 } 227 } 228 if (foundStartSegment) { 229 unreversedWays.add(w); 230 } else { 231 reversedWays.add(w); 232 } 233 } 234 } 235 } 236 237 protected static List<Node> tryJoin(Collection<Way> ways) { 238 List<Node> path = joinWithMultipolygonCode(ways); 239 if (path.isEmpty()) { 240 NodeGraph graph = NodeGraph.createNearlyUndirectedGraphFromNodeWays(ways); 241 path = graph.buildSpanningPathNoRemove(); 242 } 243 return path; 244 } 245 246 /** 247 * Use {@link Multipolygon#joinWays(Collection)} to join ways. 248 * @param ways the ways 249 * @return List of nodes of the combined ways or null if ways could not be combined to a single way. 250 * Result may contain overlapping segments. 251 */ 252 private static List<Node> joinWithMultipolygonCode(Collection<Way> ways) { 253 // sort so that old unclosed ways appear first 254 LinkedList<Way> toJoin = new LinkedList<>(ways); 255 toJoin.sort((o1, o2) -> { 256 int d = Boolean.compare(o1.isNew(), o2.isNew()); 257 if (d == 0) 258 d = Boolean.compare(o1.isClosed(), o2.isClosed()); 259 return d; 260 }); 261 Collection<JoinedWay> list = Multipolygon.joinWays(toJoin); 262 if (list.size() == 1) { 263 // ways form a single line string 264 return new ArrayList<>(list.iterator().next().getNodes()); 265 } 266 return Collections.emptyList(); 213 267 } 214 268 … … 238 292 if (combineResult == null) 239 293 return; 294 240 295 final Way selectedWay = combineResult.a; 241 296 UndoRedoHandler.getInstance().add(combineResult.b); 297 Test test = new OverlappingWays(); 298 test.startTest(null); 299 test.visit(combineResult.a); 300 test.endTest(); 301 if (test.getErrors().isEmpty()) { 302 test = new SelfIntersectingWay(); 303 test.startTest(null); 304 test.visit(combineResult.a); 305 test.endTest(); 306 } 307 if (!test.getErrors().isEmpty()) { 308 new Notification(test.getErrors().get(0).getMessage()) 309 .setIcon(JOptionPane.WARNING_MESSAGE) 310 .setDuration(Notification.TIME_SHORT) 311 .show(); 312 } 242 313 if (selectedWay != null) { 243 314 GuiHelper.runInEDT(() -> ds.setSelected(selectedWay)); … … 262 333 setEnabled(numWays >= 2); 263 334 } 335 264 336 }
Note:
See TracChangeset
for help on using the changeset viewer.