Merge branch 'develop' into Story34_Sparklines

# Conflicts:
#	src/main/java/seng302/App.java
#	src/main/resources/views/RaceView.fxml
This commit is contained in:
Kusal Ekanayake
2017-05-24 18:45:01 +12:00
12 changed files with 425 additions and 29 deletions
@@ -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
@@ -138,6 +149,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
@@ -175,8 +210,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(){
@@ -202,11 +237,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();
}
}
@@ -466,6 +499,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;
}