Changeset 17358 in josm for trunk/src/org
- Timestamp:
- 2020-11-25T11:50:22+01:00 (4 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/CreateMultipolygonAction.java
r17343 r17358 26 26 import org.openstreetmap.josm.actions.relation.DownloadSelectedIncompleteMembersAction; 27 27 import org.openstreetmap.josm.command.AddCommand; 28 import org.openstreetmap.josm.command.Change Command;28 import org.openstreetmap.josm.command.ChangeMembersCommand; 29 29 import org.openstreetmap.josm.command.ChangePropertyCommand; 30 30 import org.openstreetmap.josm.command.Command; … … 116 116 // to avoid EDT violations 117 117 SwingUtilities.invokeLater(() -> { 118 if (multipolygonRelation != null) { 119 // rather ugly: update generated a ChangeMembersCommand with a copy of the member list, so clear the list now 120 commandAndRelation.b.setMembers(null); // #see 19885 121 } 118 122 UndoRedoHandler.getInstance().add(command); 119 123 final Relation relation = (Relation) MainApplication.getLayerManager().getEditDataSet() … … 229 233 * @param selectedWays selected ways 230 234 * @param selectedMultipolygonRelation selected multipolygon relation 231 * @return pair of old and new multipolygon relation if a difference was found, else the pair contains the old relation twice 235 * @return null if ways don't build a valid multipolygon, pair of old and new multipolygon relation if a difference was found, 236 * else the pair contains the old relation twice 232 237 */ 233 238 public static Pair<Relation, Relation> updateMultipolygonRelation(Collection<Way> selectedWays, Relation selectedMultipolygonRelation) { … … 244 249 } 245 250 showErrors(mpTest.getErrors()); 251 calculated.setMembers(null); // see #19885 246 252 return null; //could not make multipolygon. 247 253 } … … 280 286 } 281 287 foundDiff |= merged.addAll(calculated.getMembers()); 288 calculated.setMembers(null); // see #19885 282 289 if (!foundDiff) { 283 290 return Pair.create(old, old); // unchanged … … 343 350 } else { 344 351 if (!unchanged) { 345 list.add(new Change Command(existingRelation, relation));352 list.add(new ChangeMembersCommand(existingRelation, new ArrayList<>(relation.getMembers()))); 346 353 } 347 354 if (list.isEmpty()) { … … 390 397 391 398 /** 392 * This method removes tags/value pairs from inner and outer ways and put them on relation if necessary 399 * This method removes tags/value pairs from inner and outer ways and put them on relation if necessary. 393 400 * Function was extended in reltoolbox plugin by Zverikk and copied back to the core 394 * @param relation the multipolygon style relation to process 401 * @param relation the multipolygon style relation to process. If it is new, the tags might be 402 * modified, else the list of commands will contain a command to modify its tags 395 403 * @return a list of commands to execute 396 404 */ … … 472 480 } 473 481 474 if (moveTags) { 482 values.remove("area"); 483 if (moveTags && !values.isEmpty()) { 475 484 // add those tag values to the relation 476 485 boolean fixed = false; 477 Relation r2 = new Relation(relation);486 Map<String, String> tagsToAdd = new HashMap<>(); 478 487 for (Entry<String, String> entry : values.entrySet()) { 479 488 String key = entry.getKey(); 480 if (!r 2.hasKey(key) && !"area".equals(key)) {489 if (!relation.hasKey(key)) { 481 490 if (relation.isNew()) 482 491 relation.put(key, entry.getValue()); 483 492 else 484 r2.put(key, entry.getValue());493 tagsToAdd.put(key, entry.getValue()); 485 494 fixed = true; 486 495 } … … 491 500 ds = MainApplication.getLayerManager().getEditDataSet(); 492 501 } 493 commands.add(new ChangeCommand(ds, relation, r2)); 494 } else { 495 r2.setMembers(null); // see #19885 502 commands.add(new ChangePropertyCommand(ds, Collections.singleton(relation), tagsToAdd)); 496 503 } 497 504 } -
trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java
r17188 r17358 26 26 import org.openstreetmap.josm.actions.ReverseWayAction.ReverseWayResult; 27 27 import org.openstreetmap.josm.command.AddCommand; 28 import org.openstreetmap.josm.command.Change Command;28 import org.openstreetmap.josm.command.ChangeMembersCommand; 29 29 import org.openstreetmap.josm.command.ChangeNodesCommand; 30 import org.openstreetmap.josm.command.ChangePropertyCommand; 30 31 import org.openstreetmap.josm.command.Command; 31 32 import org.openstreetmap.josm.command.DeleteCommand; … … 1634 1635 } 1635 1636 1636 Relation newRel = new Relation(r); 1637 List<RelationMember> members = newRel.getMembers(); 1637 List<RelationMember> members = r.getMembers(); 1638 1638 members.remove(rm); 1639 newRel.setMembers(members); 1640 1641 cmds.add(new ChangeCommand(r, newRel)); 1639 1640 cmds.add(new ChangeMembersCommand(r, members)); 1642 1641 RelationRole saverel = new RelationRole(r, rm.getRole()); 1643 1642 if (!result.contains(saverel)) { … … 1674 1673 } 1675 1674 // Add it back! 1676 Relation newRel = new Relation(r.rel); 1677 newRel.addMember(new RelationMember(r.role, outer)); 1678 cmds.add(new ChangeCommand(r.rel, newRel)); 1679 } 1680 1681 Relation newRel; 1682 RelationRole soleOuter; 1675 List<RelationMember> modifiedMembers = new ArrayList<>(r.rel.getMembers()); 1676 modifiedMembers.add(new RelationMember(r.role, outer)); 1677 cmds.add(new ChangeMembersCommand(r.rel, modifiedMembers)); 1678 } 1679 1683 1680 switch (multiouters.size()) { 1684 1681 case 0: … … 1686 1683 case 1: 1687 1684 // Found only one to be part of a multipolygon relation, so just add it back as well 1688 soleOuter = multiouters.get(0);1689 newRel = new Relation(soleOuter.rel);1690 newRel.addMember(new RelationMember(soleOuter.role, outer));1691 cmds.add(new Change Command(ds, soleOuter.rel, newRel));1685 RelationRole soleOuter = multiouters.get(0); 1686 List<RelationMember> modifiedMembers = new ArrayList<>(soleOuter.rel.getMembers()); 1687 modifiedMembers.add(new RelationMember(soleOuter.role, outer)); 1688 cmds.add(new ChangeMembersCommand(ds, soleOuter.rel, modifiedMembers)); 1692 1689 return; 1693 1690 default: 1694 1691 // Create a new relation with all previous members and (Way)outer as outer. 1695 newRel = new Relation();1692 Relation newRel = new Relation(); 1696 1693 for (RelationRole r : multiouters) { 1697 1694 // Add members … … 1718 1715 */ 1719 1716 private void stripTags(Collection<Way> ways) { 1720 for (Way w : ways) {1721 final Way wayWithoutTags = new Way(w);1722 wayWithoutTags.removeAll();1723 cmds.add(new ChangeCommand(w, wayWithoutTags));1724 }1717 Map<String, String> tagsToRemove = new HashMap<>(); 1718 ways.stream().flatMap(w -> w.keySet().stream()).forEach(k -> tagsToRemove.put(k, null)); 1719 if (tagsToRemove.isEmpty()) 1720 return; 1721 cmds.add(new ChangePropertyCommand(new ArrayList<>(ways), tagsToRemove)); 1725 1722 /* I18N: current action printed in status display */ 1726 1723 commitCommands(marktr("Remove tags from inner ways")); -
trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java
r17333 r17358 18 18 import org.openstreetmap.josm.actions.corrector.ReverseWayNoTagCorrector; 19 19 import org.openstreetmap.josm.actions.corrector.ReverseWayTagCorrector; 20 import org.openstreetmap.josm.command.Change Command;20 import org.openstreetmap.josm.command.ChangeNodesCommand; 21 21 import org.openstreetmap.josm.command.Command; 22 22 import org.openstreetmap.josm.command.SequenceCommand; … … 41 41 */ 42 42 public static class ReverseWayResult { 43 private final Way newWay;44 43 private final Collection<Command> tagCorrectionCommands; 45 44 private final Command reverseCommand; … … 47 46 /** 48 47 * Create a new {@link ReverseWayResult} 49 * @param newWay The new way primitive50 48 * @param tagCorrectionCommands The commands to correct the tags 51 49 * @param reverseCommand The command to reverse the way 52 50 */ 53 public ReverseWayResult(Way newWay, Collection<Command> tagCorrectionCommands, Command reverseCommand) { 54 this.newWay = newWay; 51 public ReverseWayResult(Collection<Command> tagCorrectionCommands, Command reverseCommand) { 55 52 this.tagCorrectionCommands = tagCorrectionCommands; 56 53 this.reverseCommand = reverseCommand; 57 }58 59 /**60 * Gets the new way object61 * @return The new, reversed way62 */63 public Way getNewWay() {64 return newWay;65 54 } 66 55 … … 150 139 public static ReverseWayResult reverseWay(Way w) throws UserCancelException { 151 140 ReverseWayNoTagCorrector.checkAndConfirmReverseWay(w); 152 Way wnew = new Way(w); 153 List<Node> nodesCopy = wnew.getNodes(); 141 List<Node> nodesCopy = w.getNodes(); 154 142 Collections.reverse(nodesCopy); 155 wnew.setNodes(nodesCopy);156 143 157 144 Collection<Command> corrCmds = Collections.<Command>emptyList(); 158 145 if (Config.getPref().getBoolean("tag-correction.reverse-way", true)) { 159 corrCmds = new ReverseWayTagCorrector().execute(w, w new);146 corrCmds = new ReverseWayTagCorrector().execute(w, w); 160 147 } 161 return new ReverseWayResult( wnew, corrCmds, new ChangeCommand(w, wnew));148 return new ReverseWayResult(corrCmds, new ChangeNodesCommand(w, new ArrayList<>(nodesCopy))); 162 149 } 163 150 -
trunk/src/org/openstreetmap/josm/command/ChangePropertyCommand.java
r16800 r17358 8 8 import java.util.Collection; 9 9 import java.util.Collections; 10 import java.util.HashMap; 10 11 import java.util.LinkedList; 11 12 import java.util.List; 12 13 import java.util.Map; 14 import java.util.Map.Entry; 13 15 import java.util.NoSuchElementException; 14 16 import java.util.Objects; … … 21 23 import org.openstreetmap.josm.data.osm.OsmPrimitive; 22 24 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 25 import org.openstreetmap.josm.data.osm.Tagged; 23 26 import org.openstreetmap.josm.tools.I18n; 24 27 import org.openstreetmap.josm.tools.ImageProvider; … … 73 76 * @param ds The target data set. Must not be {@code null} 74 77 * @param objects the objects to modify. Must not be empty 75 * @param tags the tags to set 78 * @param tags the tags to set. Caller must make sure that the tas are not changed once the command was executed. 76 79 * @since 12726 77 80 */ … … 86 89 * 87 90 * @param objects the objects to modify. Must not be empty, and objects must belong to a data set 88 * @param tags the tags to set 91 * @param tags the tags to set. Caller must make sure that the tas are not changed once the command was executed. 89 92 * @throws NullPointerException if objects is null or contain null item 90 93 * @throws NoSuchElementException if objects is empty … … 287 290 Objects.equals(tags, that.tags); 288 291 } 292 293 /** 294 * Calculate the {@link ChangePropertyCommand} that is needed to change the tags in source to be equal to those in target. 295 * @param source the source primitive 296 * @param target the target primitive 297 * @return null if no changes are needed, else a {@link ChangePropertyCommand} 298 * @since 17357 299 */ 300 public static Command build(OsmPrimitive source, Tagged target) { 301 Map<String, String> changedTags = new HashMap<>(); 302 // find tags which have to be changed or removed 303 for (Entry<String, String> tag : source.getKeys().entrySet()) { 304 String key = tag.getKey(); 305 String val = target.get(key); 306 if (!tag.getValue().equals(val)) 307 changedTags.put(key, val); // null or a different value 308 } 309 // find tags which exist only in target, they have to be added 310 for (Entry<String, String> tag : target.getKeys().entrySet()) { 311 String key = tag.getKey(); 312 if (!source.hasTag(key)) 313 changedTags.put(key, tag.getValue()); 314 } 315 if (changedTags.isEmpty()) 316 return null; 317 if (changedTags.size() == 1) { 318 Entry<String, String> tag = changedTags.entrySet().iterator().next(); 319 return new ChangePropertyCommand(Collections.singleton(source), tag.getKey(), tag.getValue()); 320 } 321 return new ChangePropertyCommand(Collections.singleton(source), new HashMap<>(changedTags)); 322 } 289 323 } -
trunk/src/org/openstreetmap/josm/command/SplitWayCommand.java
r17163 r17358 17 17 import java.util.HashSet; 18 18 import java.util.Iterator; 19 import java.util.LinkedHashSet; 19 20 import java.util.LinkedList; 20 21 import java.util.List; … … 90 91 * @param newSelection The new list of selected primitives ids (which is saved for later retrieval with {@link #getNewSelection}) 91 92 * @param originalWay The original way being split (which is saved for later retrieval with {@link #getOriginalWay}) 92 * @param newWays The resulting new ways (which is saved for later retrieval with {@link #get OriginalWay})93 * @param newWays The resulting new ways (which is saved for later retrieval with {@link #getNewWays}) 93 94 */ 94 95 public SplitWayCommand(String name, Collection<Command> commandList, … … 402 403 } catch (OsmTransferException e) { 403 404 ExceptionDialogUtil.explainException(e); 405 analysis.cleanup(); 404 406 return Optional.empty(); 405 407 } 406 408 // If missing relation members were downloaded, perform the analysis again to find the relation 407 409 // member order for all relations. 410 analysis.cleanup(); 408 411 analysis = analyseSplit(way, wayToKeep, newWays); 409 return Optional.of(splitBasedOnAnalyses(way, newWays, newSelection, analysis, indexOfWayToKeep));412 break; 410 413 case GO_AHEAD_WITHOUT_DOWNLOADS: 411 414 // Proceed with the split with the information we have. 412 415 // This can mean that there are no missing members we want, or that the user chooses to continue 413 416 // the split without downloading them. 414 return Optional.of(splitBasedOnAnalyses(way, newWays, newSelection, analysis, indexOfWayToKeep));417 break; 415 418 case USER_ABORTED: 416 419 default: 417 420 return Optional.empty(); 421 } 422 try { 423 return Optional.of(splitBasedOnAnalyses(way, newWays, newSelection, analysis, indexOfWayToKeep)); 424 } finally { 425 // see #19885 426 wayToKeep.setNodes(null); 427 analysis.cleanup(); 418 428 } 419 429 } … … 465 475 } 466 476 if (c == null) { 467 c = new Relation(r); 477 c = new Relation(r); // #19885: will be removed later 468 478 } 469 479 … … 552 562 } 553 563 } 554 555 if (c != null) {556 commandList.add(new ChangeCommand(r.getDataSet(), r, c));557 }558 564 } 559 565 changedWay.setNodes(null); // see #19885 … … 575 581 warningTypes = warnings; 576 582 this.numberOfRelations = numberOfRelations; 583 } 584 585 /** 586 * Unlink temporary copies of relations. See #19885 587 */ 588 void cleanup() { 589 for (RelationAnalysis ra : relationAnalyses) { 590 if (ra.relation.getDataSet() == null) 591 ra.relation.setMembers(null); 592 } 577 593 } 578 594 … … 688 704 } 689 705 706 Set<Relation> modifiedRelations = new LinkedHashSet<>(); 690 707 // Perform the split. 691 708 for (RelationAnalysis relationAnalysis : analysis.getRelationAnalyses()) { … … 729 746 } 730 747 } 748 modifiedRelations.add(relation); 749 } 750 for (Relation r : modifiedRelations) { 751 DataSet ds = way.getDataSet(); 752 Relation orig = (Relation) ds.getPrimitiveById(r); 753 analysis.getCommands().add(new ChangeMembersCommand(orig, new ArrayList<>(r.getMembers()))); 754 r.setMembers(null); // see #19885 731 755 } 732 756 -
trunk/src/org/openstreetmap/josm/data/osm/MultipolygonBuilder.java
r15390 r17358 118 118 MultipolygonTest mpTest = new MultipolygonTest(); 119 119 Relation calculated = mpTest.makeFromWays(ways); 120 if (!mpTest.getErrors().isEmpty()) { 121 return mpTest.getErrors().iterator().next().getMessage(); 122 } 123 Pair<List<JoinedPolygon>, List<JoinedPolygon>> outerInner = joinWays(calculated); 124 this.outerWays.clear(); 125 this.innerWays.clear(); 126 this.outerWays.addAll(outerInner.a); 127 this.innerWays.addAll(outerInner.b); 128 return null; 120 try { 121 if (!mpTest.getErrors().isEmpty()) { 122 return mpTest.getErrors().iterator().next().getMessage(); 123 } 124 Pair<List<JoinedPolygon>, List<JoinedPolygon>> outerInner = joinWays(calculated); 125 this.outerWays.clear(); 126 this.innerWays.clear(); 127 this.outerWays.addAll(outerInner.a); 128 this.innerWays.addAll(outerInner.b); 129 return null; 130 } finally { 131 calculated.setMembers(null); // see #19885 132 } 129 133 } 130 134 -
trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
r17215 r17358 1154 1154 return; 1155 1155 1156 Relation copy = new Relation(cur);1156 List<RelationMember> members = cur.getMembers(); 1157 1157 for (OsmPrimitive primitive: OsmDataManager.getInstance().getInProgressSelection()) { 1158 copy.removeMembersFor(primitive); 1159 } 1160 UndoRedoHandler.getInstance().add(new ChangeMembersCommand(cur, copy.getMembers())); 1161 copy.setMembers(null); // see #19885 1158 members.removeIf(rm -> rm.getMember() == primitive); 1159 } 1160 UndoRedoHandler.getInstance().add(new ChangeMembersCommand(cur, members)); 1162 1161 1163 1162 tagTable.clearSelection(); -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
r17172 r17358 49 49 50 50 import org.openstreetmap.josm.actions.JosmAction; 51 import org.openstreetmap.josm.command.Change Command;51 import org.openstreetmap.josm.command.ChangeMembersCommand; 52 52 import org.openstreetmap.josm.command.Command; 53 53 import org.openstreetmap.josm.data.UndoRedoHandler; … … 939 939 final Collection<TaggingPreset> presets = TaggingPresets.getMatchingPresets( 940 940 EnumSet.of(TaggingPresetType.forPrimitive(orig)), orig.getKeys(), false); 941 Relation relation= new Relation(orig);941 Relation target = new Relation(orig); 942 942 boolean modified = false; 943 943 for (OsmPrimitive p : primitivesToAdd) { 944 944 if (p instanceof Relation) { 945 List<Relation> loop = RelationChecker.checkAddMember( relation, (Relation) p);945 List<Relation> loop = RelationChecker.checkAddMember(target, (Relation) p); 946 946 if (!loop.isEmpty() && loop.get(0).equals(loop.get(loop.size() - 1))) { 947 947 warnOfCircularReferences(p, loop); 948 948 continue; 949 949 } 950 } else if (MemberTableModel.hasMembersReferringTo( relation.getMembers(), Collections.singleton(p))950 } else if (MemberTableModel.hasMembersReferringTo(target.getMembers(), Collections.singleton(p)) 951 951 && !confirmAddingPrimitive(p)) { 952 952 continue; 953 953 } 954 954 final Set<String> roles = findSuggestedRoles(presets, p); 955 relation.addMember(new RelationMember(roles.size() == 1 ? roles.iterator().next() : "", p));955 target.addMember(new RelationMember(roles.size() == 1 ? roles.iterator().next() : "", p)); 956 956 modified = true; 957 957 } 958 if (!modified) { 959 relation.setMembers(null); // see #19885 960 } 961 return modified ? new ChangeCommand(orig, relation) : null; 958 List<RelationMember> members = new ArrayList<>(target.getMembers()); 959 target.setMembers(null); // see #19885 960 return modified ? new ChangeMembersCommand(orig, members) : null; 962 961 } catch (AddAbortException ign) { 963 962 Logging.trace(ign); -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationEditor.java
r17172 r17358 14 14 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 15 15 import org.openstreetmap.josm.tools.CheckParameterUtil; 16 import org.openstreetmap.josm.tools.Logging; 16 17 17 18 /** … … 71 72 * 72 73 * @param layer the data layer the relation is a member of 73 * @param r the relation to be edited 74 * @param r the relation to be edited. If the relation doesn't belong to a {@code DataSet} 75 * callers MUST NOT use the relation after calling this method. 74 76 * @param selectedMembers a collection of relation members which shall be selected when the editor is first launched 75 77 * @return an instance of RelationEditor suitable for editing that kind of relation … … 80 82 else { 81 83 RelationEditor editor = new GenericRelationEditor(layer, r, selectedMembers); 84 if (r != null && r.getDataSet() == null) { 85 // see #19885: We have to assume that the relation was only created as container for tags and members 86 // the editor has created its own copy by now. 87 // Since the members point to the container we unlink them here. 88 Logging.debug("Member list is reset for relation {0}", r.getUniqueId()); 89 r.setMembers(null); 90 } 91 82 92 RelationDialogManager.getRelationDialogManager().positionOnScreen(editor); 83 93 RelationDialogManager.getRelationDialogManager().register(layer, r, editor); -
trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/SavingAction.java
r17172 r17358 5 5 6 6 import java.awt.Component; 7 import java.util.ArrayList; 8 import java.util.List; 7 9 8 10 import javax.swing.JOptionPane; … … 11 13 import org.openstreetmap.josm.command.AddCommand; 12 14 import org.openstreetmap.josm.command.ChangeCommand; 15 import org.openstreetmap.josm.command.ChangeMembersCommand; 16 import org.openstreetmap.josm.command.ChangePropertyCommand; 17 import org.openstreetmap.josm.command.Command; 13 18 import org.openstreetmap.josm.command.conflict.ConflictAddCommand; 14 19 import org.openstreetmap.josm.data.UndoRedoHandler; … … 86 91 tagEditorModel.applyToPrimitive(editedRelation); 87 92 getMemberTableModel().applyToRelation(editedRelation); 88 if (!editedRelation.hasEqualSemanticAttributes(originRelation, false)) { 93 List<Command> cmds = new ArrayList<>(); 94 if (originRelation.getKeys().equals(editedRelation.getKeys())) { 95 cmds.add(new ChangeMembersCommand(originRelation, editedRelation.getMembers())); 96 } 97 Command cmdProps = ChangePropertyCommand.build(originRelation, editedRelation); 98 if (cmdProps != null) 99 cmds.add(cmdProps); 100 if (cmds.size() >= 2) { 89 101 UndoRedoHandler.getInstance().add(new ChangeCommand(originRelation, editedRelation)); 90 } else { 102 } else if (!cmds.isEmpty()) { 103 UndoRedoHandler.getInstance().add(cmds.get(0)); 91 104 editedRelation.setMembers(null); // see #19885 92 105 }
Note:
See TracChangeset
for help on using the changeset viewer.