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

Last change on this file since 13915 was 13852, checked in by Don-vip, 6 years ago

SonarQube - fix more code issues

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