diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index bd4de5ef..012b3945 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -31,16 +31,16 @@ public class App extends Application } if (args.length > 1){ - sr = new StreamReceiver("localhost", 8085, "RaceStream"); + sr = new StreamReceiver("localhost", 8085, "TestThread1"); } else{ - sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"RaceStream"); -// sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream"); -// sr = new StreamReceiver("localhost", 8085, "RaceStream"); + sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1"); +// sr = new StreamReceiver("livedata.americascup.com", 4941, "TestThread1"); +// sr = new StreamReceiver("localhost", 8085, "TestThread1"); } sr.start(); - StreamParser streamParser = new StreamParser("StreamParser"); + StreamParser streamParser = new StreamParser("TestThread2"); streamParser.start(); launch(args); diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 94721e39..bb138e70 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -4,25 +4,24 @@ import javafx.animation.*; import javafx.beans.property.SimpleDoubleProperty; import javafx.fxml.FXML; import javafx.geometry.Point2D; -import javafx.geometry.Point3D; import javafx.scene.Group; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.layout.AnchorPane; import javafx.scene.paint.Color; -import javafx.scene.shape.Arc; -import javafx.scene.shape.ArcType; import javafx.scene.text.Font; import seng302.models.Boat; import seng302.models.BoatGroup; import seng302.models.Colors; import seng302.models.RaceObject; import seng302.models.mark.*; -import seng302.models.parsers.StreamPacket; import seng302.models.parsers.StreamParser; 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.util.*; import java.util.concurrent.PriorityBlockingQueue; @@ -60,6 +59,7 @@ public class CanvasController { private double referencePointY; private double metersToPixels; private List raceObjects = new ArrayList<>(); + private List raceMarks = new ArrayList<>(); //FRAME RATE 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.restore(); fitMarksToCanvas(); + + + // TODO: 1/05/17 wmu16 - Change this call to now draw the marks as from the xml drawBoats(); timer = new AnimationTimer() { @@ -134,6 +137,94 @@ public class CanvasController { //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 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 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(){ for (RaceObject raceObject : raceObjects) { raceObject.updatePosition(1000 / 60); @@ -249,6 +340,7 @@ public class CanvasController { double minLonToMaxLon = scaleRaceExtremities(); calculateReferencePointLocation(minLonToMaxLon); givePointsXY(); + addRaceBorder(); findMetersToPixels(); } @@ -258,27 +350,30 @@ public class CanvasController { * marker, rightmost marker, southern most marker and northern most marker respectively. */ private void findMinMaxPoint() { - List sortedPoints = new ArrayList<>(); - for (Mark mark : raceViewController.getRace().getCourse()) - { - if (mark.getMarkType() == MarkType.SINGLE_MARK) - sortedPoints.add(mark); - else { - sortedPoints.add(((GateMark) mark).getSingleMark1()); - sortedPoints.add(((GateMark) mark).getSingleMark2()); - } + List sortedPoints = new ArrayList<>(); + for (Limit limit : StreamParser.getXmlObject().getRaceXML().getCourseLimit()) { + sortedPoints.add(limit); } - sortedPoints.sort(Comparator.comparingDouble(Mark::getLatitude)); - minLatPoint = sortedPoints.get(0); - maxLatPoint = sortedPoints.get(sortedPoints.size()-1); + sortedPoints.sort(Comparator.comparingDouble(Limit::getLat)); + Limit minLatMark = sortedPoints.get(0); + Limit maxLatMark = 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. + 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. - if (sortedPoints.get(sortedPoints.size()-1).getLongitude() - sortedPoints.get(0).getLongitude() > 180) - Collections.reverse(sortedPoints); - minLonPoint = sortedPoints.get(0); - maxLonPoint = sortedPoints.get(sortedPoints.size()-1); + if (thisMaxLon.getLongitude() - thisMinLon.getLongitude() > 180) { + SingleMark temp = thisMinLon; + thisMinLon = thisMaxLon; + thisMaxLon = temp; + } + minLonPoint = thisMinLon; + maxLonPoint = thisMaxLon; } /** diff --git a/src/main/java/seng302/models/Race.java b/src/main/java/seng302/models/Race.java index 01d1adf8..fc7ae0ef 100644 --- a/src/main/java/seng302/models/Race.java +++ b/src/main/java/seng302/models/Race.java @@ -152,7 +152,7 @@ public class Race { /** * 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){ this.finishingOrder.add(boat); diff --git a/src/main/java/seng302/models/parsers/XMLParser.java b/src/main/java/seng302/models/parsers/XMLParser.java index a50cbcbc..6863dda1 100644 --- a/src/main/java/seng302/models/parsers/XMLParser.java +++ b/src/main/java/seng302/models/parsers/XMLParser.java @@ -27,8 +27,7 @@ public class XMLParser { private RegattaXMLObject regattaXML; private BoatXMLObject boatXML; - public XMLParser() { - } + public XMLParser() {} /** * Constructor for XMLParser