Ticket #23505: 23505.patch
| File 23505.patch, 7.7 KB (added by , 2 years ago) |
|---|
-
src/org/openstreetmap/josm/plugins/simplifyarea/SimplifyAreaAction.java
13 13 import java.util.Collection; 14 14 import java.util.HashMap; 15 15 import java.util.HashSet; 16 import java.util.LinkedHashSet; 16 17 import java.util.List; 17 18 import java.util.Map; 18 19 import java.util.Map.Entry; … … 21 22 import javax.swing.JOptionPane; 22 23 23 24 import org.openstreetmap.josm.actions.JosmAction; 24 import org.openstreetmap.josm.command.Change Command;25 import org.openstreetmap.josm.command.ChangeNodesCommand; 25 26 import org.openstreetmap.josm.command.Command; 26 27 import org.openstreetmap.josm.command.DeleteCommand; 27 28 import org.openstreetmap.josm.command.MoveCommand; 28 29 import org.openstreetmap.josm.command.SequenceCommand; 29 import org.openstreetmap.josm.data.Bounds;30 30 import org.openstreetmap.josm.data.UndoRedoHandler; 31 31 import org.openstreetmap.josm.data.coor.ILatLon; 32 32 import org.openstreetmap.josm.data.coor.LatLon; … … 40 40 import org.openstreetmap.josm.spi.preferences.Config; 41 41 import org.openstreetmap.josm.tools.ImageProvider; 42 42 import org.openstreetmap.josm.tools.Shortcut; 43 import org.openstreetmap.josm.tools.Utils;44 43 45 44 public final class SimplifyAreaAction extends JosmAction { 46 45 … … 50 49 true, "simplifyarea", true); 51 50 } 52 51 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 66 52 private static boolean confirmWayWithNodesOutsideBoundingBox() { 67 53 final ButtonSpec[] options = new ButtonSpec[] { new ButtonSpec(tr("Yes, delete nodes"), ImageProvider.get("ok"), tr("Delete nodes outside of downloaded data regions"), null), 68 54 new ButtonSpec(tr("No, abort"), ImageProvider.get("cancel"), tr("Cancel operation"), null) }; … … 90 76 91 77 @Override 92 78 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; 111 85 } 112 final Collection<Way> ways = Utils.filteredCollection(selection, Way.class);113 86 if (ways.isEmpty()) { 114 87 alertSelectAtLeastOneWay(); 115 88 return; … … 146 119 } 147 120 148 121 final Collection<Command> allCommands = new ArrayList<>(); 122 Map<Way,List<Node>> modifiedWays = new HashMap<>(); 149 123 150 124 if (!nodesReallyToRemove.isEmpty()) { 151 125 for (final Way way : ways) { … … 159 133 if (closed) { 160 134 nodes.add(nodes.get(0)); 161 135 } 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); 166 138 } 167 139 } 168 140 … … 169 141 allCommands.add(new DeleteCommand(nodesReallyToRemove)); 170 142 } 171 143 172 final Collection<Command> avgCommands = averageNearbyNodes(ways, nodesReallyToRemove );144 final Collection<Command> avgCommands = averageNearbyNodes(ways, nodesReallyToRemove, modifiedWays); 173 145 if (avgCommands != null && !avgCommands.isEmpty()) { 174 146 allCommands.add(new SequenceCommand(tr("average nearby nodes"), avgCommands)); 175 147 } 176 148 177 149 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); 179 151 UndoRedoHandler.getInstance().add(rootCommand); 180 152 MainApplication.getMap().repaint(); 181 153 } … … 199 171 } 200 172 201 173 // 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) { 203 175 final double mergeThreshold = Config.getPref().getDouble(SimplifyAreaPreferenceSetting.MERGE_THRESHOLD, 0.2); 204 176 205 177 final Map<Node, LatLon> coordMap = new HashMap<>(); … … 253 225 } 254 226 255 227 // test if both nodes have same parents 256 if ( !referrers.containsAll(referrers2) || !referrers2.containsAll(referrers)) {228 if (referrers.size() != referrers2.size() || !referrers2.containsAll(referrers)) { 257 229 continue; 258 230 } 259 231 … … 289 261 nodesToDelete.removeAll(nodesAlreadyDeleted); 290 262 if (nodesToDelete.removeAll(coordMap.keySet())) { 291 263 nodesToDelete2.addAll(nodesToDelete); 292 final Way newWay = new Way(way);293 264 final List<Node> nodes = way.getNodes(); 294 265 final boolean closed = nodes.get(0).equals(nodes.get(nodes.size() - 1)); 295 266 if (closed) { … … 300 271 nodes.add(nodes.get(0)); 301 272 } 302 273 303 newWay.setNodes(nodes);304 274 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 } 306 280 } 307 281 } 308 282 } … … 435 409 return q < 0.0 ? 0.0 : Math.sqrt(q); 436 410 } 437 411 438 public static double R = 6378135;412 public static final double R = 6378135; 439 413 440 414 public static double crossTrackError(final ILatLon l1, final ILatLon l2, final ILatLon l3) { 441 415 return R * Math.asin(sin(l1.greatCircleDistance(l2) / R) * sin(heading(l1, l2) - heading(l1, l3)));
