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

Last change on this file since 2570 was 2512, checked in by stoecker, 14 years ago

i18n updated, fixed files to reduce problems when applying patches, fix #4017

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