diff options
| -rw-r--r-- | main/src/cgeo/geocaching/connector/gc/Tile.java | 86 | ||||
| -rw-r--r-- | main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java | 33 |
2 files changed, 119 insertions, 0 deletions
diff --git a/main/src/cgeo/geocaching/connector/gc/Tile.java b/main/src/cgeo/geocaching/connector/gc/Tile.java new file mode 100644 index 0000000..f036f59 --- /dev/null +++ b/main/src/cgeo/geocaching/connector/gc/Tile.java @@ -0,0 +1,86 @@ +package cgeo.geocaching.connector.gc; + +import cgeo.geocaching.geopoint.Geopoint; + +/** + * All about tiles. + * + * @author blafoo + * + * @see http://msdn.microsoft.com/en-us/library/bb259689.aspx + * @see http + * ://svn.openstreetmap.org/applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/OsmMercator.java + */ +public class Tile { + + public static final int TILE_SIZE = 256; + + private final int tileX; + private final int tileY; + private final int zoomlevel; + private final int numberOfTiles; + + public Tile(Geopoint origin, int zoomlevel) { + this.zoomlevel = zoomlevel; + numberOfTiles = 1 << zoomlevel; + tileX = calcX(origin); + tileY = calcY(origin); + } + + public Tile(int tileX, int tileY, int zoomlevel) { + this.zoomlevel = zoomlevel; + numberOfTiles = 1 << zoomlevel; + this.tileX = tileX; + this.tileY = tileY; + } + + public long getZoomlevel() { + return zoomlevel; + } + + /** + * Calculate the tile for a Geopoint based on the Spherical Mercator. + * + * @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); + } + + public int getX() { + return tileX; + } + + public int getY() { + return tileY; + } + + /** + * Calculate the tile for a Geopoint based on the Spherical Mercator. + * + * @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); + } + + /** Calculate latitude/longitude for a given x/y position in this tile. */ + public Geopoint getCoord(UTFGridPosition pos) { + + long numberOfPixels = TILE_SIZE * numberOfTiles; + + double pixX = tileX * TILE_SIZE + pos.x * 4; + double pixY = tileY * TILE_SIZE + pos.y * 4; + + pixY += -1 * numberOfPixels / 2; + double radius = numberOfPixels / (2.0 * Math.PI); + double lat = (Math.PI / 2) - (2 * Math.atan(Math.exp(-1.0 * pixY / radius))); + lat = -1 * Math.toDegrees(lat); + + double lon = ((360.0 * pixX) / numberOfPixels) - 180.0; + return new Geopoint(lat, lon); + } + +} diff --git a/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java b/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java new file mode 100644 index 0000000..cbd7696 --- /dev/null +++ b/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java @@ -0,0 +1,33 @@ +package cgeo.geocaching.connector.gc; + +/** + * Representation of a position inside an UTFGrid + * + * @author blafoo + * + */ +public final class UTFGridPosition { + + public final int x; + public final int y; + + UTFGridPosition(final int x, final int y) { + if (x > UTFGrid.GRID_MAXX) { + throw new IllegalArgumentException("x outside grid"); + } + if (y > UTFGrid.GRID_MAXY) { + throw new IllegalArgumentException("y outside grid"); + } + this.x = x; + this.y = y; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + +} |
