Ticket #18367: 18367.patch
File 18367.patch, 4.8 KB (added by , 4 years ago) |
---|
-
src/org/openstreetmap/josm/actions/CombineWayAction.java
31 31 import org.openstreetmap.josm.data.osm.OsmUtils; 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; 37 42 import org.openstreetmap.josm.gui.Notification; … … 122 127 } 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(); 130 List<Node> path = joinWithMultipolygonCode(ways); 127 131 if (path == null) { 132 NodeGraph graph = NodeGraph.createNearlyUndirectedGraphFromNodeWays(ways); 133 path = graph.buildSpanningPathNoRemove(); 134 } 135 if (path == null) { 128 136 warnCombiningImpossible(); 129 137 return null; 130 138 } … … 138 146 List<Way> unreversedWays = new LinkedList<>(); 139 147 for (Way w: ways) { 140 148 // 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))) {149 if (w.getNodesCount() < 2) { 142 150 unreversedWays.add(w); 143 151 } else { 144 reversedWays.add(w); 152 boolean foundStartSegment = false; 153 int last = path.lastIndexOf(w.getNode(0)); 154 155 for (int i = path.indexOf(w.getNode(0)); i <= last; i++) { 156 if (path.get(i) == w.getNode(0) && i + 1 < path.size() && w.getNode(1) == path.get(i + 1)) { 157 foundStartSegment = true; 158 break; 159 } 160 } 161 if (foundStartSegment) { 162 unreversedWays.add(w); 163 } else { 164 reversedWays.add(w); 165 } 145 166 } 146 167 } 147 168 // reverse path if all ways have been reversed … … 212 233 return new Pair<>(targetWay, sequenceCommand); 213 234 } 214 235 236 /** 237 * Use {@link Multipolygon#joinWays(Collection)} to join ways. 238 * @param ways the ways 239 * @return List of nodes of the combined ways or null if ways could not be combined to a single way. 240 * Result may contain overlapping segments. 241 */ 242 private static List<Node> joinWithMultipolygonCode(Collection<Way> ways) { 243 // sort so that old unclosed ways appear first 244 LinkedList<Way> toJoin = new LinkedList<>(ways); 245 toJoin.sort((o1, o2) -> { 246 int d = Boolean.compare(o1.isNew(), o2.isNew()); 247 if (d == 0) 248 d = Boolean.compare(o1.isClosed(), o2.isClosed()); 249 return d; 250 }); 251 Collection<JoinedWay> list = Multipolygon.joinWays(toJoin); 252 if (list.size() == 1) { 253 // ways form a single line string 254 return new ArrayList<>(list.iterator().next().getNodes()); 255 } 256 return null; 257 } 258 215 259 @Override 216 260 public void actionPerformed(ActionEvent event) { 217 261 final DataSet ds = getLayerManager().getEditDataSet(); … … 237 281 238 282 if (combineResult == null) 239 283 return; 284 240 285 final Way selectedWay = combineResult.a; 241 286 UndoRedoHandler.getInstance().add(combineResult.b); 287 Test test = new OverlappingWays(); 288 test.startTest(null); 289 test.visit(combineResult.a); 290 test.endTest(); 291 if (test.getErrors().isEmpty()) { 292 test = new SelfIntersectingWay(); 293 test.startTest(null); 294 test.visit(combineResult.a); 295 test.endTest(); 296 } 297 if (!test.getErrors().isEmpty()) { 298 new Notification(test.getErrors().get(0).getMessage()) 299 .setIcon(JOptionPane.WARNING_MESSAGE) 300 .show(); 301 } 242 302 if (selectedWay != null) { 243 303 GuiHelper.runInEDT(() -> ds.setSelected(selectedWay)); 244 304 } … … 261 321 } 262 322 setEnabled(numWays >= 2); 263 323 } 324 264 325 }