source: josm/trunk/src/org/openstreetmap/josm/data/osm/QuadBucketPrimitiveStore.java@ 13766

Last change on this file since 13766 was 13766, checked in by Don-vip, 7 years ago

API alignment between Relation/RelationData and RelationMember/RelationMemberData: update of IRelation/IRelationMember interfaces

File size: 7.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm;
3
4import java.util.ArrayList;
5import java.util.Collection;
6import java.util.List;
7import java.util.function.Consumer;
8import java.util.stream.Collectors;
9
10import org.openstreetmap.josm.tools.JosmRuntimeException;
11
12/**
13 * Stores primitives in quad buckets. This can be used to hold a collection of primitives, e.g. in a {@link DataSet}
14 *
15 * This class does not do any synchronization.
16 * @author Michael Zangl
17 * @param <N> type representing OSM nodes
18 * @param <W> type representing OSM ways
19 * @param <R> type representing OSM relations
20 * @since 12048
21 */
22public class QuadBucketPrimitiveStore<N extends INode, W extends IWay<N>, R extends IRelation<?>> {
23 /**
24 * All nodes goes here, even when included in other data (ways etc). This enables the instant
25 * conversion of the whole DataSet by iterating over this data structure.
26 */
27 private final QuadBuckets<N> nodes = new QuadBuckets<>();
28
29 /**
30 * All ways (Streets etc.) in the DataSet.
31 *
32 * The way nodes are stored only in the way list.
33 */
34 private final QuadBuckets<W> ways = new QuadBuckets<>();
35
36 /**
37 * All relations/relationships
38 */
39 private final Collection<R> relations = new ArrayList<>();
40
41 /**
42 * Constructs a new {@code QuadBucketPrimitiveStore}.
43 */
44 public QuadBucketPrimitiveStore() {
45 }
46
47 /**
48 * Searches for nodes in the given bounding box.
49 * @param bbox the bounding box
50 * @return List of nodes in the given bbox. Can be empty but not null
51 */
52 public List<N> searchNodes(BBox bbox) {
53 return nodes.search(bbox);
54 }
55
56 /**
57 * Determines if the given node can be retrieved in the store through its bounding box. Useful for dataset consistency test.
58 * @param n The node to search
59 * @return {@code true} if {@code n} can be retrieved in this store, {@code false} otherwise
60 */
61 public boolean containsNode(N n) {
62 return nodes.contains(n);
63 }
64
65 /**
66 * Searches for ways in the given bounding box.
67 * @param bbox the bounding box
68 * @return List of ways in the given bbox. Can be empty but not null
69 */
70 public List<W> searchWays(BBox bbox) {
71 return ways.search(bbox);
72 }
73
74 /**
75 * Determines if the given way can be retrieved in the store through its bounding box. Useful for dataset consistency test.
76 * @param w The way to search
77 * @return {@code true} if {@code w} can be retrieved in this store, {@code false} otherwise
78 */
79 public boolean containsWay(W w) {
80 return ways.contains(w);
81 }
82
83 /**
84 * Searches for relations in the given bounding box.
85 * @param bbox the bounding box
86 * @return List of relations in the given bbox. Can be empty but not null
87 */
88 public List<R> searchRelations(BBox bbox) {
89 // QuadBuckets might be useful here (don't forget to do reindexing after some of rm is changed)
90 return relations.stream()
91 .filter(r -> r.getBBox().intersects(bbox))
92 .collect(Collectors.toList());
93 }
94
95 /**
96 * Determines if the given relation can be retrieved in the store through its bounding box. Useful for dataset consistency test.
97 * @param r The relation to search
98 * @return {@code true} if {@code r} can be retrieved in this store, {@code false} otherwise
99 */
100 public boolean containsRelation(R r) {
101 return relations.contains(r);
102 }
103
104 /**
105 * Adds a primitive to this quad bucket store
106 *
107 * @param primitive the primitive.
108 */
109 @SuppressWarnings("unchecked")
110 public void addPrimitive(IPrimitive primitive) {
111 boolean success = false;
112 if (primitive instanceof INode) {
113 success = nodes.add((N) primitive);
114 } else if (primitive instanceof IWay) {
115 success = ways.add((W) primitive);
116 } else if (primitive instanceof IRelation) {
117 success = relations.add((R) primitive);
118 }
119 if (!success) {
120 throw new JosmRuntimeException("failed to add primitive: "+primitive);
121 }
122 }
123
124 protected void removePrimitive(IPrimitive primitive) {
125 boolean success = false;
126 if (primitive instanceof INode) {
127 success = nodes.remove(primitive);
128 } else if (primitive instanceof IWay) {
129 success = ways.remove(primitive);
130 } else if (primitive instanceof IRelation) {
131 success = relations.remove(primitive);
132 }
133 if (!success) {
134 throw new JosmRuntimeException("failed to remove primitive: "+primitive);
135 }
136 }
137
138 /**
139 * Re-index the node after it's position was changed.
140 * @param node The node to re-index
141 * @param nUpdater update node position
142 * @param wUpdater update way position
143 * @param rUpdater update relation position
144 */
145 @SuppressWarnings("unchecked")
146 protected void reindexNode(N node, Consumer<N> nUpdater, Consumer<W> wUpdater, Consumer<R> rUpdater) {
147 if (!nodes.remove(node))
148 throw new JosmRuntimeException("Reindexing node failed to remove");
149 nUpdater.accept(node);
150 if (!nodes.add(node))
151 throw new JosmRuntimeException("Reindexing node failed to add");
152 for (IPrimitive primitive: node.getReferrers()) {
153 if (primitive instanceof IWay) {
154 reindexWay((W) primitive, wUpdater, rUpdater);
155 } else {
156 reindexRelation((R) primitive, rUpdater);
157 }
158 }
159 }
160
161 /**
162 * Re-index the way after it's position was changed.
163 * @param way The way to re-index
164 * @param wUpdater update way position
165 * @param rUpdater update relation position
166 */
167 @SuppressWarnings("unchecked")
168 protected void reindexWay(W way, Consumer<W> wUpdater, Consumer<R> rUpdater) {
169 BBox before = way.getBBox();
170 if (!ways.remove(way))
171 throw new JosmRuntimeException("Reindexing way failed to remove");
172 wUpdater.accept(way);
173 if (!ways.add(way))
174 throw new JosmRuntimeException("Reindexing way failed to add");
175 if (!way.getBBox().equals(before)) {
176 for (IPrimitive primitive: way.getReferrers()) {
177 reindexRelation((R) primitive, rUpdater);
178 }
179 }
180 }
181
182 /**
183 * Re-index the relation after it's position was changed.
184 * @param relation The relation to re-index
185 * @param rUpdater update relation position
186 */
187 @SuppressWarnings("unchecked")
188 protected void reindexRelation(R relation, Consumer<R> rUpdater) {
189 BBox before = relation.getBBox();
190 rUpdater.accept(relation);
191 if (!before.equals(relation.getBBox())) {
192 for (IPrimitive primitive: relation.getReferrers()) {
193 reindexRelation((R) primitive, rUpdater);
194 }
195 }
196 }
197
198 /**
199 * Removes all primitives from the this store.
200 */
201 public void clear() {
202 nodes.clear();
203 ways.clear();
204 relations.clear();
205 }
206}
Note: See TracBrowser for help on using the repository browser.