Changeset 988 in josm for trunk/src/org/openstreetmap/josm/actions
- Timestamp:
- 2008-09-18T15:19:00+02:00 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
r850 r988 7 7 import java.awt.event.KeyEvent; 8 8 import java.awt.event.MouseEvent; 9 import java.util.ArrayList;10 import java.util.Collection;11 9 import java.util.Collections; 12 import java.util.HashSet;13 import java.util.HashMap;14 import java.util.Iterator;15 import java.util.LinkedList;16 import java.util.List;17 18 import javax.swing.JOptionPane;19 10 20 11 import org.openstreetmap.josm.Main; 21 import org.openstreetmap.josm.command. *;22 import org.openstreetmap.josm. data.osm.Node;12 import org.openstreetmap.josm.command.Command; 13 import org.openstreetmap.josm.command.DeleteCommand; 23 14 import org.openstreetmap.josm.data.osm.OsmPrimitive; 24 import org.openstreetmap.josm.data.osm.Way;25 15 import org.openstreetmap.josm.data.osm.WaySegment; 26 import org.openstreetmap.josm.data.osm.Relation;27 import org.openstreetmap.josm.data.osm.RelationMember;28 import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;29 import org.openstreetmap.josm.data.osm.visitor.NameVisitor;30 16 import org.openstreetmap.josm.gui.MapFrame; 31 import org.openstreetmap.josm.tools. *;17 import org.openstreetmap.josm.tools.ImageProvider; 32 18 33 19 /** … … 88 74 Command c; 89 75 if (ctrl) { 90 c = deleteWithReferences(Main.ds.getSelected());76 c = DeleteCommand.deleteWithReferences(Main.ds.getSelected()); 91 77 } else { 92 c = delete(Main.ds.getSelected(), !alt);78 c = DeleteCommand.delete(Main.ds.getSelected(), !alt); 93 79 } 94 80 if (c != null) { … … 97 83 98 84 Main.map.repaint(); 99 85 } 100 86 101 87 /** … … 118 104 if (ws != null) { 119 105 if (shift) { 120 c = deleteWaySegment(ws);106 c = DeleteCommand.deleteWaySegment(ws); 121 107 } else if (ctrl) { 122 c = deleteWithReferences(Collections.singleton((OsmPrimitive)ws.way));108 c = DeleteCommand.deleteWithReferences(Collections.singleton((OsmPrimitive)ws.way)); 123 109 } else { 124 c = delete(Collections.singleton((OsmPrimitive)ws.way), !alt);110 c = DeleteCommand.delete(Collections.singleton((OsmPrimitive)ws.way), !alt); 125 111 } 126 112 } 127 113 } else if (ctrl) { 128 c = deleteWithReferences(Collections.singleton(sel));114 c = DeleteCommand.deleteWithReferences(Collections.singleton(sel)); 129 115 } else { 130 c = delete(Collections.singleton(sel), !alt);116 c = DeleteCommand.delete(Collections.singleton(sel), !alt); 131 117 } 132 118 if (c != null) { … … 136 122 Main.map.mapView.repaint(); 137 123 } 138 139 /**140 * Delete the primitives and everything they reference.141 *142 * If a node is deleted, the node and all ways and relations143 * the node is part of are deleted as well.144 *145 * If a way is deleted, all relations the way is member of are also deleted.146 *147 * If a way is deleted, only the way and no nodes are deleted.148 *149 * @param selection The list of all object to be deleted.150 * @return command A command to perform the deletions, or null of there is151 * nothing to delete.152 */153 private Command deleteWithReferences(Collection<OsmPrimitive> selection) {154 CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds);155 for (OsmPrimitive osm : selection)156 osm.visit(v);157 v.data.addAll(selection);158 if (v.data.isEmpty())159 return null;160 return new DeleteCommand(v.data);161 }162 163 /**164 * Try to delete all given primitives.165 *166 * If a node is used by a way, it's removed from that way. If a node or a167 * way is used by a relation, inform the user and do not delete.168 *169 * If this would cause ways with less than 2 nodes to be created, delete170 * these ways instead. If they are part of a relation, inform the user171 * and do not delete.172 *173 * @param selection The objects to delete.174 * @param alsoDeleteNodesInWay <code>true</code> if nodes should be deleted as well175 * @return command A command to perform the deletions, or null of there is176 * nothing to delete.177 */178 private int testRelation(Relation ref, OsmPrimitive osm)179 {180 NameVisitor n = new NameVisitor();181 ref.visit(n);182 NameVisitor s = new NameVisitor();183 osm.visit(s);184 String role = new String();185 for (RelationMember m : ref.members)186 {187 if (m.member == osm)188 {189 role = m.role;190 break;191 }192 }193 if (role.length() > 0)194 {195 return JOptionPane.showConfirmDialog(Main.parent,196 tr("Selection \"{0}\" is used by relation \"{1}\" with role {2}.\nDelete from relation?", s.name, n.name, role),197 tr("Conflicting relation"), JOptionPane.YES_NO_OPTION);198 }199 else200 {201 return JOptionPane.showConfirmDialog(Main.parent,202 tr("Selection \"{0}\" is used by relation \"{1}\".\nDelete from relation?", s.name, n.name),203 tr("Conflicting relation"), JOptionPane.YES_NO_OPTION);204 }205 }206 207 private Command delete(Collection<OsmPrimitive> selection, boolean alsoDeleteNodesInWay) {208 if (selection.isEmpty()) return null;209 210 Collection<OsmPrimitive> del = new HashSet<OsmPrimitive>(selection);211 Collection<Way> waysToBeChanged = new HashSet<Way>();212 HashMap<OsmPrimitive, Collection<OsmPrimitive>> relationsToBeChanged = new HashMap<OsmPrimitive, Collection<OsmPrimitive>>();213 214 if (alsoDeleteNodesInWay) {215 // Delete untagged nodes that are to be unreferenced.216 Collection<OsmPrimitive> delNodes = new HashSet<OsmPrimitive>();217 for (OsmPrimitive osm : del) {218 if (osm instanceof Way) {219 for (Node n : ((Way)osm).nodes) {220 if (!n.tagged) {221 CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);222 n.visit(v);223 v.data.removeAll(del);224 if (v.data.isEmpty()) {225 delNodes.add(n);226 }227 }228 }229 }230 }231 del.addAll(delNodes);232 }233 234 for (OsmPrimitive osm : del) {235 CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);236 osm.visit(v);237 for (OsmPrimitive ref : v.data) {238 if (del.contains(ref)) continue;239 if (ref instanceof Way) {240 waysToBeChanged.add((Way) ref);241 } else if (ref instanceof Relation) {242 if (testRelation((Relation)ref, osm) == JOptionPane.YES_OPTION)243 {244 Collection<OsmPrimitive> relset = relationsToBeChanged.get(ref);245 if(relset == null) relset = new HashSet<OsmPrimitive>();246 relset.add(osm);247 relationsToBeChanged.put(ref, relset);248 }249 else250 return null;251 } else {252 return null;253 }254 }255 }256 257 Collection<Command> cmds = new LinkedList<Command>();258 for (Way w : waysToBeChanged) {259 Way wnew = new Way(w);260 wnew.nodes.removeAll(del);261 if (wnew.nodes.size() < 2) {262 del.add(w);263 264 CollectBackReferencesVisitor v = new CollectBackReferencesVisitor(Main.ds, false);265 w.visit(v);266 for (OsmPrimitive ref : v.data) {267 if (del.contains(ref)) continue;268 if (ref instanceof Relation) {269 Boolean found = false;270 Collection<OsmPrimitive> relset = relationsToBeChanged.get(ref);271 if (relset == null)272 relset = new HashSet<OsmPrimitive>();273 else274 {275 for (OsmPrimitive m : relset) {276 if(m == w)277 {278 found = true;279 break;280 }281 }282 }283 if (!found)284 {285 if (testRelation((Relation)ref, w) == JOptionPane.YES_OPTION)286 {287 relset.add(w);288 relationsToBeChanged.put(ref, relset);289 }290 else291 return null;292 }293 } else {294 return null;295 }296 }297 } else {298 cmds.add(new ChangeCommand(w, wnew));299 }300 }301 302 Iterator<OsmPrimitive> iterator = relationsToBeChanged.keySet().iterator();303 while(iterator.hasNext())304 {305 Relation cur = (Relation)iterator.next();306 Relation rel = new Relation(cur);307 for(OsmPrimitive osm : relationsToBeChanged.get(cur))308 {309 for (RelationMember rm : rel.members) {310 if (rm.member == osm)311 {312 RelationMember mem = new RelationMember();313 mem.role = rm.role;314 mem.member = rm.member;315 rel.members.remove(mem);316 break;317 }318 }319 }320 cmds.add(new ChangeCommand(cur, rel));321 }322 323 if (!del.isEmpty()) cmds.add(new DeleteCommand(del));324 325 return new SequenceCommand(tr("Delete"), cmds);326 }327 328 private Command deleteWaySegment(WaySegment ws) {329 List<Node> n1 = new ArrayList<Node>(),330 n2 = new ArrayList<Node>();331 332 n1.addAll(ws.way.nodes.subList(0, ws.lowerIndex + 1));333 n2.addAll(ws.way.nodes.subList(ws.lowerIndex + 1, ws.way.nodes.size()));334 335 if (n1.size() < 2 && n2.size() < 2) {336 return new DeleteCommand(Collections.singleton(ws.way));337 }338 339 Way wnew = new Way(ws.way);340 wnew.nodes.clear();341 342 if (n1.size() < 2) {343 wnew.nodes.addAll(n2);344 return new ChangeCommand(ws.way, wnew);345 } else if (n2.size() < 2) {346 wnew.nodes.addAll(n1);347 return new ChangeCommand(ws.way, wnew);348 } else {349 Collection<Command> cmds = new LinkedList<Command>();350 351 wnew.nodes.addAll(n1);352 cmds.add(new ChangeCommand(ws.way, wnew));353 354 Way wnew2 = new Way();355 if (wnew.keys != null) {356 wnew2.keys = new HashMap<String, String>(wnew.keys);357 wnew2.checkTagged();358 wnew2.checkDirectionTagged();359 }360 wnew2.nodes.addAll(n2);361 cmds.add(new AddCommand(wnew2));362 363 return new SequenceCommand(tr("Split way segment"), cmds);364 }365 }366 124 367 125 @Override public String getModeHelpText() {
Note:
See TracChangeset
for help on using the changeset viewer.