- Timestamp:
- 2016-11-11T17:43:17+01:00 (8 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/data
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/coor/QuadTiling.java
r11143 r11237 75 75 * @since 6171 76 76 */ 77 public static intindex(final double lat, final double lon, final int level) {77 public static byte index(final double lat, final double lon, final int level) { 78 78 long x = lon2x(lon); 79 79 long y = lat2y(lat); 80 80 int shift = NR_LEVELS-level-1; 81 return ( int) ((x >> shift & 1) * 2 + (y >> shift & 1));81 return (byte) ((x >> shift & 1) * 2 + (y >> shift & 1)); 82 82 } 83 83 } -
trunk/src/org/openstreetmap/josm/data/osm/BBox.java
r10378 r11237 12 12 public class BBox { 13 13 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; 14 protected double xmin = Double.POSITIVE_INFINITY; 15 protected double xmax = Double.NEGATIVE_INFINITY; 16 protected double ymin = Double.POSITIVE_INFINITY; 17 protected double ymax = Double.NEGATIVE_INFINITY; 18 19 /** 20 * Constructs a new (invalid) BBox 21 */ 22 protected BBox() { } 23 18 24 19 25 /** … … 242 248 } 243 249 244 intgetIndex(final int level) {245 246 intidx1 = QuadTiling.index(ymin, xmin, level);247 248 final intidx2 = QuadTiling.index(ymin, xmax, level);250 byte getIndex(final int level) { 251 252 byte idx1 = QuadTiling.index(ymin, xmin, level); 253 254 final byte idx2 = QuadTiling.index(ymin, xmax, level); 249 255 if (idx1 == -1) idx1 = idx2; 250 256 else if (idx1 != idx2) return -1; 251 257 252 final intidx3 = QuadTiling.index(ymax, xmin, level);258 final byte idx3 = QuadTiling.index(ymax, xmin, level); 253 259 if (idx1 == -1) idx1 = idx3; 254 260 else if (idx1 != idx3) return -1; 255 261 256 final intidx4 = QuadTiling.index(ymax, xmax, level);262 final byte idx4 = QuadTiling.index(ymax, xmax, level); 257 263 if (idx1 == -1) idx1 = idx4; 258 264 else if (idx1 != idx4) return -1; -
trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java
r11143 r11237 15 15 /** 16 16 * Note: bbox of primitives added to QuadBuckets has to stay the same. In case of coordinate change, primitive must 17 * be removed and readded. 17 * be removed and re-added. 18 18 * 19 19 * This class is (no longer) thread safe. … … 23 23 public class QuadBuckets<T extends OsmPrimitive> implements Collection<T> { 24 24 private static final boolean consistency_testing = false; 25 private static final intNW_INDEX = 1;26 private static final intNE_INDEX = 3;27 private static final intSE_INDEX = 2;28 private static final intSW_INDEX = 0;25 private static final byte NW_INDEX = 1; 26 private static final byte NE_INDEX = 3; 27 private static final byte SE_INDEX = 2; 28 private static final byte SW_INDEX = 0; 29 29 30 30 static void abort(String s) { … … 32 32 } 33 33 34 public static final int MAX_OBJECTS_PER_LEVEL = 16; 35 36 static class QBLevel<T extends OsmPrimitive> { 37 private final int level; 38 private final int index; 39 private final BBox bbox; 34 private static final int MAX_OBJECTS_PER_NODE = 48; 35 36 static class QBLevel<T extends OsmPrimitive> extends BBox { 37 private final byte level; 38 private final byte index; 40 39 private final long quad; 41 40 private final QBLevel<T> parent; … … 46 45 private QBLevel<T> nw, ne, sw, se; 47 46 48 private final QuadBuckets<T> buckets; 49 50 private QBLevel<T> getChild(int index) { 47 private QBLevel<T> getChild(byte index) { 51 48 switch (index) { 52 49 case NE_INDEX: 53 50 if (ne == null) { 54 ne = new QBLevel<>(this, index , buckets);51 ne = new QBLevel<>(this, index); 55 52 } 56 53 return ne; 57 54 case NW_INDEX: 58 55 if (nw == null) { 59 nw = new QBLevel<>(this, index , buckets);56 nw = new QBLevel<>(this, index); 60 57 } 61 58 return nw; 62 59 case SE_INDEX: 63 60 if (se == null) { 64 se = new QBLevel<>(this, index , buckets);61 se = new QBLevel<>(this, index); 65 62 } 66 63 return se; 67 64 case SW_INDEX: 68 65 if (sw == null) { 69 sw = new QBLevel<>(this, index , buckets);66 sw = new QBLevel<>(this, index); 70 67 } 71 68 return sw; … … 82 79 @Override 83 80 public String toString() { 84 return super.toString() + '[' + level + "]: " + bbox();81 return super.toString() + '[' + level + "]: "; 85 82 } 86 83 87 84 /** 88 85 * Constructor for root node 89 * @param buckets quadbuckets90 86 */ 91 QBLevel(final QuadBuckets<T> buckets) { 87 QBLevel() { 88 super(-180, 90, 180, -90); 92 89 level = 0; 93 90 index = 0; 94 91 quad = 0; 95 92 parent = null; 96 bbox = new BBox(-180, 90, 180, -90); 97 this.buckets = buckets; 98 } 99 100 QBLevel(QBLevel<T> parent, int parentIndex, final QuadBuckets<T> buckets) { 93 } 94 95 QBLevel(QBLevel<T> parent, byte index) { 101 96 this.parent = parent; 102 this.level = parent.level + 1; 103 this.index = parentIndex; 104 this.buckets = buckets; 97 this.level = (byte) (parent.level + 1); 98 this.index = index; 105 99 106 100 int shift = (QuadTiling.NR_LEVELS - level) * 2; 107 long mult = 1; 108 // Java blows the big one. It seems to wrap when you shift by > 31 109 if (shift >= 30) { 110 shift -= 30; 111 mult = 1 << 30; 112 } 113 long quadpart = mult * (parentIndex << shift); 101 long quadpart = (long) index << shift; 114 102 this.quad = parent.quad | quadpart; 115 this.bbox = calculateBBox(); // calculateBBox reference quad 116 } 117 118 private BBox calculateBBox() { 119 LatLon bottomLeft = this.coor(); 120 double lat = bottomLeft.lat() + parent.height() / 2; 121 double lon = bottomLeft.lon() + parent.width() / 2; 122 return new BBox(bottomLeft.lon(), bottomLeft.lat(), lon, lat); 103 LatLon bottomLeft = QuadTiling.tile2LatLon(this.quad); 104 xmin = bottomLeft.lon(); 105 ymin = bottomLeft.lat(); 106 xmax = xmin + parent.width() / 2; 107 ymax = ymin + parent.height() / 2; 123 108 } 124 109 … … 127 112 return this; 128 113 else { 129 intidx = bbox.getIndex(level);114 byte idx = bbox.getIndex(level); 130 115 if (idx == -1) 131 116 return this; … … 163 148 164 149 for (T o : tmpcontent) { 165 intidx = o.getBBox().getIndex(level);150 byte idx = o.getBBox().getIndex(level); 166 151 if (idx == -1) { 167 152 doAddContent(o); … … 283 268 void doAdd(T o) { 284 269 if (consistency_testing) { 285 if (!matches(o, this .bbox())) {270 if (o instanceof Node && !matches(o, this)) { 286 271 o.getBBox().getIndex(level); 287 272 o.getBBox().getIndex(level - 1); 288 abort("\nobject " + o + " does not belong in node at level: " + level + " bbox: " + this.bbox());273 abort("\nobject " + o + " does not belong in node at level: " + level + " bbox: " + super.toString()); 289 274 } 290 275 } 291 276 doAddContent(o); 292 if (isLeaf() && content.size() > MAX_OBJECTS_PER_ LEVEL&& level < QuadTiling.NR_LEVELS) {277 if (isLeaf() && content.size() > MAX_OBJECTS_PER_NODE && level < QuadTiling.NR_LEVELS) { 293 278 doSplit(); 294 279 } … … 299 284 } 300 285 301 private void search(BBox searchBbox, List<T> result) { 302 if (!this. bbox().intersects(searchBbox))286 private void search(QuadBuckets<T> buckets, BBox searchBbox, List<T> result) { 287 if (!this.intersects(searchBbox)) 303 288 return; 304 else if ( bbox().bounds(searchBbox)) {289 else if (this.bounds(searchBbox)) { 305 290 buckets.searchCache = this; 306 291 } … … 313 298 314 299 if (nw != null) { 315 nw.search(searchBbox, result); 300 nw.search(buckets, searchBbox, result); 316 301 } 317 302 if (ne != null) { 318 ne.search(searchBbox, result); 303 ne.search(buckets, searchBbox, result); 319 304 } 320 305 if (se != null) { 321 se.search(searchBbox, result); 306 se.search(buckets, searchBbox, result); 322 307 } 323 308 if (sw != null) { 324 sw.search(searchBbox, result); 309 sw.search(buckets, searchBbox, result); 325 310 } 326 311 } … … 337 322 } 338 323 return -1; 339 }340 341 double width() {342 return bbox.width();343 }344 345 double height() {346 return bbox.height();347 }348 349 public BBox bbox() {350 return bbox;351 }352 353 /*354 * This gives the coordinate of the bottom-left355 * corner of the box356 */357 final LatLon coor() {358 return QuadTiling.tile2LatLon(this.quad);359 324 } 360 325 … … 404 369 @Override 405 370 public final void clear() { 406 root = new QBLevel<>( this);371 root = new QBLevel<>(); 407 372 searchCache = null; 408 373 size = 0; … … 583 548 } 584 549 550 /** 551 * Search the tree for objects in the bbox (or crossing the bbox if they are ways) 552 * @param searchBbox the bbox 553 * @return List of primitives within the bbox (or crossing the bbox if they are ways). Can be empty, but not null. 554 */ 585 555 public List<T> search(BBox searchBbox) { 586 556 List<T> ret = new ArrayList<>(); … … 590 560 } 591 561 // Walk back up the tree when the last search spot can not cover the current search 592 while (searchCache != null && !searchCache.b box().bounds(searchBbox)) {562 while (searchCache != null && !searchCache.bounds(searchBbox)) { 593 563 searchCache = searchCache.parent; 594 564 } … … 602 572 QBLevel<T> tmp = searchCache.parent; 603 573 604 searchCache.search(searchBbox, ret); 574 searchCache.search(this, searchBbox, ret); 605 575 606 576 // A way that spans this bucket may be stored in one
Note:
See TracChangeset
for help on using the changeset viewer.