mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
fcb1e5e593
- put utility classes in a package #story[1047]
56 lines
2.0 KiB
Java
56 lines
2.0 KiB
Java
package seng302.models.map;
|
|
|
|
import javafx.geometry.Point2D;
|
|
import seng302.utilities.GeoPoint;
|
|
|
|
/**
|
|
* 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 GeoPoint (lat, lng) location to be projected
|
|
* @return the projection Point2D (x, y) on planar
|
|
*/
|
|
public static Point2D toMapPoint(GeoPoint geo) {
|
|
double x, y;
|
|
Point2D origin = new Point2D(MERCATOR_RANGE / 2.0, MERCATOR_RANGE / 2.0);
|
|
x = (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())));
|
|
y = origin.getY() + 0.5 * Math.log((1 + sinY) / (1 - sinY)) * (-pixelsPerLngRadian);
|
|
return new Point2D(x, y);
|
|
}
|
|
|
|
/**
|
|
* Converts the planar projection (x, y) back to Geo Location (lat, lng)
|
|
* @param point Point2D (x, y) to be converted back
|
|
* @return the original Geo location converted from the given projection point
|
|
*/
|
|
public static GeoPoint toMapGeo(Point2D point) {
|
|
Point2D origin = new Point2D(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 GeoPoint(lat, lng);
|
|
}
|
|
}
|