mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Created Mercator projection to convert between Geo location and planar projection point.
- MapGeo and MapPoint encapsulate geo location and planar projection point into classes. #story[928]
This commit is contained in:
+3
-3
@@ -1,17 +1,17 @@
|
|||||||
package seng302.models.map;
|
package seng302.models.map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Bound class is to represent square territorial bounds on a map. It contains
|
* The Boundary class represents a square territorial bound on a map. It contains
|
||||||
* four extremity double values(N, E, S, W). N and S are represented as latitudes
|
* four extremity double values(N, E, S, W). N and S are represented as latitudes
|
||||||
* in radians. E and W are represented as longitudes in radians.
|
* in radians. E and W are represented as longitudes in radians.
|
||||||
*
|
*
|
||||||
* Created by Haoming on 10/5/17
|
* Created by Haoming on 10/5/17
|
||||||
*/
|
*/
|
||||||
public class Bound {
|
public class Boundary {
|
||||||
|
|
||||||
private double north, east, south, west;
|
private double north, east, south, west;
|
||||||
|
|
||||||
public Bound(double north, double east, double south, double west) {
|
public Boundary(double north, double east, double south, double west) {
|
||||||
this.north = north;
|
this.north = north;
|
||||||
this.east = east;
|
this.east = east;
|
||||||
this.south = south;
|
this.south = south;
|
||||||
@@ -2,28 +2,27 @@ package seng302.models.map;
|
|||||||
|
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
import java.lang.Math;
|
||||||
|
|
||||||
public class CanvasMap {
|
public class CanvasMap {
|
||||||
|
|
||||||
private Bound bound;
|
private Boundary bound;
|
||||||
private double width, height; // desired image size
|
private double width, height; // desired image size
|
||||||
private int zoom;
|
private int zoom;
|
||||||
|
|
||||||
|
private int MERCATOR_RANGE = 256;
|
||||||
private String KEY = "AIzaSyC-5oOShMCY5Oy_9L7guYMPUPFHDMr37wE";
|
private String KEY = "AIzaSyC-5oOShMCY5Oy_9L7guYMPUPFHDMr37wE";
|
||||||
|
|
||||||
public CanvasMap(Bound bound, double width, double height) {
|
public CanvasMap(Boundary bound, double width, double height) {
|
||||||
this.bound = bound;
|
this.bound = bound;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Image getMapImage() {
|
public Image getMapImage() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
System.out.println(getRequest());
|
System.out.println(getRequest());
|
||||||
URL url = new URL(getRequest());
|
URL url = new URL(getRequest());
|
||||||
@@ -37,13 +36,14 @@ public class CanvasMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getRequest() {
|
private String getRequest() {
|
||||||
zoom = 14;
|
zoom = 15;
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("https://maps.googleapis.com/maps/api/staticmap?");
|
sb.append("https://maps.googleapis.com/maps/api/staticmap?");
|
||||||
sb.append(String.format("center=%f,%f", bound.getCentreLat(), bound.getCentreLng()));
|
sb.append(String.format("center=%f,%f", bound.getCentreLat(), bound.getCentreLng()));
|
||||||
sb.append(String.format("&zoom=%d", zoom));
|
sb.append(String.format("&zoom=%d", zoom));
|
||||||
sb.append(String.format("&size=%.0fx%.0f&scale=2", width / 2, height / 2));
|
sb.append(String.format("&size=%.0fx%.0f&scale=2", width / 2, height / 2));
|
||||||
sb.append(String.format("&key=%s", KEY));
|
sb.append("&style=feature:all|element:labels|visibility:off"); // hide all labels on map
|
||||||
|
// sb.append(String.format("&key=%s", KEY));
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package seng302.models.map;
|
||||||
|
|
||||||
|
class MapGeo {
|
||||||
|
|
||||||
|
private double lat, lng;
|
||||||
|
|
||||||
|
MapGeo(double lat, double lng) {
|
||||||
|
this.lat = lat;
|
||||||
|
this.lng = lng;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getLat() {
|
||||||
|
return lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLat(double lat) {
|
||||||
|
this.lat = lat;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getLng() {
|
||||||
|
return lng;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLng(double lng) {
|
||||||
|
this.lng = lng;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package seng302.models.map;
|
||||||
|
|
||||||
|
class MapPoint {
|
||||||
|
|
||||||
|
private double x, y;
|
||||||
|
|
||||||
|
MapPoint(double x, double y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setX(double x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
double getY() {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setY(double y) {
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package seng302.models.map;
|
||||||
|
|
||||||
|
public class MercatorProjection {
|
||||||
|
|
||||||
|
private double MERCATOR_RANGE = 256;
|
||||||
|
private double pixelsPerLngDegree, pixelsPerLngRadian;
|
||||||
|
|
||||||
|
|
||||||
|
public MercatorProjection() {
|
||||||
|
pixelsPerLngDegree = MERCATOR_RANGE / 360.0;
|
||||||
|
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 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 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 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,7 +16,7 @@ public class TestMapController implements Initializable{
|
|||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
GraphicsContext gc = mapCanvas.getGraphicsContext2D();
|
GraphicsContext gc = mapCanvas.getGraphicsContext2D();
|
||||||
Bound bound = new Bound(57.662943, 11.848501, 57.673945, 11.824966);
|
Boundary bound = new Boundary(57.662943, 11.848501, 57.673945, 11.824966);
|
||||||
CanvasMap canvasMap = new CanvasMap(bound, 1280, 960);
|
CanvasMap canvasMap = new CanvasMap(bound, 1280, 960);
|
||||||
gc.drawImage(canvasMap.getMapImage(), 0, 0, 1280, 960);
|
gc.drawImage(canvasMap.getMapImage(), 0, 0, 1280, 960);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user