Changeset 18935 in josm for trunk/src


Ignore:
Timestamp:
2024-01-15T17:20:18+01:00 (10 months ago)
Author:
taylor.smock
Message:

Fix #23399: Simplify way crashes

This was primarily caused by selection updates occurring while the commands were generated. The fixes could be any of the following:

  • Synchronized collections
  • New list
  • Avoiding selection updates

The last option was taken for the following reasons:

  • Avoiding a StackOverflow exception when many ways are being simplified
  • Reduced memory allocations (>11GB to <250MB)
  • Reduced CPU cycles
File:
1 edited

Legend:

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

    r18883 r18935  
    341341     */
    342342    private static SequenceCommand buildSimplifyWaysCommand(List<Way> ways, double threshold) {
    343         Collection<Command> allCommands = ways.stream()
    344                 .map(way -> createSimplifyCommand(way, threshold))
     343        List<Command> allCommands = ways.stream()
     344                .map(way -> createSimplifyCommand(way, threshold, false))
    345345                .filter(Objects::nonNull)
    346346                .collect(StreamUtils.toUnmodifiableList());
    347347        if (allCommands.isEmpty())
    348348            return null;
     349        final List<OsmPrimitive> deletedPrimitives = allCommands.stream()
     350                .map(Command::getChildren)
     351                .flatMap(Collection::stream)
     352                .filter(DeleteCommand.class::isInstance)
     353                .map(DeleteCommand.class::cast)
     354                .map(DeleteCommand::getParticipatingPrimitives)
     355                .flatMap(Collection::stream)
     356                .collect(Collectors.toList());
     357        allCommands.get(0).getAffectedDataSet().clearSelection(deletedPrimitives);
    349358        return new SequenceCommand(
    350359                trn("Simplify {0} way", "Simplify {0} ways", allCommands.size(), allCommands.size()),
     
    372381     */
    373382    public static SequenceCommand createSimplifyCommand(Way w, double threshold) {
     383        return createSimplifyCommand(w, threshold, true);
     384    }
     385
     386    /**
     387     * Creates the SequenceCommand to simplify a way with a given threshold.
     388     *
     389     * @param w the way to simplify
     390     * @param threshold the max error threshold
     391     * @param deselect {@code true} if we want to deselect the deleted nodes
     392     * @return The sequence of commands to run
     393     */
     394    private static SequenceCommand createSimplifyCommand(Way w, double threshold, boolean deselect) {
    374395        int lower = 0;
    375396        int i = 0;
     
    418439        cmds.add(new ChangeNodesCommand(w, newNodes));
    419440        cmds.add(new DeleteCommand(w.getDataSet(), delNodes));
    420         w.getDataSet().clearSelection(delNodes);
     441        if (deselect) {
     442            w.getDataSet().clearSelection(delNodes);
     443        }
    421444        return new SequenceCommand(
    422445                trn("Simplify Way (remove {0} node)", "Simplify Way (remove {0} nodes)", delNodes.size(), delNodes.size()), cmds);
Note: See TracChangeset for help on using the changeset viewer.