source: josm/trunk/src/org/openstreetmap/josm/data/coor/QuadTiling.java@ 2422

Last change on this file since 2422 was 2422, checked in by jttt, 14 years ago
File size: 3.2 KB
Line 
1// License: GPL. Copyright 2009 by Dave Hansen, others
2package org.openstreetmap.josm.data.coor;
3
4
5public class QuadTiling
6{
7 public static int NR_LEVELS = 24;
8 public static double WORLD_PARTS = (1 << NR_LEVELS);
9
10 public static int MAX_OBJECTS_PER_LEVEL = 16;
11 // has to be a power of 2
12 public static int TILES_PER_LEVEL_SHIFT = 2;
13 public static int TILES_PER_LEVEL = 1<<TILES_PER_LEVEL_SHIFT;
14 static public int X_PARTS = 360;
15 static public int X_BIAS = -180;
16
17 static public int Y_PARTS = 180;
18 static public int Y_BIAS = -90;
19
20 public static LatLon tile2LatLon(long quad)
21 {
22 // The world is divided up into X_PARTS,Y_PARTS.
23 // The question is how far we move for each bit
24 // being set. In the case of the top level, we
25 // move half of the world.
26 double x_unit = X_PARTS/2;
27 double y_unit = Y_PARTS/2;
28 long shift = (NR_LEVELS*2)-2;
29
30 //if (debug)
31 // out("tile2xy(0x"+Long.toHexString(quad)+")");
32 double x = 0;
33 double y = 0;
34 for (int i = 0; i < NR_LEVELS; i++) {
35 long bits = (quad >> shift) & 0x3;
36 //if (debug)
37 // out("shift: " + shift + " bits: " + bits);
38 // remember x is the MSB
39 if ((bits & 0x2) != 0) {
40 x += x_unit;
41 }
42 if ((bits & 0x1) != 0) {
43 y += y_unit;
44 }
45 x_unit /= 2;
46 y_unit /= 2;
47 shift -= 2;
48 }
49 x += X_BIAS;
50 y += Y_BIAS;
51 return new LatLon(y, x);
52 }
53 static long xy2tile(long x, long y)
54 {
55 long tile = 0;
56 int i;
57 for (i = NR_LEVELS-1; i >= 0; i--)
58 {
59 long xbit = ((x >> i) & 1);
60 long ybit = ((y >> i) & 1);
61 tile <<= 2;
62 // Note that x is the MSB
63 tile |= (xbit<<1) | ybit;
64 }
65 return tile;
66 }
67 static long coorToTile(LatLon coor)
68 {
69 return quadTile(coor);
70 }
71 static long lon2x(double lon)
72 {
73 //return Math.round((lon + 180.0) * QuadBuckets.WORLD_PARTS / 360.0)-1;
74 long ret = (long)Math.floor((lon + 180.0) * WORLD_PARTS / 360.0);
75 if (ret == WORLD_PARTS) {
76 ret--;
77 }
78 return ret;
79 }
80 static long lat2y(double lat)
81 {
82 //return Math.round((lat + 90.0) * QuadBuckets.WORLD_PARTS / 180.0)-1;
83 long ret = (long)Math.floor((lat + 90.0) * WORLD_PARTS / 180.0);
84 if (ret == WORLD_PARTS) {
85 ret--;
86 }
87 return ret;
88 }
89 static public long quadTile(LatLon coor)
90 {
91 return xy2tile(lon2x(coor.lon()),
92 lat2y(coor.lat()));
93 }
94 static public int index(int level, long quad)
95 {
96 long mask = 0x00000003;
97 int total_shift = TILES_PER_LEVEL_SHIFT*(NR_LEVELS-level-1);
98 return (int)(mask & (quad >> total_shift));
99 }
100 static public int index(LatLon coor, int level)
101 {
102 // The nodes that don't return coordinates will all get
103 // stuck in a single tile. Hopefully there are not too
104 // many of them
105 if (coor == null)
106 return 0;
107 long quad = coorToTile(coor);
108 return index(level, quad);
109 }
110}
Note: See TracBrowser for help on using the repository browser.