From c5c2d4375d317fe26bd3786fab12ad26b6c54dfa Mon Sep 17 00:00:00 2001 From: William Muir Date: Mon, 1 May 2017 23:10:15 +1200 Subject: [PATCH] Changed the canvas controller to read marks from the XML as received from the server (PROTOTYPE) Gates appear to draw in the correct places although a bit jittery for some reason Boundary marks are a bit sporadic and still need lines drawn in between Large refactor of canvas controller and XMLParser still required if these two are going to work together well. Currently canvas controller is a bit of a mess. #story[469] --- src/main/java/seng302/App.java | 4 +- .../seng302/controllers/CanvasController.java | 141 ++++++++++++++++-- .../seng302/models/parsers/XMLParser.java | 3 +- 3 files changed, 128 insertions(+), 20 deletions(-) diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index 5d4ce825..012b3945 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -34,9 +34,9 @@ public class App extends Application sr = new StreamReceiver("localhost", 8085, "TestThread1"); } else{ -// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941,"TestThread1"); + 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 = new StreamReceiver("localhost", 8085, "TestThread1"); } sr.start(); diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 94721e39..7a97e998 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -21,6 +21,10 @@ 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; @@ -60,6 +64,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 @@ -100,7 +105,27 @@ public class CanvasController { gc.setFill(Color.SKYBLUE); gc.fillRect(0,0, CANVAS_WIDTH, CANVAS_HEIGHT); gc.restore(); - fitMarksToCanvas(); +// fitMarksToCanvas(); + + //Wait until wer have received the XML + while(StreamParser.getXmlObject().getRaceXML() == null) { + try { + Thread.sleep(1); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + findMinMaxPoint(); + double minLonToMaxLon = scaleRaceExtremities(); + calculateReferencePointLocation(minLonToMaxLon); + addBorderMarks(); + addCourseMarks(); + findMetersToPixels(); + + + + // TODO: 1/05/17 wmu16 - Change this call to now draw the marks as from the xml drawBoats(); timer = new AnimationTimer() { @@ -134,6 +159,75 @@ 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 addBorderMarks() { + XMLParser.RaceXMLObject raceXMLObject = StreamParser.getXmlObject().getRaceXML(); + ArrayList courselimits = raceXMLObject.getCourseLimit(); + for (Limit courselimit : courselimits) { + Mark thisMark = new SingleMark("", courselimit.getLat(), courselimit.getLng(), courselimit.getSeqID()); + RaceObject markGroup = new MarkGroup(thisMark, findScaledXY(thisMark)); + raceObjects.add(markGroup); + } + } + + + /** + * 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); @@ -258,27 +352,42 @@ 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) + List sortedPoints = new ArrayList<>(); +// for (Mark mark : raceViewController.getRace().getCourse()) +// for (Mark mark : raceMarks) +// { +// if (mark.getMarkType() == MarkType.SINGLE_MARK) +// sortedPoints.add(mark); +// else { +// sortedPoints.add(((GateMark) mark).getSingleMark1()); +// sortedPoints.add(((GateMark) mark).getSingleMark2()); +// } +// } + for (CompoundMark compoundMark : StreamParser.getXmlObject().getRaceXML().getCompoundMarks()) { + for (CompoundMark.Mark mark : compoundMark.getMarks()) { sortedPoints.add(mark); - else { - sortedPoints.add(((GateMark) mark).getSingleMark1()); - sortedPoints.add(((GateMark) mark).getSingleMark2()); } } - sortedPoints.sort(Comparator.comparingDouble(Mark::getLatitude)); - minLatPoint = sortedPoints.get(0); - maxLatPoint = sortedPoints.get(sortedPoints.size()-1); + sortedPoints.sort(Comparator.comparingDouble(CompoundMark.Mark::getTargetLat)); + CompoundMark.Mark minLatMark = sortedPoints.get(0); + CompoundMark.Mark maxLatMark = sortedPoints.get(sortedPoints.size()-1); + minLatPoint = new SingleMark(minLatMark.getMarkName(), minLatMark.getTargetLat(), minLatMark.getTargetLng(), minLatMark.getSourceID()); + maxLatPoint = new SingleMark(maxLatMark.getMarkName(), maxLatMark.getTargetLat(), maxLatMark.getTargetLng(), maxLatMark.getSourceID()); - sortedPoints.sort(Comparator.comparingDouble(Mark::getLongitude)); + sortedPoints.sort(Comparator.comparingDouble(CompoundMark.Mark::getTargetLng)); //If the course is on a point on the earth where longitudes wrap around. + CompoundMark.Mark minLonMark = sortedPoints.get(0); + CompoundMark.Mark maxLonMark = sortedPoints.get(sortedPoints.size()-1); + SingleMark thisMinLon = new SingleMark(minLonMark.getMarkName(), minLonMark.getTargetLat(), minLonMark.getTargetLng(), minLonMark.getSourceID()); + SingleMark thisMaxLon = new SingleMark(maxLonMark.getMarkName(), maxLonMark.getTargetLat(), maxLonMark.getTargetLng(), maxLonMark.getSourceID()); // 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/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