Ticket #23505: 23505.patch

File 23505.patch, 7.7 KB (added by GerdP, 2 years ago)

patch for all mentioned problems

  • src/org/openstreetmap/josm/plugins/simplifyarea/SimplifyAreaAction.java

     
    1313import java.util.Collection;
    1414import java.util.HashMap;
    1515import java.util.HashSet;
     16import java.util.LinkedHashSet;
    1617import java.util.List;
    1718import java.util.Map;
    1819import java.util.Map.Entry;
     
    2122import javax.swing.JOptionPane;
    2223
    2324import org.openstreetmap.josm.actions.JosmAction;
    24 import org.openstreetmap.josm.command.ChangeCommand;
     25import org.openstreetmap.josm.command.ChangeNodesCommand;
    2526import org.openstreetmap.josm.command.Command;
    2627import org.openstreetmap.josm.command.DeleteCommand;
    2728import org.openstreetmap.josm.command.MoveCommand;
    2829import org.openstreetmap.josm.command.SequenceCommand;
    29 import org.openstreetmap.josm.data.Bounds;
    3030import org.openstreetmap.josm.data.UndoRedoHandler;
    3131import org.openstreetmap.josm.data.coor.ILatLon;
    3232import org.openstreetmap.josm.data.coor.LatLon;
     
    4040import org.openstreetmap.josm.spi.preferences.Config;
    4141import org.openstreetmap.josm.tools.ImageProvider;
    4242import org.openstreetmap.josm.tools.Shortcut;
    43 import org.openstreetmap.josm.tools.Utils;
    4443
    4544public final class SimplifyAreaAction extends JosmAction {
    4645
     
    5049                true, "simplifyarea", true);
    5150    }
    5251
    53     private List<Bounds> getCurrentEditBounds() {
    54         return MainApplication.getLayerManager().getEditLayer().data.getDataSourceBounds();
    55     }
    56 
    57     private static boolean isInBounds(final Node node, final List<Bounds> bounds) {
    58         for (final Bounds b : bounds) {
    59             if (b.contains(node)) {
    60                 return true;
    61             }
    62         }
    63         return false;
    64     }
    65 
    6652    private static boolean confirmWayWithNodesOutsideBoundingBox() {
    6753        final ButtonSpec[] options = new ButtonSpec[] { new ButtonSpec(tr("Yes, delete nodes"), ImageProvider.get("ok"), tr("Delete nodes outside of downloaded data regions"), null),
    6854                new ButtonSpec(tr("No, abort"), ImageProvider.get("cancel"), tr("Cancel operation"), null) };
     
    9076
    9177    @Override
    9278    public void actionPerformed(final ActionEvent e) {
    93         final Collection<OsmPrimitive> selection = getLayerManager().getEditDataSet().getSelected();
    94 
    95         final List<Bounds> bounds = getCurrentEditBounds();
    96         for (final OsmPrimitive prim : selection) {
    97             if (prim instanceof Way && bounds.size() > 0) {
    98                 final Way way = (Way) prim;
    99                 // We check if each node of each way is at least in one download
    100                 // bounding box. Otherwise nodes may get deleted that are necessary by
    101                 // unloaded ways (see Ticket #1594)
    102                 for (final Node node : way.getNodes()) {
    103                     if (!isInBounds(node, bounds)) {
    104                         if (!confirmWayWithNodesOutsideBoundingBox()) {
    105                             return;
    106                         }
    107                         break;
    108                     }
    109                 }
    110             }
     79        final Collection<Way> ways = new LinkedHashSet<>(getLayerManager().getEditDataSet().getSelectedWays());
     80        ways.removeIf(w -> w.isIncomplete() || w.hasIncompleteNodes());
     81        int checkRes = Command.checkOutlyingOrIncompleteOperation(ways, null);
     82        if ((checkRes & Command.IS_OUTSIDE) != 0) {
     83            if (!confirmWayWithNodesOutsideBoundingBox())
     84                return;
    11185        }
    112         final Collection<Way> ways = Utils.filteredCollection(selection, Way.class);
    11386        if (ways.isEmpty()) {
    11487            alertSelectAtLeastOneWay();
    11588            return;
     
    146119        }
    147120
    148121        final Collection<Command> allCommands = new ArrayList<>();
     122        Map<Way,List<Node>> modifiedWays = new HashMap<>();
    149123
    150124        if (!nodesReallyToRemove.isEmpty()) {
    151125            for (final Way way : ways) {
     
    159133                    if (closed) {
    160134                        nodes.add(nodes.get(0));
    161135                    }
    162 
    163                     final Way newWay = new Way(way);
    164                     newWay.setNodes(nodes);
    165                     allCommands.add(new ChangeCommand(way, newWay));
     136                    allCommands.add(new ChangeNodesCommand(way, nodes));
     137                    modifiedWays.put(way, nodes);
    166138                }
    167139            }
    168140
     
    169141            allCommands.add(new DeleteCommand(nodesReallyToRemove));
    170142        }
    171143
    172         final Collection<Command> avgCommands = averageNearbyNodes(ways, nodesReallyToRemove);
     144        final Collection<Command> avgCommands = averageNearbyNodes(ways, nodesReallyToRemove, modifiedWays);
    173145        if (avgCommands != null && !avgCommands.isEmpty()) {
    174146            allCommands.add(new SequenceCommand(tr("average nearby nodes"), avgCommands));
    175147        }
    176148
    177149        if (!allCommands.isEmpty()) {
    178             final SequenceCommand rootCommand = new SequenceCommand(trn("Simplify {0} way", "Simplify {0} ways", allCommands.size(), allCommands.size()), allCommands);
     150            final SequenceCommand rootCommand = new SequenceCommand(trn("Simplify {0} way", "Simplify {0} ways", modifiedWays.size(), modifiedWays.size()), allCommands);
    179151            UndoRedoHandler.getInstance().add(rootCommand);
    180152            MainApplication.getMap().repaint();
    181153        }
     
    199171    }
    200172
    201173    // average nearby nodes
    202     private static Collection<Command> averageNearbyNodes(final Collection<Way> ways, final Collection<Node> nodesAlreadyDeleted) {
     174    private static Collection<Command> averageNearbyNodes(final Collection<Way> ways, final Collection<Node> nodesAlreadyDeleted, Map<Way, List<Node>> modifiedWays) {
    203175        final double mergeThreshold = Config.getPref().getDouble(SimplifyAreaPreferenceSetting.MERGE_THRESHOLD, 0.2);
    204176
    205177        final Map<Node, LatLon> coordMap = new HashMap<>();
     
    253225                    }
    254226
    255227                    // test if both nodes have same parents
    256                     if (!referrers.containsAll(referrers2) || !referrers2.containsAll(referrers)) {
     228                    if (referrers.size() != referrers2.size() || !referrers2.containsAll(referrers)) {
    257229                        continue;
    258230                    }
    259231
     
    289261            nodesToDelete.removeAll(nodesAlreadyDeleted);
    290262            if (nodesToDelete.removeAll(coordMap.keySet())) {
    291263                nodesToDelete2.addAll(nodesToDelete);
    292                 final Way newWay = new Way(way);
    293264                final List<Node> nodes = way.getNodes();
    294265                final boolean closed = nodes.get(0).equals(nodes.get(nodes.size() - 1));
    295266                if (closed) {
     
    300271                    nodes.add(nodes.get(0));
    301272                }
    302273
    303                 newWay.setNodes(nodes);
    304274                if (!way.getNodes().equals(nodes)) {
    305                     commands.add(new ChangeCommand(way, newWay));
     275                    List<Node> nodes1 = modifiedWays.get(way);
     276                    if (nodes1 == null || !nodes.equals(nodes1)) {
     277                        commands.add(new ChangeNodesCommand(way, nodes));
     278                        modifiedWays.put(way, nodes);
     279                    }
    306280                }
    307281            }
    308282        }
     
    435409        return q < 0.0 ? 0.0 : Math.sqrt(q);
    436410    }
    437411
    438     public static double R = 6378135;
     412    public static final double R = 6378135;
    439413
    440414    public static double crossTrackError(final ILatLon l1, final ILatLon l2, final ILatLon l3) {
    441415        return R * Math.asin(sin(l1.greatCircleDistance(l2) / R) * sin(heading(l1, l2) - heading(l1, l3)));