1 | // License: GPL. For details, see LICENSE file.
|
---|
2 | package org.openstreetmap.josm.data.osm;
|
---|
3 |
|
---|
4 | import java.io.FileInputStream;
|
---|
5 | import java.io.InputStream;
|
---|
6 | import java.security.SecureRandom;
|
---|
7 | import java.util.ArrayList;
|
---|
8 | import java.util.Arrays;
|
---|
9 | import java.util.Collection;
|
---|
10 | import java.util.Iterator;
|
---|
11 | import java.util.List;
|
---|
12 | import java.util.Random;
|
---|
13 |
|
---|
14 | import org.fest.reflect.core.Reflection;
|
---|
15 | import org.fest.reflect.reference.TypeRef;
|
---|
16 | import org.junit.Assert;
|
---|
17 | import org.junit.Rule;
|
---|
18 | import org.junit.Test;
|
---|
19 | import org.openstreetmap.josm.Main;
|
---|
20 | import org.openstreetmap.josm.data.coor.LatLon;
|
---|
21 | import org.openstreetmap.josm.data.projection.Projections;
|
---|
22 | import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
|
---|
23 | import org.openstreetmap.josm.io.OsmReader;
|
---|
24 | import org.openstreetmap.josm.testutils.JOSMTestRules;
|
---|
25 |
|
---|
26 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
---|
27 |
|
---|
28 | /**
|
---|
29 | * Unit tests of {@link QuadBuckets}.
|
---|
30 | */
|
---|
31 | public class QuadBucketsTest {
|
---|
32 |
|
---|
33 | /**
|
---|
34 | * Setup test.
|
---|
35 | */
|
---|
36 | @Rule
|
---|
37 | @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
|
---|
38 | public JOSMTestRules test = new JOSMTestRules();
|
---|
39 |
|
---|
40 | private void removeAllTest(DataSet ds) {
|
---|
41 | List<Node> allNodes = new ArrayList<>(ds.getNodes());
|
---|
42 | List<Way> allWays = new ArrayList<>(ds.getWays());
|
---|
43 | List<Relation> allRelations = new ArrayList<>(ds.getRelations());
|
---|
44 |
|
---|
45 | QuadBucketPrimitiveStore<Node, Way, Relation> s = Reflection.field("store").ofType(
|
---|
46 | new TypeRef<QuadBucketPrimitiveStore<Node, Way, Relation>>() {}).in(ds).get();
|
---|
47 | QuadBuckets<Node> nodes = Reflection.field("nodes").ofType(new TypeRef<QuadBuckets<Node>>() {}).in(s).get();
|
---|
48 | QuadBuckets<Way> ways = Reflection.field("ways").ofType(new TypeRef<QuadBuckets<Way>>() {}).in(s).get();
|
---|
49 | Collection<Relation> relations = Reflection.field("relations").ofType(new TypeRef<Collection<Relation>>() {}).in(s).get();
|
---|
50 |
|
---|
51 | int expectedCount = allNodes.size();
|
---|
52 | for (OsmPrimitive o: allNodes) {
|
---|
53 | ds.removePrimitive(o);
|
---|
54 | checkIterator(nodes, --expectedCount);
|
---|
55 | }
|
---|
56 | expectedCount = allWays.size();
|
---|
57 | for (OsmPrimitive o: allWays) {
|
---|
58 | ds.removePrimitive(o);
|
---|
59 | checkIterator(ways, --expectedCount);
|
---|
60 | }
|
---|
61 | for (OsmPrimitive o: allRelations) {
|
---|
62 | ds.removePrimitive(o);
|
---|
63 | }
|
---|
64 | Assert.assertTrue(nodes.isEmpty());
|
---|
65 | Assert.assertTrue(ways.isEmpty());
|
---|
66 | Assert.assertTrue(relations.isEmpty());
|
---|
67 | }
|
---|
68 |
|
---|
69 | private void checkIterator(Collection<? extends OsmPrimitive> col, int expectedCount) {
|
---|
70 | int count = 0;
|
---|
71 | Iterator<? extends OsmPrimitive> it = col.iterator();
|
---|
72 | while (it.hasNext()) {
|
---|
73 | count++;
|
---|
74 | it.next();
|
---|
75 | }
|
---|
76 | Assert.assertEquals(expectedCount, count);
|
---|
77 | }
|
---|
78 |
|
---|
79 | @Test
|
---|
80 | public void testRemove() throws Exception {
|
---|
81 | Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); // Mercator
|
---|
82 | try (InputStream fis = new FileInputStream("data_nodist/restriction.osm")) {
|
---|
83 | DataSet ds = OsmReader.parseDataSet(fis, NullProgressMonitor.INSTANCE);
|
---|
84 | removeAllTest(ds);
|
---|
85 | }
|
---|
86 | }
|
---|
87 |
|
---|
88 | @Test
|
---|
89 | public void testMove() throws Exception {
|
---|
90 | Main.setProjection(Projections.getProjectionByCode("EPSG:3857")); // Mercator
|
---|
91 | try (InputStream fis = new FileInputStream("data_nodist/restriction.osm")) {
|
---|
92 | DataSet ds = OsmReader.parseDataSet(fis, NullProgressMonitor.INSTANCE);
|
---|
93 |
|
---|
94 | for (Node n: ds.getNodes()) {
|
---|
95 | n.setCoor(new LatLon(10, 10));
|
---|
96 | }
|
---|
97 |
|
---|
98 | removeAllTest(ds);
|
---|
99 | }
|
---|
100 | }
|
---|
101 |
|
---|
102 | /**
|
---|
103 | * Test handling of objects with invalid bbox
|
---|
104 | */
|
---|
105 | @Test
|
---|
106 | public void testSpecialBBox() {
|
---|
107 | QuadBuckets<Node> qbNodes = new QuadBuckets<>();
|
---|
108 | QuadBuckets<Way> qbWays = new QuadBuckets<>();
|
---|
109 | Way w1 = new Way(1);
|
---|
110 | Way w2 = new Way(2);
|
---|
111 | Way w3 = new Way(3);
|
---|
112 | Node n1 = new Node(1);
|
---|
113 | Node n2 = new Node(2); n2.setCoor(new LatLon(10, 20));
|
---|
114 | Node n3 = new Node(3); n2.setCoor(new LatLon(20, 30));
|
---|
115 | w2.setNodes(Arrays.asList(n1));
|
---|
116 | w3.setNodes(Arrays.asList(n1, n2, n3));
|
---|
117 |
|
---|
118 | qbNodes.add(n1);
|
---|
119 | qbNodes.add(n2);
|
---|
120 | Assert.assertEquals(2, qbNodes.size());
|
---|
121 | Assert.assertTrue(qbNodes.contains(n1));
|
---|
122 | Assert.assertTrue(qbNodes.contains(n2));
|
---|
123 | Assert.assertFalse(qbNodes.contains(n3));
|
---|
124 | qbNodes.remove(n1);
|
---|
125 | Assert.assertEquals(1, qbNodes.size());
|
---|
126 | Assert.assertFalse(qbNodes.contains(n1));
|
---|
127 | Assert.assertTrue(qbNodes.contains(n2));
|
---|
128 | qbNodes.remove(n2);
|
---|
129 | Assert.assertEquals(0, qbNodes.size());
|
---|
130 | Assert.assertFalse(qbNodes.contains(n1));
|
---|
131 | Assert.assertFalse(qbNodes.contains(n2));
|
---|
132 |
|
---|
133 | qbNodes.addAll(Arrays.asList(n1, n2, n3));
|
---|
134 | qbNodes.removeAll(Arrays.asList(n1, n3));
|
---|
135 | Assert.assertEquals(1, qbNodes.size());
|
---|
136 | Assert.assertTrue(qbNodes.contains(n2));
|
---|
137 |
|
---|
138 | qbWays.add(w1);
|
---|
139 | qbWays.add(w2);
|
---|
140 | qbWays.add(w3);
|
---|
141 | Assert.assertEquals(3, qbWays.size());
|
---|
142 | Assert.assertTrue(qbWays.contains(w1));
|
---|
143 | Assert.assertTrue(qbWays.contains(w2));
|
---|
144 | Assert.assertTrue(qbWays.contains(w3));
|
---|
145 | qbWays.remove(w1);
|
---|
146 | Assert.assertEquals(2, qbWays.size());
|
---|
147 | Assert.assertFalse(qbWays.contains(w1));
|
---|
148 | Assert.assertTrue(qbWays.contains(w2));
|
---|
149 | Assert.assertTrue(qbWays.contains(w3));
|
---|
150 | qbWays.remove(w2);
|
---|
151 | Assert.assertEquals(1, qbWays.size());
|
---|
152 | Assert.assertFalse(qbWays.contains(w1));
|
---|
153 | Assert.assertFalse(qbWays.contains(w2));
|
---|
154 | Assert.assertTrue(qbWays.contains(w3));
|
---|
155 | qbWays.remove(w3);
|
---|
156 | Assert.assertEquals(0, qbWays.size());
|
---|
157 | Assert.assertFalse(qbWays.contains(w1));
|
---|
158 | Assert.assertFalse(qbWays.contains(w2));
|
---|
159 | Assert.assertFalse(qbWays.contains(w3));
|
---|
160 |
|
---|
161 | qbWays.clear();
|
---|
162 | Assert.assertEquals(0, qbWays.size());
|
---|
163 | List<Way> allWays = new ArrayList<>(Arrays.asList(w1, w2, w3));
|
---|
164 | qbWays.addAll(allWays);
|
---|
165 | Assert.assertEquals(3, qbWays.size());
|
---|
166 | int count = 0;
|
---|
167 | for (Way w : qbWays) {
|
---|
168 | Assert.assertTrue(allWays.contains(w));
|
---|
169 | count++;
|
---|
170 | }
|
---|
171 | Assert.assertEquals(3, count);
|
---|
172 | // test remove with iterator
|
---|
173 | Iterator<Way> iter = qbWays.iterator();
|
---|
174 | while (iter.hasNext()) {
|
---|
175 | iter.next();
|
---|
176 | iter.remove();
|
---|
177 | count--;
|
---|
178 | Assert.assertEquals(count, qbWays.size());
|
---|
179 | }
|
---|
180 | Assert.assertEquals(0, qbWays.size());
|
---|
181 |
|
---|
182 | }
|
---|
183 |
|
---|
184 | /**
|
---|
185 | * Add more data so that quad buckets tree has a few leaves
|
---|
186 | */
|
---|
187 | @Test
|
---|
188 | public void testSplitsWithIncompleteData() {
|
---|
189 | DataSet ds = new DataSet();
|
---|
190 | long nodeId = 1;
|
---|
191 | long wayId = 1;
|
---|
192 | final int NUM_COMPLETE_WAYS = 300;
|
---|
193 | final int NUM_INCOMPLETE_WAYS = 10;
|
---|
194 | final int NUM_NODES_PER_WAY = 20;
|
---|
195 | final int NUM_INCOMPLETE_NODES = 10;
|
---|
196 |
|
---|
197 | // force splits in quad buckets
|
---|
198 | Random random = new SecureRandom();
|
---|
199 | for (int i = 0; i < NUM_COMPLETE_WAYS; i++) {
|
---|
200 | Way w = new Way(wayId++);
|
---|
201 | List<Node> nodes = new ArrayList<>();
|
---|
202 | double center = random.nextDouble() * 10;
|
---|
203 | for (int j = 0; j < NUM_NODES_PER_WAY; j++) {
|
---|
204 | Node n = new Node(nodeId++);
|
---|
205 | double lat = random.nextDouble() * 0.001;
|
---|
206 | double lon = random.nextDouble() * 0.001;
|
---|
207 | n.setCoor(new LatLon(center + lat, center + lon));
|
---|
208 | nodes.add(n);
|
---|
209 | ds.addPrimitive(n);
|
---|
210 | }
|
---|
211 | w.setNodes(nodes);
|
---|
212 | ds.addPrimitive(w);
|
---|
213 | }
|
---|
214 | Assert.assertEquals(NUM_COMPLETE_WAYS, ds.getWays().size());
|
---|
215 | Assert.assertEquals(NUM_COMPLETE_WAYS * NUM_NODES_PER_WAY, ds.getNodes().size());
|
---|
216 |
|
---|
217 | // add some incomplete nodes
|
---|
218 | for (int i = 0; i < NUM_INCOMPLETE_NODES; i++) {
|
---|
219 | Node n = new Node(nodeId++);
|
---|
220 | n.setIncomplete(true);
|
---|
221 | ds.addPrimitive(n);
|
---|
222 | }
|
---|
223 | Assert.assertEquals(NUM_COMPLETE_WAYS * NUM_NODES_PER_WAY + NUM_INCOMPLETE_NODES, ds.getNodes().size());
|
---|
224 | // add some incomplete ways
|
---|
225 | List<Way> incompleteWays = new ArrayList<>();
|
---|
226 | for (int i = 0; i < NUM_INCOMPLETE_WAYS; i++) {
|
---|
227 | Way w = new Way(wayId++);
|
---|
228 | incompleteWays.add(w);
|
---|
229 | w.setIncomplete(true);
|
---|
230 | ds.addPrimitive(w);
|
---|
231 | }
|
---|
232 | Assert.assertEquals(NUM_COMPLETE_WAYS + NUM_INCOMPLETE_WAYS, ds.getWays().size());
|
---|
233 |
|
---|
234 | BBox planet = new BBox(-180, -90, 180, 90);
|
---|
235 | // incomplete ways should not be found with search
|
---|
236 | Assert.assertEquals(NUM_COMPLETE_WAYS, ds.searchWays(planet).size());
|
---|
237 | // incomplete ways are only retrieved via iterator or object reference
|
---|
238 | for (Way w : incompleteWays) {
|
---|
239 | Assert.assertTrue(ds.getWays().contains(w));
|
---|
240 | }
|
---|
241 |
|
---|
242 | QuadBuckets<Way> qb = new QuadBuckets<>();
|
---|
243 | qb.addAll(ds.getWays());
|
---|
244 | int count = qb.size();
|
---|
245 | Assert.assertEquals(count, ds.getWays().size());
|
---|
246 | Iterator<Way> iter = qb.iterator();
|
---|
247 | while (iter.hasNext()) {
|
---|
248 | iter.next();
|
---|
249 | iter.remove();
|
---|
250 | count--;
|
---|
251 | Assert.assertEquals(count, qb.size());
|
---|
252 | }
|
---|
253 | Assert.assertEquals(0, qb.size());
|
---|
254 | }
|
---|
255 | }
|
---|