aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/connector/gc/Tile.java
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo/geocaching/connector/gc/Tile.java')
-rw-r--r--main/src/cgeo/geocaching/connector/gc/Tile.java40
1 files changed, 29 insertions, 11 deletions
diff --git a/main/src/cgeo/geocaching/connector/gc/Tile.java b/main/src/cgeo/geocaching/connector/gc/Tile.java
index 003ff37..e62debb 100644
--- a/main/src/cgeo/geocaching/connector/gc/Tile.java
+++ b/main/src/cgeo/geocaching/connector/gc/Tile.java
@@ -13,30 +13,45 @@ import cgeo.geocaching.geopoint.Geopoint;
*/
public class Tile {
+ public static final double LATITUDE_MIN = -85.05112878;
+ public static final double LATITUDE_MAX = 85.05112878;
+ public static final double LONGITUDE_MIN = -180;
+ public static final double LONGITUDE_MAX = 180;
+
public static final int TILE_SIZE = 256;
public static final int ZOOMLEVEL_MAX = 18;
public static final int ZOOMLEVEL_MIN = 0;
+ public static final int[] NUMBER_OF_TILES = new int[ZOOMLEVEL_MAX - ZOOMLEVEL_MIN + 1];
+ public static final int[] NUMBER_OF_PIXELS = new int[ZOOMLEVEL_MAX - ZOOMLEVEL_MIN + 1];
+ static {
+ for (int z = ZOOMLEVEL_MIN; z <= ZOOMLEVEL_MAX; z++) {
+ NUMBER_OF_TILES[z] = 1 << z;
+ NUMBER_OF_PIXELS[z] = TILE_SIZE * 1 << z;
+ }
+ }
+
private final int tileX;
private final int tileY;
private final int zoomlevel;
- private final int numberOfTiles;
public Tile(Geopoint origin, int zoomlevel) {
+ assert zoomlevel >= ZOOMLEVEL_MIN && zoomlevel <= ZOOMLEVEL_MAX : "zoomlevel out of range";
+
this.zoomlevel = zoomlevel;
- numberOfTiles = 1 << zoomlevel;
tileX = calcX(origin);
tileY = calcY(origin);
}
public Tile(int tileX, int tileY, int zoomlevel) {
+ assert zoomlevel >= ZOOMLEVEL_MIN && zoomlevel <= ZOOMLEVEL_MAX : "zoomlevel out of range";
+
this.zoomlevel = zoomlevel;
- numberOfTiles = 1 << zoomlevel;
this.tileX = tileX;
this.tileY = tileY;
}
- public long getZoomlevel() {
+ public int getZoomlevel() {
return zoomlevel;
}
@@ -46,7 +61,7 @@ public class Tile {
* @see http://developers.cloudmade.com/projects/tiles/examples/convert-coordinates-to-tile-numbers
*/
private int calcX(final Geopoint origin) {
- return (int) ((origin.getLongitude() + 180.0) / 360.0 * numberOfTiles);
+ return (int) ((origin.getLongitude() + 180.0) / 360.0 * NUMBER_OF_TILES[this.zoomlevel]);
}
public int getX() {
@@ -63,9 +78,13 @@ public class Tile {
* @see http://developers.cloudmade.com/projects/tiles/examples/convert-coordinates-to-tile-numbers
*/
private int calcY(final Geopoint origin) {
- double lat_rad = Math.toRadians(origin.getLatitude());
- return (int) ((1 - (Math.log(Math.tan(lat_rad) + (1 / Math.cos(lat_rad))) / Math.PI)) / 2 * numberOfTiles);
+ // double latRad = Math.toRadians(origin.getLatitude());
+ // return (int) ((1 - (Math.log(Math.tan(latRad) + (1 / Math.cos(latRad))) / Math.PI)) / 2 * numberOfTiles);
+
+ // Optimization from Bing
+ double sinLatRad = Math.sin(Math.toRadians(origin.getLatitude()));
+ return (int) ((0.5 - Math.log((1 + sinLatRad) / (1 - sinLatRad)) / (4 * Math.PI)) * NUMBER_OF_TILES[this.zoomlevel]);
}
/**
@@ -77,11 +96,10 @@ public class Tile {
double pixX = tileX * TILE_SIZE + pos.x * 4;
double pixY = tileY * TILE_SIZE + pos.y * 4;
- long numberOfPixels = TILE_SIZE * numberOfTiles;
- double lon = ((360.0 * pixX) / numberOfPixels) - 180.0;
- double latRad = Math.atan(Math.sinh(Math.PI * (1 - 2 * pixY / numberOfPixels)));
- return new Geopoint(latRad * Geopoint.rad2deg, lon);
+ double lonDeg = ((360.0 * pixX) / NUMBER_OF_PIXELS[this.zoomlevel]) - 180.0;
+ double latRad = Math.atan(Math.sinh(Math.PI * (1 - 2 * pixY / NUMBER_OF_PIXELS[this.zoomlevel])));
+ return new Geopoint(Math.toDegrees(latRad), lonDeg);
}
@Override