Ticket #7489: 7489_unified2.diff
File 7489_unified2.diff, 34.7 KB (added by , 12 years ago) |
---|
-
src/org/openstreetmap/josm/actions/MergeSelectionAction.java
diff --git a/src/org/openstreetmap/josm/actions/MergeSelectionAction.java b/src/org/openstreetmap/josm/actions/MergeSelectionAction.java index 4c63a0b..c5c4888 100644
a b import java.awt.event.ActionEvent; 8 8 import java.awt.event.KeyEvent; 9 9 import java.util.Collection; 10 10 import java.util.List; 11 import org.openstreetmap.josm.Main; 12 import org.openstreetmap.josm.command.MergeCommand; 11 13 12 14 import org.openstreetmap.josm.data.osm.DataSet; 13 15 import org.openstreetmap.josm.data.osm.OsmPrimitive; 14 import org.openstreetmap.josm.data.osm.visitor.MergeSourceBuildingVisitor;15 16 import org.openstreetmap.josm.gui.dialogs.LayerListDialog; 16 17 import org.openstreetmap.josm.gui.layer.Layer; 17 18 import org.openstreetmap.josm.gui.layer.OsmDataLayer; … … public class MergeSelectionAction extends AbstractMergeAction { 44 45 return; 45 46 } 46 47 } 47 MergeSourceBuildingVisitor builder = new MergeSourceBuildingVisitor(getEditLayer().data); 48 ((OsmDataLayer)targetLayer).mergeFrom(builder.build()); 48 49 MergeCommand cmd = new MergeCommand((OsmDataLayer)targetLayer, getEditLayer().data, true); 50 Main.main.undoRedo.add(cmd); 49 51 } 50 52 53 @Override 51 54 public void actionPerformed(ActionEvent e) { 52 55 if (getEditLayer() == null || getEditLayer().data.getSelected().isEmpty()) 53 56 return; -
src/org/openstreetmap/josm/actions/UpdateSelectionAction.java
diff --git a/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java b/src/org/openstreetmap/josm/actions/UpdateSelectionAction.java index 09156c7..19b5381 100644
a b import java.util.Collections; 13 13 import javax.swing.JOptionPane; 14 14 15 15 import org.openstreetmap.josm.Main; 16 import org.openstreetmap.josm.command.DownloadOsmCommand; 16 17 import org.openstreetmap.josm.data.osm.DataSet; 17 18 import org.openstreetmap.josm.data.osm.OsmPrimitive; 18 19 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; … … public class UpdateSelectionAction extends JosmAction { 39 40 reader.append(getCurrentDataSet(),id, type); 40 41 try { 41 42 DataSet ds = reader.parseOsm(NullProgressMonitor.INSTANCE); 42 Main.ma p.mapView.getEditLayer().mergeFrom(ds);43 Main.main.undoRedo.add(new DownloadOsmCommand(tr("Update selected primitives"), Main.map.mapView.getEditLayer(), ds)); 43 44 } catch(Exception e) { 44 45 ExceptionDialogUtil.explainException(e); 45 46 } -
src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
diff --git a/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java b/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java index 991b381..17879aa 100644
a b import java.util.regex.Matcher; 10 10 import java.util.regex.Pattern; 11 11 12 12 import org.openstreetmap.josm.Main; 13 import org.openstreetmap.josm.actions.AutoScaleAction; 14 import org.openstreetmap.josm.command.DownloadOsmCommand; 13 15 import org.openstreetmap.josm.data.Bounds; 14 16 import org.openstreetmap.josm.data.coor.LatLon; 15 17 import org.openstreetmap.josm.data.osm.DataSet; … … public class DownloadOsmTask extends AbstractDownloadTask { 207 209 if (targetLayer == null) { 208 210 targetLayer = getFirstDataLayer(); 209 211 } 210 targetLayer.mergeFrom(dataSet); 211 computeBboxAndCenterScale(); 212 targetLayer.onPostDownloadFromServer(); 212 Main.main.undoRedo.add(new DownloadOsmCommand(tr("Download primitives from bounding box"), targetLayer, dataSet)); 213 AutoScaleAction.zoomTo(dataSet.allPrimitives()); 213 214 } 214 215 } 215 216 -
new file src/org/openstreetmap/josm/command/DownloadOsmCommand.java
diff --git a/src/org/openstreetmap/josm/command/DownloadOsmCommand.java b/src/org/openstreetmap/josm/command/DownloadOsmCommand.java new file mode 100644 index 0000000..7836f70
- + 1 // License: GPL. Copyright 2012 by Josh Doe and others 2 package org.openstreetmap.josm.command; 3 4 import java.util.ArrayList; 5 import java.util.Collection; 6 import javax.swing.Icon; 7 import org.openstreetmap.josm.data.osm.DataSet; 8 import org.openstreetmap.josm.data.osm.OsmPrimitive; 9 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 10 import static org.openstreetmap.josm.tools.I18n.marktr; 11 import static org.openstreetmap.josm.tools.I18n.tr; 12 import org.openstreetmap.josm.tools.ImageProvider; 13 14 /** 15 * A command that merges a downloaded dataset to a layer. 16 * 17 * @author joshdoe 18 */ 19 public class DownloadOsmCommand extends Command { 20 private OsmDataLayer targetLayer; 21 private DataSet sourceDataSet; 22 private MergeCommand mergeCommand; 23 private boolean requiresSaveToFile; 24 private boolean requiresUploadToServer; 25 private String commandSummary; 26 27 public DownloadOsmCommand(String commandSummary, OsmDataLayer targetLayer, DataSet sourceDataSet) { 28 super(targetLayer); 29 this.commandSummary = commandSummary; 30 this.targetLayer = targetLayer; 31 this.sourceDataSet = sourceDataSet; 32 mergeCommand = new MergeCommand(targetLayer, sourceDataSet, false); 33 } 34 35 @Override 36 public boolean executeCommand() { 37 if (!mergeCommand.executeCommand()) { 38 return false; 39 } 40 requiresSaveToFile = targetLayer.requiresSaveToFile(); 41 requiresUploadToServer = targetLayer.requiresUploadToServer(); 42 targetLayer.setRequiresSaveToFile(true); 43 targetLayer.setRequiresUploadToServer(sourceDataSet.isModified()); 44 return true; 45 } 46 47 @Override 48 public void undoCommand() { 49 mergeCommand.undoCommand(); 50 boolean oldValue; 51 oldValue = targetLayer.requiresSaveToFile(); 52 targetLayer.setRequiresSaveToFile(requiresSaveToFile); 53 requiresSaveToFile = oldValue; 54 oldValue = targetLayer.requiresUploadToServer(); 55 targetLayer.setRequiresUploadToServer(requiresUploadToServer); 56 requiresUploadToServer = oldValue; 57 } 58 59 @Override 60 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 61 throw new UnsupportedOperationException("Not supported yet."); 62 } 63 64 @Override 65 public String getDescriptionText() { 66 return commandSummary; 67 } 68 69 @Override 70 public Icon getDescriptionIcon() { 71 return ImageProvider.get("dialogs", "down"); 72 } 73 74 @Override 75 public Collection<? extends OsmPrimitive> getParticipatingPrimitives() { 76 return sourceDataSet.allPrimitives(); 77 } 78 79 private class DownloadPseudoCommand extends PseudoCommand { 80 81 @Override 82 public String getDescriptionText() { 83 return tr(marktr("Download {0} nodes, {1} ways, {2} relations"), 84 sourceDataSet.getNodes().size(), 85 sourceDataSet.getWays().size(), 86 sourceDataSet.getRelations().size()); 87 } 88 89 @Override 90 public Collection<? extends OsmPrimitive> getParticipatingPrimitives() { 91 return sourceDataSet.allPrimitives(); 92 } 93 94 @Override 95 public Icon getDescriptionIcon() { 96 return ImageProvider.get("dialogs", "down"); 97 } 98 99 } 100 @Override 101 public Collection<PseudoCommand> getChildren() { 102 ArrayList<PseudoCommand> children = new ArrayList<PseudoCommand>(); 103 children.add(new DownloadPseudoCommand()); 104 children.add(mergeCommand); 105 return children; 106 } 107 108 } -
new file src/org/openstreetmap/josm/command/MergeCommand.java
diff --git a/src/org/openstreetmap/josm/command/MergeCommand.java b/src/org/openstreetmap/josm/command/MergeCommand.java new file mode 100644 index 0000000..c36ee77
- + 1 // License: GPL. Copyright 2012 by Josh Doe and others 2 package org.openstreetmap.josm.command; 3 4 import java.awt.geom.Area; 5 import java.util.Collection; 6 import java.util.HashSet; 7 import javax.swing.Icon; 8 import javax.swing.JOptionPane; 9 import org.openstreetmap.josm.Main; 10 import org.openstreetmap.josm.data.conflict.Conflict; 11 import org.openstreetmap.josm.data.osm.*; 12 import org.openstreetmap.josm.data.osm.visitor.MergeSourceBuildingVisitor; 13 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 14 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor; 15 import org.openstreetmap.josm.tools.CheckParameterUtil; 16 import static org.openstreetmap.josm.tools.I18n.marktr; 17 import static org.openstreetmap.josm.tools.I18n.tr; 18 import org.openstreetmap.josm.tools.ImageProvider; 19 20 /** 21 * A command that merges objects from one layer to another. 22 * 23 * @author joshdoe 24 */ 25 public class MergeCommand extends Command { 26 27 private DataSetMerger merger; 28 private DataSet sourceDataSet; 29 private DataSet targetDataSet; 30 private OsmDataLayer targetLayer; 31 private Collection<DataSource> addedDataSources; 32 private String otherVersion; 33 private Collection<Conflict> addedConflicts; 34 35 /** 36 * Create command to merge all or only currently selected objects from 37 * sourceDataSet to targetLayer. 38 * 39 * @param targetLayer 40 * @param sourceDataSet 41 * @param onlySelected true to only merge objects selected in the 42 * sourceDataSet 43 */ 44 public MergeCommand(OsmDataLayer targetLayer, DataSet sourceDataSet, boolean onlySelected) { 45 this(targetLayer, sourceDataSet, onlySelected ? sourceDataSet.getSelected() : null); 46 } 47 48 /** 49 * Create command to merge the selection from the sourceDataSet to the 50 * targetLayer. 51 * 52 * @param targetLayer 53 * @param sourceDataSet 54 * @param selection 55 */ 56 public MergeCommand(OsmDataLayer targetLayer, DataSet sourceDataSet, Collection<OsmPrimitive> selection) { 57 super(targetLayer); 58 CheckParameterUtil.ensureParameterNotNull(targetLayer, "targetLayer"); 59 CheckParameterUtil.ensureParameterNotNull(sourceDataSet, "sourceDataSet"); 60 this.targetLayer = targetLayer; 61 this.targetDataSet = targetLayer.data; 62 63 // if selection present, create new dataset with just selected objects 64 // and their "hull" (otherwise use entire dataset) 65 if (selection != null && !selection.isEmpty()) { 66 Collection<OsmPrimitive> origSelection = sourceDataSet.getSelected(); 67 sourceDataSet.setSelected(selection); 68 MergeSourceBuildingVisitor builder = new MergeSourceBuildingVisitor(sourceDataSet); 69 this.sourceDataSet = builder.build(); 70 sourceDataSet.setSelected(origSelection); 71 } else { 72 this.sourceDataSet = sourceDataSet; 73 } 74 75 76 addedConflicts = new HashSet<Conflict>(); 77 addedDataSources = new HashSet<DataSource>(); 78 } 79 80 @Override 81 public boolean executeCommand() { 82 PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Merging data")); 83 monitor.setCancelable(false); 84 if (merger == null) { 85 //first time command is executed 86 merger = new DataSetMerger(targetDataSet, sourceDataSet); 87 try { 88 merger.merge(monitor); 89 } catch (DataIntegrityProblemException e) { 90 JOptionPane.showMessageDialog( 91 Main.parent, 92 e.getHtmlMessage() != null ? e.getHtmlMessage() : e.getMessage(), 93 tr("Error"), 94 JOptionPane.ERROR_MESSAGE); 95 return false; 96 97 } 98 99 Area a = targetDataSet.getDataSourceArea(); 100 101 // copy the merged layer's data source info; 102 // only add source rectangles if they are not contained in the 103 // layer already. 104 for (DataSource src : sourceDataSet.dataSources) { 105 if (a == null || !a.contains(src.bounds.asRect())) { 106 targetDataSet.dataSources.add(src); 107 addedDataSources.add(src); 108 } 109 } 110 111 otherVersion = targetDataSet.getVersion(); 112 // copy the merged layer's API version, downgrade if required 113 if (targetDataSet.getVersion() == null) { 114 targetDataSet.setVersion(sourceDataSet.getVersion()); 115 } else if ("0.5".equals(targetDataSet.getVersion()) ^ "0.5".equals(sourceDataSet.getVersion())) { 116 System.err.println(tr("Warning: mixing 0.6 and 0.5 data results in version 0.5")); 117 targetDataSet.setVersion("0.5"); 118 } 119 120 121 // FIXME: allow conflicts to be retrieved rather than added to layer? 122 if (targetLayer != null) { 123 for (Conflict<?> c : merger.getConflicts()) { 124 if (!targetLayer.getConflicts().hasConflict(c)) { 125 targetLayer.getConflicts().add(c); 126 addedConflicts.add(c); 127 } 128 } 129 } 130 } else { 131 // command is being "redone" 132 133 merger.remerge(); 134 targetDataSet.dataSources.addAll(addedDataSources); 135 136 String version = otherVersion; 137 otherVersion = targetDataSet.getVersion(); 138 targetDataSet.setVersion(version); 139 140 for (Conflict c : addedConflicts) { 141 targetLayer.getConflicts().add(c); 142 } 143 } 144 145 if (addedConflicts.size() > 0) { 146 targetLayer.warnNumNewConflicts(addedConflicts.size()); 147 } 148 149 // repaint to make sure new data is displayed properly. 150 Main.map.mapView.repaint(); 151 152 monitor.close(); 153 154 return true; 155 } 156 157 @Override 158 public void undoCommand() { 159 merger.unmerge(); 160 161 // restore data source area 162 targetDataSet.dataSources.removeAll(addedDataSources); 163 164 String version = otherVersion; 165 otherVersion = targetDataSet.getVersion(); 166 targetDataSet.setVersion(version); 167 168 for (Conflict c : addedConflicts) { 169 targetLayer.getConflicts().remove(c); 170 } 171 172 Main.map.mapView.repaint(); 173 } 174 175 @Override 176 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted, Collection<OsmPrimitive> added) { 177 throw new UnsupportedOperationException("Not supported yet."); 178 } 179 180 @Override 181 public String getDescriptionText() { 182 return tr(marktr("Merged objects: {0} added, {1} modified"), 183 merger.getAddedObjects().size(), 184 merger.getChangedObjectsMap().size()); 185 } 186 187 @Override 188 public Icon getDescriptionIcon() { 189 return ImageProvider.get("dialogs", "mergedown"); 190 } 191 192 @Override 193 public Collection<? extends OsmPrimitive> getParticipatingPrimitives() { 194 HashSet<OsmPrimitive> prims = new HashSet<OsmPrimitive>(); 195 prims.addAll(merger.getAddedObjects()); 196 prims.addAll(merger.getChangedObjectsMap().keySet()); 197 return prims; 198 } 199 } 200 No newline at end of file -
src/org/openstreetmap/josm/data/osm/DataSetMerger.java
diff --git a/src/org/openstreetmap/josm/data/osm/DataSetMerger.java b/src/org/openstreetmap/josm/data/osm/DataSetMerger.java index e66bda8..7c3d276 100644
a b public class DataSetMerger { 43 43 */ 44 44 private final Set<PrimitiveId> objectsWithChildrenToMerge; 45 45 private final Set<OsmPrimitive> objectsToDelete; 46 47 private final Map<OsmPrimitive, PrimitiveData> changedObjectsMap; 48 private final Set<OsmPrimitive> addedObjects; 49 50 private enum UndoState { 51 INIT, MERGED, UNDONE, REDONE 52 } 53 private UndoState undoState; 46 54 47 55 /** 48 56 * constructor … … public class DataSetMerger { 61 69 mergedMap = new HashMap<PrimitiveId, PrimitiveId>(); 62 70 objectsWithChildrenToMerge = new HashSet<PrimitiveId>(); 63 71 objectsToDelete = new HashSet<OsmPrimitive>(); 72 changedObjectsMap = new HashMap<OsmPrimitive, PrimitiveData>(); 73 addedObjects = new HashSet<OsmPrimitive>(); 74 undoState = UndoState.INIT; 64 75 } 65 76 66 77 /** … … public class DataSetMerger { 77 88 * @param <P> the type of the other primitive 78 89 * @param source the other primitive 79 90 */ 80 protected void mergePrimitive(OsmPrimitive source, Collection<? extends OsmPrimitive> candidates) {91 protected void mergePrimitive(OsmPrimitive source, Collection<? extends OsmPrimitive> candidates) { 81 92 if (!source.isNew() ) { 82 93 // try to merge onto a matching primitive with the same 83 94 // defined id … … public class DataSetMerger { 107 118 target.setTimestamp(source.getTimestamp()); 108 119 target.setModified(source.isModified()); 109 120 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 121 changedObjectsMap.put(target, source.save()); 110 122 return; 111 123 } 112 124 } … … public class DataSetMerger { 126 138 targetDataSet.addPrimitive(target); 127 139 mergedMap.put(source.getPrimitiveId(), target.getPrimitiveId()); 128 140 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 141 addedObjects.add(target); 129 142 } 130 143 131 144 protected OsmPrimitive getMergeTarget(OsmPrimitive mergeSource) throws IllegalStateException { … … public class DataSetMerger { 179 192 List<OsmPrimitive> referrers = target.getReferrers(); 180 193 if (referrers.isEmpty()) { 181 194 target.setDeleted(true); 182 target.mergeFrom(source); 195 if (target.mergeFrom(source)) 196 changedObjectsMap.put(target, source.save()); 183 197 it.remove(); 184 198 flag = true; 185 199 } else { … … public class DataSetMerger { 208 222 ((Relation) osm).setMembers(null); 209 223 } 210 224 } 211 for (OsmPrimitive osm: objectsToDelete) { 212 osm.setDeleted(true); 213 osm.mergeFrom(sourceDataSet.getPrimitiveById(osm.getPrimitiveId())); 225 for (OsmPrimitive target: objectsToDelete) { 226 OsmPrimitive source = sourceDataSet.getPrimitiveById(target.getPrimitiveId()); 227 target.setDeleted(true); 228 if (target.mergeFrom(source)) 229 changedObjectsMap.put(target, source.save()); 214 230 } 215 231 } 216 232 } … … public class DataSetMerger { 292 308 // target is incomplete, source completes it 293 309 // => merge source into target 294 310 // 295 target.mergeFrom(source); 311 if (target.mergeFrom(source)) 312 changedObjectsMap.put(target, source.save()); 296 313 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 297 314 } else if (!target.isIncomplete() && source.isIncomplete()) { 298 315 // target is complete and source is incomplete … … public class DataSetMerger { 318 335 if (targetDataSet.getPrimitiveById(referrer.getPrimitiveId()) == null) { 319 336 conflicts.add(new Conflict<OsmPrimitive>(target, source, true)); 320 337 target.setDeleted(false); 338 changedObjectsMap.put(target, source.save()); 321 339 break; 322 340 } 323 341 } … … public class DataSetMerger { 329 347 } else if (! target.isModified() && source.isModified()) { 330 348 // target not modified. We can assume that source is the most recent version. 331 349 // clone it into target. 332 target.mergeFrom(source); 350 if (target.mergeFrom(source)) 351 changedObjectsMap.put(target, source.save()); 333 352 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 334 353 } else if (! target.isModified() && !source.isModified() && target.getVersion() == source.getVersion()) { 335 354 // both not modified. Merge nevertheless. 336 355 // This helps when updating "empty" relations, see #4295 337 target.mergeFrom(source); 356 if (target.mergeFrom(source)) 357 changedObjectsMap.put(target, source.save()); 338 358 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 339 359 } else if (! target.isModified() && !source.isModified() && target.getVersion() < source.getVersion()) { 340 360 // my not modified but other is newer. clone other onto mine. 341 361 // 342 target.mergeFrom(source); 362 if (target.mergeFrom(source)) 363 changedObjectsMap.put(target, source.save()); 343 364 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 344 365 } else if (target.isModified() && ! source.isModified() && target.getVersion() == source.getVersion()) { 345 366 // target is same as source but target is modified 346 367 // => keep target and reset modified flag if target and source are semantically equal 347 368 if (target.hasEqualSemanticAttributes(source)) { 348 369 target.setModified(false); 370 changedObjectsMap.put(target, source.save()); 349 371 } 350 372 } else if (source.isDeleted() != target.isDeleted()) { 351 373 // target is modified and deleted state differs. … … public class DataSetMerger { 362 384 // technical attributes like timestamp or user information. Semantic 363 385 // attributes should already be equal if we get here. 364 386 // 365 target.mergeFrom(source); 387 if (target.mergeFrom(source)) 388 changedObjectsMap.put(target, source.save()); 366 389 objectsWithChildrenToMerge.add(source.getPrimitiveId()); 367 390 } 368 391 return true; … … public class DataSetMerger { 423 446 if (progressMonitor != null) { 424 447 progressMonitor.finishTask(); 425 448 } 449 450 undoState = UndoState.MERGED; 426 451 } 427 452 428 453 /** … … public class DataSetMerger { 442 467 public ConflictCollection getConflicts() { 443 468 return conflicts; 444 469 } 470 471 /** 472 * Undos the merge operation. 473 */ 474 public void unmerge() { 475 if (undoState != UndoState.MERGED && undoState != UndoState.REDONE) { 476 throw new AssertionError(); 477 } 478 479 targetDataSet.beginUpdate(); 480 481 for (PrimitiveId osm : addedObjects) { 482 targetDataSet.removePrimitive(osm); 483 } 484 485 for (Map.Entry<OsmPrimitive, PrimitiveData> e : changedObjectsMap.entrySet()) { 486 // restore previous state and save current state for opposite undo action 487 PrimitiveData old = e.getKey().save(); 488 e.getKey().load(e.getValue()); 489 e.setValue(old); 490 } 491 492 targetDataSet.endUpdate(); 493 undoState = UndoState.UNDONE; 494 } 495 496 /** 497 * Re-merge objects with dataset. Identical results as {@see #merge()}, but performed 498 * after {@see #unmerge()} has been called. 499 */ 500 public void remerge() { 501 if (undoState != UndoState.UNDONE) { 502 throw new AssertionError(); 503 } 504 505 targetDataSet.beginUpdate(); 506 507 // add back objects in order that they can be referenced by other objects 508 for (OsmPrimitive osm : OsmPrimitive.getFilteredList(addedObjects, Node.class)) { 509 targetDataSet.addPrimitive(osm); 510 } 511 for (OsmPrimitive osm : OsmPrimitive.getFilteredList(addedObjects, Way.class)) { 512 targetDataSet.addPrimitive(osm); 513 } 514 for (OsmPrimitive osm : OsmPrimitive.getFilteredList(addedObjects, Relation.class)) { 515 targetDataSet.addPrimitive(osm); 516 } 517 518 for (Map.Entry<OsmPrimitive, PrimitiveData> e : changedObjectsMap.entrySet()) { 519 // restore previous state and save current state for opposite undo action 520 PrimitiveData old = e.getKey().save(); 521 e.getKey().load(e.getValue()); 522 e.setValue(old); 523 } 524 525 targetDataSet.endUpdate(); 526 undoState = UndoState.REDONE; 527 } 528 529 public Map<OsmPrimitive, PrimitiveData> getChangedObjectsMap() { 530 return changedObjectsMap; 531 } 532 533 public Set<OsmPrimitive> getAddedObjects() { 534 return addedObjects; 535 } 445 536 } -
src/org/openstreetmap/josm/data/osm/Node.java
diff --git a/src/org/openstreetmap/josm/data/osm/Node.java b/src/org/openstreetmap/josm/data/osm/Node.java index cefa750..2030035 100644
a b public final class Node extends OsmPrimitive implements INode { 206 206 * have an assigend OSM id, the IDs have to be the same. 207 207 * 208 208 * @param other the other primitive. Must not be null. 209 * @return true if the semantic or technical attributes were changed 209 210 * @throws IllegalArgumentException thrown if other is null. 210 211 * @throws DataIntegrityProblemException thrown if either this is new and other is not, or other is new and this is not 211 212 * @throws DataIntegrityProblemException thrown if other is new and other.getId() != this.getId() 212 213 */ 213 214 @Override 214 public void mergeFrom(OsmPrimitive other) { 215 public boolean mergeFrom(OsmPrimitive other) { 216 boolean changed; 215 217 boolean locked = writeLock(); 216 218 try { 217 super.mergeFrom(other);218 if (!other.isIncomplete() ) {219 changed = super.mergeFrom(other); 220 if (!other.isIncomplete() && !((Node)other).getCoor().equals((getCoor()))) { 219 221 setCoor(((Node)other).getCoor()); 222 changed = true; 220 223 } 221 224 } finally { 222 225 writeUnlock(locked); 223 226 } 227 return changed; 224 228 } 225 229 226 230 @Override public void load(PrimitiveData data) { -
src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
diff --git a/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java b/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java index 2f06c76..a2e07b7 100644
a b abstract public class OsmPrimitive extends AbstractPrimitive implements Comparab 926 926 * Merges the technical and semantical attributes from <code>other</code> onto this. 927 927 * 928 928 * Both this and other must be new, or both must be assigned an OSM ID. If both this and <code>other</code> 929 * have an assig end OSM id, the IDs have to be the same.929 * have an assigned OSM id, the IDs have to be the same. 930 930 * 931 931 * @param other the other primitive. Must not be null. 932 * @return true if the semantic or technical attributes were changed 932 933 * @throws IllegalArgumentException thrown if other is null. 933 934 * @throws DataIntegrityProblemException thrown if either this is new and other is not, or other is new and this is not 934 935 * @throws DataIntegrityProblemException thrown if other isn't new and other.getId() != this.getId() 935 936 */ 936 public void mergeFrom(OsmPrimitive other) { 937 public boolean mergeFrom(OsmPrimitive other) { 938 if (hasEqualSemanticAttributes(other) && hasEqualTechnicalAttributes(other)) 939 return false; 940 937 941 boolean locked = writeLock(); 938 942 try { 939 943 CheckParameterUtil.ensureParameterNotNull(other, "other"); … … abstract public class OsmPrimitive extends AbstractPrimitive implements Comparab 952 956 } finally { 953 957 writeUnlock(locked); 954 958 } 959 return true; 955 960 } 956 961 957 962 /** -
src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationMemberTask.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationMemberTask.java b/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationMemberTask.java index 0c1ad81..9e68c3a 100644
a b import java.util.Set; 13 13 import javax.swing.SwingUtilities; 14 14 15 15 import org.openstreetmap.josm.Main; 16 import org.openstreetmap.josm.command.DownloadOsmCommand; 16 17 import org.openstreetmap.josm.data.osm.DataSet; 17 18 import org.openstreetmap.josm.data.osm.OsmPrimitive; 18 19 import org.openstreetmap.josm.data.osm.Relation; … … public class DownloadRelationMemberTask extends PleaseWaitRunnable { 135 136 SwingUtilities.invokeLater( 136 137 new Runnable() { 137 138 public void run() { 138 curLayer.mergeFrom(dataSet); 139 curLayer.onPostDownloadFromServer(); 139 Main.main.undoRedo.add(new DownloadOsmCommand(tr("Download relation members"), curLayer, dataSet)); 140 140 } 141 141 } 142 142 ); -
src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationTask.java
diff --git a/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationTask.java b/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationTask.java index ec140ec..d524a4f 100644
a b import java.util.Collection; 9 9 import javax.swing.SwingUtilities; 10 10 11 11 import org.openstreetmap.josm.Main; 12 import org.openstreetmap.josm.command.DownloadOsmCommand; 12 13 import org.openstreetmap.josm.data.osm.DataSet; 13 14 import org.openstreetmap.josm.data.osm.DataSetMerger; 14 15 import org.openstreetmap.josm.data.osm.Relation; … … public class DownloadRelationTask extends PleaseWaitRunnable { 98 99 SwingUtilities.invokeAndWait( 99 100 new Runnable() { 100 101 public void run() { 101 layer.mergeFrom(allDownloads); 102 layer.onPostDownloadFromServer(); 102 Main.main.undoRedo.add(new DownloadOsmCommand(tr("Download relation(s)"), layer, allDownloads)); 103 103 Main.map.repaint(); 104 104 } 105 105 } -
src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java
diff --git a/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java b/src/org/openstreetmap/josm/gui/io/DownloadPrimitivesTask.java index c1433d6..03fd341 100644
a b import java.util.List; 10 10 import java.util.Set; 11 11 12 12 import javax.swing.SwingUtilities; 13 import org.openstreetmap.josm.Main; 13 14 14 15 import org.openstreetmap.josm.actions.AutoScaleAction; 16 import org.openstreetmap.josm.command.DownloadOsmCommand; 15 17 import org.openstreetmap.josm.data.osm.DataSet; 16 18 import org.openstreetmap.josm.data.osm.DataSetMerger; 17 19 import org.openstreetmap.josm.data.osm.Node; … … public class DownloadPrimitivesTask extends PleaseWaitRunnable { 83 85 } 84 86 Runnable r = new Runnable() { 85 87 public void run() { 86 layer.mergeFrom(ds);88 Main.main.undoRedo.add(new DownloadOsmCommand(tr("Download primitives"), layer, ds)); 87 89 AutoScaleAction.zoomTo(ds.allPrimitives()); 88 layer.onPostDownloadFromServer();89 90 } 90 91 }; 91 92 -
src/org/openstreetmap/josm/gui/io/UpdatePrimitivesTask.java
diff --git a/src/org/openstreetmap/josm/gui/io/UpdatePrimitivesTask.java b/src/org/openstreetmap/josm/gui/io/UpdatePrimitivesTask.java index 59cb47c..59f0bd6 100644
a b import java.util.Collection; 10 10 import java.util.Collections; 11 11 12 12 import javax.swing.SwingUtilities; 13 import org.openstreetmap.josm.Main; 14 import org.openstreetmap.josm.command.DownloadOsmCommand; 13 15 14 16 import org.openstreetmap.josm.data.osm.DataSet; 15 17 import org.openstreetmap.josm.data.osm.DataSetMerger; … … public class UpdatePrimitivesTask extends PleaseWaitRunnable { 81 83 } 82 84 Runnable r = new Runnable() { 83 85 public void run() { 84 layer.mergeFrom(ds); 85 layer.onPostDownloadFromServer(); 86 Main.main.undoRedo.add(new DownloadOsmCommand(tr("Update primitives"), layer, ds)); 86 87 } 87 88 }; 88 89 -
src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
diff --git a/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java b/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java index 5a0f76f..db43ba5 100644
a b public class OsmDataLayer extends Layer implements Listener, SelectionChangedLis 99 99 100 100 public List<TestError> validationErrors = new ArrayList<TestError>(); 101 101 102 p rotectedvoid setRequiresSaveToFile(boolean newValue) {102 public void setRequiresSaveToFile(boolean newValue) { 103 103 boolean oldValue = requiresSaveToFile; 104 104 requiresSaveToFile = newValue; 105 105 if (oldValue != newValue) { … … public class OsmDataLayer extends Layer implements Listener, SelectionChangedLis 107 107 } 108 108 } 109 109 110 p rotectedvoid setRequiresUploadToServer(boolean newValue) {110 public void setRequiresUploadToServer(boolean newValue) { 111 111 boolean oldValue = requiresUploadToServer; 112 112 requiresUploadToServer = newValue; 113 113 if (oldValue != newValue) { … … public class OsmDataLayer extends Layer implements Listener, SelectionChangedLis 299 299 } 300 300 301 301 @Override public void mergeFrom(final Layer from) { 302 // TODO: make undo-able 302 303 final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Merging layers")); 303 304 monitor.setCancelable(false); 304 305 if (from instanceof OsmDataLayer && ((OsmDataLayer)from).isUploadDiscouraged()) { … … public class OsmDataLayer extends Layer implements Listener, SelectionChangedLis 314 315 * 315 316 * @param from the source data set 316 317 */ 318 @Deprecated 317 319 public void mergeFrom(final DataSet from) { 318 320 mergeFrom(from, null); 319 321 } … … public class OsmDataLayer extends Layer implements Listener, SelectionChangedLis 324 326 * 325 327 * @param from the source data set 326 328 */ 329 @Deprecated 327 330 public void mergeFrom(final DataSet from, ProgressMonitor progressMonitor) { 328 331 final DataSetMerger visitor = new DataSetMerger(data,from); 329 332 try { … … public class OsmDataLayer extends Layer implements Listener, SelectionChangedLis 375 378 * 376 379 * @param numNewConflicts the number of detected conflicts 377 380 */ 378 p rotectedvoid warnNumNewConflicts(int numNewConflicts) {381 public void warnNumNewConflicts(int numNewConflicts) { 379 382 if (numNewConflicts == 0) return; 380 383 381 384 String msg1 = trn(