Ticket #19859: 19859.patch
File 19859.patch, 9.1 KB (added by , 4 years ago) |
---|
-
src/org/openstreetmap/josm/plugins/terracer/TerracerAction.java
63 63 */ 64 64 public final class TerracerAction extends JosmAction { 65 65 66 private Collection<Command> commands; 67 private Collection<OsmPrimitive> primitives; 68 private TagCollection tagsInConflict; 69 66 private transient Collection<Command> commands; 67 private final transient List<Pair<TagCollection, List<OsmPrimitive>>> conflicts = new ArrayList<>(); 68 70 69 public TerracerAction() { 71 70 super(tr("Terrace a building"), "terrace", 72 71 tr("Creates individual buildings from a long building."), … … 75 74 Shortcut.SHIFT), true); 76 75 } 77 76 78 pr otectedstatic Set<Relation> findAssociatedStreets(Collection<OsmPrimitive> objects) {77 private static Set<Relation> findAssociatedStreets(Collection<OsmPrimitive> objects) { 79 78 Set<Relation> result = new HashSet<>(); 80 79 if (objects != null) { 81 80 for (OsmPrimitive c : objects) { … … 180 179 181 180 } catch (InvalidUserInputException ex) { 182 181 Logging.warn("Terracer: "+ex.getMessage()); 183 new ExtendedDialog(MainApplication.getMainFrame(), tr("Invalid selection"), new String[] {"OK"})184 .setButtonIcons( new String[] {"ok"}).setIcon(JOptionPane.INFORMATION_MESSAGE)182 new ExtendedDialog(MainApplication.getMainFrame(), tr("Invalid selection"), "OK") 183 .setButtonIcons("ok").setIcon(JOptionPane.INFORMATION_MESSAGE) 185 184 .setContent(tr("Select a single, closed way of at least four nodes. " + 186 185 "(Optionally you can also select a street for the addr:street tag " + 187 186 "and a node to mark the start of numbering.)")) … … 232 231 233 232 private void cleanup() { 234 233 commands = null; 235 primitives = null; 236 tagsInConflict = null; 234 conflicts.clear(); 237 235 } 238 236 239 237 public Integer getNumber(String number) { … … 246 244 247 245 /** 248 246 * Sorts the house number nodes according their numbers only 249 *250 * @param house251 * number nodes252 247 */ 253 248 static class HousenumberNodeComparator implements Comparator<Node> { 254 249 private final Pattern pat = Pattern.compile("^(\\d+)\\s*(.*)"); … … 314 309 boolean keepOutline, String buildingValue) throws UserCancelException { 315 310 final int nb; 316 311 Integer to = null, from = null; 317 if (housenumbers == null || housenumbers.isEmpty()) {312 if (housenumbers.isEmpty()) { 318 313 to = getNumber(end); 319 314 from = getNumber(start); 320 315 if (to != null && from != null) { … … 337 332 338 333 final boolean swap = init != null && (interp.a.lastNode().equals(init) || interp.b.lastNode().equals(init)); 339 334 340 final double frontLength = wayLength(interp.a);341 final double backLength = wayLength(interp.b);335 final double frontLength = interp.a.getLength(); 336 final double backLength = interp.b.getLength(); 342 337 343 338 // new nodes array to hold all intermediate nodes 344 339 // This set will contain at least 4 existing nodes from the original outline … … 430 425 } 431 426 } 432 427 433 UndoRedoHandler.getInstance().add(createTerracingCommand( outline));428 UndoRedoHandler.getInstance().add(createTerracingCommand()); 434 429 if (nb <= 1 && street != null) { 435 430 // Select the way (for quick selection of a new house (with the same way)) 436 431 MainApplication.getLayerManager().getEditDataSet().setSelected(street); … … 470 465 this.commands.add(new AddCommand(getLayerManager().getEditDataSet(), associatedStreet)); 471 466 } 472 467 473 private Command createTerracingCommand( final Way outline) {468 private Command createTerracingCommand() { 474 469 return new SequenceCommand(tr("Terrace"), commands) { 475 470 @Override 476 471 public boolean executeCommand() { 477 472 boolean result = super.executeCommand(); 478 if (result && tagsInConflict != null) {473 if (result && !conflicts.isEmpty()) { 479 474 try { 480 // Build conflicts commands only after all primitives have been added to dataset to fix #8942 481 List<Command> conflictCommands = CombinePrimitiveResolverDialog.launchIfNecessary( 482 tagsInConflict, primitives, Collections.singleton(outline)); 483 if (!conflictCommands.isEmpty()) { 484 List<Command> newCommands = new ArrayList<>(commands); 485 newCommands.addAll(conflictCommands); 486 setSequence(newCommands.toArray(new Command[0])); 487 // Run conflicts commands 488 for (int i = 0; i < conflictCommands.size(); i++) { 489 result = conflictCommands.get(i).executeCommand(); 490 if (!result && !continueOnError) { 491 setSequenceComplete(false); 492 undoCommands(commands.size()+i-1); 493 return false; 475 for (Pair<TagCollection, List<OsmPrimitive>> conflict : conflicts) { 476 // Build conflicts commands only after all primitives have been added to dataset to fix #8942 477 OsmPrimitive target = getLayerManager().getEditDataSet().getPrimitiveById(conflict.b.get(1)); 478 if (target == null) 479 continue; 480 List<Command> conflictCommands = CombinePrimitiveResolverDialog.launchIfNecessary( 481 conflict.a, Collections.singleton(conflict.b.get(0)), 482 Collections.singleton(target)); 483 if (!conflictCommands.isEmpty()) { 484 List<Command> newCommands = new ArrayList<>(commands); 485 newCommands.addAll(conflictCommands); 486 setSequence(newCommands.toArray(new Command[0])); 487 // Run conflicts commands 488 for (int i = 0; i < conflictCommands.size(); i++) { 489 result = conflictCommands.get(i).executeCommand(); 490 if (!result && !continueOnError) { 491 setSequenceComplete(false); 492 undoCommands(commands.size()+i-1); 493 return false; 494 } 494 495 } 495 496 } 496 497 } … … 511 512 * @param streetName the name of a street (may be null). Used if not null and street is null. 512 513 * @param associatedStreet The associated street. Used to determine if addr:street should be set or not. 513 514 * @param buildingValue The value for {@code building} key to add 514 * @return {@code outline}515 515 * @throws UserCancelException if user cancels the operation 516 516 */ 517 517 private void addressBuilding(Way outline, Way street, String streetName, Relation associatedStreet, … … 521 521 boolean numberAdded = false; 522 522 Map<String, String> tags = new HashMap<>(); 523 523 if (houseNum != null) { 524 primitives = Arrays.asList(new OsmPrimitive[]{houseNum, outline});524 List<OsmPrimitive> primitives = Arrays.asList(houseNum, outline); 525 525 526 526 TagCollection tagsToCopy = TagCollection.unionOfAllPrimitives(primitives).getTagsFor(houseNum.keySet()); 527 tagsInConflict = tagsToCopy.getTagsFor(tagsToCopy.getKeysWithMultipleValues()); 527 TagCollection tagsInConflict = tagsToCopy.getTagsFor(tagsToCopy.getKeysWithMultipleValues()); 528 if (!tagsInConflict.isEmpty()) { 529 conflicts.add(Pair.create(tagsInConflict, primitives)); 530 } 528 531 tagsToCopy = tagsToCopy.minus(tagsInConflict).minus(TagCollection.from(outline)); 529 532 530 533 for (Tag tag : tagsToCopy) { … … 582 585 } 583 586 584 587 /** 585 * Calculates the great circle length of a way by summing the great circle586 * distance of each pair of nodes.587 *588 * @param w The way to calculate length of.589 * @return The length of the way.590 */591 private double wayLength(Way w) {592 double length = 0.0;593 for (Pair<Node, Node> p : w.getNodePairs(false)) {594 length += p.a.getCoor().greatCircleDistance(p.b.getCoor());595 }596 return length;597 }598 599 /**600 588 * Given a way, try and find a definite front and back by looking at the 601 589 * segments to find the "sides". Sides are assumed to be single segments 602 590 * which cannot be contiguous.