Ticket #7159: 7159.patch

File 7159.patch, 10.4 KB (added by Don-vip, 14 years ago)

patch awaiting end of stabilization phase

  • core/src/org/openstreetmap/josm/actions/MergeLayerAction.java

     
    3838        Main.map.mapView.setActiveLayer(targetLayer);
    3939    }
    4040
    41     public void merge(Layer sourceLayer) {
     41    public void merge(final Layer sourceLayer) {
    4242        if (sourceLayer == null)
    4343            return;
    4444        List<Layer> targetLayers = LayerListDialog.getInstance().getModel().getPossibleMergeTargets(sourceLayer);
     
    4646            warnNoTargetLayersForSourceLayer(sourceLayer);
    4747            return;
    4848        }
    49         Layer targetLayer = askTargetLayer(targetLayers);
     49        final Layer targetLayer = askTargetLayer(targetLayers);
    5050        if (targetLayer == null)
    5151            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        });
    5560    }
    5661
    5762    public void actionPerformed(ActionEvent e) {
  • core/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java

     
    646646     * @return true if other isn't null and has the same tags (key/value-pairs) as this.
    647647     */
    648648    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())));
    650654    }
    651655
    652656    /**
  • core/src/org/openstreetmap/josm/data/osm/DataSetMerger.java

     
    1515
    1616import org.openstreetmap.josm.data.conflict.Conflict;
    1717import org.openstreetmap.josm.data.conflict.ConflictCollection;
     18import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1819import org.openstreetmap.josm.tools.CheckParameterUtil;
    1920
    2021/**
     
    7677     * @param <P>  the type of the other primitive
    7778     * @param source  the other primitive
    7879     */
    79     protected void mergePrimitive(OsmPrimitive source) {
     80    protected void mergePrimitive(OsmPrimitive source, Collection<? extends OsmPrimitive> candidates) {
    8081        if (!source.isNew() ) {
    8182            // try to merge onto a matching primitive with the same
    8283            // defined id
     
    9394            // try to merge onto a primitive  which has no id assigned
    9495            // yet but which is equal in its semantic attributes
    9596            //
    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             }
    10397            for (OsmPrimitive target : candidates) {
    10498                if (!target.isNew() || target.isDeleted()) {
    10599                    continue;
     
    381375     * See {@see #getConflicts()} for a map of conflicts after the merge operation.
    382376     */
    383377    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) {
    384388        if (sourceDataSet == null)
    385389            return;
     390        if (progressMonitor != null) {
     391            progressMonitor.beginTask(tr("Merging data..."), sourceDataSet.allPrimitives().size());
     392        }
    386393        targetDataSet.beginUpdate();
    387394        try {
     395                ArrayList<? extends OsmPrimitive> candidates = new ArrayList<Node>(targetDataSet.getNodes());
    388396            for (Node node: sourceDataSet.getNodes()) {
    389                 mergePrimitive(node);
     397                mergePrimitive(node, candidates);
     398                if (progressMonitor != null) {
     399                    progressMonitor.worked(1);
     400                }
    390401            }
     402            candidates.clear();
     403            candidates = new ArrayList<Way>(targetDataSet.getWays());
    391404            for (Way way: sourceDataSet.getWays()) {
    392                 mergePrimitive(way);
     405                mergePrimitive(way, candidates);
     406                if (progressMonitor != null) {
     407                    progressMonitor.worked(1);
     408                }
    393409            }
     410            candidates.clear();
     411            candidates = new ArrayList<Relation>(targetDataSet.getRelations());
    394412            for (Relation relation: sourceDataSet.getRelations()) {
    395                 mergePrimitive(relation);
     413                mergePrimitive(relation, candidates);
     414                if (progressMonitor != null) {
     415                    progressMonitor.worked(1);
     416                }
    396417            }
     418            candidates.clear();
    397419            fixReferences();
    398420        } finally {
    399421            targetDataSet.endUpdate();
    400422        }
     423        if (progressMonitor != null) {
     424            progressMonitor.finishTask();
     425        }
    401426    }
    402427
    403428    /**
  • core/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java

     
    965965    public boolean hasEqualSemanticAttributes(OsmPrimitive other) {
    966966        if (!isNew() &&  id != other.id)
    967967            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)
    969970            return false;
    970971        // can't do an equals check on the internal keys array because it is not ordered
    971972        //
  • core/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

     
    7070import org.openstreetmap.josm.gui.MapView;
    7171import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
    7272import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
     73import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
     74import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    7375import org.openstreetmap.josm.tools.DateUtils;
    7476import org.openstreetmap.josm.tools.FilteredCollection;
    7577import org.openstreetmap.josm.tools.GBC;
     
    281283    }
    282284
    283285    @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();
    285290    }
    286291
    287292    /**
     
    291296     * @param from  the source data set
    292297     */
    293298    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) {
    294309        final DataSetMerger visitor = new DataSetMerger(data,from);
    295310        try {
    296             visitor.merge();
     311            visitor.merge(progressMonitor);
    297312        } catch (DataIntegrityProblemException e) {
    298313            JOptionPane.showMessageDialog(
    299314                    Main.parent,
  • core/src/org/openstreetmap/josm/gui/progress/PleaseWaitProgressMonitor.java

     
    2525
    2626    private PleaseWaitDialog dialog;
    2727    private String windowTitle;
     28   
     29    private boolean cancelable;
    2830
    2931    public PleaseWaitProgressMonitor() {
    3032        this("");
     
    3840    public PleaseWaitProgressMonitor(Component dialogParent) {
    3941        super(new CancelHandler());
    4042        this.dialogParent = JOptionPane.getFrameForComponent(dialogParent);
     43        this.cancelable = true;
    4144    }
    4245
    4346    public PleaseWaitProgressMonitor(Component dialogParent, String windowTitle) {
     
    5760        }
    5861    };
    5962
     63    public final boolean isCancelable() {
     64        return cancelable;
     65    }
     66
     67    public final void setCancelable(boolean cancelable) {
     68        this.cancelable = cancelable;
     69    }
     70
    6071    private void doInEDT(Runnable runnable) {
    6172        EventQueue.invokeLater(runnable);
    6273    }
     
    7586                if (windowTitle != null) {
    7687                    dialog.setTitle(windowTitle);
    7788                }
    78                 dialog.setCancelEnabled(true);
     89                dialog.setCancelEnabled(cancelable);
    7990                dialog.setCancelCallback(cancelListener);
    8091                dialog.setCustomText("");
    8192                dialog.addWindowListener(windowListener);