Changeset 25862 in osm
- Timestamp:
- 2011-04-17T13:35:54+02:00 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/dumbutils/src/dumbutils/ReplaceGeometryAction.java
r25859 r25862 1 1 package dumbutils; 2 2 3 import java.awt.geom.Point2D; 3 4 import java.awt.geom.Area; 4 5 import org.openstreetmap.josm.data.osm.Node; … … 23 24 class ReplaceGeometryAction extends JosmAction { 24 25 private static final String TITLE = "Replace geometry"; 26 private static final double MAX_NODE_REPLACEMENT_DISTANCE = 3e-4; 25 27 26 28 public ReplaceGeometryAction() { … … 48 50 } 49 51 50 // Now do the replacement 51 List<Command> commands = new ArrayList<Command>(); 52 Way result = new Way(way); 53 result.setNodes(geometry.getNodes()); 54 // Copy tags from temporary way (source etc.) 55 for( String key : geometry.keySet() ) 56 result.put(key, geometry.get(key)); 57 commands.add(new ChangeCommand(way, result)); 58 commands.add(new DeleteCommand(geometry)); 59 60 // Check if there are unconnected nodes, delete them 61 Set<Node> nodesToDelete = new HashSet<Node>(); 52 // Prepare a list of nodes that are not used anywhere except in the way 53 Set<Node> nodePool = new HashSet<Node>(); 62 54 Area a = getCurrentDataSet().getDataSourceArea(); 63 55 for( Node node : way.getNodes() ) { … … 65 57 if( !node.isDeleted() && referrers.size() == 1 && referrers.get(0).equals(way) 66 58 && (node.isNewOrUndeleted() || a.contains(node.getCoor())) ) 67 node sToDelete.add(node);59 nodePool.add(node); 68 60 } 69 if( !nodesToDelete.isEmpty() ) 70 commands.add(new DeleteCommand(nodesToDelete)); 61 62 // And the same for geometry, list nodes that can be freely deleted 63 Set<Node> geometryPool = new HashSet<Node>(); 64 for( Node node : geometry.getNodes() ) { 65 List<OsmPrimitive> referrers = node.getReferrers(); 66 if( node.isNew() && !node.isDeleted() && referrers.size() == 1 67 && referrers.get(0).equals(geometry) && !way.containsNode(node) ) 68 geometryPool.add(node); 69 } 70 71 // Find new nodes that are closest to the old ones, remove matching old ones from the pool 72 Map<Node, Node> nodeAssoc = new HashMap<Node, Node>(); 73 for( Node n : geometryPool ) { 74 Node nearest = findNearestNode(n, nodePool); 75 if( nearest != null ) { 76 nodeAssoc.put(n, nearest); 77 nodePool.remove(nearest); 78 } 79 } 80 81 // Now that we have replacement list, move all unused new nodes to nodePool (and delete them afterwards) 82 for( Node n : geometryPool ) 83 if( nodeAssoc.containsKey(n) ) 84 nodePool.add(n); 85 86 // And prepare a list of nodes with all the replacements 87 List<Node> geometryNodes = geometry.getNodes(); 88 for( int i = 0; i < geometryNodes.size(); i++ ) 89 if( nodeAssoc.containsKey(geometryNodes.get(i)) ) 90 geometryNodes.set(i, nodeAssoc.get(geometryNodes.get(i))); 91 92 // Now do the replacement 93 List<Command> commands = new ArrayList<Command>(); 94 commands.add(new ChangeNodesCommand(way, geometryNodes)); 95 96 // Move old nodes to new positions 97 for( Node node : nodeAssoc.keySet() ) 98 commands.add(new MoveCommand(nodeAssoc.get(node), node.getCoor())); 99 100 // Copy tags from temporary way (source etc.) 101 for( String key : geometry.keySet() ) 102 commands.add(new ChangePropertyCommand(way, key, geometry.get(key))); 103 104 // And delete odl geometry way 105 commands.add(new DeleteCommand(geometry)); 106 107 // Delete nodes that are not used anymore 108 if( !nodePool.isEmpty() ) 109 commands.add(new DeleteCommand(nodePool)); 71 110 72 111 // Two items in undo stack: change original way and delete geometry way 73 112 Main.main.undoRedo.add(new SequenceCommand( 74 tr("Replace geometry ofway {0}", way.getDisplayName(DefaultNameFormatter.getInstance())),113 tr("Replace geometry for way {0}", way.getDisplayName(DefaultNameFormatter.getInstance())), 75 114 commands)); 115 } 116 117 /** 118 * Find node from the collection which is nearest to <tt>node</tt>. Max distance is taken in consideration. 119 * @return null if there is no such node. 120 */ 121 private Node findNearestNode( Node node, Collection<Node> nodes ) { 122 if( nodes.contains(node) ) 123 return node; 124 125 Node nearest = null; 126 double distance = MAX_NODE_REPLACEMENT_DISTANCE; 127 Point2D coor = node.getCoor(); 128 for( Node n : nodes ) { 129 double d = n.getCoor().distance(coor); 130 if( d < distance ) { 131 distance = d; 132 nearest = n; 133 } 134 } 135 return nearest; 76 136 } 77 137 }
Note:
See TracChangeset
for help on using the changeset viewer.