Ignore:
Timestamp:
2015-10-27T18:31:03+01:00 (4 years ago)
Author:
simon04
Message:

fix #11992 see #10730 - Joining Overlapping Areas results in RuntimeException

JoinAreasAction somehow requires that the first way chunk keeps the id of the split way.
SplitWayAction#Strategy allows to specify how to determine the way chunk which keeps the to id.

Location:
trunk/src/org/openstreetmap/josm/actions
Files:
2 edited

Legend:

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

    r8931 r8955  
    942942
    943943        if (chunks.size() > 1) {
    944             SplitWayResult split = SplitWayAction.splitWay(getEditLayer(), way, chunks, Collections.<OsmPrimitive>emptyList());
     944            SplitWayResult split = SplitWayAction.splitWay(getEditLayer(), way, chunks,
     945                    Collections.<OsmPrimitive>emptyList(), SplitWayAction.Strategy.keepFirstChunk());
    945946
    946947            //execute the command, we need the results
  • trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java

    r8931 r8955  
    197197
    198198            final List<Way> newWays = createNewWaysFromChunks(selectedWay, wayChunks);
    199             final Way wayToKeep = determineWayToKeep(newWays);
     199            final Way wayToKeep = Strategy.keepLongestChunk().determineWayToKeep(newWays);
    200200
    201201            if (ExpertToggleAction.isExpert() && !selectedWay.isNew()) {
     
    297297
    298298    /**
    299      * Determines which way chunk should reuse the old id and its history. Selects the one with the highest node count.
    300      * @param wayChunks the way chunks
    301      * @return the way to keep
    302      */
    303     protected static Way determineWayToKeep(Iterable<Way> wayChunks) {
    304         Way wayToKeep = null;
    305         for (Way i : wayChunks) {
    306             if (wayToKeep == null || i.getNodesCount() > wayToKeep.getNodesCount()) {
    307                 wayToKeep = i;
    308             }
    309         }
    310         return wayToKeep;
    311     }
     299     * Determines which way chunk should reuse the old id and its history
     300     *
     301     * @since 8954
     302     */
     303    public static abstract class Strategy {
     304
     305        /**
     306         * Determines which way chunk should reuse the old id and its history.
     307         *
     308         * @param wayChunks the way chunks
     309         * @return the way to keep
     310         */
     311        public abstract Way determineWayToKeep(Iterable<Way> wayChunks);
     312
     313        /**
     314         * Returns a strategy which selects the way chunk with the highest node count to keep.
     315         */
     316        public static Strategy keepLongestChunk() {
     317            return new Strategy() {
     318                @Override
     319                public Way determineWayToKeep(Iterable<Way> wayChunks) {
     320                    Way wayToKeep = null;
     321                    for (Way i : wayChunks) {
     322                        if (wayToKeep == null || i.getNodesCount() > wayToKeep.getNodesCount()) {
     323                            wayToKeep = i;
     324                        }
     325                    }
     326                    return wayToKeep;
     327                }
     328            };
     329        }
     330
     331        /**
     332         * Returns a strategy which selects the first way chunk.
     333         */
     334        public static Strategy keepFirstChunk() {
     335            return new Strategy() {
     336                @Override
     337                public Way determineWayToKeep(Iterable<Way> wayChunks) {
     338                    return wayChunks.iterator().next();
     339                }
     340            };
     341        }
     342    }
     343
    312344
    313345    /**
     
    483515    public static SplitWayResult splitWay(OsmDataLayer layer, Way way, List<List<Node>> wayChunks,
    484516            Collection<? extends OsmPrimitive> selection) {
     517        return splitWay(layer, way, wayChunks, selection, Strategy.keepLongestChunk());
     518    }
     519
     520    /**
     521     * Splits the way {@code way} into chunks of {@code wayChunks} and replies
     522     * the result of this process in an instance of {@link SplitWayResult}.
     523     * The {@link org.openstreetmap.josm.actions.SplitWayAction.Strategy} is used to determine which
     524     * way chunk should reuse the old id and its history.
     525     *
     526     * Note that changes are not applied to the data yet. You have to
     527     * submit the command in {@link SplitWayResult#getCommand()} first,
     528     * i.e. {@code Main.main.undoredo.add(result.getCommand())}.
     529     *
     530     * @param layer the layer which the way belongs to. Must not be null.
     531     * @param way the way to split. Must not be null.
     532     * @param wayChunks the list of way chunks into the way is split. Must not be null.
     533     * @param selection The list of currently selected primitives
     534     * @param splitStrategy The strategy used to determine which way chunk should reuse the old id and its history
     535     * @return the result from the split operation
     536     * @since 8954
     537     */
     538    public static SplitWayResult splitWay(OsmDataLayer layer, Way way, List<List<Node>> wayChunks,
     539            Collection<? extends OsmPrimitive> selection, Strategy splitStrategy) {
    485540        // build a list of commands, and also a new selection list
    486541        final List<OsmPrimitive> newSelection = new ArrayList<>(selection.size() + wayChunks.size());
     
    491546
    492547        // Determine which part reuses the existing way
    493         final Way wayToKeep = determineWayToKeep(newWays);
     548        final Way wayToKeep = splitStrategy.determineWayToKeep(newWays);
    494549
    495550        return doSplitWay(layer, way, wayToKeep, newWays, newSelection);
Note: See TracChangeset for help on using the changeset viewer.