Changeset 988 in josm
- Timestamp:
- 2008-09-18T15:19:00+02:00 (16 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 3 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() { -
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 } -
trunk/src/org/openstreetmap/josm/gui/dialogs/RelationEditor.java
r810 r988 320 320 tr("Highlight the member from the current table row as JOSM's selection"), KeyEvent.VK_S, new ActionListener() { 321 321 public void actionPerformed(ActionEvent e) { 322 int[] rows = memberTable.getSelectedRows(); 323 ArrayList<OsmPrimitive> sel = new ArrayList<OsmPrimitive>(rows.length); 324 for (int i : rows) { sel.add((OsmPrimitive)memberTable.getValueAt(i, 1)); } 322 ArrayList<OsmPrimitive> sel; 323 int cnt = memberTable.getSelectedRowCount(); 324 if(cnt > 0) 325 { 326 sel = new ArrayList<OsmPrimitive>(cnt); 327 for (int i : memberTable.getSelectedRows()) 328 sel.add((OsmPrimitive)memberTable.getValueAt(i, 1)); 329 } 330 else 331 { 332 cnt = memberTable.getRowCount(); 333 sel = new ArrayList<OsmPrimitive>(cnt); 334 for (int i = 0; i < cnt; ++i) 335 sel.add((OsmPrimitive)memberTable.getValueAt(i, 1)); 336 } 325 337 Main.ds.setSelected(sel); 326 338 }
Note:
See TracChangeset
for help on using the changeset viewer.