Ticket #13361: 13361_v3.patch
File 13361_v3.patch, 26.6 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 { 16 private double xmin; 17 private double xmax; 18 private double ymin; 19 private double ymax; 13 20 14 private double xmin = Double.POSITIVE_INFINITY; 15 private double xmax = Double.NEGATIVE_INFINITY; 16 private double ymin = Double.POSITIVE_INFINITY; 17 private double ymax = Double.NEGATIVE_INFINITY; 21 /** 22 * Constructs a new (invalid) BBox 23 */ 24 public BBox() { 25 setInvalid(); 26 } 18 27 19 28 /** 20 29 * Constructs a new {@code BBox} defined by a single point. … … 24 33 * @since 6203 25 34 */ 26 35 public BBox(final double x, final double y) { 27 xmax = xmin = x; 28 ymax = ymin = y; 29 sanity(); 36 if (Double.isNaN(x) || Double.isNaN(y)) { 37 setInvalid(); 38 } else { 39 xmin = x; 40 ymin = y; 41 xmax = x; 42 ymax = y; 43 sanity(); 44 } 30 45 } 31 46 32 47 /** 33 48 * Constructs a new {@code BBox} defined by points <code>a</code> and <code>b</code>. 34 * Result is minimal BBox containing both points .49 * Result is minimal BBox containing both points if they are both valid, else undefined 35 50 * 36 51 * @param a first point 37 52 * @param b second point … … 52 67 this.ymax = copy.ymax; 53 68 } 54 69 70 /** 71 * Create minimal BBox so that {@code this.bounds(ax,ay)} and {@code this.bounds(bx,by)} will both return true 72 * @param ax left or right X value (-180 .. 180) 73 * @param ay top or bottom Y value (-90 .. 90) 74 * @param bx left or right X value (-180 .. 180) 75 * @param by top or bottom Y value (-90 .. 90) 76 */ 55 77 public BBox(double ax, double ay, double bx, double by) { 78 if (Double.isNaN(ax) || Double.isNaN(ay) || Double.isNaN(bx) || Double.isNaN(by)) { 79 setInvalid(); 80 return; // use default which is an invalid BBox 81 } 56 82 57 83 if (ax > bx) { 58 84 xmax = ax; … … 69 95 ymax = by; 70 96 ymin = ay; 71 97 } 72 73 98 sanity(); 74 99 } 75 100 101 /** 102 * Create BBox for all nodes of the way with known coordinates. 103 * If no node has a known coordinate, an invalid BBox is returned. 104 * @param w the way 105 */ 76 106 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 } 107 setInvalid(); 108 w.getNodes().forEach((n) -> add(n.getCoor())); 84 109 } 85 110 111 /** 112 * Create BBox for a node. An invalid BBox is returned if the coordinates are not known. 113 * @param n the node 114 */ 86 115 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 } 116 if (n.isLatLonKnown()) 117 add(n.getCoor()); 118 else 119 setInvalid(); 94 120 } 95 121 122 private void setInvalid() { 123 xmin = Double.POSITIVE_INFINITY; 124 xmax = Double.NEGATIVE_INFINITY; 125 ymin = Double.POSITIVE_INFINITY; 126 ymax = Double.NEGATIVE_INFINITY; 127 } 128 96 129 private void sanity() { 97 130 if (xmin < -180.0) { 98 131 xmin = -180.0; … … 108 141 } 109 142 } 110 143 144 /** 145 * Add a point to an existing BBox. Extends this bbox if necessary so that this.bounds(c) will return true 146 * if c is a valid LatLon instance. 147 * @param c a LatLon point 148 */ 111 149 public final void add(LatLon c) { 112 add(c.lon(), c.lat()); 150 if (c != null && c.isValid()) 151 add(c.lon(), c.lat()); 113 152 } 114 153 115 154 /** … … 118 157 * @param y Y coordinate 119 158 */ 120 159 public final void add(double x, double y) { 160 if (Double.isNaN(x) || Double.isNaN(y)) 161 return; 121 162 xmin = Math.min(xmin, x); 122 163 xmax = Math.max(xmax, x); 123 164 ymin = Math.min(ymin, y); … … 125 166 sanity(); 126 167 } 127 168 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(); 169 /** 170 * Extends this bbox to include the bbox other. Does nothing if other is not valid. 171 * @param other a bbox 172 */ 173 public final void add(BBox other) { 174 if (other.isValid()) { 175 xmin = Math.min(xmin, other.xmin); 176 xmax = Math.max(xmax, other.xmax); 177 ymin = Math.min(ymin, other.ymin); 178 ymax = Math.max(ymax, other.ymax); 179 sanity(); 180 } 134 181 } 135 182 183 /** 184 * Extends this bbox to include the bbox of the primitive extended by extraSpace. 185 * @param primitive an OSM primitive 186 * @param extraSpace the value to extend the primitives bbox. Unit is in LatLon degrees. 187 */ 136 188 public void addPrimitive(OsmPrimitive primitive, double extraSpace) { 137 189 BBox primBbox = primitive.getBBox(); 138 190 add(primBbox.xmin - extraSpace, primBbox.ymin - extraSpace); … … 278 330 && Double.compare(b.xmin, xmin) == 0 && Double.compare(b.ymin, ymin) == 0; 279 331 } 280 332 333 /** 334 * @return true if the bbox covers a part of the planets surface 335 * Height and width must be non-negative, but may (both) be 0. 336 */ 337 public boolean isValid() { 338 return (xmin <= xmax && ymin <= ymax); 339 } 340 341 /** 342 * @return true if the bbox covers a part of the planets surface 343 */ 344 public boolean isInWorld() { 345 return !(xmin < -180.0 || xmax > 180.0 || ymin < -90.0 || ymax > 90.0); 346 } 347 281 348 @Override 282 349 public String toString() { 283 350 return "[ x: " + xmin + " -> " + xmax + ", y: " + ymin + " -> " + ymax + " ]"; -
src/org/openstreetmap/josm/data/osm/DataSet.java
508 508 throw new DataIntegrityProblemException( 509 509 tr("Unable to add primitive {0} to the dataset because it is already included", primitive.toString())); 510 510 511 primitive.updatePosition(); // Set cached bbox for way and relation (required for reindexWay and reinexRelation to work properly) 511 allPrimitives.add(primitive); 512 primitive.setDataset(this); 513 primitive.updatePosition(); // Set cached bbox for way and relation (required for reindexWay and reindexRelation to work properly) 512 514 boolean success = false; 513 515 if (primitive instanceof Node) { 514 516 success = nodes.add((Node) primitive); … … 519 521 } 520 522 if (!success) 521 523 throw new RuntimeException("failed to add primitive: "+primitive); 522 allPrimitives.add(primitive);523 primitive.setDataset(this);524 524 firePrimitivesAdded(Collections.singletonList(primitive), false); 525 525 } finally { 526 526 endUpdate(); -
src/org/openstreetmap/josm/data/osm/Node.java
325 325 326 326 @Override 327 327 public BBox getBBox() { 328 return new BBox( this);328 return new BBox(lon, lat); 329 329 } 330 330 331 331 @Override 332 protected void addToBBox(BBox box, Set<PrimitiveId> visited) { 333 box.add(lon, lat); 334 } 335 336 @Override 332 337 public void updatePosition() { 333 338 // Do nothing 334 339 } … … 408 413 return !isNewOrUndeleted() && getDataSet() != null && getDataSet().getDataSourceArea() != null 409 414 && getCoor() != null && !getCoor().isIn(getDataSet().getDataSourceArea()); 410 415 } 416 411 417 } -
src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
1481 1481 public boolean isMultipolygon() { 1482 1482 return false; 1483 1483 } 1484 1485 /** 1486 * If necessary, extend the bbox to contain this primitive 1487 * @param box a bbox instance 1488 * @param visited a set of visited members or null 1489 */ 1490 protected abstract void addToBBox(BBox box, Set<PrimitiveId> visited); 1484 1491 } -
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 } … … 501 505 private QBLevel<T> currentNode; 502 506 private int contentIndex; 503 507 private int iteratedOver; 508 private Iterator<T> invalidBBoxIterator = invalidBBoxPrimitives.iterator(); 509 boolean fromInvalidBBoxPrimitives; 504 510 QuadBuckets<T> qb; 505 511 506 512 final QBLevel<T> nextContentNode(QBLevel<T> q) { … … 527 533 528 534 @Override 529 535 public boolean hasNext() { 530 if (this.peek() == null) 531 return false; 536 if (this.peek() == null) { 537 fromInvalidBBoxPrimitives = true; 538 return invalidBBoxIterator.hasNext(); 539 } 532 540 return true; 533 541 } 534 542 … … 549 557 550 558 @Override 551 559 public T next() { 560 if (fromInvalidBBoxPrimitives) 561 return invalidBBoxIterator.next(); 552 562 T ret = peek(); 553 563 if (ret == null) 554 564 throw new NoSuchElementException(); … … 559 569 560 570 @Override 561 571 public void remove() { 562 // two uses 563 // 1. Back up to the thing we just returned 564 // 2. move the index back since we removed 565 // an element 566 contentIndex--; 567 T object = peek(); 568 if (currentNode.removeContent(object)) 572 if (fromInvalidBBoxPrimitives) { 573 invalidBBoxIterator.remove(); 569 574 qb.size--; 575 } else { 576 // two uses 577 // 1. Back up to the thing we just returned 578 // 2. move the index back since we removed 579 // an element 580 contentIndex--; 581 T object = peek(); 582 if (currentNode.removeContent(object)) 583 qb.size--; 584 585 } 570 586 } 571 587 } 572 588 … … 585 601 return size == 0; 586 602 } 587 603 604 /** 605 * Search for elements in the given bbox. 606 * @param searchBbox the bbox 607 * @return a list of elements, maybe empty but never null 608 */ 588 609 public List<T> search(BBox searchBbox) { 589 610 List<T> ret = new ArrayList<>(); 611 if (!searchBbox.isValid()) { 612 return ret; 613 } 590 614 // Doing this cuts down search cost on a real-life data set by about 25% 591 615 if (searchCache == null) { 592 616 searchCache = root; -
src/org/openstreetmap/josm/data/osm/Relation.java
427 427 428 428 @Override 429 429 public BBox getBBox() { 430 RelationMember[] members = this.members; 430 if (getDataSet() != null && bbox != null) 431 return new BBox(bbox); // use cached value 431 432 432 if (members.length == 0) 433 return new BBox(0, 0, 0, 0); 434 if (getDataSet() == null) 435 return calculateBBox(new HashSet<PrimitiveId>()); 436 else { 437 if (bbox == null) { 438 bbox = calculateBBox(new HashSet<PrimitiveId>()); 439 } 440 if (bbox == null) 441 return new BBox(0, 0, 0, 0); // No real members 442 else 443 return new BBox(bbox); 444 } 433 BBox box = new BBox(); 434 addToBBox(box, new HashSet<PrimitiveId>()); 435 if (getDataSet() != null) 436 bbox = box; // set cache 437 return new BBox(box); 445 438 } 446 439 447 private BBox calculateBBox(Set<PrimitiveId> visitedRelations) { 448 if (visitedRelations.contains(this)) 449 return null; 450 visitedRelations.add(this); 451 452 RelationMember[] members = this.members; 453 if (members.length == 0) 454 return null; 455 else { 456 BBox result = null; 457 for (RelationMember rm:members) { 458 BBox box = rm.isRelation() ? rm.getRelation().calculateBBox(visitedRelations) : rm.getMember().getBBox(); 459 if (box != null) { 460 if (result == null) { 461 result = box; 462 } else { 463 result.add(box); 464 } 465 } 466 } 467 return result; 440 @Override 441 protected void addToBBox(BBox box, Set<PrimitiveId> visited) { 442 for (RelationMember rm : members) { 443 if (visited.add(rm.getMember())) 444 rm.getMember().addToBBox(box, visited); 468 445 } 469 446 } 470 447 471 448 @Override 472 449 public void updatePosition() { 473 bbox = calculateBBox(new HashSet<PrimitiveId>()); 450 bbox = null; // make sure that it is recalculated 451 bbox = getBBox(); 474 452 } 475 453 476 454 @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.Before; 5 8 import org.junit.Test; 6 9 import org.openstreetmap.josm.JOSMFixture; 10 import org.openstreetmap.josm.data.coor.LatLon; 7 11 8 12 import nl.jqno.equalsverifier.EqualsVerifier; 9 13 import nl.jqno.equalsverifier.Warning; 10 11 14 /** 12 15 * Unit tests for class {@link BBox}. 13 16 */ … … 30 33 .suppress(Warning.NONFINAL_FIELDS) 31 34 .verify(); 32 35 } 36 37 @Test 38 public void testLatLonConstructor() { 39 LatLon latLon1 = new LatLon(10, 20); 40 LatLon latLon2 = new LatLon(20, 10); 41 BBox b1 = new BBox(latLon1, latLon2); 42 BBox b2 = new BBox(latLon2, latLon1); 43 assertTrue(b1.bounds(latLon1)); 44 assertTrue(b2.bounds(latLon1)); 45 assertTrue(b1.bounds(latLon2)); 46 assertTrue(b2.bounds(latLon2)); 47 assertTrue(b2.bounds(b1)); 48 assertTrue(b1.bounds(b2)); 49 50 // invalid latlon values 51 LatLon invalid1 = new LatLon(-190, 340); 52 BBox b3 = new BBox(invalid1, latLon1); 53 BBox b4 = new BBox(latLon1, invalid1); 54 BBox b5 = new BBox(invalid1, invalid1); 55 // what should be the result? 56 assertTrue(b3.isValid()); 57 assertTrue(b4.isValid()); 58 assertTrue(b3.bounds(latLon1)); 59 assertTrue(b4.bounds(latLon1)); 60 assertFalse(b5.isValid()); 61 } 62 33 63 } -
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.BeforeClass; 9 11 import org.junit.Test; … … 41 43 assertNull(n.getCoor()); 42 44 assertFalse(n.isOutsideDownloadArea()); 43 45 } 46 47 /** 48 * Test BBox calculation with Node 49 */ 50 @Test 51 public void testBBox() { 52 DataSet ds = new DataSet(); 53 Node n1 = new Node(1); 54 Node n2 = new Node(2); 55 Node n3 = new Node(3); 56 Node n4 = new Node(4); 57 n1.setIncomplete(true); 58 n2.setCoor(new LatLon(10, 10)); 59 n3.setCoor(new LatLon(20, 20)); 60 n4.setCoor(new LatLon(90, 180)); 61 ds.addPrimitive(n1); 62 ds.addPrimitive(n2); 63 ds.addPrimitive(n3); 64 ds.addPrimitive(n4); 65 66 assertFalse(n1.getBBox().isValid()); 67 assertTrue(n2.getBBox().isValid()); 68 assertTrue(n3.getBBox().isValid()); 69 assertTrue(n4.getBBox().isValid()); 70 BBox box1 = n1.getBBox(); 71 box1.add(n2.getCoor()); 72 assertTrue(box1.isValid()); 73 BBox box2 = n2.getBBox(); 74 box2.add(n1.getCoor()); 75 assertTrue(box2.isValid()); 76 assertEquals(box1, box2); 77 box1.add(n3.getCoor()); 78 assertTrue(box1.isValid()); 79 assertEquals(box1.getCenter(), new LatLon(15, 15)); 80 } 44 81 } -
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; … … 173 174 Assert.assertEquals(count, qbWays.size()); 174 175 } 175 176 Assert.assertEquals(0, qbWays.size()); 177 176 178 } 179 180 /** 181 * Add more data so that quad buckets tree has a few leaves 182 */ 183 @Test 184 public void testSplitsWithIncompleteData() { 185 DataSet ds = new DataSet(); 186 long nodeId = 1; 187 long wayId = 1; 188 final int NUM_COMPLETE_WAYS = 300; 189 final int NUM_INCOMPLETE_WAYS = 10; 190 final int NUM_NODES_PER_WAY = 20; 191 final int NUM_INCOMPLETE_NODES = 10; 192 193 // force splits in quad buckets 194 Random random = new Random(31); 195 for (int i = 0; i < NUM_COMPLETE_WAYS; i++) { 196 Way w = new Way(wayId++); 197 List<Node> nodes = new ArrayList<>(); 198 double center = random.nextDouble() * 10; 199 for (int j = 0; j < NUM_NODES_PER_WAY; j++) { 200 Node n = new Node(nodeId++); 201 double lat = random.nextDouble() * 0.001; 202 double lon = random.nextDouble() * 0.001; 203 n.setCoor(new LatLon(center + lat, center + lon)); 204 nodes.add(n); 205 ds.addPrimitive(n); 206 } 207 w.setNodes(nodes); 208 ds.addPrimitive(w); 209 } 210 Assert.assertEquals(NUM_COMPLETE_WAYS, ds.getWays().size()); 211 Assert.assertEquals(NUM_COMPLETE_WAYS * NUM_NODES_PER_WAY, ds.getNodes().size()); 212 213 // add some incomplete nodes 214 List<Node> incompleteNodes = new ArrayList<>(); 215 for (int i = 0; i < NUM_INCOMPLETE_NODES; i++) { 216 Node n = new Node(nodeId++); 217 incompleteNodes.add(n); 218 n.setIncomplete(true); 219 ds.addPrimitive(n); 220 } 221 Assert.assertEquals(NUM_COMPLETE_WAYS * NUM_NODES_PER_WAY + NUM_INCOMPLETE_NODES, ds.getNodes().size()); 222 // add some incomplete ways 223 List<Way> incompleteWays = new ArrayList<>(); 224 for (int i = 0; i < NUM_INCOMPLETE_WAYS; i++) { 225 Way w = new Way(wayId++); 226 incompleteWays.add(w); 227 w.setIncomplete(true); 228 ds.addPrimitive(w); 229 } 230 Assert.assertEquals(NUM_COMPLETE_WAYS + NUM_INCOMPLETE_WAYS, ds.getWays().size()); 231 232 BBox planet = new BBox(-180, -90, 180, 90); 233 // incomplete ways should not be found with search 234 Assert.assertEquals(NUM_COMPLETE_WAYS, ds.searchWays(planet).size()); 235 // incomplete ways are only retrieved via iterator or object reference 236 for (Way w : incompleteWays) { 237 Assert.assertTrue(ds.getWays().contains(w)); 238 } 239 240 QuadBuckets<Way> qb = new QuadBuckets<>(); 241 qb.addAll(ds.getWays()); 242 int count = qb.size(); 243 Assert.assertEquals(count, ds.getWays().size()); 244 Iterator<Way> iter = qb.iterator(); 245 while (iter.hasNext()) { 246 iter.next(); 247 iter.remove(); 248 count--; 249 Assert.assertEquals(count, qb.size()); 250 } 251 Assert.assertEquals(0, qb.size()); 252 } 177 253 } -
test/unit/org/openstreetmap/josm/data/osm/RelationTest.java
74 74 w1.addNode(n3); 75 75 Assert.assertEquals(w1.getBBox(), r1.getBBox()); 76 76 Assert.assertEquals(w1.getBBox(), r2.getBBox()); 77 78 // create incomplete node and add it to the relation, this must not change the bbox 79 BBox oldBBox = r2.getBBox(); 80 Node n4 = new Node(); 81 n4.setIncomplete(true); 82 ds.addPrimitive(n4); 83 r2.addMember(new RelationMember("", n4)); 84 85 Assert.assertEquals(oldBBox, r2.getBBox()); 77 86 } 78 87 79 88 @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 }