source: josm/src/org/openstreetmap/josm/data/osm/DataSet.java@ 18

Last change on this file since 18 was 18, checked in by imi, 19 years ago

added Server connection to osm server.

File size: 7.9 KB
Line 
1package org.openstreetmap.josm.data.osm;
2
3import java.util.Collection;
4import java.util.Collections;
5import java.util.HashMap;
6import java.util.HashSet;
7import java.util.Iterator;
8import java.util.LinkedList;
9import java.util.Map;
10import java.util.Set;
11
12import org.openstreetmap.josm.data.Bounds;
13import org.openstreetmap.josm.data.SelectionTracker;
14
15/**
16 * DataSet is the data behind one window in the application. It can consist of only a few
17 * points up to the whole osm database. DataSet's can be merged together, split up into
18 * several different ones, saved, (up/down/disk)loaded etc.
19 *
20 * Note, that DataSet is not an osm-primitive, so it has no key association but a few
21 * members to store some information.
22 *
23 * @author imi
24 */
25public class DataSet extends SelectionTracker implements Cloneable {
26
27 /**
28 * All nodes goes here, even when included in other data (tracks etc).
29 * This enables the instant conversion of the whole DataSet by iterating over
30 * this data structure.
31 */
32 public Collection<Node> nodes = new LinkedList<Node>();
33
34 /**
35 * All pending line segments goes here. Pending line segments are those, that
36 * are in this list but are in no track.
37 */
38 private Collection<LineSegment> pendingLineSegments = new LinkedList<LineSegment>();
39
40 /**
41 * All tracks (Streets etc.) in the DataSet.
42 *
43 * The nodes of the track segments of this track must be objects from
44 * the nodes list, however the track segments are stored only in the
45 * track list.
46 */
47 private Collection<Track> tracks = new LinkedList<Track>();
48
49 /**
50 * Add the track to the tracklist.
51 */
52 public void addTrack(Track t) {
53 tracks.add(t);
54 }
55 /**
56 * Remove the track from the tracklist.
57 */
58 public void removeTrack(Track t) {
59 t.destroy();
60 tracks.remove(t);
61 }
62 /**
63 * Return a read-only collection of all tracks
64 */
65 public Collection<Track> tracks() {
66 return Collections.unmodifiableCollection(tracks);
67 }
68
69 /**
70 * Add a newly created line segment to the pending lines list.
71 */
72 public void addPendingLineSegment(LineSegment ls) {
73 pendingLineSegments.add(ls);
74 }
75 /**
76 * Remove a line segment from the pending lines list, because it has been
77 * assigned to the track.
78 * @param ls The line segment from the pending list
79 * @param t The track, that will hold the line segment
80 * @param end <code>true</code> to attach on the end. <code>false</code>
81 * to attach on the beginning.
82 */
83 public void assignPendingLineSegment(LineSegment ls, Track t, boolean end) {
84 pendingLineSegments.remove(ls);
85 if (end)
86 t.add(ls);
87 else
88 t.addStart(ls);
89 }
90 /**
91 * Delete the pending line segment without moving it anywhere.
92 */
93 public void destroyPendingLineSegment(LineSegment ls) {
94 pendingLineSegments.remove(ls);
95 ls.destroy();
96 }
97 /**
98 * Return an read-only iterator over all pending line segments.
99 */
100 public Collection<LineSegment> pendingLineSegments() {
101 return Collections.unmodifiableCollection(pendingLineSegments);
102 }
103
104 /**
105 * Return the bounds of this DataSet, depending on X/Y values.
106 * The min of the return value is the upper left GeoPoint, the max the lower
107 * down GeoPoint, regarding to the X/Y values.
108 *
109 * Return null, if any point not converted yet or if there are no points at all.
110 *
111 * @return Bounding coordinate structure.
112 */
113 public Bounds getBoundsXY() {
114 if (nodes.isEmpty())
115 return null;
116
117 Node first = nodes.iterator().next();
118 Bounds b = new Bounds(first.coor.clone(), first.coor.clone());
119 for (Node w : nodes)
120 {
121 if (Double.isNaN(w.coor.x) || Double.isNaN(w.coor.y))
122 return null;
123 if (w.coor.x < b.min.x)
124 b.min.x = w.coor.x;
125 if (w.coor.y < b.min.y)
126 b.min.y = w.coor.y;
127 if (w.coor.x > b.max.x)
128 b.max.x = w.coor.x;
129 if (w.coor.y > b.max.y)
130 b.max.y = w.coor.y;
131 }
132 return b;
133 }
134
135 /**
136 * Return the bounds of this DataSet, depending on lat/lon values.
137 * The min of the return value is the upper left GeoPoint, the max the lower
138 * down GeoPoint.
139 *
140 * Return null, if any point does not have lat/lon or if there are no
141 * points at all.
142 *
143 * @return Bounding coordinate structure.
144 */
145 public Bounds getBoundsLatLon() {
146 if (nodes.isEmpty())
147 return null;
148
149 Node first = nodes.iterator().next();
150 Bounds b = new Bounds(first.coor.clone(), first.coor.clone());
151 for (Node w : nodes)
152 {
153 if (Double.isNaN(w.coor.lat) || Double.isNaN(w.coor.lon))
154 return null;
155 if (w.coor.lat < b.min.lat)
156 b.min.lat = w.coor.lat;
157 if (w.coor.lon < b.min.lon)
158 b.min.lon = w.coor.lon;
159 if (w.coor.lat > b.max.lat)
160 b.max.lat = w.coor.lat;
161 if (w.coor.lon > b.max.lon)
162 b.max.lon = w.coor.lon;
163 }
164 return b;
165 }
166
167 /**
168 * Remove the selection of the whole dataset.
169 */
170 public void clearSelection() {
171 clearSelection(nodes);
172 clearSelection(tracks);
173 for (Track t : tracks)
174 clearSelection(t.segments());
175 }
176
177 /**
178 * Return a list of all selected objects. Even keys are returned.
179 * @return List of all selected objects.
180 */
181 @Override
182 public Collection<OsmPrimitive> getSelected() {
183 Collection<OsmPrimitive> sel = getSelected(nodes);
184 sel.addAll(getSelected(pendingLineSegments));
185 sel.addAll(getSelected(tracks));
186 for (Track t : tracks)
187 sel.addAll(getSelected(t.segments()));
188 return sel;
189 }
190
191 /**
192 * Import the given dataset by merging all data with this dataset.
193 * The objects imported are not cloned, so from now on, these data belong
194 * to both datasets. So use mergeFrom only if you are about to abandon the
195 * other dataset or this dataset.
196 *
197 * @param ds The DataSet to merge into this one.
198 * @param mergeEqualNodes If <code>true</code>, nodes with the same lat/lon
199 * are merged together.
200 */
201 public void mergeFrom(DataSet ds, boolean mergeEqualNodes) {
202 System.out.println(nodes.size()+" "+pendingLineSegments.size()+" "+tracks.size());
203 if (mergeEqualNodes) {
204 Map<Node, Node> mergeMap = new HashMap<Node, Node>();
205 Set<Node> nodesToAdd = new HashSet<Node>();
206 for (Node n : nodes) {
207 for (Iterator<Node> it = ds.nodes.iterator(); it.hasNext();) {
208 Node dsn = it.next();
209 if (n.coor.equalsLatLon(dsn.coor)) {
210 mergeMap.put(dsn, n);
211 n.mergeFrom(dsn);
212 it.remove();
213 } else {
214 nodesToAdd.add(dsn);
215 }
216 }
217 }
218 nodes.addAll(nodesToAdd);
219 for (Track t : ds.tracks) {
220 for (LineSegment ls : t.segments()) {
221 Node n = mergeMap.get(ls.getStart());
222 if (n != null)
223 ls.start = n;
224 n = mergeMap.get(ls.getEnd());
225 if (n != null)
226 ls.end = n;
227 }
228 }
229 tracks.addAll(ds.tracks);
230 for (LineSegment ls : ds.pendingLineSegments) {
231 Node n = mergeMap.get(ls.getStart());
232 if (n != null)
233 ls.start = n;
234 n = mergeMap.get(ls.getEnd());
235 if (n != null)
236 ls.end = n;
237 }
238 pendingLineSegments.addAll(ds.pendingLineSegments);
239 } else {
240 nodes.addAll(ds.nodes);
241 tracks.addAll(ds.tracks);
242 pendingLineSegments.addAll(ds.pendingLineSegments);
243 }
244 System.out.println(nodes.size()+" "+pendingLineSegments.size()+" "+tracks.size());
245 }
246
247 /**
248 * Remove the selection from every value in the collection.
249 * @param list The collection to remove the selection from.
250 */
251 private void clearSelection(Collection<? extends OsmPrimitive> list) {
252 if (list == null)
253 return;
254 for (OsmPrimitive osm : list) {
255 osm.setSelected(false, this);
256 if (osm.keys != null)
257 clearSelection(osm.keys.keySet());
258 }
259 }
260
261 /**
262 * Return all selected items in the collection.
263 * @param list The collection from which the selected items are returned.
264 */
265 private Collection<OsmPrimitive> getSelected(Collection<? extends OsmPrimitive> list) {
266 Collection<OsmPrimitive> sel = new HashSet<OsmPrimitive>();
267 if (list == null)
268 return sel;
269 for (OsmPrimitive osm : list) {
270 if (osm.isSelected())
271 sel.add(osm);
272 if (osm.keys != null)
273 sel.addAll(getSelected(osm.keys.keySet()));
274 }
275 return sel;
276 }
277
278
279 @Override
280 public DataSet clone() {
281 try {return (DataSet)super.clone();} catch (CloneNotSupportedException e) {}
282 return null;
283 }
284}
Note: See TracBrowser for help on using the repository browser.