Changeset 3392 in josm for trunk/src/org/openstreetmap
- Timestamp:
- 2010-07-29T08:22:51+02:00 (14 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java
r3156 r3392 10 10 import java.util.ArrayList; 11 11 import java.util.Collection; 12 import java.util.HashMap;13 12 import java.util.HashSet; 14 13 import java.util.Iterator; 15 14 import java.util.LinkedList; 16 15 import java.util.List; 17 import java.util.Map;18 16 import java.util.Set; 19 import java.util.Map.Entry;20 17 21 18 import javax.swing.JOptionPane; … … 98 95 List<Node> selectedNodes = OsmPrimitive.getFilteredList(selection, Node.class); 99 96 List<Way> selectedWays = OsmPrimitive.getFilteredList(selection, Way.class); 100 101 if (!checkSelection(selection)) { 97 List<Relation> selectedRelations = OsmPrimitive.getFilteredList(selection, Relation.class); 98 List<Way> applicableWays = getApplicableWays(selectedWays, selectedNodes); 99 100 if (applicableWays == null) { 102 101 JOptionPane.showMessageDialog( 103 102 Main.parent, 104 tr("The current selection cannot be used for splitting ."),103 tr("The current selection cannot be used for splitting - no node is selected."), 105 104 tr("Warning"), 106 JOptionPane.WARNING_MESSAGE 107 ); 105 JOptionPane.WARNING_MESSAGE); 108 106 return; 109 } 110 111 112 Way selectedWay = null; 113 if (!selectedWays.isEmpty()){ 114 selectedWay = selectedWays.get(0); 115 } 116 117 // If only nodes are selected, try to guess which way to split. This works if there 118 // is exactly one way that all nodes are part of. 119 if (selectedWay == null && !selectedNodes.isEmpty()) { 120 Map<Way, Integer> wayOccurenceCounter = new HashMap<Way, Integer>(); 121 for (Node n : selectedNodes) { 122 for (Way w : OsmPrimitive.getFilteredList(n.getReferrers(), Way.class)) { 123 if (!w.isUsable()) { 124 continue; 125 } 107 } else if (applicableWays.isEmpty()) { 108 JOptionPane.showMessageDialog(Main.parent, 109 tr("The selected nodes do not share the same way."), 110 tr("Warning"), 111 JOptionPane.WARNING_MESSAGE); 112 return; 113 } 114 115 { // Remove ways that doesn't have selected node in the middle 116 Iterator<Way> it = applicableWays.iterator(); 117 WAY_LOOP: 118 while (it.hasNext()) { 119 Way w = it.next(); 120 assert w.isUsable(); // Way is referrer of selected node(s) so it must be usable 126 121 int last = w.getNodesCount() - 1; 127 if (last <= 0) {128 continue; // zero or one node ways129 }130 122 boolean circular = w.isClosed(); 131 int i = 0; 132 for (Node wn : w.getNodes()) {133 i f ((circular || (i > 0 && i < last)) && n.equals(wn)) {134 Integer old = wayOccurenceCounter.get(w);135 wayOccurenceCounter.put(w, (old == null) ? 1 : old + 1);136 break;123 124 for (Node n : selectedNodes) { 125 int i = w.getNodes().indexOf(n); 126 if (!(circular || (i > 0 && i < last))) { 127 it.remove(); 128 continue WAY_LOOP; 137 129 } 138 i++;139 130 } 140 131 } 141 } 142 if (wayOccurenceCounter.isEmpty()) { 143 JOptionPane.showMessageDialog(Main.parent, 144 trn("The selected node is not in the middle of any way.", 145 "The selected nodes are not in the middle of any way.", 146 selectedNodes.size()), 147 tr("Warning"), 148 JOptionPane.WARNING_MESSAGE); 149 return; 150 } 151 152 for (Entry<Way, Integer> entry : wayOccurenceCounter.entrySet()) { 153 if (entry.getValue().equals(selectedNodes.size())) { 154 if (selectedWay != null) { 155 JOptionPane.showMessageDialog(Main.parent, 156 trn("There is more than one way using the node you selected. Please select the way also.", 157 "There is more than one way using the nodes you selected. Please select the way also.", 158 selectedNodes.size()), 159 tr("Warning"), 160 JOptionPane.WARNING_MESSAGE); 161 return; 162 } 163 selectedWay = entry.getKey(); 164 } 165 } 166 167 if (selectedWay == null) { 168 JOptionPane.showMessageDialog(Main.parent, 169 tr("The selected nodes do not share the same way."), 170 tr("Warning"), 171 JOptionPane.WARNING_MESSAGE); 172 return; 173 } 174 175 // If a way and nodes are selected, verify that the nodes are part of the way. 176 } else if (selectedWay != null && !selectedNodes.isEmpty()) { 177 178 HashSet<Node> nds = new HashSet<Node>(selectedNodes); 179 nds.removeAll(selectedWay.getNodes()); 180 if (!nds.isEmpty()) { 181 JOptionPane.showMessageDialog(Main.parent, 182 trn("The selected way does not contain the selected node.", 183 "The selected way does not contain all the selected nodes.", 184 selectedNodes.size()), 185 tr("Warning"), 186 JOptionPane.WARNING_MESSAGE); 187 return; 188 } 189 } 132 } 133 134 if (applicableWays.isEmpty()) { 135 JOptionPane.showMessageDialog(Main.parent, 136 trn("The selected node is not in the middle of any way.", 137 "The selected nodes are not in the middle of any way.", 138 selectedNodes.size()), 139 tr("Warning"), 140 JOptionPane.WARNING_MESSAGE); 141 return; 142 } else if (applicableWays.size() > 1) { 143 JOptionPane.showMessageDialog(Main.parent, 144 trn("There is more than one way using the node you selected. Please select the way also.", 145 "There is more than one way using the nodes you selected. Please select the way also.", 146 selectedNodes.size()), 147 tr("Warning"), 148 JOptionPane.WARNING_MESSAGE); 149 return; 150 } 151 152 // Finally, applicableWays contains only one perfect way 153 Way selectedWay = applicableWays.get(0); 190 154 191 155 List<List<Node>> wayChunks = buildSplitChunks(selectedWay, selectedNodes); 192 156 if (wayChunks != null) { 193 SplitWayResult result = splitWay(getEditLayer(),selectedWay, wayChunks); 157 List<OsmPrimitive> sel = new ArrayList<OsmPrimitive>(selectedWays.size() + selectedRelations.size()); 158 sel.addAll(selectedWays); 159 sel.addAll(selectedRelations); 160 SplitWayResult result = splitWay(getEditLayer(),selectedWay, wayChunks, sel); 194 161 Main.main.undoRedo.add(result.getCommand()); 195 162 getCurrentDataSet().setSelected(result.getNewSelection()); … … 197 164 } 198 165 199 /** 200 * Checks if the selection consists of something we can work with. 201 * Checks only if the number and type of items selected looks good; 202 * does not check whether the selected items are really a valid 203 * input for splitting (this would be too expensive to be carried 204 * out from the selectionChanged listener). 205 */ 206 private boolean checkSelection(Collection<? extends OsmPrimitive> selection) { 207 boolean way = false; 208 boolean node = false; 209 for (OsmPrimitive p : selection) { 210 if (p instanceof Way && !way) { 211 way = true; 212 } else if (p instanceof Node) { 213 node = true; 214 } else 215 return false; 216 } 217 return node; 166 private List<Way> getApplicableWays(List<Way> selectedWays, List<Node> selectedNodes) { 167 if (selectedNodes.isEmpty()) 168 return null; 169 170 // List of ways shared by all nodes 171 List<Way> result = new ArrayList<Way>(OsmPrimitive.getFilteredList(selectedNodes.get(0).getReferrers(), Way.class)); 172 for (int i=1; i<selectedNodes.size(); i++) { 173 Iterator<Way> it = result.iterator(); 174 List<OsmPrimitive> ref = selectedNodes.get(i).getReferrers(); 175 while (it.hasNext()) { 176 if (!ref.contains(it.next())) { 177 it.remove(); 178 } 179 } 180 } 181 182 { // Remove broken ways 183 Iterator<Way> it = result.iterator(); 184 while (it.hasNext()) { 185 if (it.next().getNodesCount() <= 2) { 186 it.remove(); 187 } 188 } 189 } 190 191 if (selectedWays.isEmpty()) 192 return result; 193 else { 194 // Return only selected ways 195 Iterator<Way> it = result.iterator(); 196 while (it.hasNext()) { 197 if (!selectedWays.contains(it.next())) { 198 it.remove(); 199 } 200 } 201 return result; 202 } 203 218 204 } 219 205 … … 301 287 * @return 302 288 */ 303 public static SplitWayResult splitWay(OsmDataLayer layer, Way way, List<List<Node>> wayChunks ) {289 public static SplitWayResult splitWay(OsmDataLayer layer, Way way, List<List<Node>> wayChunks, Collection<? extends OsmPrimitive> selection) { 304 290 // build a list of commands, and also a new selection list 305 291 Collection<Command> commandList = new ArrayList<Command>(wayChunks.size()); 306 List<Way> newSelection = new ArrayList<Way>(wayChunks.size()); 292 List<OsmPrimitive> newSelection = new ArrayList<OsmPrimitive>(selection.size() + wayChunks.size()); 293 newSelection.addAll(selection); 307 294 308 295 Iterator<List<Node>> chunkIt = wayChunks.iterator(); … … 312 299 changedWay.setNodes(chunkIt.next()); 313 300 commandList.add(new ChangeCommand(way, changedWay)); 314 newSelection.add(way); 301 if (!newSelection.contains(way)) { 302 newSelection.add(way); 303 } 315 304 316 305 List<Way> newWays = new ArrayList<Way>(); … … 495 484 * @return the result from the split operation 496 485 */ 497 static public SplitWayResult split(OsmDataLayer layer, Way way, List<Node> atNodes ){486 static public SplitWayResult split(OsmDataLayer layer, Way way, List<Node> atNodes, Collection<? extends OsmPrimitive> selection){ 498 487 List<List<Node>> chunks = buildSplitChunks(way, atNodes); 499 488 if (chunks == null) return null; 500 return splitWay(layer,way, chunks );489 return splitWay(layer,way, chunks, selection); 501 490 } 502 491 … … 516 505 return; 517 506 } 518 setEnabled(checkSelection(selection)); 507 for (OsmPrimitive primitive: selection) { 508 if (primitive instanceof Node) { 509 setEnabled(true); // Selection still can be wrong, but let SplitWayAction process and tell user what's wrong 510 return; 511 } 512 } 513 setEnabled(false); 519 514 } 520 515 } -
trunk/src/org/openstreetmap/josm/command/DeleteCommand.java
r3336 r3392 23 23 import javax.swing.JOptionPane; 24 24 import javax.swing.JPanel; 25 import javax.swing.tree.DefaultMutableTreeNode;26 import javax.swing.tree.MutableTreeNode;27 25 28 26 import org.openstreetmap.josm.Main; … … 185 183 186 184 @Override public Collection<PseudoCommand> getChildren() { 187 if (toDelete.size() == 1) {185 if (toDelete.size() == 1) 188 186 return null; 189 }else {187 else { 190 188 List<PseudoCommand> children = new ArrayList<PseudoCommand>(); 191 189 for (final OsmPrimitive osm : toDelete) { … … 193 191 @Override public JLabel getDescription() { 194 192 return new JLabel( 195 tr("Deleted ''{0}''",196 osm.getDisplayName(DefaultNameFormatter.getInstance())),197 ImageProvider.get(OsmPrimitiveType.from(osm)), JLabel.HORIZONTAL);198 193 tr("Deleted ''{0}''", 194 osm.getDisplayName(DefaultNameFormatter.getInstance())), 195 ImageProvider.get(OsmPrimitiveType.from(osm)), JLabel.HORIZONTAL); 196 } 199 197 @Override public Collection<? extends OsmPrimitive> getParticipatingPrimitives() { 200 198 return Collections.singleton(osm); … … 425 423 chunks.add(n1); 426 424 chunks.add(n2); 427 return SplitWayAction.splitWay(layer,ws.way, chunks ).getCommand();425 return SplitWayAction.splitWay(layer,ws.way, chunks, Collections.<OsmPrimitive>emptyList()).getCommand(); 428 426 } 429 427 } … … 443 441 if (a != null) { 444 442 for (OsmPrimitive osm : primitivesToDelete) { 445 if (osm.isIncomplete()) 443 if (osm.isIncomplete()) { 446 444 incomplete = true; 447 else if (osm instanceof Node && !osm.isNewOrUndeleted()448 && !a.contains(((Node) osm).getCoor()))445 } else if (osm instanceof Node && !osm.isNewOrUndeleted() 446 && !a.contains(((Node) osm).getCoor())) { 449 447 outside = true; 448 } 450 449 } 451 450 } … … 453 452 { 454 453 for (OsmPrimitive osm : primitivesToDelete) 455 if (osm.isIncomplete()) 454 if (osm.isIncomplete()) { 456 455 incomplete = true; 456 } 457 457 } 458 458 if(outside)
Note:
See TracChangeset
for help on using the changeset viewer.