Ticket #13361: 13361_v6.patch
File 13361_v6.patch, 26.2 KB (added by , 8 years ago) |
---|
-
src/org/openstreetmap/josm/data/osm/BBox.java
9 9 import org.openstreetmap.josm.data.coor.QuadTiling; 10 10 import org.openstreetmap.josm.tools.Utils; 11 11 12 /** 13 * A bounding box with latitude / longitude coordinates 14 */ 12 15 public class BBox { 13 14 16 private double xmin = Double.POSITIVE_INFINITY; 15 17 private double xmax = Double.NEGATIVE_INFINITY; 16 18 private double ymin = Double.POSITIVE_INFINITY; … … 17 19 private double ymax = Double.NEGATIVE_INFINITY; 18 20 19 21 /** 22 * Constructs a new (invalid) BBox 23 */ 24 public BBox() { } 25 26 /** 20 27 * Constructs a new {@code BBox} defined by a single point. 21 28 * 22 29 * @param x X coordinate … … 24 31 * @since 6203 25 32 */ 26 33 public BBox(final double x, final double y) { 27 xmax = xmin = x; 28 ymax = ymin = y; 29 sanity(); 34 if (!Double.isNaN(x) && !Double.isNaN(y)) { 35 xmin = x; 36 ymin = y; 37 xmax = x; 38 ymax = y; 39 } 30 40 } 31 41 32 42 /** 33 43 * Constructs a new {@code BBox} defined by points <code>a</code> and <code>b</code>. 34 * Result is minimal BBox containing both points .44 * Result is minimal BBox containing both points if they are both valid, else undefined 35 45 * 36 46 * @param a first point 37 47 * @param b second point … … 52 62 this.ymax = copy.ymax; 53 63 } 54 64 65 /** 66 * Create minimal BBox so that {@code this.bounds(ax,ay)} and {@code this.bounds(bx,by)} will both return true 67 * @param ax left or right X value (-180 .. 180) 68 * @param ay top or bottom Y value (-90 .. 90) 69 * @param bx left or right X value (-180 .. 180) 70 * @param by top or bottom Y value (-90 .. 90) 71 */ 55 72 public BBox(double ax, double ay, double bx, double by) { 73 if (Double.isNaN(ax) || Double.isNaN(ay) || Double.isNaN(bx) || Double.isNaN(by)) { 74 return; // use default which is an invalid BBox 75 } 56 76 57 77 if (ax > bx) { 58 78 xmax = ax; … … 69 89 ymax = by; 70 90 ymin = ay; 71 91 } 72 73 sanity();74 92 } 75 93 94 /** 95 * Create BBox for all nodes of the way with known coordinates. 96 * If no node has a known coordinate, an invalid BBox is returned. 97 * @param w the way 98 */ 76 99 public BBox(Way w) { 77 for (Node n : w.getNodes()) { 78 LatLon coor = n.getCoor(); 79 if (coor == null) { 80 continue; 81 } 82 add(coor); 83 } 100 w.getNodes().forEach((n) -> add(n.getCoor())); 84 101 } 85 102 103 /** 104 * Create BBox for a node. An invalid BBox is returned if the coordinates are not known. 105 * @param n the node 106 */ 86 107 public BBox(Node n) { 87 LatLon coor = n.getCoor(); 88 if (coor == null) { 89 xmin = xmax = ymin = ymax = 0; 90 } else { 91 xmin = xmax = coor.lon(); 92 ymin = ymax = coor.lat(); 93 } 108 if (n.isLatLonKnown()) 109 add(n.getCoor()); 94 110 } 95 111 96 private void sanity() { 97 if (xmin < -180.0) { 98 xmin = -180.0; 99 } 100 if (xmax > 180.0) { 101 xmax = 180.0; 102 } 103 if (ymin < -90.0) { 104 ymin = -90.0; 105 } 106 if (ymax > 90.0) { 107 ymax = 90.0; 108 } 109 } 110 112 /** 113 * Add a point to an existing BBox. Extends this bbox if necessary so that this.bounds(c) will return true 114 * if c is a valid LatLon instance. 115 * @param c a LatLon point 116 */ 111 117 public final void add(LatLon c) { 112 add(c.lon(), c.lat()); 118 if (c != null && c.isValid()) 119 add(c.lon(), c.lat()); 113 120 } 114 121 115 122 /** … … 118 125 * @param y Y coordinate 119 126 */ 120 127 public final void add(double x, double y) { 128 if (Double.isNaN(x) || Double.isNaN(y)) 129 return; 121 130 xmin = Math.min(xmin, x); 122 131 xmax = Math.max(xmax, x); 123 132 ymin = Math.min(ymin, y); 124 133 ymax = Math.max(ymax, y); 125 sanity();126 134 } 127 135 128 public final void add(BBox box) { 129 xmin = Math.min(xmin, box.xmin); 130 xmax = Math.max(xmax, box.xmax); 131 ymin = Math.min(ymin, box.ymin); 132 ymax = Math.max(ymax, box.ymax); 133 sanity(); 136 /** 137 * Extends this bbox to include the bbox other. Does nothing if other is not valid. 138 * @param other a bbox 139 */ 140 public final void add(BBox other) { 141 if (other.isValid()) { 142 xmin = Math.min(xmin, other.xmin); 143 xmax = Math.max(xmax, other.xmax); 144 ymin = Math.min(ymin, other.ymin); 145 ymax = Math.max(ymax, other.ymax); 146 } 134 147 } 135 148 149 /** 150 * Extends this bbox to include the bbox of the primitive extended by extraSpace. 151 * @param primitive an OSM primitive 152 * @param extraSpace the value to extend the primitives bbox. Unit is in LatLon degrees. 153 */ 136 154 public void addPrimitive(OsmPrimitive primitive, double extraSpace) { 137 155 BBox primBbox = primitive.getBBox(); 138 156 add(primBbox.xmin - extraSpace, primBbox.ymin - extraSpace); … … 278 296 && Double.compare(b.xmin, xmin) == 0 && Double.compare(b.ymin, ymin) == 0; 279 297 } 280 298 299 /** 300 * @return true if the bbox covers a part of the planets surface 301 * Height and width must be non-negative, but may (both) be 0. 302 */ 303 public boolean isValid() { 304 return (xmin <= xmax && ymin <= ymax); 305 } 306 307 /** 308 * @return true if the bbox covers a part of the planets surface 309 */ 310 public boolean isInWorld() { 311 return !(xmin < -180.0 || xmax > 180.0 || ymin < -90.0 || ymax > 90.0); 312 } 313 281 314 @Override 282 315 public String toString() { 283 316 return "[ x: " + xmin + " -> " + xmax + ", y: " + ymin + " -> " + ymax + " ]"; -
src/org/openstreetmap/josm/data/osm/DataSet.java
503 503 throw new DataIntegrityProblemException( 504 504 tr("Unable to add primitive {0} to the dataset because it is already included", primitive.toString())); 505 505 506 primitive.updatePosition(); // Set cached bbox for way and relation (required for reindexWay and reinexRelation to work properly) 506 allPrimitives.add(primitive); 507 primitive.setDataset(this); 508 primitive.updatePosition(); // Set cached bbox for way and relation (required for reindexWay and reindexRelation to work properly) 507 509 boolean success = false; 508 510 if (primitive instanceof Node) { 509 511 success = nodes.add((Node) primitive); … … 514 516 } 515 517 if (!success) 516 518 throw new RuntimeException("failed to add primitive: "+primitive); 517 allPrimitives.add(primitive);518 primitive.setDataset(this);519 519 firePrimitivesAdded(Collections.singletonList(primitive), false); 520 520 } finally { 521 521 endUpdate(); -
src/org/openstreetmap/josm/data/osm/Node.java
329 329 330 330 @Override 331 331 public BBox getBBox() { 332 return new BBox( this);332 return new BBox(lon, lat); 333 333 } 334 334 335 335 @Override 336 protected void addToBBox(BBox box, Set<PrimitiveId> visited) { 337 box.add(lon, lat); 338 } 339 340 @Override 336 341 public void updatePosition() { 337 342 // Do nothing 338 343 } -
src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
1416 1416 public boolean isMultipolygon() { 1417 1417 return false; 1418 1418 } 1419 1420 /** 1421 * If necessary, extend the bbox to contain this primitive 1422 * @param box a bbox instance 1423 * @param visited a set of visited members or null 1424 */ 1425 protected abstract void addToBBox(BBox box, Set<PrimitiveId> visited); 1419 1426 } -
src/org/openstreetmap/josm/data/osm/QuadBuckets.java
5 5 import java.util.Arrays; 6 6 import java.util.Collection; 7 7 import java.util.Iterator; 8 import java.util.LinkedHashSet; 8 9 import java.util.List; 9 10 import java.util.NoSuchElementException; 10 11 … … 31 32 throw new AssertionError(s); 32 33 } 33 34 34 p ublicstatic final int MAX_OBJECTS_PER_LEVEL = 16;35 private static final int MAX_OBJECTS_PER_LEVEL = 16; 35 36 36 37 static class QBLevel<T extends OsmPrimitive> { 37 38 private final int level; … … 181 182 } 182 183 183 184 boolean matches(final T o, final BBox searchBbox) { 184 if (o instanceof Node) {185 final LatLon latLon = ((Node) o).getCoor();186 // node without coords -> bbox[0,0,0,0]187 return searchBbox.bounds(latLon != null ? latLon : LatLon.ZERO);188 }189 185 return o.getBBox().intersects(searchBbox); 190 186 } 191 187 … … 393 389 private QBLevel<T> root; 394 390 private QBLevel<T> searchCache; 395 391 private int size; 392 private Collection<T> invalidBBoxPrimitives; 396 393 397 394 /** 398 395 * Constructs a new {@code QuadBuckets}. … … 404 401 @Override 405 402 public final void clear() { 406 403 root = new QBLevel<>(this); 404 invalidBBoxPrimitives = new LinkedHashSet<>(); 407 405 searchCache = null; 408 406 size = 0; 409 407 } … … 410 408 411 409 @Override 412 410 public boolean add(T n) { 413 root.add(n); 411 if (n.getBBox().isValid()) 412 root.add(n); 413 else 414 invalidBBoxPrimitives.add(n); 414 415 size++; 415 416 return true; 416 417 } … … 460 461 T t = (T) o; 461 462 searchCache = null; // Search cache might point to one of removed buckets 462 463 QBLevel<T> bucket = root.findBucket(t.getBBox()); 463 if (bucket.removeContent(t)) { 464 boolean removed = bucket.removeContent(t); 465 if (!removed) 466 removed = invalidBBoxPrimitives.remove(o); 467 if (removed) 464 468 size--; 465 return true; 466 } else 467 return false; 469 return removed; 468 470 } 469 471 470 472 @Override … … 471 473 public boolean contains(Object o) { 472 474 @SuppressWarnings("unchecked") 473 475 T t = (T) o; 476 if (!t.getBBox().isValid()) 477 return invalidBBoxPrimitives.contains(o); 474 478 QBLevel<T> bucket = root.findBucket(t.getBBox()); 475 479 return bucket != null && bucket.content != null && bucket.content.contains(t); 476 480 } … … 500 504 class QuadBucketIterator implements Iterator<T> { 501 505 private QBLevel<T> currentNode; 502 506 private int contentIndex; 507 private Iterator<T> invalidBBoxIterator = invalidBBoxPrimitives.iterator(); 508 boolean fromInvalidBBoxPrimitives; 503 509 QuadBuckets<T> qb; 504 510 505 511 final QBLevel<T> nextContentNode(QBLevel<T> q) { … … 525 531 526 532 @Override 527 533 public boolean hasNext() { 528 if (this.peek() == null) 529 return false; 534 if (this.peek() == null) { 535 fromInvalidBBoxPrimitives = true; 536 return invalidBBoxIterator.hasNext(); 537 } 530 538 return true; 531 539 } 532 540 … … 547 555 548 556 @Override 549 557 public T next() { 558 if (fromInvalidBBoxPrimitives) 559 return invalidBBoxIterator.next(); 550 560 T ret = peek(); 551 561 if (ret == null) 552 562 throw new NoSuchElementException(); … … 556 566 557 567 @Override 558 568 public void remove() { 559 // two uses 560 // 1. Back up to the thing we just returned 561 // 2. move the index back since we removed 562 // an element 563 contentIndex--; 564 T object = peek(); 565 if (currentNode.removeContent(object)) 569 if (fromInvalidBBoxPrimitives) { 570 invalidBBoxIterator.remove(); 566 571 qb.size--; 572 } else { 573 // two uses 574 // 1. Back up to the thing we just returned 575 // 2. move the index back since we removed 576 // an element 577 contentIndex--; 578 T object = peek(); 579 if (currentNode.removeContent(object)) 580 qb.size--; 581 582 } 567 583 } 568 584 } 569 585 … … 582 598 return size == 0; 583 599 } 584 600 601 /** 602 * Search for elements in the given bbox. 603 * @param searchBbox the bbox 604 * @return a list of elements, maybe empty but never null 605 */ 585 606 public List<T> search(BBox searchBbox) { 586 607 List<T> ret = new ArrayList<>(); 608 if (!searchBbox.isValid()) { 609 return ret; 610 } 587 611 // Doing this cuts down search cost on a real-life data set by about 25% 588 612 if (searchCache == null) { 589 613 searchCache = root; -
src/org/openstreetmap/josm/data/osm/Relation.java
446 446 447 447 @Override 448 448 public BBox getBBox() { 449 RelationMember[] members = this.members; 449 if (getDataSet() != null && bbox != null) 450 return new BBox(bbox); // use cached value 450 451 451 if (members.length == 0) 452 return new BBox(0, 0, 0, 0); 453 if (getDataSet() == null) 454 return calculateBBox(new HashSet<PrimitiveId>()); 455 else { 456 if (bbox == null) { 457 bbox = calculateBBox(new HashSet<PrimitiveId>()); 458 } 459 if (bbox == null) 460 return new BBox(0, 0, 0, 0); // No real members 461 else 462 return new BBox(bbox); 463 } 452 BBox box = new BBox(); 453 addToBBox(box, new HashSet<PrimitiveId>()); 454 if (getDataSet() != null) 455 bbox = box; // set cache 456 return new BBox(box); 464 457 } 465 458 466 private BBox calculateBBox(Set<PrimitiveId> visitedRelations) { 467 if (visitedRelations.contains(this)) 468 return null; 469 visitedRelations.add(this); 470 471 RelationMember[] members = this.members; 472 if (members.length == 0) 473 return null; 474 else { 475 BBox result = null; 476 for (RelationMember rm:members) { 477 BBox box = rm.isRelation() ? rm.getRelation().calculateBBox(visitedRelations) : rm.getMember().getBBox(); 478 if (box != null) { 479 if (result == null) { 480 result = box; 481 } else { 482 result.add(box); 483 } 484 } 485 } 486 return result; 459 @Override 460 protected void addToBBox(BBox box, Set<PrimitiveId> visited) { 461 for (RelationMember rm : members) { 462 if (visited.add(rm.getMember())) 463 rm.getMember().addToBBox(box, visited); 487 464 } 488 465 } 489 466 490 467 @Override 491 468 public void updatePosition() { 492 bbox = calculateBBox(new HashSet<PrimitiveId>()); 469 bbox = null; // make sure that it is recalculated 470 bbox = getBBox(); 493 471 } 494 472 495 473 @Override -
src/org/openstreetmap/josm/data/osm/Way.java
633 633 } 634 634 635 635 @Override 636 protected void addToBBox(BBox box, Set<PrimitiveId> visited) { 637 box.add(getBBox()); 638 } 639 640 @Override 636 641 public void updatePosition() { 637 642 bbox = new BBox(this); 638 643 } -
test/unit/org/openstreetmap/josm/data/osm/BBoxTest.java
1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.data.osm; 3 3 4 import static org.junit.Assert.assertFalse; 5 import static org.junit.Assert.assertTrue; 6 4 7 import org.junit.Rule; 5 8 import org.junit.Test; 9 import org.openstreetmap.josm.data.coor.LatLon; 6 10 import org.openstreetmap.josm.testutils.JOSMTestRules; 7 11 8 12 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; … … 30 34 .suppress(Warning.NONFINAL_FIELDS) 31 35 .verify(); 32 36 } 37 38 /** 39 * Test LatLon constructor which might result in invalid bbox 40 */ 41 @Test 42 public void testLatLonConstructor() { 43 LatLon latLon1 = new LatLon(10, 20); 44 LatLon latLon2 = new LatLon(20, 10); 45 BBox b1 = new BBox(latLon1, latLon2); 46 BBox b2 = new BBox(latLon2, latLon1); 47 assertTrue(b1.bounds(latLon1)); 48 assertTrue(b2.bounds(latLon1)); 49 assertTrue(b1.bounds(latLon2)); 50 assertTrue(b2.bounds(latLon2)); 51 assertTrue(b2.bounds(b1)); 52 assertTrue(b1.bounds(b2)); 53 54 // invalid latlon values 55 LatLon invalid1 = new LatLon(-190, 340); 56 BBox b3 = new BBox(invalid1, latLon1); 57 BBox b4 = new BBox(latLon1, invalid1); 58 BBox b5 = new BBox(invalid1, invalid1); 59 // what should be the result? 60 assertTrue(b3.isValid()); 61 assertTrue(b4.isValid()); 62 assertTrue(b3.bounds(latLon1)); 63 assertTrue(b4.bounds(latLon1)); 64 assertTrue(b5.isValid()); 65 assertFalse(b5.isInWorld()); 66 } 67 33 68 } -
test/unit/org/openstreetmap/josm/data/osm/NodeTest.java
1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.data.osm; 3 3 4 import static org.junit.Assert.assertEquals; 4 5 import static org.junit.Assert.assertFalse; 5 6 import static org.junit.Assert.assertNotNull; 6 7 import static org.junit.Assert.assertNull; 8 import static org.junit.Assert.assertTrue; 7 9 8 10 import org.junit.Rule; 9 11 import org.junit.Test; … … 42 44 assertNull(n.getCoor()); 43 45 assertFalse(n.isOutsideDownloadArea()); 44 46 } 47 48 /** 49 * Test BBox calculation with Node 50 */ 51 @Test 52 public void testBBox() { 53 DataSet ds = new DataSet(); 54 Node n1 = new Node(1); 55 Node n2 = new Node(2); 56 Node n3 = new Node(3); 57 Node n4 = new Node(4); 58 n1.setIncomplete(true); 59 n2.setCoor(new LatLon(10, 10)); 60 n3.setCoor(new LatLon(20, 20)); 61 n4.setCoor(new LatLon(90, 180)); 62 ds.addPrimitive(n1); 63 ds.addPrimitive(n2); 64 ds.addPrimitive(n3); 65 ds.addPrimitive(n4); 66 67 assertFalse(n1.getBBox().isValid()); 68 assertTrue(n2.getBBox().isValid()); 69 assertTrue(n3.getBBox().isValid()); 70 assertTrue(n4.getBBox().isValid()); 71 BBox box1 = n1.getBBox(); 72 box1.add(n2.getCoor()); 73 assertTrue(box1.isValid()); 74 BBox box2 = n2.getBBox(); 75 box2.add(n1.getCoor()); 76 assertTrue(box2.isValid()); 77 assertEquals(box1, box2); 78 box1.add(n3.getCoor()); 79 assertTrue(box1.isValid()); 80 assertEquals(box1.getCenter(), new LatLon(15, 15)); 81 } 45 82 } -
test/unit/org/openstreetmap/josm/data/osm/QuadBucketsTest.java
8 8 import java.util.Collection; 9 9 import java.util.Iterator; 10 10 import java.util.List; 11 import java.util.Random; 11 12 12 13 import org.fest.reflect.core.Reflection; 13 14 import org.fest.reflect.reference.TypeRef; … … 174 175 Assert.assertEquals(count, qbWays.size()); 175 176 } 176 177 Assert.assertEquals(0, qbWays.size()); 178 177 179 } 180 181 /** 182 * Add more data so that quad buckets tree has a few leaves 183 */ 184 @Test 185 public void testSplitsWithIncompleteData() { 186 DataSet ds = new DataSet(); 187 long nodeId = 1; 188 long wayId = 1; 189 final int NUM_COMPLETE_WAYS = 300; 190 final int NUM_INCOMPLETE_WAYS = 10; 191 final int NUM_NODES_PER_WAY = 20; 192 final int NUM_INCOMPLETE_NODES = 10; 193 194 // force splits in quad buckets 195 Random random = new Random(31); 196 for (int i = 0; i < NUM_COMPLETE_WAYS; i++) { 197 Way w = new Way(wayId++); 198 List<Node> nodes = new ArrayList<>(); 199 double center = random.nextDouble() * 10; 200 for (int j = 0; j < NUM_NODES_PER_WAY; j++) { 201 Node n = new Node(nodeId++); 202 double lat = random.nextDouble() * 0.001; 203 double lon = random.nextDouble() * 0.001; 204 n.setCoor(new LatLon(center + lat, center + lon)); 205 nodes.add(n); 206 ds.addPrimitive(n); 207 } 208 w.setNodes(nodes); 209 ds.addPrimitive(w); 210 } 211 Assert.assertEquals(NUM_COMPLETE_WAYS, ds.getWays().size()); 212 Assert.assertEquals(NUM_COMPLETE_WAYS * NUM_NODES_PER_WAY, ds.getNodes().size()); 213 214 // add some incomplete nodes 215 List<Node> incompleteNodes = new ArrayList<>(); 216 for (int i = 0; i < NUM_INCOMPLETE_NODES; i++) { 217 Node n = new Node(nodeId++); 218 incompleteNodes.add(n); 219 n.setIncomplete(true); 220 ds.addPrimitive(n); 221 } 222 Assert.assertEquals(NUM_COMPLETE_WAYS * NUM_NODES_PER_WAY + NUM_INCOMPLETE_NODES, ds.getNodes().size()); 223 // add some incomplete ways 224 List<Way> incompleteWays = new ArrayList<>(); 225 for (int i = 0; i < NUM_INCOMPLETE_WAYS; i++) { 226 Way w = new Way(wayId++); 227 incompleteWays.add(w); 228 w.setIncomplete(true); 229 ds.addPrimitive(w); 230 } 231 Assert.assertEquals(NUM_COMPLETE_WAYS + NUM_INCOMPLETE_WAYS, ds.getWays().size()); 232 233 BBox planet = new BBox(-180, -90, 180, 90); 234 // incomplete ways should not be found with search 235 Assert.assertEquals(NUM_COMPLETE_WAYS, ds.searchWays(planet).size()); 236 // incomplete ways are only retrieved via iterator or object reference 237 for (Way w : incompleteWays) { 238 Assert.assertTrue(ds.getWays().contains(w)); 239 } 240 241 QuadBuckets<Way> qb = new QuadBuckets<>(); 242 qb.addAll(ds.getWays()); 243 int count = qb.size(); 244 Assert.assertEquals(count, ds.getWays().size()); 245 Iterator<Way> iter = qb.iterator(); 246 while (iter.hasNext()) { 247 iter.next(); 248 iter.remove(); 249 count--; 250 Assert.assertEquals(count, qb.size()); 251 } 252 Assert.assertEquals(0, qb.size()); 253 } 178 254 } -
test/unit/org/openstreetmap/josm/data/osm/RelationTest.java
75 75 w1.addNode(n3); 76 76 Assert.assertEquals(w1.getBBox(), r1.getBBox()); 77 77 Assert.assertEquals(w1.getBBox(), r2.getBBox()); 78 79 // create incomplete node and add it to the relation, this must not change the bbox 80 BBox oldBBox = r2.getBBox(); 81 Node n4 = new Node(); 82 n4.setIncomplete(true); 83 ds.addPrimitive(n4); 84 r2.addMember(new RelationMember("", n4)); 85 86 Assert.assertEquals(oldBBox, r2.getBBox()); 78 87 } 79 88 80 89 @Test -
test/unit/org/openstreetmap/josm/data/osm/WayTest.java
1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.data.osm; 3 4 import static org.junit.Assert.assertEquals; 5 import static org.junit.Assert.assertFalse; 6 import static org.junit.Assert.assertTrue; 7 8 import java.util.Arrays; 9 10 import org.junit.BeforeClass; 11 import org.junit.Test; 12 import org.openstreetmap.josm.JOSMFixture; 13 import org.openstreetmap.josm.data.coor.LatLon; 14 15 /** 16 * Unit tests of the {@code Node} class. 17 */ 18 public class WayTest { 19 20 /** 21 * Setup test. 22 */ 23 @BeforeClass 24 public static void setUpBeforeClass() { 25 JOSMFixture.createUnitTestFixture().init(); 26 } 27 28 /** 29 * Test BBox calculation with Way 30 */ 31 @Test 32 public void testBBox() { 33 DataSet ds = new DataSet(); 34 Node n1 = new Node(1); 35 Node n2 = new Node(2); 36 Node n3 = new Node(3); 37 Node n4 = new Node(4); 38 n1.setIncomplete(true); 39 n2.setCoor(new LatLon(10, 10)); 40 n3.setCoor(new LatLon(20, 20)); 41 n4.setCoor(new LatLon(90, 180)); 42 ds.addPrimitive(n1); 43 ds.addPrimitive(n2); 44 ds.addPrimitive(n3); 45 ds.addPrimitive(n4); 46 Way way = new Way(1); 47 assertFalse(way.getBBox().isValid()); 48 way.setNodes(Arrays.asList(n1)); 49 assertFalse(way.getBBox().isValid()); 50 way.setNodes(Arrays.asList(n2)); 51 assertTrue(way.getBBox().isValid()); 52 way.setNodes(Arrays.asList(n1, n2)); 53 assertTrue(way.getBBox().isValid()); 54 assertEquals(way.getBBox(), new BBox(10, 10)); 55 } 56 }