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

Last change on this file since 3530 was 3158, checked in by jttt, 14 years ago

Use simple casting instead of Math.floor(). Should do the same thing for this number range and it's much faster. Fixed return value of Storage.add()

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