Ticket #9024: quads.diff
File quads.diff, 11.3 KB (added by , 11 years ago) |
---|
-
src/org/openstreetmap/josm/data/Bounds.java
364 364 if (b.maxLat < minLat || b.minLat > maxLat) 365 365 return false; 366 366 367 if (crosses180thMeridian() && !b.crosses180thMeridian()) {368 return intersectsLonCrossing(this, b);369 } else if (!crosses180thMeridian() && b.crosses180thMeridian()){370 return intersectsLonCrossing(b, this);371 } else if (crosses180thMeridian() && b.crosses180thMeridian()) {372 return true;373 } else {374 return b.maxLon >= minLon && b.minLon <= maxLon;367 boolean bcross = b.crosses180thMeridian(); 368 if (crosses180thMeridian()){ 369 if (bcross){ 370 return true; 371 } 372 else { 373 return intersectsLonCrossing(this, b); 374 } 375 375 } 376 else { 377 if (bcross){ 378 return intersectsLonCrossing(b, this); 379 } 380 else { 381 return b.maxLon >= minLon && b.minLon <= maxLon; 382 } 383 } 376 384 } 377 385 378 386 /** … … 389 397 * @return the bounding box to Rectangle2D.Double 390 398 */ 391 399 public Rectangle2D.Double asRect() { 392 double w = maxLon -minLon + (crosses180thMeridian() ? 360.0 : 0.0);400 double w = maxLon - minLon + (crosses180thMeridian() ? 360.0 : 0.0); 393 401 return new Rectangle2D.Double(minLon, minLat, w, maxLat-minLat); 394 402 } 395 403 -
src/org/openstreetmap/josm/data/osm/BBox.java
50 50 this.ymax = copy.ymax; 51 51 } 52 52 53 public BBox(double a_x, double a_y, double b_x, double b_y) 54 53 public BBox(double a_x, double a_y, double b_x, double b_y) { 54 55 55 if (a_x > b_x) { 56 56 xmax = a_x; 57 57 xmin = b_x; … … 59 59 xmax = b_x; 60 60 xmin = a_x; 61 61 } 62 62 63 63 if (a_y > b_y) { 64 64 ymax = a_y; 65 65 ymin = b_y; … … 67 67 ymax = b_y; 68 68 ymin = a_y; 69 69 } 70 70 71 71 sanity(); 72 72 } 73 73 … … 77 77 if (coor == null) { 78 78 continue; 79 79 } 80 add (coor);80 addNoSanity(coor.lon(), coor.lat()); 81 81 } 82 sanity(); 82 83 } 83 84 84 85 public BBox(Node n) { … … 88 89 } else { 89 90 xmin = xmax = coor.lon(); 90 91 ymin = ymax = coor.lat(); 92 sanity(); 91 93 } 92 94 } 93 95 94 private void sanity() 96 private void sanity() { 95 97 if (xmin < -180.0) { 96 98 xmin = -180.0; 97 99 } 98 if (xmax > 99 xmax = 100 if (xmax > 180.0) { 101 xmax = 180.0; 100 102 } 101 if (ymin < 102 ymin = 103 if (ymin < -90.0) { 104 ymin = -90.0; 103 105 } 104 if (ymax > 105 ymax = 106 if (ymax > 90.0) { 107 ymax = 90.0; 106 108 } 107 109 } 108 110 … … 111 113 } 112 114 113 115 /** 114 * Extends this bbox to include the point (x, y) 116 * Extends this bbox to include the point (x, y). 115 117 */ 116 118 public void add(double x, double y) { 119 addNoSanity(x, y); 120 sanity(); 121 } 122 123 private void addNoSanity(double x, double y) { 117 124 xmin = Math.min(xmin, x); 118 125 xmax = Math.max(xmax, x); 119 126 ymin = Math.min(ymin, y); 120 127 ymax = Math.max(ymax, y); 121 sanity();122 128 } 123 129 124 130 public void add(BBox box) { … … 131 137 132 138 public void addPrimitive(OsmPrimitive primitive, double extraSpace) { 133 139 BBox primBbox = primitive.getBBox(); 134 add(primBbox.xmin - extraSpace, primBbox.ymin - extraSpace); 135 add(primBbox.xmax + extraSpace, primBbox.ymax + extraSpace); 140 addNoSanity(primBbox.xmin - extraSpace, primBbox.ymin - extraSpace); 141 addNoSanity(primBbox.xmax + extraSpace, primBbox.ymax + extraSpace); 142 sanity(); 136 143 } 137 144 138 145 public double height() { 139 return ymax -ymin;146 return ymax - ymin; 140 147 } 141 148 142 149 public double width() { 143 return xmax -xmin;150 return xmax - xmin; 144 151 } 145 152 146 153 /** … … 148 155 * this bbox. 149 156 */ 150 157 public boolean bounds(BBox b) { 151 if (!(xmin <= b.xmin) || 152 !(xmax >= b.xmax) || 153 !(ymin <= b.ymin) || 154 !(ymax >= b.ymax)) 158 if (!(xmin <= b.xmin) || !(xmax >= b.xmax) || !(ymin <= b.ymin) || !(ymax >= b.ymax)) 155 159 return false; 156 160 return true; 157 161 } … … 160 164 * Tests, weather the Point c lies within the bbox. 161 165 */ 162 166 public boolean bounds(LatLon c) { 163 if ((xmin <= c.lon()) && 164 (xmax >= c.lon()) && 165 (ymin <= c.lat()) && 166 (ymax >= c.lat())) 167 if ((xmin <= c.lon()) && (xmax >= c.lon()) && (ymin <= c.lat()) && (ymax >= c.lat())) 167 168 return true; 168 169 return false; 169 170 } … … 237 238 } 238 239 239 240 public LatLon getCenter() { 240 return new LatLon( ymin + (ymax-ymin)/2.0, xmin + (xmax-xmin)/2.0);241 return new LatLon((ymin + ymax) / 2, (xmin + xmax) / 2); 241 242 } 242 243 243 244 int getIndex(final int level) { … … 259 260 return idx1; 260 261 } 261 262 263 /** 264 * 265 * 266 * @param index 267 * @return 268 */ 269 public BBox quadrant(int index) { 270 271 final double cx = (xmin + xmax) / 2; 272 final double cy = (ymin + ymax) / 2; 273 274 switch (index) { 275 case QuadBuckets.SE_INDEX: 276 return new BBox(cx, ymin, xmax, cy); 277 case QuadBuckets.SW_INDEX: 278 return new BBox(xmin, ymin, cx, cy); 279 case QuadBuckets.NE_INDEX: 280 return new BBox(cx, cy, xmax, ymax); 281 case QuadBuckets.NW_INDEX: 282 return new BBox(xmin, cy, cx, ymax); 283 } 284 285 return null; 286 } 287 262 288 @Override 263 289 public int hashCode() { 264 return (int) (ymin * xmin);290 return (int) (ymin * xmin); 265 291 } 266 292 267 293 @Override 268 294 public boolean equals(Object o) { 269 295 if (o instanceof BBox) { 270 BBox b = (BBox) o;296 BBox b = (BBox) o; 271 297 return b.xmax == xmax && b.ymax == ymax && b.xmin == xmin && b.ymin == ymin; 272 298 } else 273 299 return false; … … 275 301 276 302 @Override 277 303 public String toString() { 278 return "[ x: " + xmin + " -> " + xmax + 279 ", y: " + ymin + " -> " + ymax + " ]"; 304 return "[ x: " + xmin + " -> " + xmax + ", y: " + ymin + " -> " + ymax + " ]"; 280 305 } 281 306 282 307 public String toStringCSV(String separator) { 283 return Utils.join(separator, Arrays.asList( 284 LatLon.cDdFormatter.format(xmin), 285 LatLon.cDdFormatter.format(ymin), 286 LatLon.cDdFormatter.format(xmax), 287 LatLon.cDdFormatter.format(ymax))); 308 return Utils.join( 309 separator, 310 Arrays.asList(LatLon.cDdFormatter.format(xmin), LatLon.cDdFormatter.format(ymin), 311 LatLon.cDdFormatter.format(xmax), LatLon.cDdFormatter.format(ymax))); 288 312 } 289 313 } -
src/org/openstreetmap/josm/data/osm/QuadBuckets.java
20 20 */ 21 21 public class QuadBuckets<T extends OsmPrimitive> implements Collection<T> { 22 22 private static final boolean consistency_testing = false; 23 private static final int NW_INDEX = 1; 24 private static final int NE_INDEX = 3; 25 private static final int SE_INDEX = 2; 26 private static final int SW_INDEX = 0; 23 24 static final int NW_INDEX = 1; 25 static final int NE_INDEX = 3; 26 static final int SE_INDEX = 2; 27 static final int SW_INDEX = 0; 27 28 28 29 static void abort(String s) { 29 30 throw new AssertionError(s); … … 35 36 private final int level; 36 37 private final int index; 37 38 private final BBox bbox; 38 private final long quad;39 39 private final QBLevel<T> parent; 40 40 private boolean isLeaf = true; 41 41 … … 88 88 public QBLevel(final QuadBuckets<T> buckets) { 89 89 level = 0; 90 90 index = 0; 91 quad = 0;92 91 parent = null; 93 92 bbox = new BBox(-180, 90, 180, -90); 94 93 this.buckets = buckets; … … 99 98 this.level = parent.level + 1; 100 99 this.index = parent_index; 101 100 this.buckets = buckets; 102 103 int shift = (QuadTiling.NR_LEVELS - level) * 2; 104 long mult = 1; 105 // Java blows the big one. It seems to wrap when you shift by > 31 106 if (shift >= 30) { 107 shift -= 30; 108 mult = 1 << 30; 109 } 110 long this_quadpart = mult * (parent_index << shift); 111 this.quad = parent.quad | this_quadpart; 112 this.bbox = calculateBBox(); // calculateBBox reference quad 101 102 this.bbox = parent.bbox.quadrant(parent_index); 103 104 //System.out.println(parent_index + "\t" + parent.bbox + " -> " + bbox); 113 105 } 114 106 115 private BBox calculateBBox() {116 LatLon bottom_left = this.coor();117 double lat = bottom_left.lat() + parent.height() / 2;118 double lon = bottom_left.lon() + parent.width() / 2;119 return new BBox(bottom_left.lon(), bottom_left.lat(), lon, lat);120 }121 122 107 QBLevel<T> findBucket(BBox bbox) { 123 108 if (!hasChildren()) 124 109 return this; … … 267 252 } 268 253 269 254 QBLevel<T> nextNode() { 270 if (!this.hasChildren())271 return this.nextSibling();272 return this.firstChild();255 final QBLevel<T> firstChild = this.firstChild(); 256 257 return firstChild != null ? firstChild : nextSibling(); 273 258 } 274 259 275 260 QBLevel<T> nextContentNode() { … … 301 286 } 302 287 303 288 private void search(BBox search_bbox, List<T> result) { 304 if (! this.bbox().intersects(search_bbox))289 if (!bbox.intersects(search_bbox)) 305 290 return; 306 else if (bbox ().bounds(search_bbox)) {291 else if (bbox.bounds(search_bbox)) { 307 292 buckets.search_cache = this; 308 293 } 309 294 … … 327 312 } 328 313 } 329 314 330 public String quads() {331 return Long.toHexString(quad);332 }333 334 315 int index_of(QBLevel<T> find_this) { 335 316 QBLevel<T>[] children = getChildren(); 336 317 for (int i = 0; i < QuadTiling.TILES_PER_LEVEL; i++) { … … 352 333 return bbox; 353 334 } 354 335 355 /*356 * This gives the coordinate of the bottom-left357 * corner of the box358 */359 LatLon coor() {360 return QuadTiling.tile2LatLon(this.quad);361 }362 363 336 void remove_from_parent() { 364 337 if (parent == null) 365 338 return;