Files
Party-Parrots-At-Sea/src/main/java/seng302/models/map/MercatorProjection.java
T
Haoming Yin 8f93956ff1 Added methods to calculate optimal map size given a geo boundary.
- From zoom level 20 to 1, once find a size that contains the whole boundary, then the size will be used to retrieve map image from google

#story[928]
2017-05-24 00:49:03 +12:00

53 lines
2.0 KiB
Java

package seng302.models.map;
/**
* An utility class useful to convert between Geo locations and Mercator projection
* planar coordinates.
* Created by Haoming on 15/5/2017
*/
public class MercatorProjection {
private static final double MERCATOR_RANGE = 256;
private static final double pixelsPerLngDegree = MERCATOR_RANGE / 360.0;
private static final double pixelsPerLngRadian = MERCATOR_RANGE / (2 * Math.PI);
/**
* A help function keeps the value in bound between -0.9999 and 0.9999.
* @param value in bound value
* @return the value in bound
*/
private static double bound(double value) {
return Math.min(Math.max(value, -0.9999), 0.9999);
}
/**
* Projects a Geo Location (lat, lng) on a planar
* @param geo MapGeo (lat, lng) location to be projected
* @return the projection GeoPoint (x, y) on planar
*/
public static MapPoint toMapPoint(MapGeo geo) {
MapPoint point = new MapPoint(0, 0);
MapPoint origin = new MapPoint(MERCATOR_RANGE / 2.0, MERCATOR_RANGE / 2.0);
point.setX(origin.getX() + geo.getLng() * pixelsPerLngDegree);
// NOTE(appleton): Truncating to 0.9999 effectively limits latitude to
// 89.189. This is about a third of a tile past the edge of the world tile.
double sinY = bound(Math.sin(Math.toRadians(geo.getLat())));
point.setY(origin.getY() + 0.5 * Math.log((1 + sinY) / (1 - sinY)) * (-pixelsPerLngRadian));
return point;
}
/**
* Converts the planar projection (x, y) back to Geo Location (lat, lng)
* @param point MapPoint (x, y) to be converted back
* @return the original Geo location converted from the given projection point
*/
public static MapGeo toMapGeo(MapPoint point) {
MapPoint origin = new MapPoint(MERCATOR_RANGE / 2.0, MERCATOR_RANGE / 2.0);
double lng = (point.getX() - origin.getX()) / pixelsPerLngDegree;
double latRadians = (point.getY() - origin.getY()) / (-pixelsPerLngRadian);
double lat = Math.toDegrees(2 * Math.atan(Math.exp(latRadians)) - Math.PI / 2.0);
return new MapGeo(lat, lng);
}
}