Changeset 12688 in josm
- Timestamp:
- 2017-08-28T18:48:58+02:00 (7 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/PurgeAction.java
r12641 r12688 13 13 import java.util.ArrayList; 14 14 import java.util.Collection; 15 import java.util.HashSet;16 15 import java.util.List; 17 import java.util.Set;18 16 19 17 import javax.swing.AbstractAction; … … 32 30 import org.openstreetmap.josm.command.PurgeCommand; 33 31 import org.openstreetmap.josm.data.osm.DataSet; 34 import org.openstreetmap.josm.data.osm.Node;35 32 import org.openstreetmap.josm.data.osm.OsmPrimitive; 36 import org.openstreetmap.josm.data.osm.Relation;37 import org.openstreetmap.josm.data.osm.RelationMember;38 import org.openstreetmap.josm.data.osm.Way;39 33 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 40 34 import org.openstreetmap.josm.gui.MainApplication; … … 64 58 protected boolean modified; 65 59 66 protected transient Set<OsmPrimitive> toPurge;67 /**68 * finally, contains all objects that are purged69 */70 protected transient Set<OsmPrimitive> toPurgeChecked;71 /**72 * Subset of toPurgeChecked. Marks primitives that remain in the dataset, but incomplete.73 */74 protected transient Set<OsmPrimitive> makeIncomplete;75 60 /** 76 61 * Subset of toPurgeChecked. Those that have not been in the selection. … … 82 67 */ 83 68 public PurgeAction() { 84 this(true);85 }86 87 /**88 * Constructs a new {@code PurgeAction} with optional shortcut.89 * @param addShortcut controls whether the shortcut should be registered or not, as for toolbar registration90 * @since 1161191 */92 public PurgeAction(boolean addShortcut) {93 69 /* translator note: other expressions for "purge" might be "forget", "clean", "obliterate", "prune" */ 94 super(tr("Purge..."), "purge", tr("Forget objects but do not delete them on server when uploading."), addShortcut ?95 Shortcut.registerShortcut("system:purge", tr("Edit: {0}", tr("Purge")), KeyEvent.VK_P, Shortcut.CTRL_SHIFT) 96 : null, addShortcut);70 super(tr("Purge..."), "purge", tr("Forget objects but do not delete them on server when uploading."), 71 Shortcut.registerShortcut("system:purge", tr("Edit: {0}", tr("Purge")), KeyEvent.VK_P, Shortcut.CTRL_SHIFT), 72 true); 97 73 putValue("help", HelpUtil.ht("/Action/Purge")); 98 74 } … … 141 117 public PurgeCommand getPurgeCommand(Collection<OsmPrimitive> sel) { 142 118 layer = getLayerManager().getEditLayer(); 143 144 toPurge = new HashSet<>(sel);145 119 toPurgeAdditionally = new ArrayList<>(); 146 toPurgeChecked = new HashSet<>(); 147 148 // Add referrer, unless the object to purge is not new and the parent is a relation 149 Set<OsmPrimitive> toPurgeRecursive = new HashSet<>(); 150 while (!toPurge.isEmpty()) { 151 152 for (OsmPrimitive osm: toPurge) { 153 for (OsmPrimitive parent: osm.getReferrers()) { 154 if (toPurge.contains(parent) || toPurgeChecked.contains(parent) || toPurgeRecursive.contains(parent)) { 155 continue; 156 } 157 if (parent instanceof Way || (parent instanceof Relation && osm.isNew())) { 158 toPurgeAdditionally.add(parent); 159 toPurgeRecursive.add(parent); 160 } 161 } 162 toPurgeChecked.add(osm); 163 } 164 toPurge = toPurgeRecursive; 165 toPurgeRecursive = new HashSet<>(); 166 } 167 168 makeIncomplete = new HashSet<>(); 169 170 // Find the objects that will be incomplete after purging. 171 // At this point, all parents of new to-be-purged primitives are 172 // also to-be-purged and 173 // all parents of not-new to-be-purged primitives are either 174 // to-be-purged or of type relation. 175 TOP: 176 for (OsmPrimitive child : toPurgeChecked) { 177 if (child.isNew()) { 178 continue; 179 } 180 for (OsmPrimitive parent : child.getReferrers()) { 181 if (parent instanceof Relation && !toPurgeChecked.contains(parent)) { 182 makeIncomplete.add(child); 183 continue TOP; 184 } 185 } 186 } 187 188 // Add untagged way nodes. Do not add nodes that have other referrers not yet to-be-purged. 189 if (Main.pref.getBoolean("purge.add_untagged_waynodes", true)) { 190 Set<OsmPrimitive> wayNodes = new HashSet<>(); 191 for (OsmPrimitive osm : toPurgeChecked) { 192 if (osm instanceof Way) { 193 Way w = (Way) osm; 194 NODE: 195 for (Node n : w.getNodes()) { 196 if (n.isTagged() || toPurgeChecked.contains(n)) { 197 continue; 198 } 199 for (OsmPrimitive ref : n.getReferrers()) { 200 if (ref != w && !toPurgeChecked.contains(ref)) { 201 continue NODE; 202 } 203 } 204 wayNodes.add(n); 205 } 206 } 207 } 208 toPurgeChecked.addAll(wayNodes); 209 toPurgeAdditionally.addAll(wayNodes); 210 } 211 212 if (Main.pref.getBoolean("purge.add_relations_with_only_incomplete_members", true)) { 213 Set<Relation> relSet = new HashSet<>(); 214 for (OsmPrimitive osm : toPurgeChecked) { 215 for (OsmPrimitive parent : osm.getReferrers()) { 216 if (parent instanceof Relation 217 && !(toPurgeChecked.contains(parent)) 218 && hasOnlyIncompleteMembers((Relation) parent, toPurgeChecked, relSet)) { 219 relSet.add((Relation) parent); 220 } 221 } 222 } 223 224 // Add higher level relations (list gets extended while looping over it) 225 List<Relation> relLst = new ArrayList<>(relSet); 226 for (int i = 0; i < relLst.size(); ++i) { // foreach loop not applicable since list gets extended while looping over it 227 for (OsmPrimitive parent : relLst.get(i).getReferrers()) { 228 if (!(toPurgeChecked.contains(parent)) 229 && hasOnlyIncompleteMembers((Relation) parent, toPurgeChecked, relLst)) { 230 relLst.add((Relation) parent); 231 } 232 } 233 } 234 relSet = new HashSet<>(relLst); 235 toPurgeChecked.addAll(relSet); 236 toPurgeAdditionally.addAll(relSet); 237 } 238 239 modified = false; 240 for (OsmPrimitive osm : toPurgeChecked) { 241 if (osm.isModified()) { 242 modified = true; 243 break; 244 } 245 } 246 247 return layer != null ? new PurgeCommand(layer, toPurgeChecked, makeIncomplete) : 248 new PurgeCommand(toPurgeChecked.iterator().next().getDataSet(), toPurgeChecked, makeIncomplete); 120 PurgeCommand cmd = PurgeCommand.build(layer, sel, toPurgeAdditionally); 121 modified = cmd.getParticipatingPrimitives().stream().anyMatch(OsmPrimitive::isModified); 122 return cmd; 249 123 } 250 124 … … 323 197 setEnabled(selection != null && !selection.isEmpty()); 324 198 } 325 326 private static boolean hasOnlyIncompleteMembers(327 Relation r, Collection<OsmPrimitive> toPurge, Collection<? extends OsmPrimitive> moreToPurge) {328 for (RelationMember m : r.getMembers()) {329 if (!m.getMember().isIncomplete() && !toPurge.contains(m.getMember()) && !moreToPurge.contains(m.getMember()))330 return false;331 }332 return true;333 }334 199 } -
trunk/src/org/openstreetmap/josm/command/PurgeCommand.java
r12672 r12688 16 16 import javax.swing.Icon; 17 17 18 import org.openstreetmap.josm.Main; 18 19 import org.openstreetmap.josm.data.conflict.Conflict; 19 20 import org.openstreetmap.josm.data.conflict.ConflictCollection; … … 26 27 import org.openstreetmap.josm.data.osm.Relation; 27 28 import org.openstreetmap.josm.data.osm.RelationData; 29 import org.openstreetmap.josm.data.osm.RelationMember; 28 30 import org.openstreetmap.josm.data.osm.Storage; 29 31 import org.openstreetmap.josm.data.osm.Way; … … 309 311 Objects.equals(purgedConflicts, that.purgedConflicts); 310 312 } 313 314 /** 315 * Creates a new {@code PurgeCommand} to purge selected OSM primitives. 316 * @param layer optional osm data layer, can be null 317 * @param sel selected OSM primitives 318 * @param toPurgeAdditionally optional list that will be filled with primitives to be purged that have not been in the selection 319 * @return command to purge selected OSM primitives 320 * @since 12688 321 */ 322 public static PurgeCommand build(OsmDataLayer layer, Collection<OsmPrimitive> sel, List<OsmPrimitive> toPurgeAdditionally) { 323 Set<OsmPrimitive> toPurge = new HashSet<>(sel); 324 // finally, contains all objects that are purged 325 Set<OsmPrimitive> toPurgeChecked = new HashSet<>(); 326 327 // Add referrer, unless the object to purge is not new and the parent is a relation 328 Set<OsmPrimitive> toPurgeRecursive = new HashSet<>(); 329 while (!toPurge.isEmpty()) { 330 331 for (OsmPrimitive osm: toPurge) { 332 for (OsmPrimitive parent: osm.getReferrers()) { 333 if (toPurge.contains(parent) || toPurgeChecked.contains(parent) || toPurgeRecursive.contains(parent)) { 334 continue; 335 } 336 if (parent instanceof Way || (parent instanceof Relation && osm.isNew())) { 337 if (toPurgeAdditionally != null) { 338 toPurgeAdditionally.add(parent); 339 } 340 toPurgeRecursive.add(parent); 341 } 342 } 343 toPurgeChecked.add(osm); 344 } 345 toPurge = toPurgeRecursive; 346 toPurgeRecursive = new HashSet<>(); 347 } 348 349 // Subset of toPurgeChecked. Marks primitives that remain in the dataset, but incomplete. 350 Set<OsmPrimitive> makeIncomplete = new HashSet<>(); 351 352 // Find the objects that will be incomplete after purging. 353 // At this point, all parents of new to-be-purged primitives are 354 // also to-be-purged and 355 // all parents of not-new to-be-purged primitives are either 356 // to-be-purged or of type relation. 357 TOP: 358 for (OsmPrimitive child : toPurgeChecked) { 359 if (child.isNew()) { 360 continue; 361 } 362 for (OsmPrimitive parent : child.getReferrers()) { 363 if (parent instanceof Relation && !toPurgeChecked.contains(parent)) { 364 makeIncomplete.add(child); 365 continue TOP; 366 } 367 } 368 } 369 370 // Add untagged way nodes. Do not add nodes that have other referrers not yet to-be-purged. 371 if (Main.pref.getBoolean("purge.add_untagged_waynodes", true)) { 372 Set<OsmPrimitive> wayNodes = new HashSet<>(); 373 for (OsmPrimitive osm : toPurgeChecked) { 374 if (osm instanceof Way) { 375 Way w = (Way) osm; 376 NODE: 377 for (Node n : w.getNodes()) { 378 if (n.isTagged() || toPurgeChecked.contains(n)) { 379 continue; 380 } 381 for (OsmPrimitive ref : n.getReferrers()) { 382 if (ref != w && !toPurgeChecked.contains(ref)) { 383 continue NODE; 384 } 385 } 386 wayNodes.add(n); 387 } 388 } 389 } 390 toPurgeChecked.addAll(wayNodes); 391 if (toPurgeAdditionally != null) { 392 toPurgeAdditionally.addAll(wayNodes); 393 } 394 } 395 396 if (Main.pref.getBoolean("purge.add_relations_with_only_incomplete_members", true)) { 397 Set<Relation> relSet = new HashSet<>(); 398 for (OsmPrimitive osm : toPurgeChecked) { 399 for (OsmPrimitive parent : osm.getReferrers()) { 400 if (parent instanceof Relation 401 && !(toPurgeChecked.contains(parent)) 402 && hasOnlyIncompleteMembers((Relation) parent, toPurgeChecked, relSet)) { 403 relSet.add((Relation) parent); 404 } 405 } 406 } 407 408 // Add higher level relations (list gets extended while looping over it) 409 List<Relation> relLst = new ArrayList<>(relSet); 410 for (int i = 0; i < relLst.size(); ++i) { // foreach loop not applicable since list gets extended while looping over it 411 for (OsmPrimitive parent : relLst.get(i).getReferrers()) { 412 if (!(toPurgeChecked.contains(parent)) 413 && hasOnlyIncompleteMembers((Relation) parent, toPurgeChecked, relLst)) { 414 relLst.add((Relation) parent); 415 } 416 } 417 } 418 relSet = new HashSet<>(relLst); 419 toPurgeChecked.addAll(relSet); 420 if (toPurgeAdditionally != null) { 421 toPurgeAdditionally.addAll(relSet); 422 } 423 } 424 425 return layer != null ? new PurgeCommand(layer, toPurgeChecked, makeIncomplete) 426 : new PurgeCommand(toPurgeChecked.iterator().next().getDataSet(), toPurgeChecked, makeIncomplete); 427 } 428 429 private static boolean hasOnlyIncompleteMembers( 430 Relation r, Collection<OsmPrimitive> toPurge, Collection<? extends OsmPrimitive> moreToPurge) { 431 for (RelationMember m : r.getMembers()) { 432 if (!m.getMember().isIncomplete() && !toPurge.contains(m.getMember()) && !moreToPurge.contains(m.getMember())) 433 return false; 434 } 435 return true; 436 } 311 437 } -
trunk/src/org/openstreetmap/josm/tools/RightAndLefthandTraffic.java
r12620 r12688 21 21 import org.openstreetmap.josm.actions.JoinAreasAction.JoinAreasResult; 22 22 import org.openstreetmap.josm.actions.JoinAreasAction.Multipolygon; 23 import org.openstreetmap.josm. actions.PurgeAction;23 import org.openstreetmap.josm.command.PurgeCommand; 24 24 import org.openstreetmap.josm.data.coor.LatLon; 25 25 import org.openstreetmap.josm.data.osm.DataSet; … … 104 104 } 105 105 // Purge all other ways and relations so dataset only contains lefthand traffic data 106 new PurgeAction(false).getPurgeCommand(toPurge).executeCommand();106 PurgeCommand.build(null, toPurge, null).executeCommand(); 107 107 // Combine adjacent countries into a single polygon 108 108 Collection<Way> optimizedWays = new ArrayList<>();
Note:
See TracChangeset
for help on using the changeset viewer.