Changeset 23 in josm for src/org/openstreetmap/josm/data/osm/DataSet.java
- Timestamp:
- 2005-10-27T00:38:03+02:00 (18 years ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
src/org/openstreetmap/josm/data/osm/DataSet.java
r22 r23 1 package org.openstreetmap.josm. command;1 package org.openstreetmap.josm.data.osm; 2 2 3 3 import java.util.Collection; 4 import java.util.Collections;5 4 import java.util.HashMap; 6 5 import java.util.HashSet; 7 import java.util.Iterator;8 6 import java.util.LinkedList; 9 7 import java.util.Map; … … 12 10 import org.openstreetmap.josm.data.Bounds; 13 11 import org.openstreetmap.josm.data.SelectionTracker; 14 import org.openstreetmap.josm.data.osm.LineSegment; 15 import org.openstreetmap.josm.data.osm.Node; 16 import org.openstreetmap.josm.data.osm.OsmPrimitive; 17 import org.openstreetmap.josm.data.osm.Track; 12 import org.openstreetmap.josm.data.osm.visitor.AllNodesVisitor; 18 13 19 14 /** … … 41 36 * are in this list but are in no track. 42 37 */ 43 Collection<LineSegment> pendingLineSegments = new LinkedList<LineSegment>();38 public Collection<LineSegment> pendingLineSegments = new LinkedList<LineSegment>(); 44 39 45 40 /** … … 50 45 * track list. 51 46 */ 52 Collection<Track> tracks = new LinkedList<Track>(); 53 54 /** 55 * Add the track to the tracklist. 56 */ 57 public void addTrack(Track t) { 58 tracks.add(t); 59 } 60 /** 61 * Remove the track from the tracklist. 62 */ 63 public void removeTrack(Track t) { 64 t.destroy(); 65 tracks.remove(t); 66 } 67 /** 68 * Return a read-only collection of all tracks 69 */ 70 public Collection<Track> tracks() { 71 return Collections.unmodifiableCollection(tracks); 72 } 73 74 /** 75 * Add a newly created line segment to the pending lines list. 76 */ 77 public void addPendingLineSegment(LineSegment ls) { 78 pendingLineSegments.add(ls); 79 } 80 /** 81 * Remove a line segment from the pending lines list, because it has been 82 * assigned to the track. 83 * @param ls The line segment from the pending list 84 * @param t The track, that will hold the line segment 85 * @param end <code>true</code> to attach on the end. <code>false</code> 86 * to attach on the beginning. 87 */ 88 public void assignPendingLineSegment(LineSegment ls, Track t, boolean end) { 89 pendingLineSegments.remove(ls); 90 if (end) 91 t.add(ls); 92 else 93 t.addStart(ls); 94 } 95 /** 96 * Delete the pending line segment without moving it anywhere. 97 */ 98 public void destroyPendingLineSegment(LineSegment ls) { 99 pendingLineSegments.remove(ls); 100 ls.destroy(); 101 } 102 /** 103 * Return an read-only iterator over all pending line segments. 104 */ 105 public Collection<LineSegment> pendingLineSegments() { 106 return Collections.unmodifiableCollection(pendingLineSegments); 107 } 108 47 public Collection<Track> tracks = new LinkedList<Track>(); 48 49 50 /** 51 * This is a list of all back references of nodes to their track usage. 52 */ 53 public Map<Node, Set<Track>> nodeTrackRef = new HashMap<Node, Set<Track>>(); 54 /** 55 * This is a list of all back references of nodes to their line segments. 56 */ 57 public Map<Node, Set<LineSegment>> nodeLsRef = new HashMap<Node, Set<LineSegment>>(); 58 /** 59 * This is a list of all back references of lines to their tracks. 60 */ 61 public Map<LineSegment, Set<Track>> lsTrackRef = new HashMap<LineSegment, Set<Track>>(); 62 63 /** 64 * Add a back reference from the node to the line segment. 65 */ 66 public void addBackReference(Node from, LineSegment to) { 67 Set<LineSegment> references = nodeLsRef.get(from); 68 if (references == null) 69 references = new HashSet<LineSegment>(); 70 references.add(to); 71 nodeLsRef.put(from, references); 72 } 73 /** 74 * Add a back reference from the node to the track. 75 */ 76 public void addBackReference(Node from, Track to) { 77 Set<Track> references = nodeTrackRef.get(from); 78 if (references == null) 79 references = new HashSet<Track>(); 80 references.add(to); 81 nodeTrackRef.put(from, references); 82 } 83 /** 84 * Add a back reference from the line segment to the track. 85 */ 86 public void addBackReference(LineSegment from, Track to) { 87 Set<Track> references = lsTrackRef.get(from); 88 if (references == null) 89 references = new HashSet<Track>(); 90 references.add(to); 91 lsTrackRef.put(from, references); 92 } 93 94 /** 95 * Removes all references to and from this line segment. 96 */ 97 public void removeBackReference(LineSegment ls) { 98 Set<LineSegment> s = nodeLsRef.get(ls.start); 99 if (s != null) 100 s.remove(ls); 101 s = nodeLsRef.get(ls.end); 102 if (s != null) 103 s.remove(ls); 104 lsTrackRef.remove(ls); 105 } 106 /** 107 * Removes all references to and from the node. 108 */ 109 public void removeBackReference(Node n) { 110 nodeLsRef.remove(n); 111 nodeTrackRef.remove(n); 112 } 113 /** 114 * Removes all references to and from the track. 115 */ 116 public void removeBackReference(Track t) { 117 Collection<Node> nodes = AllNodesVisitor.getAllNodes(t); 118 for (Node n : nodes) { 119 Set<Track> s = nodeTrackRef.get(n); 120 if (s != null) 121 s.remove(t); 122 } 123 for (LineSegment ls : t.segments) { 124 Set<Track> s = lsTrackRef.get(ls); 125 if (s != null) 126 s.remove(t); 127 } 128 } 129 130 /** 131 * Rebuild the caches of back references. 132 */ 133 public void rebuildBackReferences() { 134 nodeTrackRef.clear(); 135 nodeLsRef.clear(); 136 lsTrackRef.clear(); 137 for (Track t : tracks) { 138 for (LineSegment ls : t.segments) { 139 addBackReference(ls.start, ls); 140 addBackReference(ls.end, ls); 141 addBackReference(ls.start, t); 142 addBackReference(ls.end, t); 143 addBackReference(ls, t); 144 } 145 } 146 for (LineSegment ls : pendingLineSegments) { 147 addBackReference(ls.start, ls); 148 addBackReference(ls.end, ls); 149 } 150 } 151 109 152 /** 110 153 * Return the bounds of this DataSet, depending on X/Y values. … … 177 220 clearSelection(tracks); 178 221 for (Track t : tracks) 179 clearSelection(t.segments ());222 clearSelection(t.segments); 180 223 } 181 224 … … 190 233 sel.addAll(getSelected(tracks)); 191 234 for (Track t : tracks) 192 sel.addAll(getSelected(t.segments ()));235 sel.addAll(getSelected(t.segments)); 193 236 return sel; 194 237 } … … 198 241 * The objects imported are not cloned, so from now on, these data belong 199 242 * to both datasets. So use mergeFrom only if you are about to abandon the 200 * other dataset or this dataset. 243 * other dataset. 244 * 245 * Elements are tried to merged. 246 * Nodes are merged first, if their lat/lon are equal. 247 * Line segments are merged, if they have the same nodes. 248 * Tracs are merged, if they consist of the same line segments. 249 * 250 * Additional to that, every two objects with the same id are merged. 201 251 * 202 252 * @param ds The DataSet to merge into this one. 203 * @param mergeEqualNodes If <code>true</code>, nodes with the same lat/lon 204 * are merged together. 205 */ 206 public void mergeFrom(DataSet ds, boolean mergeEqualNodes) { 207 if (mergeEqualNodes && !nodes.isEmpty()) { 208 Map<Node, Node> mergeMap = new HashMap<Node, Node>(); 209 Set<Node> nodesToAdd = new HashSet<Node>(); 210 for (Node n : nodes) { 211 for (Iterator<Node> it = ds.nodes.iterator(); it.hasNext();) { 212 Node dsn = it.next(); 213 if (n.coor.equalsLatLon(dsn.coor)) { 214 mergeMap.put(dsn, n); 215 n.mergeFrom(dsn); 216 it.remove(); 217 } else { 218 nodesToAdd.add(dsn); 219 } 253 * @return A list of all primitives that were used in the conjunction. That 254 * is all used primitives (the merged primitives and all added ones). 255 */ 256 public Collection<OsmPrimitive> mergeFrom(DataSet ds) { 257 Collection<OsmPrimitive> data = new LinkedList<OsmPrimitive>(); 258 259 Set<LineSegment> myLineSegments = new HashSet<LineSegment>(); 260 myLineSegments.addAll(pendingLineSegments); 261 for (Track t : tracks) 262 myLineSegments.addAll(t.segments); 263 264 Set<LineSegment> otherLineSegments = new HashSet<LineSegment>(); 265 otherLineSegments.addAll(ds.pendingLineSegments); 266 for (Track t : ds.tracks) 267 otherLineSegments.addAll(t.segments); 268 269 270 // merge nodes 271 272 Map<Node, Node> nodeMap = new HashMap<Node, Node>(); 273 // find mergable 274 for (Node otherNode : ds.nodes) 275 for (Node myNode : nodes) 276 if (otherNode.coor.equalsLatLon(myNode.coor)) 277 nodeMap.put(otherNode, myNode); 278 // add 279 data.addAll(new HashSet<Node>(nodeMap.values())); 280 for (Node n : ds.nodes) { 281 if (!nodeMap.containsKey(n)) { 282 nodes.add(n); 283 data.add(n); 284 } 285 } 286 // reassign 287 for (LineSegment ls : otherLineSegments) { 288 Node n = nodeMap.get(ls.start); 289 if (n != null) 290 ls.start = n; 291 n = nodeMap.get(ls.end); 292 if (n != null) 293 ls.end = n; 294 } 295 296 297 // merge line segments 298 299 Map<LineSegment, LineSegment> lsMap = new HashMap<LineSegment, LineSegment>(); 300 // find mergable 301 for (LineSegment otherLS : otherLineSegments) 302 for (LineSegment myLS : myLineSegments) 303 if (otherLS.start == myLS.start && otherLS.end == myLS.end) 304 lsMap.put(otherLS, myLS); 305 // add pendings (ls from track are added later 306 for (LineSegment ls : ds.pendingLineSegments) { 307 if (!lsMap.containsKey(ls)) { 308 pendingLineSegments.add(ls); 309 data.add(ls); 310 } 311 } 312 // reassign 313 for (Track t : ds.tracks) { 314 for (int i = 0; i < t.segments.size(); ++i) { 315 LineSegment newLS = lsMap.get(t.segments.get(i)); 316 if (newLS != null) 317 t.segments.set(i, newLS); 318 } 319 } 320 321 322 // merge tracks 323 LinkedList<Track> trackToAdd = new LinkedList<Track>(); 324 for (Track otherTrack : ds.tracks) { 325 boolean found = false; 326 for (Track myTrack : tracks) { 327 if (myTrack.segments.equals(otherTrack.segments)) { 328 found = true; 329 data.add(myTrack); 330 break; 220 331 } 221 332 } 222 nodes.addAll(nodesToAdd); 223 for (Track t : ds.tracks) { 224 for (LineSegment ls : t.segments()) { 225 Node n = mergeMap.get(ls.getStart()); 226 if (n != null) 227 ls.start = n; 228 n = mergeMap.get(ls.getEnd()); 229 if (n != null) 230 ls.end = n; 231 } 232 } 233 tracks.addAll(ds.tracks); 234 for (LineSegment ls : ds.pendingLineSegments) { 235 Node n = mergeMap.get(ls.getStart()); 236 if (n != null) 237 ls.start = n; 238 n = mergeMap.get(ls.getEnd()); 239 if (n != null) 240 ls.end = n; 241 } 242 pendingLineSegments.addAll(ds.pendingLineSegments); 243 } else { 244 nodes.addAll(ds.nodes); 245 tracks.addAll(ds.tracks); 246 pendingLineSegments.addAll(ds.pendingLineSegments); 247 } 333 if (!found) 334 trackToAdd.add(otherTrack); 335 } 336 data.addAll(trackToAdd); 337 tracks.addAll(trackToAdd); 338 339 rebuildBackReferences(); 340 return data; 248 341 } 249 342
Note:
See TracChangeset
for help on using the changeset viewer.