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

Last change on this file since 2439 was 2439, checked in by jttt, 14 years ago

Added DatasetListener, Dataset now fire events everytime one of its primitives is changed. Used new Dataset listener in RelationListDialog

  • Property svn:eol-style set to native
File size: 28.0 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.data.osm;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.geom.Area;
7import java.util.ArrayList;
8import java.util.Arrays;
9import java.util.Collection;
10import java.util.Collections;
11import java.util.Comparator;
12import java.util.HashMap;
13import java.util.HashSet;
14import java.util.Iterator;
15import java.util.LinkedHashSet;
16import java.util.LinkedList;
17import java.util.List;
18import java.util.Map;
19import java.util.Set;
20
21import org.openstreetmap.josm.data.SelectionChangedListener;
22import org.openstreetmap.josm.data.osm.QuadBuckets.BBox;
23
24/**
25 * DataSet is the data behind the application. It can consists of only a few points up to the whole
26 * osm database. DataSet's can be merged together, saved, (up/down/disk)loaded etc.
27 *
28 * Note that DataSet is not an osm-primitive and so has no key association but a few members to
29 * store some information.
30 *
31 * @author imi
32 */
33public class DataSet implements Cloneable {
34
35 private static class IdHash implements Hash<PrimitiveId,OsmPrimitive> {
36
37 public int getHashCode(PrimitiveId k) {
38 return (int)k.getUniqueId() ^ k.getType().hashCode();
39 }
40
41 public boolean equals(PrimitiveId key, OsmPrimitive value) {
42 if (key == null || value == null) return false;
43 return key.getUniqueId() == value.getUniqueId() && key.getType() == value.getType();
44 }
45 }
46
47 private Storage<OsmPrimitive> allPrimitives = new Storage<OsmPrimitive>(new IdHash());
48 private Map<PrimitiveId, OsmPrimitive> primitivesMap = allPrimitives.foreignKey(new IdHash());
49 private List<DataSetListener> listeners = new ArrayList<DataSetListener>();
50
51 /**
52 * The API version that created this data set, if any.
53 */
54 private String version;
55
56 /**
57 * Replies the API version this dataset was created from. May be null.
58 *
59 * @return the API version this dataset was created from. May be null.
60 */
61 public String getVersion() {
62 return version;
63 }
64
65 /**
66 * Sets the API version this dataset was created from.
67 *
68 * @param version the API version, i.e. "0.5" or "0.6"
69 */
70 public void setVersion(String version) {
71 this.version = version;
72 }
73
74 /**
75 * All nodes goes here, even when included in other data (ways etc). This enables the instant
76 * conversion of the whole DataSet by iterating over this data structure.
77 */
78 private QuadBuckets<Node> nodes = new QuadBuckets<Node>();
79
80 /**
81 * Replies an unmodifiable collection of nodes in this dataset
82 *
83 * @return an unmodifiable collection of nodes in this dataset
84 */
85 public Collection<Node> getNodes() {
86 return Collections.unmodifiableCollection(nodes);
87 }
88
89 public List<Node> searchNodes(BBox bbox) {
90 return nodes.search(bbox);
91 }
92
93 /**
94 * All ways (Streets etc.) in the DataSet.
95 *
96 * The way nodes are stored only in the way list.
97 */
98 private QuadBuckets<Way> ways = new QuadBuckets<Way>();
99
100 /**
101 * Replies an unmodifiable collection of ways in this dataset
102 *
103 * @return an unmodifiable collection of ways in this dataset
104 */
105 public Collection<Way> getWays() {
106 return Collections.unmodifiableCollection(ways);
107 }
108
109 public List<Way> searchWays(BBox bbox) {
110 return ways.search(bbox);
111 }
112
113 /**
114 * All relations/relationships
115 */
116 private Collection<Relation> relations = new LinkedList<Relation>();
117
118 /**
119 * Replies an unmodifiable collection of relations in this dataset
120 *
121 * @return an unmodifiable collection of relations in this dataset
122 */
123 public Collection<Relation> getRelations() {
124 return Collections.unmodifiableCollection(relations);
125 }
126
127 /**
128 * All data sources of this DataSet.
129 */
130 public Collection<DataSource> dataSources = new LinkedList<DataSource>();
131
132 /**
133 * @return A collection containing all primitives of the dataset. The data is ordered after:
134 * first come nodes, then ways, then relations. Ordering in between the categories is not
135 * guaranteed.
136 */
137 public List<OsmPrimitive> allPrimitives() {
138 List<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
139 o.addAll(nodes);
140 o.addAll(ways);
141 o.addAll(relations);
142 return o;
143 }
144
145 /**
146 * @return A collection containing all not-deleted primitives (except keys).
147 */
148 public Collection<OsmPrimitive> allNonDeletedPrimitives() {
149 Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
150 for (OsmPrimitive osm : allPrimitives())
151 if (osm.isVisible() && !osm.isDeleted()) {
152 o.add(osm);
153 }
154 return o;
155 }
156
157 public Collection<OsmPrimitive> allNonDeletedCompletePrimitives() {
158 Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
159 for (OsmPrimitive osm : allPrimitives())
160 if (osm.isVisible() && !osm.isDeleted() && !osm.incomplete) {
161 o.add(osm);
162 }
163 return o;
164 }
165
166 public Collection<OsmPrimitive> allNonDeletedPhysicalPrimitives() {
167 Collection<OsmPrimitive> o = new LinkedList<OsmPrimitive>();
168 for (OsmPrimitive osm : allPrimitives())
169 if (osm.isVisible() && !osm.isDeleted() && !osm.incomplete && !(osm instanceof Relation)) {
170 o.add(osm);
171 }
172 return o;
173 }
174
175 /**
176 * Adds a primitive to the dataset
177 *
178 * @param primitive the primitive. Ignored if null.
179 */
180 public void addPrimitive(OsmPrimitive primitive) {
181 if (getPrimitiveById(primitive) != null)
182 throw new DataIntegrityProblemException(
183 tr("Unable to add primitive {0} to the dataset because it's already included", primitive.toString()));
184
185 if (primitive instanceof Node) {
186 nodes.add((Node) primitive);
187 } else if (primitive instanceof Way) {
188 ways.add((Way) primitive);
189 } else if (primitive instanceof Relation) {
190 relations.add((Relation) primitive);
191 }
192 allPrimitives.add(primitive);
193 primitive.setDataset(this);
194 firePrimitivesAdded(Collections.singletonList(primitive));
195 }
196
197 public OsmPrimitive addPrimitive(PrimitiveData data) {
198 OsmPrimitive result;
199 if (data instanceof NodeData) {
200 result = new Node();
201 } else if (data instanceof WayData) {
202 result = new Way();
203 } else if (data instanceof RelationData) {
204 result = new Relation();
205 } else
206 throw new AssertionError();
207 result.setDataset(this);
208 result.load(data);
209 addPrimitive(result);
210 return result;
211 }
212
213 /**
214 * Removes a primitive from the dataset. This method only removes the
215 * primitive form the respective collection of primitives managed
216 * by this dataset, i.e. from {@see #nodes}, {@see #ways}, or
217 * {@see #relations}. References from other primitives to this
218 * primitive are left unchanged.
219 *
220 * @param primitive the primitive
221 */
222 public void removePrimitive(PrimitiveId primitiveId) {
223 OsmPrimitive primitive = getPrimitiveByIdChecked(primitiveId);
224 if (primitive == null)
225 return;
226 if (primitive instanceof Node) {
227 nodes.remove(primitive);
228 } else if (primitive instanceof Way) {
229 ways.remove(primitive);
230 } else if (primitive instanceof Relation) {
231 relations.remove(primitive);
232 }
233 selectedPrimitives.remove(primitive);
234 allPrimitives.remove(primitive);
235 primitive.setDataset(null);
236 firePrimitivesRemoved(Collections.singletonList(primitive));
237 }
238
239
240 /*---------------------------------------------------
241 * SELECTION HANDLING
242 *---------------------------------------------------*/
243
244 /**
245 * A list of listeners to selection changed events. The list is static, as listeners register
246 * themselves for any dataset selection changes that occur, regardless of the current active
247 * dataset. (However, the selection does only change in the active layer)
248 */
249 public static Collection<SelectionChangedListener> selListeners = new LinkedList<SelectionChangedListener>();
250
251 /**
252 * notifies all registered selection change listeners about the current selection of
253 * primitives
254 *
255 * @param sel the current selection
256 */
257 private static void notifySelectionChangeListeners(Collection<? extends OsmPrimitive> sel) {
258 for (SelectionChangedListener l : selListeners) {
259 l.selectionChanged(sel);
260 }
261 }
262
263 /**
264 * Notifies all registered {@see SelectionChangedListener} about the current selection in
265 * this dataset.
266 *
267 */
268 public void fireSelectionChanged(){
269 notifySelectionChangeListeners(selectedPrimitives);
270 }
271
272
273 LinkedHashSet<OsmPrimitive> selectedPrimitives = new LinkedHashSet<OsmPrimitive>();
274
275 public Collection<OsmPrimitive> getSelectedNodesAndWays() {
276 Collection<OsmPrimitive> sel = new LinkedList<OsmPrimitive>();
277 for (OsmPrimitive osm : selectedPrimitives) {
278 if (osm instanceof Way ||
279 osm instanceof Node) {
280 sel.add(osm);
281 }
282 }
283 return sel;
284 }
285
286
287 /**
288 * Return a list of all selected objects. Even keys are returned.
289 * @return List of all selected objects.
290 */
291 public Collection<OsmPrimitive> getSelected() {
292 // It would be nice to have this be a copy-on-write list
293 // or an Collections.unmodifiableList(). It would be
294 // much faster for large selections. May users just
295 // call this, and only check the .size().
296 return new ArrayList<OsmPrimitive>(selectedPrimitives);
297 }
298
299 /**
300 * Return selected nodes.
301 */
302 public Collection<OsmPrimitive> getSelectedNodes() {
303 return getSelected(nodes);
304 }
305
306 /**
307 * Return selected ways.
308 */
309 public Collection<OsmPrimitive> getSelectedWays() {
310 return getSelected(ways);
311 }
312
313 /**
314 * Return selected relations.
315 */
316 public Collection<OsmPrimitive> getSelectedRelations() {
317 return getSelected(relations);
318 }
319
320 /**
321 * Return all selected items in the collection.
322 * @param list The collection from which the selected items are returned.
323 */
324 private Collection<OsmPrimitive> getSelected(Collection<? extends OsmPrimitive> list) {
325 if (list == null)
326 return new LinkedList<OsmPrimitive>();
327 // getSelected() is called with large lists, so
328 // creating the return list from the selection
329 // should be faster most of the time.
330 Collection<OsmPrimitive> sel = new LinkedHashSet<OsmPrimitive>(selectedPrimitives);
331 sel.retainAll(list);
332 return sel;
333 }
334
335 public boolean isSelected(OsmPrimitive osm) {
336 return selectedPrimitives.contains(osm);
337 }
338
339
340 public void toggleSelected(Collection<? extends PrimitiveId> osm) {
341 boolean changed = false;
342 for (PrimitiveId o : osm) {
343 changed = changed | this.__toggleSelected(o);
344 }
345 if (changed) {
346 fireSelectionChanged();
347 }
348 }
349 public void toggleSelected(PrimitiveId... osm) {
350 toggleSelected(Arrays.asList(osm));
351 }
352 private boolean __toggleSelected(PrimitiveId primitiveId) {
353 OsmPrimitive primitive = getPrimitiveByIdChecked(primitiveId);
354 if (primitive == null)
355 return false;
356 if (!selectedPrimitives.remove(primitive)) {
357 selectedPrimitives.add(primitive);
358 }
359 return true;
360 }
361
362 /**
363 * Sets the current selection to the primitives in <code>selection</code>.
364 * Notifies all {@see SelectionChangedListener} if <code>fireSelectionChangeEvent</code> is true.
365 *
366 * @param selection the selection
367 * @param fireSelectionChangeEvent true, if the selection change listeners are to be notified; false, otherwise
368 */
369 public void setSelected(Collection<? extends PrimitiveId> selection, boolean fireSelectionChangeEvent) {
370 boolean wasEmpty = selectedPrimitives.isEmpty();
371 selectedPrimitives = new LinkedHashSet<OsmPrimitive>();
372 addSelected(selection, fireSelectionChangeEvent);
373 if (!wasEmpty && selectedPrimitives.isEmpty() && fireSelectionChangeEvent) {
374 fireSelectionChanged();
375 }
376 }
377
378 /**
379 * Sets the current selection to the primitives in <code>selection</code>
380 * and notifies all {@see SelectionChangedListener}.
381 *
382 * @param selection the selection
383 */
384 public void setSelected(Collection<? extends PrimitiveId> selection) {
385 setSelected(selection, true /* fire selection change event */);
386 }
387
388 public void setSelected(PrimitiveId... osm) {
389 if (osm.length == 1 && osm[0] == null) {
390 setSelected();
391 return;
392 }
393 List<PrimitiveId> list = Arrays.asList(osm);
394 setSelected(list);
395 }
396
397 /**
398 * Adds the primitives in <code>selection</code> to the current selection
399 * and notifies all {@see SelectionChangedListener}.
400 *
401 * @param selection the selection
402 */
403 public void addSelected(Collection<? extends PrimitiveId> selection) {
404 addSelected(selection, true /* fire selection change event */);
405 }
406
407 public void addSelected(PrimitiveId... osm) {
408 addSelected(Arrays.asList(osm));
409 }
410
411 /**
412 * Adds the primitives in <code>selection</code> to the current selection.
413 * Notifies all {@see SelectionChangedListener} if <code>fireSelectionChangeEvent</code> is true.
414 *
415 * @param selection the selection
416 * @param fireSelectionChangeEvent true, if the selection change listeners are to be notified; false, otherwise
417 */
418 public void addSelected(Collection<? extends PrimitiveId> selection, boolean fireSelectionChangeEvent) {
419 boolean changed = false;
420 for (PrimitiveId id: selection) {
421 OsmPrimitive primitive = getPrimitiveByIdChecked(id);
422 if (primitive != null) {
423 changed = changed | selectedPrimitives.add(primitive);
424 }
425 }
426 if (fireSelectionChangeEvent && changed) {
427 fireSelectionChanged();
428 }
429 }
430
431 /**
432 * Remove the selection from every value in the collection.
433 * @param list The collection to remove the selection from.
434 */
435 public void clearSelection(PrimitiveId... osm) {
436 clearSelection(Arrays.asList(osm));
437 }
438 public void clearSelection(Collection<? extends PrimitiveId> list) {
439 boolean changed = false;
440 for (PrimitiveId id:list) {
441 OsmPrimitive primitive = getPrimitiveById(id);
442 if (primitive != null) {
443 changed = changed | selectedPrimitives.remove(primitive);
444 }
445 }
446 if (changed) {
447 fireSelectionChanged();
448 }
449 }
450 public void clearSelection() {
451 if (!selectedPrimitives.isEmpty()) {
452 selectedPrimitives.clear();
453 fireSelectionChanged();
454 }
455 }
456
457
458 /*------------------------------------------------------
459 * FILTERED / DISABLED HANDLING
460 *-----------------------------------------------------*/
461
462 public void setDisabled(OsmPrimitive... osm) {
463 if (osm.length == 1 && osm[0] == null) {
464 setDisabled();
465 return;
466 }
467 clearDisabled(nodes);
468 clearDisabled(ways);
469 clearDisabled(relations);
470 for (OsmPrimitive o : osm)
471 if (o != null) {
472 o.setDisabled(true);
473 }
474 }
475
476 public void setFiltered(Collection<? extends OsmPrimitive> selection) {
477 clearFiltered(nodes);
478 clearFiltered(ways);
479 clearFiltered(relations);
480 for (OsmPrimitive osm : selection) {
481 osm.setFiltered(true);
482 }
483 }
484
485 public void setFiltered(OsmPrimitive... osm) {
486 if (osm.length == 1 && osm[0] == null) {
487 setFiltered();
488 return;
489 }
490 clearFiltered(nodes);
491 clearFiltered(ways);
492 clearFiltered(relations);
493 for (OsmPrimitive o : osm)
494 if (o != null) {
495 o.setFiltered(true);
496 }
497 }
498
499 public void setDisabled(Collection<? extends OsmPrimitive> selection) {
500 clearDisabled(nodes);
501 clearDisabled(ways);
502 clearDisabled(relations);
503 for (OsmPrimitive osm : selection) {
504 osm.setDisabled(true);
505 }
506 }
507
508
509 /**
510 * Remove the filtered parameter from every value in the collection.
511 * @param list The collection to remove the filtered parameter from.
512 */
513 private void clearFiltered(Collection<? extends OsmPrimitive> list) {
514 if (list == null)
515 return;
516 for (OsmPrimitive osm : list) {
517 osm.setFiltered(false);
518 }
519 }
520 /**
521 * Remove the disabled parameter from every value in the collection.
522 * @param list The collection to remove the disabled parameter from.
523 */
524 private void clearDisabled(Collection<? extends OsmPrimitive> list) {
525 if (list == null)
526 return;
527 for (OsmPrimitive osm : list) {
528 osm.setDisabled(false);
529 }
530 }
531
532
533 @Override public DataSet clone() {
534 DataSet ds = new DataSet();
535 for (Node n : nodes) {
536 ds.addPrimitive(new Node(n));
537 }
538 for (Way w : ways) {
539 ds.addPrimitive(new Way(w));
540 }
541 for (Relation e : relations) {
542 ds.addPrimitive(new Relation(e));
543 }
544 for (DataSource source : dataSources) {
545 ds.dataSources.add(new DataSource(source.bounds, source.origin));
546 }
547 ds.version = version;
548 return ds;
549 }
550
551 /**
552 * Returns the total area of downloaded data (the "yellow rectangles").
553 * @return Area object encompassing downloaded data.
554 */
555 public Area getDataSourceArea() {
556 if (dataSources.isEmpty()) return null;
557 Area a = new Area();
558 for (DataSource source : dataSources) {
559 // create area from data bounds
560 a.add(new Area(source.bounds.asRect()));
561 }
562 return a;
563 }
564
565 // Provide well-defined sorting for collections of OsmPrimitives.
566 // FIXME: probably not a good place to put this code.
567 public static OsmPrimitive[] sort(Collection<? extends OsmPrimitive> list) {
568 OsmPrimitive[] selArr = new OsmPrimitive[list.size()];
569 final HashMap<Object, String> h = new HashMap<Object, String>();
570 selArr = list.toArray(selArr);
571 Arrays.sort(selArr, new Comparator<OsmPrimitive>() {
572 public int compare(OsmPrimitive a, OsmPrimitive b) {
573 if (a.getClass() == b.getClass()) {
574 String as = h.get(a);
575 if (as == null) {
576 as = a.getName() != null ? a.getName() : Long.toString(a.getId());
577 h.put(a, as);
578 }
579 String bs = h.get(b);
580 if (bs == null) {
581 bs = b.getName() != null ? b.getName() : Long.toString(b.getId());
582 h.put(b, bs);
583 }
584 int res = as.compareTo(bs);
585 if (res != 0)
586 return res;
587 }
588 return a.compareTo(b);
589 }
590 });
591 return selArr;
592 }
593
594 /**
595 * returns a primitive with a given id from the data set. null, if no such primitive
596 * exists
597 *
598 * @param id uniqueId of the primitive. Might be < 0 for newly created primitives
599 * @param type the type of the primitive. Must not be null.
600 * @return the primitive
601 * @exception NullPointerException thrown, if type is null
602 */
603 public OsmPrimitive getPrimitiveById(long id, OsmPrimitiveType type) {
604 return getPrimitiveById(new SimplePrimitiveId(id, type), false);
605 }
606
607 public OsmPrimitive getPrimitiveById(PrimitiveId primitiveId) {
608 return getPrimitiveById(primitiveId, false);
609 }
610
611 public OsmPrimitive getPrimitiveById(PrimitiveId primitiveId, boolean createNew) {
612 OsmPrimitive result = primitivesMap.get(primitiveId);
613
614 if (result == null && createNew) {
615 switch (primitiveId.getType()) {
616 case NODE: result = new Node(primitiveId.getUniqueId(), true); break;
617 case WAY: result = new Way(primitiveId.getUniqueId(), true); break;
618 case RELATION: result = new Relation(primitiveId.getUniqueId(), true); break;
619 }
620 addPrimitive(result);
621 }
622
623 return result;
624 }
625
626 /**
627 * Show message and stack trace in log in case primitive is not found
628 * @param primitiveId
629 * @return Primitive by id.
630 */
631 private OsmPrimitive getPrimitiveByIdChecked(PrimitiveId primitiveId) {
632 OsmPrimitive result = getPrimitiveById(primitiveId);
633 if (result == null) {
634 System.out.println(tr("JOSM expected to find primitive [{0} {1}] in dataset but it's not there. Please report this "
635 + " at http://josm.openstreetmap.de . This is not a critical error, it should be safe to continue in your work.",
636 primitiveId.getType(), Long.toString(primitiveId.getUniqueId())));
637 new Exception().printStackTrace();
638 }
639
640 return result;
641 }
642
643 public Set<Long> getPrimitiveIds() {
644 HashSet<Long> ret = new HashSet<Long>();
645 for (OsmPrimitive primitive : nodes) {
646 ret.add(primitive.getId());
647 }
648 for (OsmPrimitive primitive : ways) {
649 ret.add(primitive.getId());
650 }
651 for (OsmPrimitive primitive : relations) {
652 ret.add(primitive.getId());
653 }
654 return ret;
655 }
656
657 protected void deleteWay(Way way) {
658 way.setNodes(null);
659 way.setDeleted(true);
660 }
661
662 /**
663 * removes all references from ways in this dataset to a particular node
664 *
665 * @param node the node
666 */
667 public void unlinkNodeFromWays(Node node) {
668 for (Way way: ways) {
669 List<Node> nodes = way.getNodes();
670 if (nodes.remove(node)) {
671 if (nodes.size() < 2) {
672 deleteWay(way);
673 } else {
674 way.setNodes(nodes);
675 }
676 }
677 }
678 }
679
680 /**
681 * removes all references from relations in this dataset to this primitive
682 *
683 * @param primitive the primitive
684 */
685 public void unlinkPrimitiveFromRelations(OsmPrimitive primitive) {
686 for (Relation relation : relations) {
687 Iterator<RelationMember> it = relation.getMembers().iterator();
688 while(it.hasNext()) {
689 RelationMember member = it.next();
690 if (member.getMember().equals(primitive)) {
691 it.remove();
692 }
693 }
694 }
695 }
696
697 /**
698 * removes all references from from other primitives to the
699 * referenced primitive
700 *
701 * @param referencedPrimitive the referenced primitive
702 */
703 public void unlinkReferencesToPrimitive(OsmPrimitive referencedPrimitive) {
704 if (referencedPrimitive instanceof Node) {
705 unlinkNodeFromWays((Node)referencedPrimitive);
706 unlinkPrimitiveFromRelations(referencedPrimitive);
707 } else {
708 unlinkPrimitiveFromRelations(referencedPrimitive);
709 }
710 }
711
712 /**
713 * Replies a list of parent relations which refer to the relation
714 * <code>child</code>. Replies an empty list if child is null.
715 *
716 * @param child the child relation
717 * @return a list of parent relations which refer to the relation
718 * <code>child</code>
719 */
720 public List<Relation> getParentRelations(Relation child) {
721 ArrayList<Relation> parents = new ArrayList<Relation>();
722 if (child == null)
723 return parents;
724 for (Relation parent : relations) {
725 if (parent == child) {
726 continue;
727 }
728 for (RelationMember member: parent.getMembers()) {
729 if (member.refersTo(child)) {
730 parents.add(parent);
731 break;
732 }
733 }
734 }
735 return parents;
736 }
737
738 /**
739 * Replies true if there is at least one primitive in this dataset with
740 * {@see OsmPrimitive#isModified()} == <code>true</code>.
741 *
742 * @return true if there is at least one primitive in this dataset with
743 * {@see OsmPrimitive#isModified()} == <code>true</code>.
744 */
745 public boolean isModified() {
746 for (Node n: nodes) {
747 if (n.isModified()) return true;
748 }
749 for (Way w: ways) {
750 if (w.isModified()) return true;
751 }
752 for (Relation r: relations) {
753 if (r.isModified()) return true;
754 }
755 return false;
756 }
757
758 /**
759 * Reindex all nodes and ways after their coordinates were changed. This is a temporary solution, reindexing should
760 * be automatic in the future
761 * @deprecated Reindexing should be automatic
762 */
763 @Deprecated
764 public void reindexAll() {
765 List<Node> ntmp = new ArrayList<Node>(nodes);
766 nodes.clear();
767 nodes.addAll(ntmp);
768 List<Way> wtmp = new ArrayList<Way>(ways);
769 ways.clear();
770 ways.addAll(wtmp);
771 }
772
773 private void reindexNode(Node node) {
774 nodes.remove(node);
775 nodes.add(node);
776 for (Way way:OsmPrimitive.getFilteredList(node.getReferrers(), Way.class)) {
777 ways.remove(way);
778 way.updatePosition();
779 ways.add(way);
780 }
781 }
782
783 private void reindexWay(Way way) {
784 ways.remove(way);
785 way.updatePosition();
786 ways.add(way);
787 }
788
789
790 public void addDataSetListener(DataSetListener dsl) {
791 listeners.add(dsl);
792 }
793
794 public void removeDataSetListener(DataSetListener dsl) {
795 listeners.remove(dsl);
796 }
797
798 void firePrimitivesAdded(Collection<? extends OsmPrimitive> added) {
799 for (DataSetListener dsl : listeners) {
800 dsl.primtivesAdded(added);
801 }
802 }
803
804 void firePrimitivesRemoved(Collection<? extends OsmPrimitive> removed) {
805 for (DataSetListener dsl : listeners) {
806 dsl.primtivesRemoved(removed);
807 }
808 }
809
810 void fireTagsChanged(OsmPrimitive prim) {
811 for (DataSetListener dsl : listeners) {
812 dsl.tagsChanged(prim);
813 }
814 }
815
816 void fireRelationMembersChanged(Relation r) {
817 for (DataSetListener dsl : listeners) {
818 dsl.relationMembersChanged(r);
819 }
820 }
821
822 public void fireNodeMoved(Node node) {
823 reindexNode(node);
824 for (DataSetListener dsl : listeners) {
825 dsl.nodeMoved(node);
826 }
827 }
828
829 public void fireWayNodesChanged(Way way) {
830 reindexWay(way);
831 for (DataSetListener dsl : listeners) {
832 dsl.wayNodesChanged(way);
833 }
834 }
835
836 public void clenupDeletedPrimitives() {
837 if (cleanupDeleted(nodes.iterator())
838 | cleanupDeleted(ways.iterator())
839 | cleanupDeleted(relations.iterator())) {
840 fireSelectionChanged();
841 }
842 }
843
844 private boolean cleanupDeleted(Iterator<? extends OsmPrimitive> it) {
845 boolean changed = false;
846 while (it.hasNext()) {
847 OsmPrimitive primitive = it.next();
848 if (primitive.isDeleted()) {
849 selectedPrimitives.remove(primitive);
850 allPrimitives.remove(primitive);
851 primitive.setDataset(null);
852 changed = true;
853 it.remove();
854 }
855 }
856 return changed;
857 }
858
859 /**
860 * Removes all primitives from the dataset and resets the currently selected primitives
861 * to the empty collection. Also notifies selection change listeners if necessary.
862 *
863 */
864 public void clear() {
865 clearSelection();
866 for (OsmPrimitive primitive:allPrimitives) {
867 primitive.setDataset(null);
868 }
869 nodes.clear();
870 ways.clear();
871 relations.clear();
872 allPrimitives.clear();
873 }
874}
Note: See TracBrowser for help on using the repository browser.