- Timestamp:
- 2010-03-21T09:56:49+01:00 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java
r3145 r3150 51 51 System.out.print(s + " " + (float)((i+1)*100.0/total) + "% done \r"); 52 52 } 53 // 24 levels of buckets gives us bottom-level54 // buckets that are about 2 meters on a side.55 // That should do. :)56 public static int NR_LEVELS = 24;57 public static double WORLD_PARTS = (1 << NR_LEVELS);58 53 59 54 public static int MAX_OBJECTS_PER_LEVEL = 16; … … 85 80 this.parent = parent; 86 81 this.level = parent.level + 1; 87 int shift = (Quad Buckets.NR_LEVELS - level) * 2;82 int shift = (QuadTiling.NR_LEVELS - level) * 2; 88 83 long mult = 1; 89 84 // Java blows the big one. It seems to wrap when … … 110 105 LatLon top_right = new LatLon(lat, lon); 111 106 return new BBox(bottom_left, top_right); 107 } 108 109 QBLevel findBucket(BBox bbox) { 110 if (isLeaf()) 111 return this; 112 else { 113 int index = get_index(bbox, level); 114 if (index == -1) 115 return this; 116 if (children[index] == null) { 117 children[index] = new QBLevel(this, index); 118 } 119 return children[index].findBucket(bbox); 120 } 112 121 } 113 122 … … 142 151 // at the given level. If the primitive can not 143 152 // fit into a single quad at this level, return -1 144 int get_index(T o, int level) 145 { 146 if (debug) { 147 out("getting index for " + o + " at level: " + level); 148 } 153 int get_index(BBox bbox, int level) { 149 154 int index = -1; 150 for (LatLon c : o.getBBox().points()) {155 for (LatLon c : bbox.points()) { 151 156 if (debug) { 152 157 out("getting index for point: " + c); … … 163 168 out("other point index: " + another_index); 164 169 } 165 if (another_index != index) { 166 // This happens at level 0 sometimes when a way has no 167 // nodes present. 168 if (debug) { 169 out("primitive ("+o.getId()+") would have gone across two quads " 170 + another_index + "/" + index + " at level: " + level + " "); 171 } 170 if (another_index != index) 172 171 return -1; 173 }174 172 } 175 173 return index; … … 181 179 * is a dead end. 182 180 */ 183 void __split() 184 { 181 void __split() { 185 182 if (debug) { 186 183 out("splitting "+this.bbox()+" level "+level+" with " … … 194 191 List<T> tmpcontent = content; 195 192 content = null; 196 for (T o : tmpcontent) { 197 int new_index = get_index(o, level); 198 if (new_index == -1) { 199 this.__add_content(o); 200 //out("adding content to branch: " + this); 201 continue; 202 } 203 if (children == null) { 204 children = newChildren(); 205 } 206 if (children[new_index] == null) { 207 children[new_index] = new QBLevel(this, new_index); 208 } 209 QBLevel child = children[new_index]; 210 if (debug) { 211 out("putting "+o+"(q:"+Long.toHexString(QuadTiling.quadTile(o.getBBox().points().get(0)))+") into ["+new_index+"] " + child.bbox()); 212 } 213 child.add(o); 214 } 215 } 216 void split() { 217 synchronized(split_lock) { 218 __split(); 219 } 220 } 193 children = newChildren(); 194 for (T o: tmpcontent) { 195 add(o); 196 } 197 if (!hasChildren()) { 198 // All items stay at this level (get_index == 1). Create at least first child to keep the contract 199 // that at least one child always exists 200 children[0] = new QBLevel(this, 0); 201 } 202 } 203 221 204 boolean __add_content(T o) 222 205 { … … 233 216 return ret; 234 217 } 235 void __add_to_leaf(T o)236 {237 __add_content(o);238 if (content.size() > MAX_OBJECTS_PER_LEVEL) {239 if (debug) {240 out("["+level+"] deciding to split");241 }242 if (level >= NR_LEVELS-1) {243 if (debug) {244 out("can not split, but too deep: " + level + " size: " + content.size());245 }246 return;247 }248 int before_size = -1;249 if (consistency_testing) {250 before_size = this.size();251 }252 this.split();253 if (consistency_testing) {254 int after_size = this.size();255 if (before_size != after_size) {256 abort("["+level+"] split done before: " + before_size + " after: " + after_size);257 }258 }259 return;260 }261 }262 263 218 boolean matches(T o, BBox search_bbox) 264 219 { … … 461 416 return ret; 462 417 } 463 boolean add(T n) 464 {418 419 void doAdd(T o) { 465 420 if (consistency_testing) { 466 if (!matches( n, this.bbox())) {421 if (!matches(o, this.bbox())) { 467 422 out("-----------------------------"); 468 423 debug = true; 469 get_index( n, level);470 get_index( n, level-1);424 get_index(o.getBBox(), level); 425 get_index(o.getBBox(), level-1); 471 426 int nr = 0; 472 427 for (QBLevel sibling : parent.children) { 473 428 out("sibling["+ (nr++) +"]: " + sibling.bbox() + " this: " + (this==sibling)); 474 429 } 475 abort("\nobject " + n+ " does not belong in node at level: " + level + " bbox: " + this.bbox());430 abort("\nobject " + o + " does not belong in node at level: " + level + " bbox: " + this.bbox()); 476 431 } 477 432 } 478 433 synchronized (split_lock) { 479 if (isLeaf()) { 480 __add_to_leaf(n); 481 } else { 482 __add_to_branch(n); 483 } 484 } 485 return true; 486 } 487 QBLevel __add_to_branch(T n) 488 { 489 int index = get_index(n, level); 490 if (index == -1) { 491 if (debug) { 492 out("unable to get index for " + n + "at level: " + level + ", adding content to branch: " + this); 493 } 494 this.__add_content(n); 495 return this; 496 } 497 if (debug) { 498 out("[" + level + "]: " + n + 499 " index " + index + " levelquad:" + this.quads() + " level bbox:" + this.bbox()); 500 out(" put in child["+index+"]"); 501 } 502 if (children[index] == null) { 503 children[index] = new QBLevel(this, index); 504 } 505 children[index].add(n); 506 return this; 507 } 434 __add_content(o); 435 if (isLeaf() && content.size() > MAX_OBJECTS_PER_LEVEL && level < QuadTiling.NR_LEVELS) { 436 __split(); 437 } 438 } 439 } 440 441 void add(T o) { 442 synchronized (split_lock) { 443 findBucket(o.getBBox()).doAdd(o); 444 } 445 } 446 508 447 private List<T> search(BBox search_bbox) 509 448 { … … 667 606 public boolean add(T n) 668 607 { 669 if (debug) { 670 out("QuadBuckets() add: " + n + " size now: " + this.size()); 671 } 672 int before_size = -1; 673 if (consistency_testing) { 674 before_size = root.size(); 675 } 676 boolean ret; 677 // A way with no nodes will have an infinitely large 678 // bounding box. Just stash it in the root node. 679 if (!n.isUsable()) { 680 synchronized (split_lock) { 681 ret = root.__add_content(n); 682 } 683 } else { 684 ret = root.add(n); 685 } 686 if (consistency_testing) { 687 int end_size = root.size(); 688 if (ret) { 689 end_size--; 690 } 691 if (before_size != end_size) { 692 abort("size inconsistency before add: " + before_size + " after: " + end_size); 693 } 694 } 695 if (debug) { 696 out("QuadBuckets() add: " + n + " size after: " + this.size()); 697 } 698 return ret; 699 } 700 public void reindex() 701 { 702 QBLevel newroot = new QBLevel(); 703 Iterator<T> i = this.iterator(); 704 while (i.hasNext()) { 705 T o = i.next(); 706 newroot.add(o); 707 } 708 root = newroot; 608 609 root.add(n); 610 return true; 709 611 } 710 612 public void unsupported()
Note:
See TracChangeset
for help on using the changeset viewer.