diff --git a/src/main/java/seng302/models/map/Bound.java b/src/main/java/seng302/models/map/Boundary.java similarity index 78% rename from src/main/java/seng302/models/map/Bound.java rename to src/main/java/seng302/models/map/Boundary.java index aa700423..f2d1302c 100644 --- a/src/main/java/seng302/models/map/Bound.java +++ b/src/main/java/seng302/models/map/Boundary.java @@ -1,17 +1,17 @@ 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 * in radians. E and W are represented as longitudes in radians. * * Created by Haoming on 10/5/17 */ -public class Bound { +public class Boundary { 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.east = east; this.south = south; diff --git a/src/main/java/seng302/models/map/CanvasMap.java b/src/main/java/seng302/models/map/CanvasMap.java index 4a524e49..a86be90b 100644 --- a/src/main/java/seng302/models/map/CanvasMap.java +++ b/src/main/java/seng302/models/map/CanvasMap.java @@ -2,28 +2,27 @@ package seng302.models.map; import javafx.scene.image.Image; -import javax.imageio.ImageIO; import javax.net.ssl.HttpsURLConnection; -import java.awt.image.BufferedImage; -import java.io.BufferedReader; -import java.io.InputStreamReader; import java.net.URL; +import java.lang.Math; + public class CanvasMap { - private Bound bound; + private Boundary bound; private double width, height; // desired image size private int zoom; + + private int MERCATOR_RANGE = 256; 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.width = width; this.height = height; } public Image getMapImage() { - try { System.out.println(getRequest()); URL url = new URL(getRequest()); @@ -37,13 +36,14 @@ public class CanvasMap { } private String getRequest() { - zoom = 14; + zoom = 15; StringBuilder sb = new StringBuilder(); sb.append("https://maps.googleapis.com/maps/api/staticmap?"); sb.append(String.format("center=%f,%f", bound.getCentreLat(), bound.getCentreLng())); sb.append(String.format("&zoom=%d", zoom)); 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(); } } diff --git a/src/main/java/seng302/models/map/MapGeo.java b/src/main/java/seng302/models/map/MapGeo.java new file mode 100644 index 00000000..96af1dd5 --- /dev/null +++ b/src/main/java/seng302/models/map/MapGeo.java @@ -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; + } +} diff --git a/src/main/java/seng302/models/map/MapPoint.java b/src/main/java/seng302/models/map/MapPoint.java new file mode 100644 index 00000000..aa0e55d0 --- /dev/null +++ b/src/main/java/seng302/models/map/MapPoint.java @@ -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; + } +} diff --git a/src/main/java/seng302/models/map/MercatorProjection.java b/src/main/java/seng302/models/map/MercatorProjection.java new file mode 100644 index 00000000..4a442123 --- /dev/null +++ b/src/main/java/seng302/models/map/MercatorProjection.java @@ -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); + } +} diff --git a/src/main/java/seng302/models/map/TestMapController.java b/src/main/java/seng302/models/map/TestMapController.java index 720dd408..6d656231 100644 --- a/src/main/java/seng302/models/map/TestMapController.java +++ b/src/main/java/seng302/models/map/TestMapController.java @@ -16,7 +16,7 @@ public class TestMapController implements Initializable{ @Override public void initialize(URL location, ResourceBundle resources) { 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); gc.drawImage(canvasMap.getMapImage(), 0, 0, 1280, 960); }