Changeset 18024 in josm


Ignore:
Timestamp:
2021-07-14T23:49:56+02:00 (3 years ago)
Author:
Don-vip
Message:

fix #20935 - fix IAE: "Node pair not part of way" when splitting way (second patch by Bjoeni)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java

    r18004 r18024  
    3636import org.openstreetmap.josm.data.osm.Way;
    3737import org.openstreetmap.josm.data.osm.WaySegment;
     38import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
     39import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
     40import org.openstreetmap.josm.data.osm.event.DataSetListener;
     41import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
     42import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
     43import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
     44import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
     45import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
     46import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
    3847import org.openstreetmap.josm.gui.ExtendedDialog;
    3948import org.openstreetmap.josm.gui.MainApplication;
     
    146155
    147156            if (ExpertToggleAction.isExpert() && !selectedWay.isNew()) {
    148                 final ExtendedDialog dialog = new SegmentToKeepSelectionDialog(selectedWay, newWays, wayToKeep, sel);
     157                final ExtendedDialog dialog = new SegmentToKeepSelectionDialog(selectedWay, newWays, wayToKeep, selectedNodes, sel);
    149158                dialog.toggleEnable("way.split.segment-selection-dialog");
    150159                if (!dialog.toggleCheckState()) {
     
    166175        static final AtomicInteger DISPLAY_COUNT = new AtomicInteger();
    167176        final transient Way selectedWay;
    168         final transient List<Way> newWays;
    169177        final JList<Way> list;
    170178        final transient List<OsmPrimitive> selection;
    171         final transient Way wayToKeep;
    172 
    173         SegmentToKeepSelectionDialog(Way selectedWay, List<Way> newWays, Way wayToKeep, List<OsmPrimitive> selection) {
     179        final transient List<Node> selectedNodes;
     180        final SplitWayDataSetListener dataSetListener;
     181        transient List<Way> newWays;
     182        transient Way wayToKeep;
     183
     184        SegmentToKeepSelectionDialog(
     185                Way selectedWay, List<Way> newWays, Way wayToKeep, List<Node> selectedNodes, List<OsmPrimitive> selection) {
    174186            super(MainApplication.getMainFrame(), tr("Which way segment should reuse the history of {0}?", selectedWay.getId()),
    175187                    new String[]{tr("Ok"), tr("Cancel")}, true);
     
    177189            this.selectedWay = selectedWay;
    178190            this.newWays = newWays;
     191            this.selectedNodes = selectedNodes;
    179192            this.selection = selection;
    180193            this.wayToKeep = wayToKeep;
    181194            this.list = new JList<>(newWays.toArray(new Way[0]));
     195            this.dataSetListener = new SplitWayDataSetListener();
     196
    182197            configureList();
    183198
     
    210225
    211226        protected void setHighlightedWaySegments(Collection<WaySegment> segments) {
    212             selectedWay.getDataSet().setHighlightedWaySegments(segments);
    213             MainApplication.getMap().mapView.repaint();
     227            DataSet ds = selectedWay.getDataSet();
     228            if (ds != null) {
     229                ds.setHighlightedWaySegments(segments);
     230                MainApplication.getMap().mapView.repaint();
     231            }
    214232        }
    215233
     
    217235        public void setVisible(boolean visible) {
    218236            super.setVisible(visible);
     237            DataSet ds = selectedWay.getDataSet();
    219238            if (visible) {
    220239                DISPLAY_COUNT.incrementAndGet();
    221240                list.setSelectedValue(wayToKeep, true);
     241                if (ds != null) {
     242                    ds.addDataSetListener(dataSetListener);
     243                }
    222244            } else {
     245                if (ds != null) {
     246                    ds.removeDataSetListener(dataSetListener);
     247                }
    223248                setHighlightedWaySegments(Collections.emptyList());
    224249                DISPLAY_COUNT.decrementAndGet();
    225                 if (getValue() != 1) {
     250                if (getValue() != 1 && selectedWay.getDataSet() != null) {
    226251                    newWays.forEach(w -> w.setNodes(null)); // see 19885
    227252                }
     
    235260            if (getValue() == 1) {
    236261                doSplitWay(selectedWay, list.getSelectedValue(), newWays, selection);
     262            }
     263        }
     264
     265        private class SplitWayDataSetListener implements DataSetListener {
     266
     267            @Override
     268            public void primitivesAdded(PrimitivesAddedEvent event) {
     269            }
     270
     271            @Override
     272            public void primitivesRemoved(PrimitivesRemovedEvent event) {
     273                if (event.getPrimitives().stream().anyMatch(p -> p instanceof Way)) {
     274                    updateWaySegments();
     275                }
     276            }
     277
     278            @Override
     279            public void tagsChanged(TagsChangedEvent event) {}
     280
     281            @Override
     282            public void nodeMoved(NodeMovedEvent event) {}
     283
     284            @Override
     285            public void wayNodesChanged(WayNodesChangedEvent event) {
     286                updateWaySegments();
     287            }
     288
     289            @Override
     290            public void relationMembersChanged(RelationMembersChangedEvent event) {}
     291
     292            @Override
     293            public void otherDatasetChange(AbstractDatasetChangedEvent event) {}
     294
     295            @Override
     296            public void dataChanged(DataChangedEvent event) {}
     297
     298            private void updateWaySegments() {
     299                if (!selectedWay.isUsable()) {
     300                    setVisible(false);
     301                    return;
     302                }
     303
     304                List<List<Node>> chunks = SplitWayCommand.buildSplitChunks(selectedWay, selectedNodes);
     305                if (chunks == null) {
     306                    setVisible(false);
     307                    return;
     308                }
     309
     310                newWays = SplitWayCommand.createNewWaysFromChunks(selectedWay, chunks);
     311                if (list.getSelectedIndex() < newWays.size()) {
     312                    wayToKeep = newWays.get(list.getSelectedIndex());
     313                } else {
     314                    wayToKeep = SplitWayCommand.Strategy.keepLongestChunk().determineWayToKeep(newWays);
     315                }
     316                list.setListData(newWays.toArray(new Way[0]));
     317                list.setSelectedValue(wayToKeep, true);
    237318            }
    238319        }
Note: See TracChangeset for help on using the changeset viewer.