- Timestamp:
- 2009-09-13T12:33:18+02:00 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java
r2102 r2113 10 10 import java.util.HashSet; 11 11 import java.util.LinkedList; 12 import java.util.List; 12 13 import java.util.Set; 13 14 … … 150 151 151 152 /** 152 * Merges the nodes in <code>node</code> onto one of the nodes. Uses the dataset 153 * managed by <code>layer</code> as reference. <code>backreferences</code> is precomputed 154 * collection of all parent/child references in the dataset. 155 * 156 * @param layer layer the reference data layer. Must not be null. 157 * @param backreferences if null, backreferneces are first computed from layer.data; otherwise 158 * backreferences.getSource() == layer.data must hold 159 * @param nodes the collection of nodes. Ignored if null. 160 * @param targetNode the target node the collection of nodes is merged to. Must not be null. 161 * @throw IllegalArgumentException thrown if layer is null 162 * @throw IllegalArgumentException thrown if backreferences.getSource() != layer.data 163 */ 164 public static Command mergeNodes(OsmDataLayer layer, BackreferencedDataSet backreferences, Collection<Node> nodes, Node targetNode) { 165 if (layer == null) 166 throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "nodes")); 167 if (targetNode == null) 168 throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "targetNode")); 169 if (nodes == null) 170 return null; 171 if (backreferences == null) { 172 backreferences = new BackreferencedDataSet(layer.data); 173 backreferences.build(); 174 } 175 176 Set<RelationToChildReference> relationToNodeReferences = backreferences.getRelationToChildReferences(nodes); 177 178 // build the tag collection 179 // 180 TagCollection nodeTags = TagCollection.unionOfAllPrimitives(nodes); 181 completeTagCollectionWithMissingTags(nodeTags, nodes); 182 TagCollection nodeTagsToEdit = new TagCollection(nodeTags); 183 completeTagCollectionForEditing(nodeTagsToEdit); 184 185 // launch a conflict resolution dialog, if necessary 186 // 187 CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance(); 188 dialog.getTagConflictResolverModel().populate(nodeTagsToEdit); 189 dialog.getRelationMemberConflictResolverModel().populate(relationToNodeReferences); 190 dialog.setTargetPrimitive(targetNode); 191 dialog.prepareDefaultDecisions(); 192 if (! nodeTags.isApplicableToPrimitive() || relationToNodeReferences.size() > 1) { 193 dialog.setVisible(true); 194 if (dialog.isCancelled()) 195 return null; 196 } 197 LinkedList<Command> cmds = new LinkedList<Command>(); 198 199 // the nodes we will have to delete 200 // 201 Collection<OsmPrimitive> nodesToDelete = new HashSet<OsmPrimitive>(nodes); 202 nodesToDelete.remove(targetNode); 203 204 // change the ways referring to at least one of the merge nodes 205 // 206 Collection<Way> waysToDelete= new HashSet<Way>(); 207 for (Way w : OsmPrimitive.getFilteredList(backreferences.getParents(nodesToDelete), Way.class)) { 208 // OK - this way contains one or more nodes to change 153 * Fixes the parent ways referring to one of the nodes. 154 * 155 * Replies null, if the ways could not be fixed, i.e. because a way would have to be delted 156 * which is referred to by a relation. 157 * 158 * @param backreferences the backreference data set 159 * @param nodesToDelete the collection of nodes to be deleted 160 * @param targetNode the target node the other nodes are merged to 161 * @return a list of command; null, the ways could not be fixed 162 */ 163 protected static List<Command> fixParentWays(BackreferencedDataSet backreferences, Collection<OsmPrimitive> nodesToDelete, Node targetNode) { 164 List<Command> cmds = new ArrayList<Command>(); 165 Set<Way> waysToDelete = new HashSet<Way>(); 166 167 for (Way w: OsmPrimitive.getFilteredList(backreferences.getParents(nodesToDelete), Way.class)) { 209 168 ArrayList<Node> newNodes = new ArrayList<Node>(w.getNodesCount()); 210 169 for (Node n: w.getNodes()) { 211 if (! nodesToDelete.contains(n) ) {170 if (! nodesToDelete.contains(n) && n != targetNode) { 212 171 newNodes.add(n); 172 } else if (newNodes.isEmpty()) { 173 newNodes.add(targetNode); 174 } else if (newNodes.get(newNodes.size()-1) != targetNode) { 175 // make sure we collapse a sequence of deleted nodes 176 // to exactly one occurrence of the merged target node 177 // 178 newNodes.add(targetNode); 213 179 } else { 214 newNodes.add(targetNode);180 // drop the node 215 181 } 216 182 } … … 236 202 } 237 203 } 204 return cmds; 205 } 206 207 /** 208 * Merges the nodes in <code>node</code> onto one of the nodes. Uses the dataset 209 * managed by <code>layer</code> as reference. <code>backreferences</code> is precomputed 210 * collection of all parent/child references in the dataset. 211 * 212 * @param layer layer the reference data layer. Must not be null. 213 * @param backreferences if null, backreferneces are first computed from layer.data; otherwise 214 * backreferences.getSource() == layer.data must hold 215 * @param nodes the collection of nodes. Ignored if null. 216 * @param targetNode the target node the collection of nodes is merged to. Must not be null. 217 * @throw IllegalArgumentException thrown if layer is null 218 * @throw IllegalArgumentException thrown if backreferences.getSource() != layer.data 219 */ 220 public static Command mergeNodes(OsmDataLayer layer, BackreferencedDataSet backreferences, Collection<Node> nodes, Node targetNode) { 221 if (layer == null) 222 throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "nodes")); 223 if (targetNode == null) 224 throw new IllegalArgumentException(tr("parameter ''{0}'' must not be null", "targetNode")); 225 if (nodes == null) 226 return null; 227 if (backreferences == null) { 228 backreferences = new BackreferencedDataSet(layer.data); 229 backreferences.build(); 230 } 231 232 Set<RelationToChildReference> relationToNodeReferences = backreferences.getRelationToChildReferences(nodes); 233 234 // build the tag collection 235 // 236 TagCollection nodeTags = TagCollection.unionOfAllPrimitives(nodes); 237 completeTagCollectionWithMissingTags(nodeTags, nodes); 238 TagCollection nodeTagsToEdit = new TagCollection(nodeTags); 239 completeTagCollectionForEditing(nodeTagsToEdit); 240 241 // launch a conflict resolution dialog, if necessary 242 // 243 CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance(); 244 dialog.getTagConflictResolverModel().populate(nodeTagsToEdit); 245 dialog.getRelationMemberConflictResolverModel().populate(relationToNodeReferences); 246 dialog.setTargetPrimitive(targetNode); 247 dialog.prepareDefaultDecisions(); 248 if (! nodeTags.isApplicableToPrimitive() || relationToNodeReferences.size() > 1) { 249 dialog.setVisible(true); 250 if (dialog.isCancelled()) 251 return null; 252 } 253 LinkedList<Command> cmds = new LinkedList<Command>(); 254 255 // the nodes we will have to delete 256 // 257 Collection<OsmPrimitive> nodesToDelete = new HashSet<OsmPrimitive>(nodes); 258 nodesToDelete.remove(targetNode); 259 260 // change the ways referring to at least one of the merge nodes 261 // 262 Collection<Way> waysToDelete= new HashSet<Way>(); 263 List<Command> wayFixCommands = fixParentWays( 264 backreferences, 265 nodesToDelete, 266 targetNode 267 ); 268 if (wayFixCommands == null) 269 return null; 270 else { 271 cmds.addAll(wayFixCommands); 272 } 238 273 239 274 // build the commands
Note:
See TracChangeset
for help on using the changeset viewer.