diff options
Diffstat (limited to 'main/src/cgeo/geocaching/connector/gc/Tile.java')
-rw-r--r-- | main/src/cgeo/geocaching/connector/gc/Tile.java | 40 |
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 |