Ticket #7159: 7159.patch
| File 7159.patch, 10.4 KB (added by , 14 years ago) |
|---|
-
core/src/org/openstreetmap/josm/actions/MergeLayerAction.java
38 38 Main.map.mapView.setActiveLayer(targetLayer); 39 39 } 40 40 41 public void merge( Layer sourceLayer) {41 public void merge(final Layer sourceLayer) { 42 42 if (sourceLayer == null) 43 43 return; 44 44 List<Layer> targetLayers = LayerListDialog.getInstance().getModel().getPossibleMergeTargets(sourceLayer); … … 46 46 warnNoTargetLayersForSourceLayer(sourceLayer); 47 47 return; 48 48 } 49 Layer targetLayer = askTargetLayer(targetLayers);49 final Layer targetLayer = askTargetLayer(targetLayers); 50 50 if (targetLayer == null) 51 51 return; 52 targetLayer.mergeFrom(sourceLayer); 53 Main.map.mapView.removeLayer(sourceLayer); 54 Main.map.mapView.setActiveLayer(targetLayer); 52 Main.worker.submit(new Runnable() { 53 @Override 54 public void run() { 55 targetLayer.mergeFrom(sourceLayer); 56 Main.map.mapView.removeLayer(sourceLayer); 57 Main.map.mapView.setActiveLayer(targetLayer); 58 } 59 }); 55 60 } 56 61 57 62 public void actionPerformed(ActionEvent e) { -
core/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java
646 646 * @return true if other isn't null and has the same tags (key/value-pairs) as this. 647 647 */ 648 648 public boolean hasSameTags(OsmPrimitive other) { 649 return getKeys().equals(other.getKeys()); 649 // We cannot directly use Arrays.equals(keys, other.keys) as keys is not ordered by key 650 // but we can at least check if both arrays are null or of the same size before creating 651 // and comparing the key maps (costly operation, see #7159) 652 return (keys == null && other.keys == null) 653 || (keys != null && other.keys != null && keys.length == other.keys.length && (keys.length == 0 || getKeys().equals(other.getKeys()))); 650 654 } 651 655 652 656 /** -
core/src/org/openstreetmap/josm/data/osm/DataSetMerger.java
15 15 16 16 import org.openstreetmap.josm.data.conflict.Conflict; 17 17 import org.openstreetmap.josm.data.conflict.ConflictCollection; 18 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 18 19 import org.openstreetmap.josm.tools.CheckParameterUtil; 19 20 20 21 /** … … 76 77 * @param <P> the type of the other primitive 77 78 * @param source the other primitive 78 79 */ 79 protected void mergePrimitive(OsmPrimitive source ) {80 protected void mergePrimitive(OsmPrimitive source, Collection<? extends OsmPrimitive> candidates) { 80 81 if (!source.isNew() ) { 81 82 // try to merge onto a matching primitive with the same 82 83 // defined id … … 93 94 // try to merge onto a primitive which has no id assigned 94 95 // yet but which is equal in its semantic attributes 95 96 // 96 Collection<? extends OsmPrimitive> candidates = null;97 switch (source.getType()) {98 case NODE: candidates = targetDataSet.getNodes(); break;99 case WAY: candidates = targetDataSet.getWays(); break;100 case RELATION: candidates = targetDataSet.getRelations(); break;101 default: throw new AssertionError();102 }103 97 for (OsmPrimitive target : candidates) { 104 98 if (!target.isNew() || target.isDeleted()) { 105 99 continue; … … 381 375 * See {@see #getConflicts()} for a map of conflicts after the merge operation. 382 376 */ 383 377 public void merge() { 378 merge(null); 379 } 380 381 /** 382 * Runs the merge operation. Successfully merged {@see OsmPrimitive}s are in 383 * {@see #getMyDataSet()}. 384 * 385 * See {@see #getConflicts()} for a map of conflicts after the merge operation. 386 */ 387 public void merge(ProgressMonitor progressMonitor) { 384 388 if (sourceDataSet == null) 385 389 return; 390 if (progressMonitor != null) { 391 progressMonitor.beginTask(tr("Merging data..."), sourceDataSet.allPrimitives().size()); 392 } 386 393 targetDataSet.beginUpdate(); 387 394 try { 395 ArrayList<? extends OsmPrimitive> candidates = new ArrayList<Node>(targetDataSet.getNodes()); 388 396 for (Node node: sourceDataSet.getNodes()) { 389 mergePrimitive(node); 397 mergePrimitive(node, candidates); 398 if (progressMonitor != null) { 399 progressMonitor.worked(1); 400 } 390 401 } 402 candidates.clear(); 403 candidates = new ArrayList<Way>(targetDataSet.getWays()); 391 404 for (Way way: sourceDataSet.getWays()) { 392 mergePrimitive(way); 405 mergePrimitive(way, candidates); 406 if (progressMonitor != null) { 407 progressMonitor.worked(1); 408 } 393 409 } 410 candidates.clear(); 411 candidates = new ArrayList<Relation>(targetDataSet.getRelations()); 394 412 for (Relation relation: sourceDataSet.getRelations()) { 395 mergePrimitive(relation); 413 mergePrimitive(relation, candidates); 414 if (progressMonitor != null) { 415 progressMonitor.worked(1); 416 } 396 417 } 418 candidates.clear(); 397 419 fixReferences(); 398 420 } finally { 399 421 targetDataSet.endUpdate(); 400 422 } 423 if (progressMonitor != null) { 424 progressMonitor.finishTask(); 425 } 401 426 } 402 427 403 428 /** -
core/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
965 965 public boolean hasEqualSemanticAttributes(OsmPrimitive other) { 966 966 if (!isNew() && id != other.id) 967 967 return false; 968 if (isIncomplete() && ! other.isIncomplete() || !isIncomplete() && other.isIncomplete()) 968 // if (isIncomplete() && ! other.isIncomplete() || !isIncomplete() && other.isIncomplete()) 969 if (isIncomplete() ^ other.isIncomplete()) // exclusive or operator for performance (see #7159) 969 970 return false; 970 971 // can't do an equals check on the internal keys array because it is not ordered 971 972 // -
core/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
70 70 import org.openstreetmap.josm.gui.MapView; 71 71 import org.openstreetmap.josm.gui.dialogs.LayerListDialog; 72 72 import org.openstreetmap.josm.gui.dialogs.LayerListPopup; 73 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor; 74 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 73 75 import org.openstreetmap.josm.tools.DateUtils; 74 76 import org.openstreetmap.josm.tools.FilteredCollection; 75 77 import org.openstreetmap.josm.tools.GBC; … … 281 283 } 282 284 283 285 @Override public void mergeFrom(final Layer from) { 284 mergeFrom(((OsmDataLayer)from).data); 286 final PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Merging layers")); 287 monitor.setCancelable(false); 288 mergeFrom(((OsmDataLayer)from).data, monitor); 289 monitor.close(); 285 290 } 286 291 287 292 /** … … 291 296 * @param from the source data set 292 297 */ 293 298 public void mergeFrom(final DataSet from) { 299 mergeFrom(from, null); 300 } 301 302 /** 303 * merges the primitives in dataset <code>from</code> into the dataset of 304 * this layer 305 * 306 * @param from the source data set 307 */ 308 public void mergeFrom(final DataSet from, ProgressMonitor progressMonitor) { 294 309 final DataSetMerger visitor = new DataSetMerger(data,from); 295 310 try { 296 visitor.merge( );311 visitor.merge(progressMonitor); 297 312 } catch (DataIntegrityProblemException e) { 298 313 JOptionPane.showMessageDialog( 299 314 Main.parent, -
core/src/org/openstreetmap/josm/gui/progress/PleaseWaitProgressMonitor.java
25 25 26 26 private PleaseWaitDialog dialog; 27 27 private String windowTitle; 28 29 private boolean cancelable; 28 30 29 31 public PleaseWaitProgressMonitor() { 30 32 this(""); … … 38 40 public PleaseWaitProgressMonitor(Component dialogParent) { 39 41 super(new CancelHandler()); 40 42 this.dialogParent = JOptionPane.getFrameForComponent(dialogParent); 43 this.cancelable = true; 41 44 } 42 45 43 46 public PleaseWaitProgressMonitor(Component dialogParent, String windowTitle) { … … 57 60 } 58 61 }; 59 62 63 public final boolean isCancelable() { 64 return cancelable; 65 } 66 67 public final void setCancelable(boolean cancelable) { 68 this.cancelable = cancelable; 69 } 70 60 71 private void doInEDT(Runnable runnable) { 61 72 EventQueue.invokeLater(runnable); 62 73 } … … 75 86 if (windowTitle != null) { 76 87 dialog.setTitle(windowTitle); 77 88 } 78 dialog.setCancelEnabled( true);89 dialog.setCancelEnabled(cancelable); 79 90 dialog.setCancelCallback(cancelListener); 80 91 dialog.setCustomText(""); 81 92 dialog.addWindowListener(windowListener);
