mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
@@ -15,8 +15,10 @@ public class App extends Application {
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
Parent root = FXMLLoader.load(getClass().getResource("/views/MainView.fxml"));
|
||||
primaryStage.setTitle("RaceVision");
|
||||
primaryStage.setScene(new Scene(root));
|
||||
primaryStage.setMaximized(true);
|
||||
primaryStage.setScene(new Scene(root, 1530, 960));
|
||||
primaryStage.setMaxWidth(1530);
|
||||
primaryStage.setMaxHeight(960);
|
||||
// primaryStage.setMaximized(true);
|
||||
|
||||
primaryStage.show();
|
||||
primaryStage.setOnCloseRequest(e -> {
|
||||
@@ -64,6 +66,7 @@ public class App extends Application {
|
||||
else{
|
||||
// sr = new StreamReceiver("localhost", 4949, "RaceStream");
|
||||
sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
|
||||
// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream");
|
||||
}
|
||||
|
||||
sr.start();
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
package seng302.controllers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.fxml.FXML;
|
||||
@@ -12,22 +7,29 @@ import javafx.geometry.Point2D;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.text.Font;
|
||||
import seng302.models.BoatGroup;
|
||||
import seng302.models.Colors;
|
||||
import seng302.models.Yacht;
|
||||
import seng302.models.mark.GateMark;
|
||||
import seng302.models.mark.Mark;
|
||||
import seng302.models.mark.MarkGroup;
|
||||
import seng302.models.mark.MarkType;
|
||||
import seng302.models.mark.SingleMark;
|
||||
import seng302.models.map.Boundary;
|
||||
import seng302.models.map.CanvasMap;
|
||||
import seng302.models.mark.*;
|
||||
import seng302.models.stream.StreamParser;
|
||||
import seng302.models.stream.XMLParser;
|
||||
import seng302.models.stream.XMLParser.RaceXMLObject.Limit;
|
||||
import seng302.models.stream.XMLParser.RaceXMLObject.Participant;
|
||||
import seng302.models.stream.packets.BoatPositionPacket;
|
||||
import seng302.server.simulator.GeoUtility;
|
||||
import seng302.server.simulator.mark.Position;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.PriorityBlockingQueue;
|
||||
|
||||
/**
|
||||
* Created by ptg19 on 15/03/17.
|
||||
@@ -42,15 +44,18 @@ public class CanvasController {
|
||||
private ResizableCanvas canvas;
|
||||
private Group group;
|
||||
private GraphicsContext gc;
|
||||
private ImageView mapImage;
|
||||
|
||||
private final int MARK_SIZE = 10;
|
||||
private final int BUFFER_SIZE = 50;
|
||||
private final int PANEL_WIDTH = 1260; // it should be 1280 but, minors 40 to cancel the bias.
|
||||
private final int PANEL_HEIGHT = 960;
|
||||
private final int CANVAS_WIDTH = 720;
|
||||
private final int CANVAS_HEIGHT = 720;
|
||||
private final int LHS_BUFFER = BUFFER_SIZE;
|
||||
private final int RHS_BUFFER = BUFFER_SIZE + MARK_SIZE / 2;
|
||||
private final int RHS_BUFFER = BUFFER_SIZE;
|
||||
private final int TOP_BUFFER = BUFFER_SIZE;
|
||||
private final int BOT_BUFFER = TOP_BUFFER + MARK_SIZE / 2;
|
||||
private final int BOT_BUFFER = TOP_BUFFER;
|
||||
private boolean horizontalInversion = false;
|
||||
|
||||
private double distanceScaleFactor;
|
||||
@@ -61,6 +66,8 @@ public class CanvasController {
|
||||
private Mark maxLonPoint;
|
||||
private double referencePointX;
|
||||
private double referencePointY;
|
||||
private double metersPerPixelX;
|
||||
private double metersPerPixelY;
|
||||
|
||||
private List<MarkGroup> markGroups = new ArrayList<>();
|
||||
private List<BoatGroup> boatGroups = new ArrayList<>();
|
||||
@@ -87,6 +94,12 @@ public class CanvasController {
|
||||
canvas = new ResizableCanvas();
|
||||
group = new Group();
|
||||
|
||||
// create image view for map, bind panel size to image
|
||||
mapImage = new ImageView();
|
||||
canvasPane.getChildren().add(mapImage);
|
||||
mapImage.fitWidthProperty().bind(canvasPane.widthProperty());
|
||||
mapImage.fitHeightProperty().bind(canvasPane.heightProperty());
|
||||
|
||||
canvasPane.getChildren().add(canvas);
|
||||
canvasPane.getChildren().add(group);
|
||||
// Bind canvas size to stack pane size.
|
||||
@@ -97,11 +110,9 @@ public class CanvasController {
|
||||
public void initializeCanvas (){
|
||||
|
||||
gc = canvas.getGraphicsContext2D();
|
||||
gc.save();
|
||||
gc.setFill(Color.SKYBLUE);
|
||||
gc.fillRect(0,0, CANVAS_WIDTH, CANVAS_HEIGHT);
|
||||
gc.restore();
|
||||
gc.setGlobalAlpha(0.5);
|
||||
fitMarksToCanvas();
|
||||
drawGoogleMap();
|
||||
|
||||
|
||||
// TODO: 1/05/17 wmu16 - Change this call to now draw the marks as from the xml
|
||||
@@ -137,6 +148,30 @@ public class CanvasController {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* First find the top right and bottom left points' geo locations, then retrieve
|
||||
* map from google to display on image view. - Haoming 22/5/2017
|
||||
*/
|
||||
private void drawGoogleMap() {
|
||||
findMetersPerPixel();
|
||||
Point2D topLeftPoint = findScaledXY(maxLatPoint.getLatitude(), minLonPoint.getLongitude());
|
||||
// distance from top left extreme to panel origin (top left corner)
|
||||
double distanceFromTopLeftToOrigin = Math.sqrt(Math.pow(topLeftPoint.getX() * metersPerPixelX, 2) + Math.pow(topLeftPoint.getY() * metersPerPixelY, 2));
|
||||
// angle from top left extreme to panel origin
|
||||
double bearingFromTopLeftToOrigin = Math.toDegrees(Math.atan2(-topLeftPoint.getX(), topLeftPoint.getY()));
|
||||
// the top left extreme
|
||||
Position topLeftPos = new Position(maxLatPoint.getLatitude(), minLonPoint.getLongitude());
|
||||
Position originPos = GeoUtility.getGeoCoordinate(topLeftPos, bearingFromTopLeftToOrigin, distanceFromTopLeftToOrigin);
|
||||
|
||||
// distance from origin corner to bottom right corner of the panel
|
||||
double distanceFromOriginToBottomRight = Math.sqrt(Math.pow(PANEL_HEIGHT* metersPerPixelY, 2) + Math.pow(PANEL_WIDTH * metersPerPixelX, 2));
|
||||
double bearingFromOriginToBottomRight = Math.toDegrees(Math.atan2(PANEL_WIDTH, -PANEL_HEIGHT));
|
||||
Position bottomRightPos = GeoUtility.getGeoCoordinate(originPos, bearingFromOriginToBottomRight, distanceFromOriginToBottomRight);
|
||||
|
||||
Boundary boundary = new Boundary(originPos.getLat(), bottomRightPos.getLng(), bottomRightPos.getLat(), originPos.getLng());
|
||||
CanvasMap canvasMap = new CanvasMap(boundary);
|
||||
mapImage.setImage(canvasMap.getMapImage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds border marks to the canvas, taken from the XML file
|
||||
@@ -174,8 +209,8 @@ public class CanvasController {
|
||||
borderPoint2.getX(), borderPoint2.getY());
|
||||
xBoundaryPoints[courseLimits.size()-1] = borderPoint1.getX();
|
||||
yBoundaryPoints[courseLimits.size()-1] = borderPoint1.getY();
|
||||
gc.setFill(Color.LIGHTBLUE);
|
||||
gc.fillPolygon(xBoundaryPoints,yBoundaryPoints,yBoundaryPoints.length);
|
||||
// gc.setFill(Color.LIGHTBLUE);
|
||||
// gc.fillPolygon(xBoundaryPoints,yBoundaryPoints,yBoundaryPoints.length);
|
||||
}
|
||||
|
||||
private void updateGroups(){
|
||||
@@ -201,11 +236,9 @@ public class CanvasController {
|
||||
|
||||
private void checkForCourseChanges() {
|
||||
if (StreamParser.isNewRaceXmlReceived()){
|
||||
gc.setFill(Color.SKYBLUE);
|
||||
gc.fillRect(0,0, CANVAS_WIDTH, CANVAS_HEIGHT);
|
||||
gc.restore();
|
||||
gc.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
|
||||
drawGoogleMap();
|
||||
addRaceBorder();
|
||||
canvas.toBack();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,6 +498,27 @@ public class CanvasController {
|
||||
return new Point2D(xAxisLocation, yAxisLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the number of meters per pixel.
|
||||
*/
|
||||
private void findMetersPerPixel () {
|
||||
Point2D p1, p2;
|
||||
Mark m1, m2;
|
||||
double theta, distance, dx, dy, dHorizontal, dVertical;
|
||||
m1 = new SingleMark("m1", maxLatPoint.getLatitude(), minLonPoint.getLongitude(), 1);
|
||||
m2 = new SingleMark("m2", minLatPoint.getLatitude(), maxLonPoint.getLongitude(), 2);
|
||||
p1 = findScaledXY(m1);
|
||||
p2 = findScaledXY(m2);
|
||||
theta = Mark.calculateHeadingRad(m1, m2);
|
||||
distance = Mark.calculateDistance(m1, m2);
|
||||
dHorizontal = Math.abs(Math.sin(theta) * distance);
|
||||
dVertical = Math.abs(Math.cos(theta) * distance);
|
||||
dx = Math.abs(p1.getX() - p2.getX());
|
||||
dy = Math.abs(p1.getY() - p2.getY());
|
||||
metersPerPixelX = dHorizontal / dx;
|
||||
metersPerPixelY = dVertical / dy;
|
||||
}
|
||||
|
||||
List<BoatGroup> getBoatGroups() {
|
||||
return boatGroups;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package seng302.models.map;
|
||||
|
||||
/**
|
||||
* The Boundary class represents a rectangle territorial boundary 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 Boundary {
|
||||
|
||||
private double northLat, eastLng, southLat, westLng;
|
||||
|
||||
public Boundary(double northLat, double eastLng, double southLat, double westLng) {
|
||||
this.northLat = northLat;
|
||||
this.eastLng = eastLng;
|
||||
this.southLat = southLat;
|
||||
this.westLng = westLng;
|
||||
}
|
||||
|
||||
double getCentreLat() {
|
||||
return (northLat + southLat) / 2;
|
||||
}
|
||||
|
||||
double getCentreLng() {
|
||||
return (eastLng + westLng) / 2;
|
||||
}
|
||||
|
||||
double getNorthLat() {
|
||||
return northLat;
|
||||
}
|
||||
|
||||
double getEastLng() {
|
||||
return eastLng;
|
||||
}
|
||||
|
||||
double getSouthLat() {
|
||||
return southLat;
|
||||
}
|
||||
|
||||
double getWestLng() {
|
||||
return westLng;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package seng302.models.map;
|
||||
|
||||
import javafx.scene.image.Image;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
import java.lang.Math;
|
||||
|
||||
/**
|
||||
* CanvasMap retrieves a map image with given geo boundary from Google Map server.
|
||||
* By passing a rectangle like geo boundary, it returns a map image with the
|
||||
* highest resolution. However, due to free quote account usage limit, the maximum
|
||||
* resolution is only 1280 * 1280.
|
||||
*
|
||||
* Created by Haoming on 15/5/2017
|
||||
*/
|
||||
public class CanvasMap {
|
||||
|
||||
private Boundary boundary;
|
||||
private long width, height; // desired image size
|
||||
private int zoom;
|
||||
|
||||
private String KEY = "AIzaSyC-5oOShMCY5Oy_9L7guYMPUPFHDMr37wE";
|
||||
|
||||
public CanvasMap(Boundary boundary) {
|
||||
this.boundary = boundary;
|
||||
calculateOptimalMapSize();
|
||||
}
|
||||
|
||||
public Image getMapImage() {
|
||||
try {
|
||||
URL url = new URL(getRequest());
|
||||
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
||||
|
||||
return new Image(connection.getInputStream());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String getRequest() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("https://maps.googleapis.com/maps/api/staticmap?");
|
||||
sb.append(String.format("center=%f,%f", boundary.getCentreLat(), boundary.getCentreLng()));
|
||||
sb.append(String.format("&zoom=%d", zoom));
|
||||
sb.append(String.format("&size=%dx%d&scale=2", width, height));
|
||||
sb.append("&style=feature:all|element:labels|visibility:off"); // hide all labels on map
|
||||
// sb.append(String.format("&markers=%f,%f", boundary.getSouthLat(), boundary.getWestLng()));
|
||||
// sb.append(String.format("&key=%s", KEY));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void calculateOptimalMapSize() {
|
||||
for (int z = 20; z > 0; z--) {
|
||||
MapSize mapSize = getMapSize(z, boundary);
|
||||
zoom = z;
|
||||
width = mapSize.width;
|
||||
height = mapSize.height;
|
||||
// if map size is valid, exit the loop as we have the highest resolution
|
||||
if (mapSize.isValid()) break;
|
||||
}
|
||||
}
|
||||
|
||||
private MapSize getMapSize(int zoom, Boundary boundary) {
|
||||
double scale = Math.pow(2, zoom);
|
||||
MapGeo geoSW = new MapGeo(boundary.getSouthLat(), boundary.getWestLng());
|
||||
MapGeo geoNE = new MapGeo(boundary.getNorthLat(), boundary.getEastLng());
|
||||
MapPoint pointSW = MercatorProjection.toMapPoint(geoSW);
|
||||
MapPoint pointNE = MercatorProjection.toMapPoint(geoNE);
|
||||
return new MapSize(Math.abs(pointNE.getX() - pointSW.getX()) * scale,
|
||||
Math.abs(pointNE.getY() - pointSW.getY()) * scale);
|
||||
}
|
||||
|
||||
class MapSize {
|
||||
long width, height;
|
||||
|
||||
MapSize(double width, double height) {
|
||||
this.width = Math.round(width);
|
||||
this.height = Math.round(height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map size is valid when width and height are both less than 640 pixels
|
||||
* @return true if both dimensions are less than 640px
|
||||
*/
|
||||
boolean isValid() {
|
||||
return Math.max(width, height) <= 640;
|
||||
}
|
||||
}
|
||||
|
||||
public long getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public long getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getZoom() {
|
||||
return zoom;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package seng302.models.map;
|
||||
|
||||
/**
|
||||
* A class represent Geo location (latitude, longitude).
|
||||
* Created by Haoming on 15/5/2017
|
||||
*/
|
||||
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,31 @@
|
||||
package seng302.models.map;
|
||||
|
||||
/**
|
||||
* A class represent euclidean planar point (x, y)
|
||||
* Created by Haoming on 15/5/2017
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package seng302.models.map;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.canvas.Canvas;
|
||||
import javafx.scene.canvas.GraphicsContext;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class TestMapController implements Initializable{
|
||||
|
||||
@FXML
|
||||
private Canvas mapCanvas;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
GraphicsContext gc = mapCanvas.getGraphicsContext2D();
|
||||
Boundary bound = new Boundary(57.662943, 11.848501, 57.673945, 11.824966);
|
||||
CanvasMap canvasMap = new CanvasMap(bound);
|
||||
gc.drawImage(canvasMap.getMapImage(), 0, 0, canvasMap.getWidth(), canvasMap.getHeight());
|
||||
}
|
||||
}
|
||||
@@ -4,4 +4,4 @@
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
|
||||
<AnchorPane fx:id="canvasPane" prefHeight="960.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.controllers.CanvasController" />
|
||||
<AnchorPane fx:id="canvasPane" maxHeight="960.0" maxWidth="1280.0" prefHeight="960.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.controllers.CanvasController" />
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.scene.control.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import javafx.scene.shape.*?>
|
||||
<?import javafx.scene.text.*?>
|
||||
|
||||
<GridPane prefHeight="1080.0" prefWidth="1920.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.controllers.RaceViewController">
|
||||
<GridPane maxHeight="960.0" maxWidth="1530.0" prefHeight="960.0" prefWidth="1530.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.controllers.RaceViewController">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints maxWidth="246.0" minWidth="246.0" prefWidth="246.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="1034.0" />
|
||||
@@ -16,7 +17,7 @@
|
||||
<RowConstraints />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<AnchorPane prefHeight="200.0" prefWidth="200.0" style="-fx-background-color: #2C2c36;" GridPane.rowSpan="3">
|
||||
<AnchorPane prefHeight="960.0" prefWidth="250.0" style="-fx-background-color: #2C2c36;" GridPane.rowSpan="3">
|
||||
<children>
|
||||
<Label layoutX="11.0" layoutY="259.0" text="Team Position" textFill="WHITE" />
|
||||
<Label layoutX="13.0" layoutY="432.0" text="Settings" textFill="WHITE" />
|
||||
@@ -51,7 +52,7 @@
|
||||
<ComboBox fx:id="boatSelectionComboBox" layoutX="37.0" layoutY="664.0" prefHeight="25.0" prefWidth="170.0" promptText="Select Boat" styleClass="combo-box-base" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<AnchorPane fx:id="contentAnchorPane" prefHeight="960.0" prefWidth="1280.0" style="-fx-background-color: skyblue;" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowSpan="2147483647" GridPane.valignment="TOP">
|
||||
<AnchorPane fx:id="contentAnchorPane" maxHeight="960.0" maxWidth="1280.0" prefHeight="960.0" prefWidth="1280.0" style="-fx-background-color: skyblue;" GridPane.columnIndex="1" GridPane.halignment="LEFT" GridPane.rowSpan="2147483647" GridPane.valignment="TOP">
|
||||
<children>
|
||||
<fx:include fx:id="includedCanvas" source="CanvasView.fxml" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
</children></AnchorPane>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.scene.canvas.*?>
|
||||
|
||||
|
||||
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="960.0" prefWidth="1280.0" style="-fx-background-color: #ddd;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="seng302.models.map.TestMapController">
|
||||
<children>
|
||||
<Canvas fx:id="mapCanvas" height="960.0" width="1280.0" />
|
||||
</children>
|
||||
</Pane>
|
||||
@@ -0,0 +1,42 @@
|
||||
package seng302.models.map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Unit test for Mercator Project class.
|
||||
* Created by hyi25 on 15/05/17.
|
||||
*/
|
||||
public class MercatorProjectionTest {
|
||||
@Test
|
||||
public void toMapPoint() throws Exception {
|
||||
MapGeo geo1 = new MapGeo(12.485394, 19.38947);
|
||||
MapPoint actualPoint1 = MercatorProjection.toMapPoint(geo1);
|
||||
MapPoint expectedPoint1 = new MapPoint(141.78806755555556, 119.0503853635612);
|
||||
assertEquals(expectedPoint1.getX(), actualPoint1.getX(), 0.0001);
|
||||
assertEquals(expectedPoint1.getY(), actualPoint1.getY(), 0.0001);
|
||||
|
||||
MapGeo geo2 = new MapGeo(77.456432, -23.456462);
|
||||
MapPoint actualPoint2 = MercatorProjection.toMapPoint(geo2);
|
||||
MapPoint expectedPoint2 = new MapPoint(111.31984924444444, 38.03143323746788);
|
||||
assertEquals(expectedPoint2.getX(), actualPoint2.getX(), 0.0001);
|
||||
assertEquals(expectedPoint2.getY(), actualPoint2.getY(), 0.0001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toMapGeo() throws Exception {
|
||||
MapPoint point1 = new MapPoint(123.1234, 25.4565);
|
||||
MapGeo actualGeo1 = MercatorProjection.toMapGeo(point1);
|
||||
MapGeo expectedGeo1 = new MapGeo(80.77043127275441, -6.857718749999995);
|
||||
assertEquals(expectedGeo1.getLat(), actualGeo1.getLat(), 0.0001);
|
||||
assertEquals(expectedGeo1.getLng(), actualGeo1.getLng(), 0.0001);
|
||||
|
||||
MapPoint point2 = new MapPoint(1.235, 255.4565);
|
||||
MapGeo actualGeo2 = MercatorProjection.toMapGeo(point2);
|
||||
MapGeo expectedGeo2 = new MapGeo(-84.98475532898011, -178.26328125);
|
||||
assertEquals(expectedGeo2.getLat(), actualGeo2.getLat(), 0.0001);
|
||||
assertEquals(expectedGeo2.getLng(), actualGeo2.getLng(), 0.0001);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user