source: josm/trunk/src/org/openstreetmap/josm/gui/datatransfer/data/PrimitiveTransferData.java@ 12725

Last change on this file since 12725 was 12725, checked in by bastiK, 7 years ago

see #15229 - deprecate ILatLon#getEastNorth() so ILatLon has no dependency on Main.proj

File size: 5.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.datatransfer.data;
3
4import java.awt.datatransfer.DataFlavor;
5import java.io.Serializable;
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.Collections;
9import java.util.HashSet;
10import java.util.LinkedList;
11import java.util.Queue;
12
13import org.openstreetmap.josm.data.ProjectionBounds;
14import org.openstreetmap.josm.data.coor.EastNorth;
15import org.openstreetmap.josm.data.osm.NodeData;
16import org.openstreetmap.josm.data.osm.OsmPrimitive;
17import org.openstreetmap.josm.data.osm.PrimitiveData;
18import org.openstreetmap.josm.data.osm.Relation;
19import org.openstreetmap.josm.data.osm.Way;
20import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
21import org.openstreetmap.josm.tools.CompositeList;
22
23/**
24 * A list of primitives that are transfered. The list allows you to implicitly add primitives.
25 * It distinguishes between primitives that were directly added and implicitly added ones.
26 * @author Michael Zangl
27 * @since 10604
28 */
29public final class PrimitiveTransferData implements Serializable {
30 private static final long serialVersionUID = 1L;
31
32 /**
33 * The data flavor used to represent this class.
34 */
35 public static final DataFlavor DATA_FLAVOR = new DataFlavor(PrimitiveTransferData.class, "OSM Primitives");
36
37 private static final class GetReferences implements ReferenceGetter {
38 @Override
39 public Collection<? extends OsmPrimitive> getReferredPrimitives(OsmPrimitive primitive) {
40 if (primitive instanceof Way) {
41 return ((Way) primitive).getNodes();
42 } else if (primitive instanceof Relation) {
43 return ((Relation) primitive).getMemberPrimitivesList();
44 } else {
45 return Collections.emptyList();
46 }
47 }
48 }
49
50 @FunctionalInterface
51 private interface ReferenceGetter {
52 Collection<? extends OsmPrimitive> getReferredPrimitives(OsmPrimitive primitive);
53 }
54
55 private final ArrayList<PrimitiveData> direct;
56 private final ArrayList<PrimitiveData> referenced;
57
58 /**
59 * Create the new transfer data.
60 * @param primitives The primitives to transfer
61 * @param referencedGetter A function that allows to get the primitives referenced by the primitives variable.
62 * It will be queried recursively.
63 */
64 private PrimitiveTransferData(Collection<? extends OsmPrimitive> primitives, ReferenceGetter referencedGetter) {
65 // convert to hash set first to remove duplicates
66 HashSet<OsmPrimitive> visited = new HashSet<>(primitives);
67 this.direct = new ArrayList<>(visited.size());
68
69 this.referenced = new ArrayList<>();
70 Queue<OsmPrimitive> toCheck = new LinkedList<>();
71 for (OsmPrimitive p : visited) {
72 direct.add(p.save());
73 toCheck.addAll(referencedGetter.getReferredPrimitives(p));
74 }
75 while (!toCheck.isEmpty()) {
76 OsmPrimitive p = toCheck.poll();
77 if (visited.add(p)) {
78 referenced.add(p.save());
79 toCheck.addAll(referencedGetter.getReferredPrimitives(p));
80 }
81 }
82 }
83
84 /**
85 * Gets all primitives directly added.
86 * @return The primitives
87 */
88 public Collection<PrimitiveData> getDirectlyAdded() {
89 return Collections.unmodifiableList(direct);
90 }
91
92 /**
93 * Gets all primitives that were added because they were referenced.
94 * @return The primitives
95 */
96 public Collection<PrimitiveData> getReferenced() {
97 return Collections.unmodifiableList(referenced);
98 }
99
100 /**
101 * Gets a List of all primitives added to this set.
102 * @return That list.
103 */
104 public Collection<PrimitiveData> getAll() {
105 return new CompositeList<>(direct, referenced);
106 }
107
108 /**
109 * Creates a new {@link PrimitiveTransferData} object that only contains the primitives.
110 * @param primitives The primitives to contain.
111 * @return That set.
112 */
113 public static PrimitiveTransferData getData(Collection<? extends OsmPrimitive> primitives) {
114 return new PrimitiveTransferData(primitives, primitive -> Collections.emptyList());
115 }
116
117 /**
118 * Creates a new {@link PrimitiveTransferData} object that contains the primitives and all references.
119 * @param primitives The primitives to contain.
120 * @return That set.
121 */
122 public static PrimitiveTransferData getDataWithReferences(Collection<? extends OsmPrimitive> primitives) {
123 return new PrimitiveTransferData(primitives, new GetReferences());
124 }
125
126 /**
127 * Compute the center of all nodes.
128 * @return The center or null if this buffer has no location.
129 */
130 public EastNorth getCenter() {
131 BoundingXYVisitor visitor = new BoundingXYVisitor();
132 for (PrimitiveData pd : getAll()) {
133 if (pd instanceof NodeData && !pd.isIncomplete()) {
134 visitor.visit(((NodeData) pd));
135 }
136 }
137 ProjectionBounds bounds = visitor.getBounds();
138 if (bounds == null) {
139 return null;
140 } else {
141 return bounds.getCenter();
142 }
143 }
144
145 /**
146 * Tests wheter this set contains any primitives that have invalid data.
147 * @return <code>true</code> if invalid data is contained in this set.
148 */
149 public boolean hasIncompleteData() {
150 return getAll().stream().anyMatch(p -> p.isIncomplete() || !p.isVisible());
151 }
152}
Note: See TracBrowser for help on using the repository browser.