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