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

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

Fixed #3898 Selection is broken

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