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

Last change on this file since 12122 was 12049, checked in by michael2402, 7 years ago

Move quad bucket store of dataset to separate class.

File size: 6.8 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.stream.Collectors;
8
9import org.openstreetmap.josm.data.coor.EastNorth;
10import org.openstreetmap.josm.data.coor.LatLon;
11import org.openstreetmap.josm.tools.JosmRuntimeException;
12
13/**
14 * Stores primitives in quad buckets. This can be used to hold a collection of primitives, e.g. in a {@link DataSet}
15 *
16 * This class does not do any synchronization.
17 * @author Michael Zangl
18 * @since 12048
19 */
20public class QuadBucketPrimitiveStore {
21 /**
22 * All nodes goes here, even when included in other data (ways etc). This enables the instant
23 * conversion of the whole DataSet by iterating over this data structure.
24 */
25 private final QuadBuckets<Node> nodes = new QuadBuckets<>();
26
27 /**
28 * All ways (Streets etc.) in the DataSet.
29 *
30 * The way nodes are stored only in the way list.
31 */
32 private final QuadBuckets<Way> ways = new QuadBuckets<>();
33
34 /**
35 * All relations/relationships
36 */
37 private final Collection<Relation> relations = new ArrayList<>();
38
39 /**
40 * Searches for nodes in the given bounding box.
41 * @param bbox the bounding box
42 * @return List of nodes in the given bbox. Can be empty but not null
43 */
44 public List<Node> searchNodes(BBox bbox) {
45 return nodes.search(bbox);
46 }
47
48 /**
49 * Determines if the given node can be retrieved in the data set through its bounding box. Useful for dataset consistency test.
50 * For efficiency reasons this method does not lock the dataset, you have to lock it manually.
51 *
52 * @param n The node to search
53 * @return {@code true} if {@code n} ban be retrieved in this data set, {@code false} otherwise
54 * @since 7501
55 */
56 public boolean containsNode(Node n) {
57 return nodes.contains(n);
58 }
59
60 /**
61 * Searches for ways in the given bounding box.
62 * @param bbox the bounding box
63 * @return List of ways in the given bbox. Can be empty but not null
64 */
65 public List<Way> searchWays(BBox bbox) {
66 return ways.search(bbox);
67 }
68
69 /**
70 * Determines if the given way can be retrieved in the data set through its bounding box. Useful for dataset consistency test.
71 * For efficiency reasons this method does not lock the dataset, you have to lock it manually.
72 *
73 * @param w The way to search
74 * @return {@code true} if {@code w} ban be retrieved in this data set, {@code false} otherwise
75 * @since 7501
76 */
77 public boolean containsWay(Way w) {
78 return ways.contains(w);
79 }
80
81 /**
82 * Searches for relations in the given bounding box.
83 * @param bbox the bounding box
84 * @return List of relations in the given bbox. Can be empty but not null
85 */
86 public List<Relation> searchRelations(BBox bbox) {
87 // QuadBuckets might be useful here (don't forget to do reindexing after some of rm is changed)
88 return relations.stream()
89 .filter(r -> r.getBBox().intersects(bbox))
90 .collect(Collectors.toList());
91 }
92
93 /**
94 * Determines if the given relation can be retrieved in the data set through its bounding box. Useful for dataset consistency test.
95 * For efficiency reasons this method does not lock the dataset, you have to lock it manually.
96 *
97 * @param r The relation to search
98 * @return {@code true} if {@code r} ban be retrieved in this data set, {@code false} otherwise
99 * @since 7501
100 */
101 public boolean containsRelation(Relation r) {
102 return relations.contains(r);
103 }
104
105 /**
106 * Adds a primitive to this quad bucket store
107 *
108 * @param primitive the primitive.
109 */
110 public void addPrimitive(OsmPrimitive primitive) {
111 boolean success = false;
112 if (primitive instanceof Node) {
113 success = nodes.add((Node) primitive);
114 } else if (primitive instanceof Way) {
115 success = ways.add((Way) primitive);
116 } else if (primitive instanceof Relation) {
117 success = relations.add((Relation) primitive);
118 }
119 if (!success) {
120 throw new JosmRuntimeException("failed to add primitive: "+primitive);
121 }
122 }
123
124 protected void removePrimitive(OsmPrimitive primitive) {
125 boolean success = false;
126 if (primitive instanceof Node) {
127 success = nodes.remove(primitive);
128 } else if (primitive instanceof Way) {
129 success = ways.remove(primitive);
130 } else if (primitive instanceof Relation) {
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 relation after it's position was changed.
140 * @param node The node to re-index
141 * @param newCoor The new coordinates
142 * @param eastNorth The new east/north position
143 */
144 protected void reindexNode(Node node, LatLon newCoor, EastNorth eastNorth) {
145 if (!nodes.remove(node))
146 throw new JosmRuntimeException("Reindexing node failed to remove");
147 node.setCoorInternal(newCoor, eastNorth);
148 if (!nodes.add(node))
149 throw new JosmRuntimeException("Reindexing node failed to add");
150 for (OsmPrimitive primitive: node.getReferrers()) {
151 if (primitive instanceof Way) {
152 reindexWay((Way) primitive);
153 } else {
154 reindexRelation((Relation) primitive);
155 }
156 }
157 }
158
159 /**
160 * Re-index the way after it's position was changed.
161 * @param way The way to re-index
162 */
163 protected void reindexWay(Way way) {
164 BBox before = way.getBBox();
165 if (!ways.remove(way))
166 throw new JosmRuntimeException("Reindexing way failed to remove");
167 way.updatePosition();
168 if (!ways.add(way))
169 throw new JosmRuntimeException("Reindexing way failed to add");
170 if (!way.getBBox().equals(before)) {
171 for (OsmPrimitive primitive: way.getReferrers()) {
172 reindexRelation((Relation) primitive);
173 }
174 }
175 }
176
177 /**
178 * Re-index the relation after it's position was changed.
179 * @param relation The relation to re-index
180 */
181 protected static void reindexRelation(Relation relation) {
182 BBox before = relation.getBBox();
183 relation.updatePosition();
184 if (!before.equals(relation.getBBox())) {
185 for (OsmPrimitive primitive: relation.getReferrers()) {
186 reindexRelation((Relation) primitive);
187 }
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.