Changeset 27505 in osm for applications/editors/josm/plugins
- Timestamp:
- 2012-01-20T00:49:33+01:00 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/utilsplugin2/src/utilsplugin2/dumbutils/ReplaceGeometryAction.java
r26885 r27505 18 18 19 19 /** 20 * Replaces already existing way with the other, fresh created. Select both ways and push the button.20 * Replaces already existing object (id>0) with a new object (id<0). 21 21 * 22 22 * @author Zverik … … 27 27 28 28 public ReplaceGeometryAction() { 29 super(TITLE, "dumbutils/replacegeometry", tr("Replace geometry of selected waywith a new one"),29 super(TITLE, "dumbutils/replacegeometry", tr("Replace geometry of selected object with a new one"), 30 30 Shortcut.registerShortcut("tools:replacegeometry", tr("Tool: {0}", TITLE), KeyEvent.VK_G, 31 31 Shortcut.GROUP_HOTKEY, Shortcut.SHIFT_DEFAULT), true); … … 33 33 34 34 @Override 35 public void actionPerformed( ActionEvent e ) { 36 if( getCurrentDataSet() == null ) return; 35 public void actionPerformed(ActionEvent e) { 36 if (getCurrentDataSet() == null) { 37 return; 38 } 39 37 40 // There must be two ways selected: one with id > 0 and one new. 38 List< Way> selection = OsmPrimitive.getFilteredList(getCurrentDataSet().getSelected(), Way.class);39 if ( selection.size() != 2) {41 List<OsmPrimitive> selection = new ArrayList(getCurrentDataSet().getSelected()); 42 if (selection.size() != 2) { 40 43 JOptionPane.showMessageDialog(Main.parent, 41 tr("This tool replaces geometry of one way with another, and requires two ways to be selected."),44 tr("This tool replaces geometry of one object with another, and so requires exactly two objects to be selected."), 42 45 TITLE, JOptionPane.INFORMATION_MESSAGE); 43 46 return; 44 47 } 48 49 OsmPrimitive firstObject = selection.get(0); 50 OsmPrimitive secondObject = selection.get(1); 51 52 if (firstObject instanceof Way && secondObject instanceof Way) { 53 replaceWayWithWay(Arrays.asList((Way) firstObject, (Way) secondObject)); 54 } else if (firstObject instanceof Node && secondObject instanceof Way) { 55 replaceNodeWithWay((Node) firstObject, (Way) secondObject); 56 } else if (secondObject instanceof Node && firstObject instanceof Way) { 57 replaceNodeWithWay((Node) secondObject, (Way) firstObject); 58 } else { 59 JOptionPane.showMessageDialog(Main.parent, 60 tr("This tool can only replace a node with a way, or a way with a way."), 61 TITLE, JOptionPane.INFORMATION_MESSAGE); 62 return; 63 } 64 } 65 66 public void replaceNodeWithWay(Node node, Way way) { 67 if (!node.getReferrers().isEmpty()) { 68 JOptionPane.showMessageDialog(Main.parent, tr("Node has referrers, cannot replace with way."), TITLE, JOptionPane.INFORMATION_MESSAGE); 69 return; 70 } 71 Node nodeToReplace = null; 72 // see if we need to replace a node in the replacement way 73 if (!node.isNew()) { 74 // Prepare a list of nodes that are not used anywhere except in the way 75 Collection<Node> nodePool = getUnimportantNodes(way); 76 nodeToReplace = findNearestNode(node, nodePool); 77 } 78 79 List<Command> commands = new ArrayList<Command>(); 80 AbstractMap<String, String> nodeTags = (AbstractMap<String, String>) node.getKeys(); 81 82 // replace sacrificial node in way with node that is being upgraded 83 if (nodeToReplace != null) { 84 List<Node> wayNodes = way.getNodes(); 85 int idx = wayNodes.indexOf(nodeToReplace); 86 wayNodes.set(idx, node); 87 if (idx == 0) { 88 // node is at start/end of way 89 wayNodes.set(wayNodes.size() - 1, node); 90 } 91 commands.add(new ChangeNodesCommand(way, wayNodes)); 92 commands.add(new MoveCommand(node, nodeToReplace.getCoor())); 93 commands.add(new DeleteCommand(nodeToReplace)); 94 95 // delete tags from node 96 if (!nodeTags.isEmpty()) { 97 AbstractMap<String, String> nodeTagsToDelete = new HashMap<String, String>(); 98 for (String key : nodeTags.keySet()) { 99 nodeTagsToDelete.put(key, null); 100 } 101 commands.add(new ChangePropertyCommand(Arrays.asList(node), nodeTagsToDelete)); 102 } 103 } else { 104 // no node to replace, so just delete the original node 105 commands.add(new DeleteCommand(node)); 106 } 107 108 // Copy tags from node 109 // TODO: use merge tag conflict dialog instead 110 commands.add(new ChangePropertyCommand(Arrays.asList(way), nodeTags)); 111 112 getCurrentDataSet().setSelected(way); 113 114 Main.main.undoRedo.add(new SequenceCommand( 115 tr("Replace geometry for way {0}", way.getDisplayName(DefaultNameFormatter.getInstance())), 116 commands)); 117 } 118 119 public void replaceWayWithWay(List<Way> selection) { 120 boolean overrideNewCheck = false; 45 121 int idxNew = selection.get(0).isNew() ? 0 : 1; 46 boolean overrideNewCheck = false; 47 if( selection.get(1-idxNew).isNew() ) { 48 // if both are new, select the one with all the DB nodes 49 boolean areNewNodes = false; 50 for( Node n : selection.get(0).getNodes() ) 51 if( n.isNew() ) 52 areNewNodes = true; 53 idxNew = areNewNodes ? 0 : 1; 54 overrideNewCheck = true; 55 for( Node n : selection.get(1-idxNew).getNodes() ) 56 if( n.isNew() ) 57 overrideNewCheck = false; 58 } 122 123 if( selection.get(1-idxNew).isNew() ) { 124 // if both are new, select the one with all the DB nodes 125 boolean areNewNodes = false; 126 for (Node n : selection.get(0).getNodes()) { 127 if (n.isNew()) { 128 areNewNodes = true; 129 } 130 } 131 idxNew = areNewNodes ? 0 : 1; 132 overrideNewCheck = true; 133 for (Node n : selection.get(1 - idxNew).getNodes()) { 134 if (n.isNew()) { 135 overrideNewCheck = false; 136 } 137 } 138 } 59 139 Way geometry = selection.get(idxNew); 60 140 Way way = selection.get(1 - idxNew); … … 67 147 68 148 // Prepare a list of nodes that are not used anywhere except in the way 69 Set<Node> nodePool = new HashSet<Node>(); 70 Area a = getCurrentDataSet().getDataSourceArea(); 71 for( Node node : way.getNodes() ) { 72 List<OsmPrimitive> referrers = node.getReferrers(); 73 if( !node.isDeleted() && referrers.size() == 1 && referrers.get(0).equals(way) 74 && (node.isNewOrUndeleted() || a == null || a.contains(node.getCoor())) ) 75 nodePool.add(node); 76 } 149 Collection<Node> nodePool = getUnimportantNodes(way); 77 150 78 151 // And the same for geometry, list nodes that can be freely deleted … … 134 207 } 135 208 209 /** 210 * Create a list of nodes that are not used anywhere except in the way. 211 * @param way 212 * @return 213 */ 214 public Collection<Node> getUnimportantNodes(Way way) { 215 Set<Node> nodePool = new HashSet<Node>(); 216 Area a = getCurrentDataSet().getDataSourceArea(); 217 for (Node n : way.getNodes()) { 218 List<OsmPrimitive> referrers = n.getReferrers(); 219 if (!n.isDeleted() && referrers.size() == 1 && referrers.get(0).equals(way) 220 && (n.isNewOrUndeleted() || a == null || a.contains(n.getCoor()))) { 221 nodePool.add(n); 222 } 223 } 224 return nodePool; 225 } 226 136 227 /** 137 228 * Find node from the collection which is nearest to <tt>node</tt>. Max distance is taken in consideration.
Note:
See TracChangeset
for help on using the changeset viewer.