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:
@@ -31,16 +31,16 @@ public class App extends Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (args.length > 1){
|
if (args.length > 1){
|
||||||
sr = new StreamReceiver("localhost", 8085, "RaceStream");
|
sr = new StreamReceiver("localhost", 8085, "TestThread1");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"RaceStream");
|
sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1");
|
||||||
// sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
|
// sr = new StreamReceiver("livedata.americascup.com", 4941, "TestThread1");
|
||||||
// sr = new StreamReceiver("localhost", 8085, "RaceStream");
|
// sr = new StreamReceiver("localhost", 8085, "TestThread1");
|
||||||
}
|
}
|
||||||
|
|
||||||
sr.start();
|
sr.start();
|
||||||
StreamParser streamParser = new StreamParser("StreamParser");
|
StreamParser streamParser = new StreamParser("TestThread2");
|
||||||
streamParser.start();
|
streamParser.start();
|
||||||
|
|
||||||
launch(args);
|
launch(args);
|
||||||
|
|||||||
@@ -4,25 +4,24 @@ import javafx.animation.*;
|
|||||||
import javafx.beans.property.SimpleDoubleProperty;
|
import javafx.beans.property.SimpleDoubleProperty;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.geometry.Point2D;
|
import javafx.geometry.Point2D;
|
||||||
import javafx.geometry.Point3D;
|
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
import javafx.scene.canvas.Canvas;
|
import javafx.scene.canvas.Canvas;
|
||||||
import javafx.scene.canvas.GraphicsContext;
|
import javafx.scene.canvas.GraphicsContext;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.shape.Arc;
|
|
||||||
import javafx.scene.shape.ArcType;
|
|
||||||
import javafx.scene.text.Font;
|
import javafx.scene.text.Font;
|
||||||
import seng302.models.Boat;
|
import seng302.models.Boat;
|
||||||
import seng302.models.BoatGroup;
|
import seng302.models.BoatGroup;
|
||||||
import seng302.models.Colors;
|
import seng302.models.Colors;
|
||||||
import seng302.models.RaceObject;
|
import seng302.models.RaceObject;
|
||||||
import seng302.models.mark.*;
|
import seng302.models.mark.*;
|
||||||
import seng302.models.parsers.StreamPacket;
|
|
||||||
import seng302.models.parsers.StreamParser;
|
import seng302.models.parsers.StreamParser;
|
||||||
import seng302.models.parsers.packets.BoatPositionPacket;
|
import seng302.models.parsers.packets.BoatPositionPacket;
|
||||||
|
import seng302.models.parsers.XMLParser;
|
||||||
|
import seng302.models.parsers.XMLParser.RaceXMLObject.CompoundMark;
|
||||||
|
import seng302.models.parsers.XMLParser.RaceXMLObject.Limit;
|
||||||
|
import seng302.models.mark.Mark;
|
||||||
|
|
||||||
import java.sql.Time;
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.PriorityBlockingQueue;
|
import java.util.concurrent.PriorityBlockingQueue;
|
||||||
@@ -60,6 +59,7 @@ public class CanvasController {
|
|||||||
private double referencePointY;
|
private double referencePointY;
|
||||||
private double metersToPixels;
|
private double metersToPixels;
|
||||||
private List<RaceObject> raceObjects = new ArrayList<>();
|
private List<RaceObject> raceObjects = new ArrayList<>();
|
||||||
|
private List<Mark> raceMarks = new ArrayList<>();
|
||||||
|
|
||||||
//FRAME RATE
|
//FRAME RATE
|
||||||
private static final double UPDATE_TIME = 0.016666; // 1 / 60 ie 60fps
|
private static final double UPDATE_TIME = 0.016666; // 1 / 60 ie 60fps
|
||||||
@@ -101,6 +101,9 @@ public class CanvasController {
|
|||||||
gc.fillRect(0,0, CANVAS_WIDTH, CANVAS_HEIGHT);
|
gc.fillRect(0,0, CANVAS_WIDTH, CANVAS_HEIGHT);
|
||||||
gc.restore();
|
gc.restore();
|
||||||
fitMarksToCanvas();
|
fitMarksToCanvas();
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: 1/05/17 wmu16 - Change this call to now draw the marks as from the xml
|
||||||
drawBoats();
|
drawBoats();
|
||||||
timer = new AnimationTimer() {
|
timer = new AnimationTimer() {
|
||||||
|
|
||||||
@@ -134,6 +137,94 @@ public class CanvasController {
|
|||||||
//timer.start();
|
//timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds border marks to the canvas, taken from the XML file
|
||||||
|
*
|
||||||
|
* NOTE: This is quite confusing as objects are grabbed from the XMLParser such as Mark and CompoundMark which are
|
||||||
|
* named the same as those in the model package but are, however not the same, so they do not have things such as
|
||||||
|
* a type and must be derived from the number of marks in a compound mark etc..
|
||||||
|
*/
|
||||||
|
private void addRaceBorder() {
|
||||||
|
XMLParser.RaceXMLObject raceXMLObject = StreamParser.getXmlObject().getRaceXML();
|
||||||
|
ArrayList<Limit> courseLimits = raceXMLObject.getCourseLimit();
|
||||||
|
gc.setStroke(Color.DARKRED);
|
||||||
|
gc.setLineWidth(3);
|
||||||
|
|
||||||
|
for (int i = 0; i < courseLimits.size() - 1; i++) {
|
||||||
|
Limit thisPoint1 = courseLimits.get(i);
|
||||||
|
SingleMark thisMark1 = new SingleMark("", thisPoint1.getLat(), thisPoint1.getLng(), thisPoint1.getSeqID());
|
||||||
|
Limit thisPoint2 = courseLimits.get(i+1);
|
||||||
|
SingleMark thisMark2 = new SingleMark("", thisPoint2.getLat(), thisPoint2.getLng(), thisPoint2.getSeqID());
|
||||||
|
Point2D borderPoint1 = findScaledXY(thisMark1);
|
||||||
|
Point2D borderPoint2 = findScaledXY(thisMark2);
|
||||||
|
gc.strokeLine(borderPoint1.getX(), borderPoint1.getY(),
|
||||||
|
borderPoint2.getX(), borderPoint2.getY());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Limit thisPoint1 = courseLimits.get(courseLimits.size()-1);
|
||||||
|
SingleMark thisMark1 = new SingleMark("", thisPoint1.getLat(), thisPoint1.getLng(), thisPoint1.getSeqID());
|
||||||
|
Limit thisPoint2 = courseLimits.get(0);
|
||||||
|
SingleMark thisMark2 = new SingleMark("", thisPoint2.getLat(), thisPoint2.getLng(), thisPoint2.getSeqID());
|
||||||
|
Point2D borderPoint1 = findScaledXY(thisMark1);
|
||||||
|
Point2D borderPoint2 = findScaledXY(thisMark2);
|
||||||
|
|
||||||
|
gc.strokeLine(borderPoint1.getX(), borderPoint1.getY(),
|
||||||
|
borderPoint2.getX(), borderPoint2.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the course marks to the canvas, taken from the XMl file
|
||||||
|
*
|
||||||
|
* NOTE: This is quite confusing as objects are grabbed from the XMLParser such as Mark and CompoundMark which are
|
||||||
|
* named the same as those in the model package but are, however not the same, so they do not have things such as
|
||||||
|
* a type and must be derived from the number of marks in a compound mark etc..
|
||||||
|
*/
|
||||||
|
private void addCourseMarks() {
|
||||||
|
XMLParser.RaceXMLObject raceXMLObject = StreamParser.getXmlObject().getRaceXML();
|
||||||
|
ArrayList<CompoundMark> compoundMarks = raceXMLObject.getCompoundMarks();
|
||||||
|
RaceObject markGroup;
|
||||||
|
|
||||||
|
for (CompoundMark compoundMark : compoundMarks) {
|
||||||
|
|
||||||
|
//If the compound mark has 2 marks then its a gate mark
|
||||||
|
if (compoundMark.getMarks().size() == 2) {
|
||||||
|
CompoundMark.Mark mark1 = compoundMark.getMarks().get(0);
|
||||||
|
CompoundMark.Mark mark2 = compoundMark.getMarks().get(1);
|
||||||
|
SingleMark singleMark1 = new SingleMark(mark1.getMarkName(), mark1.getTargetLat(), mark1.getTargetLng(), mark1.getSourceID());
|
||||||
|
SingleMark singleMark2 = new SingleMark(mark1.getMarkName(), mark2.getTargetLat(), mark2.getTargetLng(), mark2.getSourceID());
|
||||||
|
GateMark thisGateMark = new GateMark(compoundMark.getcMarkName(),
|
||||||
|
(compoundMark.getMarkID().equals(1)) ? MarkType.OPEN_GATE : MarkType.CLOSED_GATE,
|
||||||
|
singleMark1,
|
||||||
|
singleMark2,
|
||||||
|
singleMark1.getLatitude(),
|
||||||
|
singleMark1.getLongitude());
|
||||||
|
|
||||||
|
markGroup = new MarkGroup(thisGateMark,
|
||||||
|
findScaledXY(thisGateMark.getSingleMark1()),
|
||||||
|
findScaledXY(thisGateMark.getSingleMark2()));
|
||||||
|
|
||||||
|
raceObjects.add(markGroup);
|
||||||
|
raceMarks.add(thisGateMark);
|
||||||
|
|
||||||
|
//Otherwise its a single mark
|
||||||
|
} else {
|
||||||
|
CompoundMark.Mark singleMark = compoundMark.getMarks().get(0);
|
||||||
|
Mark thisSingleMark = new SingleMark(singleMark.getMarkName(),
|
||||||
|
singleMark.getTargetLat(),
|
||||||
|
singleMark.getTargetLng(),
|
||||||
|
singleMark.getSourceID());
|
||||||
|
|
||||||
|
markGroup = new MarkGroup(thisSingleMark, findScaledXY(thisSingleMark));
|
||||||
|
raceObjects.add(markGroup);
|
||||||
|
raceMarks.add(thisSingleMark);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateRaceObjects(){
|
private void updateRaceObjects(){
|
||||||
for (RaceObject raceObject : raceObjects) {
|
for (RaceObject raceObject : raceObjects) {
|
||||||
raceObject.updatePosition(1000 / 60);
|
raceObject.updatePosition(1000 / 60);
|
||||||
@@ -249,6 +340,7 @@ public class CanvasController {
|
|||||||
double minLonToMaxLon = scaleRaceExtremities();
|
double minLonToMaxLon = scaleRaceExtremities();
|
||||||
calculateReferencePointLocation(minLonToMaxLon);
|
calculateReferencePointLocation(minLonToMaxLon);
|
||||||
givePointsXY();
|
givePointsXY();
|
||||||
|
addRaceBorder();
|
||||||
findMetersToPixels();
|
findMetersToPixels();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,27 +350,30 @@ public class CanvasController {
|
|||||||
* marker, rightmost marker, southern most marker and northern most marker respectively.
|
* marker, rightmost marker, southern most marker and northern most marker respectively.
|
||||||
*/
|
*/
|
||||||
private void findMinMaxPoint() {
|
private void findMinMaxPoint() {
|
||||||
List<Mark> sortedPoints = new ArrayList<>();
|
List<Limit> sortedPoints = new ArrayList<>();
|
||||||
for (Mark mark : raceViewController.getRace().getCourse())
|
for (Limit limit : StreamParser.getXmlObject().getRaceXML().getCourseLimit()) {
|
||||||
{
|
sortedPoints.add(limit);
|
||||||
if (mark.getMarkType() == MarkType.SINGLE_MARK)
|
|
||||||
sortedPoints.add(mark);
|
|
||||||
else {
|
|
||||||
sortedPoints.add(((GateMark) mark).getSingleMark1());
|
|
||||||
sortedPoints.add(((GateMark) mark).getSingleMark2());
|
|
||||||
}
|
}
|
||||||
}
|
sortedPoints.sort(Comparator.comparingDouble(Limit::getLat));
|
||||||
sortedPoints.sort(Comparator.comparingDouble(Mark::getLatitude));
|
Limit minLatMark = sortedPoints.get(0);
|
||||||
minLatPoint = sortedPoints.get(0);
|
Limit maxLatMark = sortedPoints.get(sortedPoints.size()-1);
|
||||||
maxLatPoint = sortedPoints.get(sortedPoints.size()-1);
|
minLatPoint = new SingleMark(minLatMark.toString(), minLatMark.getLat(), minLatMark.getLng(), minLatMark.getSeqID());
|
||||||
|
maxLatPoint = new SingleMark(maxLatMark.toString(), maxLatMark.getLat(), maxLatMark.getLng(), maxLatMark.getSeqID());
|
||||||
|
|
||||||
sortedPoints.sort(Comparator.comparingDouble(Mark::getLongitude));
|
sortedPoints.sort(Comparator.comparingDouble(Limit::getLng));
|
||||||
//If the course is on a point on the earth where longitudes wrap around.
|
//If the course is on a point on the earth where longitudes wrap around.
|
||||||
|
Limit minLonMark = sortedPoints.get(0);
|
||||||
|
Limit maxLonMark = sortedPoints.get(sortedPoints.size()-1);
|
||||||
|
SingleMark thisMinLon = new SingleMark(minLonMark.toString(), minLonMark.getLat(), minLonMark.getLng(), minLonMark.getSeqID());
|
||||||
|
SingleMark thisMaxLon = new SingleMark(maxLonMark.toString(), maxLonMark.getLat(), maxLonMark.getLng(), maxLonMark.getSeqID());
|
||||||
// TODO: 30/03/17 cir27 - Correctly account for longitude wrapping around.
|
// TODO: 30/03/17 cir27 - Correctly account for longitude wrapping around.
|
||||||
if (sortedPoints.get(sortedPoints.size()-1).getLongitude() - sortedPoints.get(0).getLongitude() > 180)
|
if (thisMaxLon.getLongitude() - thisMinLon.getLongitude() > 180) {
|
||||||
Collections.reverse(sortedPoints);
|
SingleMark temp = thisMinLon;
|
||||||
minLonPoint = sortedPoints.get(0);
|
thisMinLon = thisMaxLon;
|
||||||
maxLonPoint = sortedPoints.get(sortedPoints.size()-1);
|
thisMaxLon = temp;
|
||||||
|
}
|
||||||
|
minLonPoint = thisMinLon;
|
||||||
|
maxLonPoint = thisMaxLon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ public class Race {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a boat as finished
|
* Set a boat as finished
|
||||||
* @param boat The boat that has finished the race
|
* @param boat The boat that has finished the race/home/cosc/student/wmu16
|
||||||
*/
|
*/
|
||||||
public void setBoatFinished(Boat boat){
|
public void setBoatFinished(Boat boat){
|
||||||
this.finishingOrder.add(boat);
|
this.finishingOrder.add(boat);
|
||||||
|
|||||||
@@ -27,8 +27,7 @@ public class XMLParser {
|
|||||||
private RegattaXMLObject regattaXML;
|
private RegattaXMLObject regattaXML;
|
||||||
private BoatXMLObject boatXML;
|
private BoatXMLObject boatXML;
|
||||||
|
|
||||||
public XMLParser() {
|
public XMLParser() {}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for XMLParser
|
* Constructor for XMLParser
|
||||||
|
|||||||
Reference in New Issue
Block a user