From c4fe116267d53dfaea558763fb33a71c0cfcf71a Mon Sep 17 00:00:00 2001 From: Calum Date: Mon, 15 May 2017 15:17:54 +1200 Subject: [PATCH 1/9] MarkGroups refactored to be independent of BoatGroups as their functionality has diverged. #issue[10] #refactor --- .../seng302/controllers/CanvasController.java | 81 ++++++--- .../controllers/RaceViewController.java | 20 +-- src/main/java/seng302/models/BoatGroup.java | 36 +++- src/main/java/seng302/models/RaceObject.java | 87 ---------- .../java/seng302/models/mark/MarkGroup.java | 159 +++--------------- 5 files changed, 110 insertions(+), 273 deletions(-) delete mode 100644 src/main/java/seng302/models/RaceObject.java diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 53582740..a2e00a23 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -17,6 +17,7 @@ import seng302.models.stream.packets.BoatPositionPacket; import seng302.models.stream.XMLParser; import seng302.models.stream.XMLParser.RaceXMLObject.Limit; import seng302.models.mark.Mark; +import seng302.server.simulator.Boat; import java.text.DecimalFormat; import java.util.*; @@ -53,7 +54,8 @@ public class CanvasController { private Mark maxLonPoint; private double referencePointX; private double referencePointY; - private List raceObjects = new ArrayList<>(); + private List markGroups = new ArrayList<>(); + private List boatGroups = new ArrayList<>(); private List raceMarks = new ArrayList<>(); //FRAME RATE @@ -172,21 +174,26 @@ public class CanvasController { gc.fillPolygon(xBoundaryPoints,yBoundaryPoints,yBoundaryPoints.length); } - private void updateRaceObjects(){ - for (RaceObject raceObject : raceObjects) { - raceObject.updatePosition(1000 / 60); + private void updateGroups(){ + for (BoatGroup boatGroup : boatGroups) { + boatGroup.updatePosition(1000 / 60); // some raceObjects will have multiply ID's (for instance gate marks) - for (long id : raceObject.getRaceIds()) { //checking if the current "ID" has any updates associated with it + if (StreamParser.boatPositions.containsKey(boatGroup.getRaceId())) { + moveBoatGroup(boatGroup); + } + } + for (MarkGroup markGroup : markGroups) { + for (int id : markGroup.getRaceIds()) { if (StreamParser.boatPositions.containsKey(id)) { - move(id, raceObject); + moveMarkGroup(id, markGroup); } } } } - private void move(long id, RaceObject raceObject){ - PriorityBlockingQueue movementQueue = StreamParser.boatPositions.get(id); + private void moveBoatGroup(BoatGroup boatGroup) { + PriorityBlockingQueue movementQueue = StreamParser.boatPositions.get(boatGroup.getRaceId()); if (movementQueue.size() > 0){ // BoatPositionPacket positionPacket = movementQueue.peek(); // @@ -202,9 +209,9 @@ public class CanvasController { // if (timeDiff > delayTime) { try { BoatPositionPacket positionPacket = movementQueue.take(); - Point2D p2d = latLonToXY(positionPacket.getLat(), positionPacket.getLon()); + Point2D p2d = findScaledXY(positionPacket.getLat(), positionPacket.getLon()); double heading = 360.0 / 0xffff * positionPacket.getHeading(); - raceObject.setDestination(p2d.getX(), p2d.getY(), heading, positionPacket.getGroundSpeed(), (int) id); + boatGroup.setDestination(p2d.getX(), p2d.getY(), heading, positionPacket.getGroundSpeed(), boatGroup.getRaceId()); } catch (InterruptedException e){ e.printStackTrace(); } @@ -212,6 +219,31 @@ public class CanvasController { } } + void moveMarkGroup (int raceId, MarkGroup markGroup) { + PriorityBlockingQueue movementQueue = StreamParser.boatPositions.get(raceId); + if (movementQueue.size() > 0){ +// BoatPositionPacket positionPacket = movementQueue.peek(); +// +// //this code adds a delay to reading from the movementQueue +// //in case things being put into the movement queue are slightly +// //out of order +// int delayTime = 1000; +// int loopTime = delayTime * 10; +// long timeDiff = (System.currentTimeMillis()%loopTime - positionPacket.getTimeValid()%loopTime); +// if (timeDiff < 0){ +// timeDiff = loopTime + timeDiff; +// } +// if (timeDiff > delayTime) { + try { + BoatPositionPacket positionPacket = movementQueue.take(); + Point2D p2d = findScaledXY(positionPacket.getLat(), positionPacket.getLon()); + markGroup.moveMarkTo(p2d.getX(), p2d.getY(), raceId); + } catch (InterruptedException e){ + e.printStackTrace(); + } + } + } + class ResizableCanvas extends Canvas { ResizableCanvas() { @@ -277,11 +309,11 @@ public class CanvasController { BoatGroup boatGroup = new BoatGroup(boat, boat.getColour()); // boatGroup.moveTo(startingX, startingY, 0d); //boatGroup.setStage(raceViewController.getStage()); - raceObjects.add(boatGroup); + boatGroups.add(boatGroup); boatAnnotations.getChildren().add(boatGroup.getLowPriorityAnnotations()); } group.getChildren().add(boatAnnotations); - group.getChildren().addAll(raceObjects); + group.getChildren().addAll(boatGroups); } /** @@ -393,35 +425,35 @@ public class CanvasController { private void givePointsXY() { List allPoints = StreamParser.getXmlObject().getRaceXML().getCompoundMarks(); List processed = new ArrayList<>(); - RaceObject markGroup; + MarkGroup markGroup; for (XMLParser.RaceXMLObject.CompoundMark mark : allPoints) { if (!processed.contains(mark)) { if (mark.getMarkType() != MarkType.SINGLE_MARK) { markGroup = new MarkGroup(mark, findScaledXY(mark.getMarks().get(0)), findScaledXY(mark.getMarks().get(1))); - raceObjects.add(markGroup); + markGroups.add(markGroup); } else { markGroup = new MarkGroup(mark, findScaledXY(mark.getMarks().get(0))); - raceObjects.add(markGroup); + markGroups.add(markGroup); } processed.add(mark); } } + group.getChildren().addAll(boatGroups); } private Point2D findScaledXY (Mark unscaled) { - return findScaledXY (minLatPoint.getLatitude(), minLatPoint.getLongitude(), - unscaled.getLatitude(), unscaled.getLongitude()); + return findScaledXY (unscaled.getLatitude(), unscaled.getLongitude()); } - private Point2D findScaledXY (double latA, double lonA, double latB, double lonB) { + private Point2D findScaledXY (double unscaledLat, double unscaledLon) { double distanceFromReference; double angleFromReference; int xAxisLocation = (int) referencePointX; int yAxisLocation = (int) referencePointY; - angleFromReference = Mark.calculateHeadingRad(latA, lonA, latB, lonB); - distanceFromReference = Mark.calculateDistance(latA, lonA, latB, lonB); + angleFromReference = Mark.calculateHeadingRad(minLatPoint.getLatitude(), minLatPoint.getLongitude(), unscaledLat, unscaledLon); + distanceFromReference = Mark.calculateDistance(minLatPoint.getLatitude(), minLatPoint.getLongitude(), unscaledLat, unscaledLon); if (angleFromReference >= 0 && angleFromReference <= Math.PI / 2) { xAxisLocation += (int) Math.round(distanceScaleFactor * Math.sin(angleFromReference) * distanceFromReference); yAxisLocation -= (int) Math.round(distanceScaleFactor * Math.cos(angleFromReference) * distanceFromReference); @@ -441,12 +473,7 @@ public class CanvasController { return new Point2D(xAxisLocation, yAxisLocation); } - - private Point2D latLonToXY (double latitude, double longitude) { - return findScaledXY(minLatPoint.getLatitude(), minLatPoint.getLongitude(), latitude, longitude); - } - - List getRaceObjects() { - return raceObjects; + List getBoatGroups() { + return boatGroups; } } \ No newline at end of file diff --git a/src/main/java/seng302/controllers/RaceViewController.java b/src/main/java/seng302/controllers/RaceViewController.java index a1bb9651..4ff0327d 100644 --- a/src/main/java/seng302/controllers/RaceViewController.java +++ b/src/main/java/seng302/controllers/RaceViewController.java @@ -201,47 +201,35 @@ public class RaceViewController extends Thread{ private void setAnnotations(Integer annotationLevel) { switch (annotationLevel) { case 0: - for (RaceObject ro : includedCanvasController.getRaceObjects()) { - if(ro instanceof BoatGroup) { - BoatGroup bg = (BoatGroup) ro; + for (BoatGroup bg : includedCanvasController.getBoatGroups()) { bg.setTeamNameObjectVisible(false); bg.setVelocityObjectVisible(false); bg.setLineGroupVisible(false); bg.setWakeVisible(false); - } } break; case 1: - for (RaceObject ro : includedCanvasController.getRaceObjects()) { - if(ro instanceof BoatGroup) { - BoatGroup bg = (BoatGroup) ro; + for (BoatGroup bg : includedCanvasController.getBoatGroups()) { bg.setTeamNameObjectVisible(true); bg.setVelocityObjectVisible(false); bg.setLineGroupVisible(false); bg.setWakeVisible(false); - } } break; case 2: - for (RaceObject ro : includedCanvasController.getRaceObjects()) { - if(ro instanceof BoatGroup) { - BoatGroup bg = (BoatGroup) ro; + for (BoatGroup bg : includedCanvasController.getBoatGroups()) { bg.setTeamNameObjectVisible(true); bg.setVelocityObjectVisible(false); bg.setLineGroupVisible(true); bg.setWakeVisible(false); - } } break; case 3: - for (RaceObject ro : includedCanvasController.getRaceObjects()) { - if(ro instanceof BoatGroup) { - BoatGroup bg = (BoatGroup) ro; + for (BoatGroup bg : includedCanvasController.getBoatGroups()) { bg.setTeamNameObjectVisible(true); bg.setVelocityObjectVisible(true); bg.setLineGroupVisible(true); bg.setWakeVisible(true); - } } break; } diff --git a/src/main/java/seng302/models/BoatGroup.java b/src/main/java/seng302/models/BoatGroup.java index 57dd48db..54cb5e8c 100644 --- a/src/main/java/seng302/models/BoatGroup.java +++ b/src/main/java/seng302/models/BoatGroup.java @@ -19,7 +19,7 @@ import java.util.List; * UpdatePosition is called unless the window is minimized in which case it attempts to store animations and apply them * when the window is maximised. */ -public class BoatGroup extends RaceObject{ +public class BoatGroup extends Group{ //Constants for drawing private static final double TEAMNAME_X_OFFSET = 10d; @@ -32,6 +32,12 @@ public class BoatGroup extends RaceObject{ private Point2D lastPoint; private int wakeGenerationDelay = 10; private double distanceTravelled; + private double pixelVelocityX; + private double pixelVelocityY; + private double currentRotation; + private double rotationalGoal; + private double rotationalVelocity; + private static final int expectedUpdateInterval = 200; //Graphical objects private Yacht boat; private Group lineGroup = new Group(); @@ -194,7 +200,7 @@ public class BoatGroup extends RaceObject{ * @param rotation Rotation to move graphics to. * @param raceIds RaceID of the object to move. */ - public void setDestination (double newXValue, double newYValue, double rotation, double groundSpeed, int... raceIds) { + public void setDestination (double newXValue, double newYValue, double rotation, double groundSpeed, int raceIds) { if (hasRaceId(raceIds)) { if (setToInitialLocation) { destinationSet = true; @@ -254,7 +260,7 @@ public class BoatGroup extends RaceObject{ } } - public void setDestination (double newXValue, double newYValue, double groundSpeed, int... raceIDs) { + public void setDestination (double newXValue, double newYValue, double groundSpeed, int raceIDs) { destinationSet = true; if (hasRaceId(raceIDs)) { @@ -318,8 +324,8 @@ public class BoatGroup extends RaceObject{ * * @return An array containing all ID's associated with this RaceObject. */ - public int[] getRaceIds () { - return new int[] {boat.getSourceID()}; + public int getRaceId() { + return boat.getSourceID(); } /** @@ -355,4 +361,24 @@ public class BoatGroup extends RaceObject{ } }); } + + /** + * Calculates the rotational velocity required to reach the rotationalGoal from the currentRotation. + */ + protected void calculateRotationalVelocity () { + if (Math.abs(rotationalGoal - currentRotation) > 180) { + if (rotationalGoal - currentRotation >= 0) { + this.rotationalVelocity = ((rotationalGoal - currentRotation) - 360) / expectedUpdateInterval; + } else { + this.rotationalVelocity = (360 + (rotationalGoal - currentRotation)) / expectedUpdateInterval; + } + } else { + this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval; + } + //Sometimes the rotation is too large to be realistic. In that case just do it instantly. + if (Math.abs(rotationalVelocity) > 1) { + rotationalVelocity = 0; + rotateTo(rotationalGoal); + } + } } diff --git a/src/main/java/seng302/models/RaceObject.java b/src/main/java/seng302/models/RaceObject.java deleted file mode 100644 index 91f02971..00000000 --- a/src/main/java/seng302/models/RaceObject.java +++ /dev/null @@ -1,87 +0,0 @@ -package seng302.models; - -import javafx.geometry.Point2D; -import javafx.scene.Group; - -/** - * RaceObject defines the behaviour that animated objects whose position is updated from a yacht race data stream must - * adhere to. - */ -public abstract class RaceObject extends Group { - - //Time between sections of race - protected static double expectedUpdateInterval = 200; - - protected double rotationalGoal; - protected double currentRotation; - protected double rotationalVelocity; - protected double pixelVelocityX; - protected double pixelVelocityY; - - public Point2D getPosition () { - return new Point2D(super.getLayoutX(), getLayoutY()); - } - - public static double getExpectedUpdateInterval() { - return expectedUpdateInterval; - } - - /** - * - */ - public static void setExpectedUpdateInterval(double expectedUpdateInterval) { - RaceObject.expectedUpdateInterval = expectedUpdateInterval; - } - - /** - * Calculates the rotational velocity required to reach the rotationalGoal from the currentRotation. - */ - protected void calculateRotationalVelocity () { - if (Math.abs(rotationalGoal - currentRotation) > 180) { - if (rotationalGoal - currentRotation >= 0) { - this.rotationalVelocity = ((rotationalGoal - currentRotation) - 360) / expectedUpdateInterval; - } else { - this.rotationalVelocity = (360 + (rotationalGoal - currentRotation)) / expectedUpdateInterval; - } - } else { - this.rotationalVelocity = (rotationalGoal - currentRotation) / expectedUpdateInterval; - } - //Sometimes the rotation is too large to be realistic. In that case just do it instantly. - if (Math.abs(rotationalVelocity) > 1) { - rotationalVelocity = 0; - rotateTo(rotationalGoal); - } - } - - /** - * Sets the destination of everything within the RaceObject that has an ID in the array raceIds. The destination is - * set to the co-ordinates (x, y) with the given rotation. - * @param x X co-ordinate to move the graphics to. - * @param y Y co-ordinate to move the graphics to. - * @param rotation Rotation to move graphics to. - * @param raceIds RaceID of the object to move. - */ - public abstract void setDestination (double x, double y, double rotation, double groundSpeed, int... raceIds); - /** - * Sets the destination of everything within the RaceObject that has an ID in the array raceIds. The destination is - * set to the co-ordinates (x, y). - * @param x X co-ordinate to move the graphic to. - * @param y Y co-ordinate to move the graphic to. - * @param raceIds RaceID to the object to move. - */ - public abstract void setDestination (double x, double y, double groundSpeed, int... raceIds); - - public abstract void updatePosition (long timeInterval); - - public abstract void moveTo (double x, double y, double rotation); - - public abstract void moveTo (double x, double y); - - public abstract void moveGroupBy(double x, double y, double rotation); - - public abstract void rotateTo (double rotation); - - public abstract boolean hasRaceId (int... raceIds); - - public abstract int[] getRaceIds (); -} diff --git a/src/main/java/seng302/models/mark/MarkGroup.java b/src/main/java/seng302/models/mark/MarkGroup.java index 78a97d58..22fe05d8 100644 --- a/src/main/java/seng302/models/mark/MarkGroup.java +++ b/src/main/java/seng302/models/mark/MarkGroup.java @@ -1,12 +1,11 @@ package seng302.models.mark; import javafx.geometry.Point2D; -import javafx.scene.Node; +import javafx.scene.Group; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Line; import javafx.scene.transform.Rotate; -import seng302.models.RaceObject; import java.util.ArrayList; import java.util.List; @@ -14,7 +13,7 @@ import java.util.List; /** * Created by CJIRWIN on 26/04/2017. */ -public class MarkGroup extends RaceObject { +public class MarkGroup extends Group { private static int MARK_RADIUS = 5; private static int LINE_THICKNESS = 2; @@ -23,14 +22,8 @@ public class MarkGroup extends RaceObject { private List marks = new ArrayList<>(); private Mark mainMark; - private double[] nodePixelVelocitiesX; - private double[] nodePixelVelocitiesY; - private Point2D[] nodeDestinations; public MarkGroup (Mark mark, Point2D... points) { - nodePixelVelocitiesX = new double[points.length]; - nodePixelVelocitiesY = new double[points.length]; - nodeDestinations = new Point2D[points.length]; marks.add(mark); mainMark = mark; Color color = Color.BLACK; @@ -47,25 +40,14 @@ public class MarkGroup extends RaceObject { MARK_RADIUS, color ); - nodeDestinations = new Point2D[]{ - new Point2D(markCircle.getCenterX(), markCircle.getCenterY() - ) - }; super.getChildren().add(markCircle); } else { -// marks.add(((GateMark) mark).getSingleMark1()); -// marks.add(((GateMark) mark).getSingleMark2()); - nodePixelVelocitiesX = new double[]{0d,0d}; - nodePixelVelocitiesY = new double[]{0d,0d}; - nodeDestinations = new Point2D[2]; - markCircle = new Circle( points[0].getX(), points[0].getY(), MARK_RADIUS, color ); - nodeDestinations[0] = new Point2D(markCircle.getCenterX(), markCircle.getCenterY()); super.getChildren().add(markCircle); markCircle = new Circle( @@ -74,7 +56,6 @@ public class MarkGroup extends RaceObject { MARK_RADIUS, color ); - nodeDestinations[1] = new Point2D(markCircle.getCenterX(), markCircle.getCenterY()); super.getChildren().add(markCircle); Line line = new Line( points[0].getX(), @@ -91,117 +72,27 @@ public class MarkGroup extends RaceObject { } } - public void setDestination (double x, double y, double rotation, double groundSpeed, int... raceIds) { - setDestination(x, y, 0, raceIds); - this.rotationalGoal = rotation; - calculateRotationalVelocity(); - } - - public void setDestination (double x, double y, double groundSpeed, int... raceIds) { - for (int i = 0; i < marks.size(); i++) - for (int id : raceIds) - if (id == marks.get(i).getId()) - setDestinationChild(x, y, 0, Math.max(0, i-1)); - } - - - private void setDestinationChild (double x, double y, double speed, int childIndex) { - //double relativeX = x - super.getLayoutX(); - //double relativeY = y - super.getLayoutY(); - Circle markCircle = (Circle) super.getChildren().get(childIndex); - this.nodeDestinations[childIndex] = new Point2D(x, y); - //if (Math.abs(relativeX - markCircle.getCenterX()) > 30 && Math.abs(relativeY - markCircle.getCenterY()) > 30) { - this.nodePixelVelocitiesX[childIndex] = (x - markCircle.getCenterX()) / expectedUpdateInterval; - this.nodePixelVelocitiesY[childIndex] = (y - markCircle.getCenterY()) / expectedUpdateInterval; - //} - } - - public void rotateTo (double rotation) { - if (mainMark.getMarkType() != MarkType.SINGLE_MARK) { - Line line = (Line) super.getChildren().get(2); - double xCenter = Math.abs(line.getEndX() - line.getStartX()); - double yCenter = Math.abs(line.getEndY() - line.getStartY()); - super.getTransforms().setAll(new Rotate(rotation, xCenter, yCenter)); - } - } - - public void updatePosition (long timeInterval) { - Circle markCircle = (Circle) super.getChildren().get(0); - - if (nodePixelVelocitiesX[0] > 0 && markCircle.getCenterX() > nodeDestinations[0].getX() || - nodePixelVelocitiesX[0] < 0 && markCircle.getCenterX() < nodeDestinations[0].getY()) - nodePixelVelocitiesX[0] = 0; - else if (nodePixelVelocitiesX[0] != 0) - markCircle.setCenterX(markCircle.getCenterX() + nodePixelVelocitiesX[0] * timeInterval); - - if (nodePixelVelocitiesY[0] > 0 && markCircle.getCenterY() > nodeDestinations[0].getY() || - nodePixelVelocitiesY[0] < 0 && markCircle.getCenterY() < nodeDestinations[0].getY()) - nodePixelVelocitiesY[0] = 0; - else if (nodePixelVelocitiesY[0] != 0) - markCircle.setCenterY(markCircle.getCenterY() + nodePixelVelocitiesY[0] * timeInterval); - - if (mainMark.getMarkType() != MarkType.SINGLE_MARK) { - - Line line = (Line) super.getChildren().get(2); - line.setStartX(markCircle.getCenterX()); - line.setStartY(markCircle.getCenterY()); - - markCircle = (Circle) super.getChildren().get(1); - - if (nodePixelVelocitiesX[1] > 0 && markCircle.getCenterX() >= nodeDestinations[1].getX() || - nodePixelVelocitiesX[1] < 0 && markCircle.getCenterX() <= nodeDestinations[1].getX()) - nodePixelVelocitiesX[1] = 0; - else if (nodePixelVelocitiesX[1] != 0) - markCircle.setCenterX(markCircle.getCenterX() + nodePixelVelocitiesX[1] * timeInterval); - - if (nodePixelVelocitiesY[1] > 0 && markCircle.getCenterY() > nodeDestinations[1].getY() || - nodePixelVelocitiesY[1] < 0 && markCircle.getCenterY() < nodeDestinations[1].getY()) - nodePixelVelocitiesY[1] = 0; - else if (nodePixelVelocitiesY[1] != 0) - markCircle.setCenterY(markCircle.getCenterY() + nodePixelVelocitiesY[1] * timeInterval); - line.setEndX(markCircle.getCenterX()); - line.setEndY(markCircle.getCenterY()); - } - } - - public void moveGroupBy (double x, double y, double rotation) { - if (mainMark.getMarkType() != MarkType.SINGLE_MARK) { - Line line = (Line) super.getChildren().get(2); - for (int childIndex = 0; childIndex < 2; childIndex++){ - Circle mark = (Circle) super.getChildren().get(childIndex); - mark.setCenterY(mark.getCenterY() + y); - mark.setCenterX(mark.getCenterX() + x); - } - line.setStartX(line.getStartX() + x); - line.setStartY(line.getStartY() + y); - line.setEndX(line.getEndX() + x); - line.setEndY(line.getEndY() + y); - } else { - Circle mark = (Circle) super.getChildren().get(0); - mark.setCenterY(mark.getCenterY() + y); - mark.setCenterX(mark.getCenterX() + x); - } - rotateTo(currentRotation + rotation); - } - - public void moveTo (double x, double y, double rotation) { - moveTo(x, y); - rotateTo(rotation); - } - - public void moveTo (double x, double y) { - Circle markCircle = (Circle) super.getChildren().get(0); - markCircle.setCenterX(x); - markCircle.setCenterY(y); - if (mainMark.getMarkType() != MarkType.SINGLE_MARK) { - markCircle = (Circle) super.getChildren().get(1); + public void moveMarkTo (double x, double y, int raceId) + { + if (mainMark.getMarkType() == MarkType.SINGLE_MARK) { + Circle markCircle = (Circle) super.getChildren().get(0); markCircle.setCenterX(x); markCircle.setCenterY(y); - Line line = (Line) super.getChildren().get(2); - line.setStartX(x); - line.setStartY(y); - line.setEndX(x); - line.setEndY(y); + } else { + Circle markCircle1 = (Circle) super.getChildren().get(0); + Circle markCircle2 = (Circle) super.getChildren().get(1); + Line connectingLine = (Line) super.getChildren().get(2); + if (marks.get(1).getId() == raceId) { + markCircle1.setCenterX(x); + markCircle1.setCenterY(y); + connectingLine.setStartX(markCircle1.getCenterX()); + connectingLine.setStartY(markCircle1.getCenterY()); + } else if (marks.get(2).getId() == raceId) { + markCircle2.setCenterX(x); + markCircle2.setCenterY(y); + connectingLine.setEndX(markCircle2.getCenterX()); + connectingLine.setEndY(markCircle2.getCenterY()); + } } } @@ -213,14 +104,6 @@ public class MarkGroup extends RaceObject { return false; } - public static int getMarkRadius() { - return MARK_RADIUS; - } - - public static void setMarkRadius(int markRadius) { - MARK_RADIUS = markRadius; - } - public int[] getRaceIds () { int[] idArray = new int[marks.size()]; int i = 0; From 23bc643c91e431361958440fbff1d808e96f5d8b Mon Sep 17 00:00:00 2001 From: Calum Date: Mon, 15 May 2017 15:20:21 +1200 Subject: [PATCH 2/9] Removed some unused functions and imports caused by code refactor. #chore --- src/main/java/seng302/models/BoatGroup.java | 20 ------------------- .../java/seng302/models/mark/MarkGroup.java | 1 - 2 files changed, 21 deletions(-) diff --git a/src/main/java/seng302/models/BoatGroup.java b/src/main/java/seng302/models/BoatGroup.java index 54cb5e8c..45b707e1 100644 --- a/src/main/java/seng302/models/BoatGroup.java +++ b/src/main/java/seng302/models/BoatGroup.java @@ -260,31 +260,11 @@ public class BoatGroup extends Group{ } } - public void setDestination (double newXValue, double newYValue, double groundSpeed, int raceIDs) { - destinationSet = true; - - if (hasRaceId(raceIDs)) { - double rotation = Math.abs( - Math.toDegrees( - Math.atan( - (newYValue - boatPoly.getLayoutY()) / (newXValue - boatPoly.getLayoutX()) - ) - ) - ); - setDestination(newXValue, newYValue, rotation, groundSpeed, raceIDs); - } - } - public void rotateTo (double rotation) { currentRotation = rotation; boatPoly.getTransforms().setAll(new Rotate(rotation)); } - public void forceRotation () { - rotateTo (rotationalGoal); - wake.rotate(rotationalGoal); - } - public void setTeamNameObjectVisible(Boolean visible) { teamNameObject.setVisible(visible); } diff --git a/src/main/java/seng302/models/mark/MarkGroup.java b/src/main/java/seng302/models/mark/MarkGroup.java index 22fe05d8..b428c5ed 100644 --- a/src/main/java/seng302/models/mark/MarkGroup.java +++ b/src/main/java/seng302/models/mark/MarkGroup.java @@ -5,7 +5,6 @@ import javafx.scene.Group; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Line; -import javafx.scene.transform.Rotate; import java.util.ArrayList; import java.util.List; From 3fd13ddc0ae48626c56ed549ac35179a3f59e461 Mon Sep 17 00:00:00 2001 From: alistairjmcintyre Date: Wed, 17 May 2017 19:46:05 +1200 Subject: [PATCH 3/9] Adjusted XMLParser to use model Mark objects rather than the simple datatype that existed in the XMLParser previously. Began attempting to implement them into the canvas controller but have issues #[issue10] --- .../seng302/controllers/CanvasController.java | 36 +- src/main/java/seng302/models/mark/Mark.java | 1 - .../java/seng302/models/stream/XMLParser.java | 374 +++++++++++------- 3 files changed, 251 insertions(+), 160 deletions(-) diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index a2e00a23..6b34732d 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -125,7 +125,7 @@ public class CanvasController { // TODO: 1/05/17 cir27 - Make the RaceObjects update on the actual delay. elapsedNanos = 1000 / 60; - updateRaceObjects(); + //updateRaceObjects(); if (StreamParser.isRaceFinished()) { this.stop(); } @@ -423,23 +423,29 @@ public class CanvasController { * are scaled according to the distanceScaleFactor variable. */ private void givePointsXY() { - List allPoints = StreamParser.getXmlObject().getRaceXML().getCompoundMarks(); - List processed = new ArrayList<>(); - MarkGroup markGroup; + Map allPoints = StreamParser.getXmlObject().getRaceXML().getCompoundMarks(); + List processed = new ArrayList<>(); + MarkGroup markGroup; - for (XMLParser.RaceXMLObject.CompoundMark mark : allPoints) { - if (!processed.contains(mark)) { - if (mark.getMarkType() != MarkType.SINGLE_MARK) { - markGroup = new MarkGroup(mark, findScaledXY(mark.getMarks().get(0)), findScaledXY(mark.getMarks().get(1))); - markGroups.add(markGroup); - } else { - markGroup = new MarkGroup(mark, findScaledXY(mark.getMarks().get(0))); - markGroups.add(markGroup); + for (Map.Entry cMark : allPoints) { + Integer cMarkId = cMark.getKey(); + Mark mark = cMark.getValue(); + if (!processed.contains(mark)) { + if (mark.getMarkType() != MarkType.SINGLE_MARK) { + GateMark gMark = (GateMark) mark; + + markGroup = new MarkGroup(mark, findScaledXY(gMark.getSingleMark1()), findScaledXY(gMark.getSingleMark2())); //should be 2 objects in the list. + markGroups.add(markGroup); + } else { + SingleMark sMark = (SingleMark) mark; + + markGroup = new MarkGroup(mark, findScaledXY(sMark)); + markGroups.add(markGroup); + } + processed.add((mark)); } - processed.add(mark); } - } - group.getChildren().addAll(boatGroups); + group.getChildren().addAll(boatGroups); } private Point2D findScaledXY (Mark unscaled) { diff --git a/src/main/java/seng302/models/mark/Mark.java b/src/main/java/seng302/models/mark/Mark.java index a32ba20f..ce5a6f4a 100644 --- a/src/main/java/seng302/models/mark/Mark.java +++ b/src/main/java/seng302/models/mark/Mark.java @@ -132,5 +132,4 @@ public abstract class Mark { public void setId(int id) { this.id = id; } - } diff --git a/src/main/java/seng302/models/stream/XMLParser.java b/src/main/java/seng302/models/stream/XMLParser.java index 181c1e2f..43595cea 100644 --- a/src/main/java/seng302/models/stream/XMLParser.java +++ b/src/main/java/seng302/models/stream/XMLParser.java @@ -1,27 +1,30 @@ package seng302.models.stream; +import java.util.List; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import seng302.models.Yacht; +import seng302.models.mark.GateMark; +import seng302.models.mark.Mark; import seng302.models.mark.MarkType; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; +import seng302.models.mark.SingleMark; /** * Class to create an XML object from the XML Packet Messages. * * Example usage: * - * Document doc; // some xml document - * Integer xmlMessageType; // an Integer of value 5, 6, 7 - * - * xmlP = new XMLParser(doc, xmlMessageType); - * RegattaXMLObject rXmlObj = xmlP.createRegattaXML(); // creates a regattaXML object. + * Document doc; // some xml document + * Integer xmlMessageType; // an Integer of value 5, 6, 7 * + * xmlP = new XMLParser(doc, xmlMessageType); + * RegattaXMLObject rXmlObj = xmlP.createRegattaXML(); // creates a regattaXML object. */ public class XMLParser { @@ -31,10 +34,12 @@ public class XMLParser { private RegattaXMLObject regattaXML; private BoatXMLObject boatXML; - public XMLParser() {} + public XMLParser() { + } /** * Constructor for XMLParser + * * @param doc Document to create XML object. * @param messageType Defines if a message is a RegattaXML(5), RaceXML(6), BoatXML(7). */ @@ -53,13 +58,22 @@ public class XMLParser { } } - public RaceXMLObject getRaceXML() { return raceXML; } - public RegattaXMLObject getRegattaXML() { return regattaXML; } - public BoatXMLObject getBoatXML() { return boatXML; } + public RaceXMLObject getRaceXML() { + return raceXML; + } + + public RegattaXMLObject getRegattaXML() { + return regattaXML; + } + + public BoatXMLObject getBoatXML() { + return boatXML; + } /** * Returns the text content of a given child element tag, assuming it exists, as an Integer. + * * @param ele Document Element with child elements. * @param tag Tag to find in document elements child elements. * @return Text content from tag if found, null otherwise. @@ -75,6 +89,7 @@ public class XMLParser { /** * Returns the text content of a given child element tag, assuming it exists, as an String. + * * @param ele Document Element with child elements. * @param tag Tag to find in document elements child elements. * @return Text content from tag if found, null otherwise. @@ -90,6 +105,7 @@ public class XMLParser { /** * Returns the text content of a given child element tag, assuming it exists, as a Double. + * * @param ele Document Element with child elements. * @param tag Tag to find in document elements child elements. * @return Text content from tag if found, null otherwise. @@ -105,9 +121,11 @@ public class XMLParser { /** * Returns the text content of an attribute of a given Node, assuming it exists, as a String. + * * @param n A node object that should have some attributes * @param attr The attribute you want to get from the given node. - * @return The String representation of the text content of an attribute in the given node, else returns null. + * @return The String representation of the text content of an attribute in the given node, else + * returns null. */ private static String getNodeAttributeString(Node n, String attr) { Node attrItem = n.getAttributes().getNamedItem(attr); @@ -120,9 +138,11 @@ public class XMLParser { /** * Returns the text content of an attribute of a given Node, assuming it exists, as an Integer. + * * @param n A node object that should have some attributes * @param attr The attribute you want to get from the given node. - * @return The Integer representation of the text content of an attribute in the given node, else returns null. + * @return The Integer representation of the text content of an attribute in the given node, + * else returns null. */ private static Integer getNodeAttributeInt(Node n, String attr) { Node attrItem = n.getAttributes().getNamedItem(attr); @@ -135,9 +155,11 @@ public class XMLParser { /** * Returns the text content of an attribute of a given Node, assuming it exists, as a Double. + * * @param n A node object that should have some attributes * @param attr The attribute you want to get from the given node. - * @return The Double representation of the text content of an attribute in the given node, else returns null. + * @return The Double representation of the text content of an attribute in the given node, else + * returns null. */ private static Double getNodeAttributeDouble(Node n, String attr) { Node attrItem = n.getAttributes().getNamedItem(attr); @@ -149,6 +171,7 @@ public class XMLParser { } public class RegattaXMLObject { + //Regatta Info private Integer regattaID; private String regattaName; @@ -160,6 +183,7 @@ public class XMLParser { /** * Constructor for a RegattaXMLObject. * Takes the information from a Document object and creates a more usable format. + * * @param doc XML Document Object */ RegattaXMLObject(Document doc) { @@ -173,12 +197,29 @@ public class XMLParser { this.utcOffset = getElementInt(docEle, "UtcOffset"); } - public Integer getRegattaID() { return regattaID; } - public String getRegattaName() { return regattaName; } - public String getCourseName() { return courseName; } - public Double getCentralLat() { return centralLat; } - public Double getCentralLng() { return centralLng; } - public Integer getUtcOffset() { return utcOffset; } + public Integer getRegattaID() { + return regattaID; + } + + public String getRegattaName() { + return regattaName; + } + + public String getCourseName() { + return courseName; + } + + public Double getCentralLat() { + return centralLat; + } + + public Double getCentralLng() { + return centralLng; + } + + public Integer getUtcOffset() { + return utcOffset; + } } @@ -195,13 +236,14 @@ public class XMLParser { //Non atomic race attributes private ArrayList participants; - private ArrayList course; + private Map course; private ArrayList compoundMarkSequence; private ArrayList courseLimit; /** * Constructor for a RaceXMLObject. * Takes the information from a Document object and creates a more usable format. + * * @param doc XML Document Object */ RaceXMLObject(Document doc) { @@ -213,8 +255,9 @@ public class XMLParser { this.creationTimeDate = getElementString(docEle, "CreationTimeDate"); Node raceStart = docEle.getElementsByTagName("RaceStartTime").item(0); - this.raceStartTime = getNodeAttributeString(raceStart, "Start") ; - this.postponeStatus = Boolean.parseBoolean(getNodeAttributeString(raceStart, "Postpone")); + this.raceStartTime = getNodeAttributeString(raceStart, "Start"); + this.postponeStatus = Boolean + .parseBoolean(getNodeAttributeString(raceStart, "Postpone")); //Participants participants = new ArrayList<>(); @@ -238,21 +281,13 @@ public class XMLParser { } //Course - course = new ArrayList<>(); - - NodeList cMarkList = docEle.getElementsByTagName("Course").item(0).getChildNodes(); - for (int i = 0; i < cMarkList.getLength(); i++) { - Node cMarkNode = cMarkList.item(i); - if (cMarkNode.getNodeName().equals("CompoundMark")) { - CompoundMark cMark = new CompoundMark(cMarkNode); - course.add(cMark); - } - } + course = createCompoundMarks(docEle); //Course Mark Sequence compoundMarkSequence = new ArrayList<>(); - NodeList cornerList = docEle.getElementsByTagName("CompoundMarkSequence").item(0).getChildNodes(); + NodeList cornerList = docEle.getElementsByTagName("CompoundMarkSequence").item(0) + .getChildNodes(); for (int i = 0; i < cornerList.getLength(); i++) { Node cornerNode = cornerList.item(i); if (cornerNode.getNodeName().equals("Corner")) { @@ -274,18 +309,97 @@ public class XMLParser { } } - public Integer getRaceID() { return raceID; } - public String getRaceType() { return raceType; } - public String getCreationTimeDate() { return creationTimeDate; } - public String getRaceStartTime() { return raceStartTime; } - public Boolean getPostponeStatus() { return postponeStatus; } - public ArrayList getParticipants() { return participants; } - public ArrayList getCompoundMarks() { return course; } - public ArrayList getCompoundMarkSequence() { return compoundMarkSequence; } - public ArrayList getCourseLimit() { return courseLimit; } + private Map createCompoundMarks(Element docEle) { + Map cMarks = new HashMap<>(); + + NodeList cMarkList = docEle.getElementsByTagName("Course").item(0).getChildNodes(); + for (int i = 0; i < cMarkList.getLength(); i++) { + Node cMarkNode = cMarkList.item(i); + + if (cMarkNode.getNodeName().equals("CompoundMark")) { + Integer markID = getNodeAttributeInt(cMarkNode, "CompoundMarkID"); + Mark mark = createMark(cMarkNode); + + cMarks.put(markID, mark); + } + } + + return cMarks; + } + + private Mark createMark(Node compoundMark) { + + List marksList = new ArrayList<>(); + String cMarkName = getNodeAttributeString(compoundMark, "Name"); + + NodeList childMarks = compoundMark.getChildNodes(); + + for (int i = 0; i < childMarks.getLength(); i++) { + Node markNode = childMarks.item(i); + if (markNode.getNodeName().equals("Mark")) { + + Integer sourceID = getNodeAttributeInt(markNode, "SourceID"); + String markName = getNodeAttributeString(markNode, "Name"); + Double targetLat = getNodeAttributeDouble(markNode, "TargetLat"); + Double targetLng = getNodeAttributeDouble(markNode, "TargetLng"); + + SingleMark mark = new SingleMark(markName, targetLat, targetLng, sourceID); + marksList.add(mark); + } + } + + System.out.println(marksList.size()); + if (marksList.size() == 1) { + return marksList.get(0); + } else if (marksList.size() == 2) { + return new GateMark(cMarkName, MarkType.OPEN_GATE, marksList.get(0), + marksList.get(1), marksList.get(0).getLatitude(), + marksList.get(0).getLongitude()); + } else { + return null; + } + + } + + public Integer getRaceID() { + return raceID; + } + + public String getRaceType() { + return raceType; + } + + public String getCreationTimeDate() { + return creationTimeDate; + } + + public String getRaceStartTime() { + return raceStartTime; + } + + public Boolean getPostponeStatus() { + return postponeStatus; + } + + public ArrayList getParticipants() { + return participants; + } + + public Map getCompoundMarks() { + return course; + } + + public ArrayList getCompoundMarkSequence() { + return compoundMarkSequence; + } + + public ArrayList getCourseLimit() { + return courseLimit; + } public class Participant { + Integer sourceID; String entry; @@ -294,65 +408,17 @@ public class XMLParser { this.entry = entry; } - public Integer getsourceID() { return sourceID; } - public String getEntry() { return entry; } - } - - public class CompoundMark { - private Integer markID; - private String cMarkName; - private MarkType markType; - private ArrayList marks; - - CompoundMark(Node compoundMark) { - marks = new ArrayList<>(); - this.markID = getNodeAttributeInt(compoundMark, "CompoundMarkID"); - this.cMarkName = getNodeAttributeString(compoundMark, "Name"); - NodeList childMarks = compoundMark.getChildNodes(); - if (childMarks.getLength() > 1){ - markType = MarkType.OPEN_GATE; - } else { - markType = MarkType.SINGLE_MARK; - } - - for (int i = 0; i < childMarks.getLength(); i++) { - Node markNode = childMarks.item(i); - if (markNode.getNodeName().equals("Mark")) { - Mark mark = new Mark(markNode); - marks.add(mark); - } - } + public Integer getsourceID() { + return sourceID; } - public Integer getMarkID() { return markID; } - public String getcMarkName() { return cMarkName; } - public MarkType getMarkType() { return markType; } - public ArrayList getMarks() { return marks; } - - public class Mark { - private Integer seqID; - private Integer sourceID; - private String markName; - private Double targetLat; - private Double targetLng; - - Mark(Node markNode) { - this.seqID = getNodeAttributeInt(markNode, "SeqID"); - this.sourceID = getNodeAttributeInt(markNode, "SourceID"); - this.markName = getNodeAttributeString(markNode, "Name"); - this.targetLat = getNodeAttributeDouble(markNode, "TargetLat"); - this.targetLng = getNodeAttributeDouble(markNode, "TargetLng"); - } - - public Integer getSeqID() { return seqID; } - public Integer getSourceID() { return sourceID; } - public String getMarkName() { return markName; } - public Double getTargetLat() { return targetLat; } - public Double getTargetLng() { return targetLng; } + public String getEntry() { + return entry; } } public class Corner { + private Integer seqID; private Integer compoundMarkID; private String rounding; @@ -365,13 +431,25 @@ public class XMLParser { this.zoneSize = getNodeAttributeInt(cornerNode, "ZoneSize"); } - public Integer getSeqID() { return seqID; } - public Integer getCompoundMarkID() { return compoundMarkID; } - public String getRounding() { return rounding; } - public Integer getZoneSize() { return zoneSize; } + public Integer getSeqID() { + return seqID; + } + + public Integer getCompoundMarkID() { + return compoundMarkID; + } + + public String getRounding() { + return rounding; + } + + public Integer getZoneSize() { + return zoneSize; + } } public class Limit { + private Integer seqID; private Double lat; private Double lng; @@ -382,9 +460,17 @@ public class XMLParser { this.lng = getNodeAttributeDouble(limitNode, "Lon"); } - public Integer getSeqID() { return seqID; } - public Double getLat() { return lat; } - public Double getLng() { return lng; } + public Integer getSeqID() { + return seqID; + } + + public Double getLat() { + return lat; + } + + public Double getLng() { + return lng; + } } } @@ -410,6 +496,7 @@ public class XMLParser { /** * Constructor for a BoatXMLObject. * Takes the information from a Document object and creates a more usable format. + * * @param doc XML Document Object */ BoatXMLObject(Document doc) { @@ -429,7 +516,7 @@ public class XMLParser { Node zoneLimitsList = settingsList.item(7); this.zoneLimits = new ArrayList<>(); for (int i = 0; i < zoneLimitsList.getAttributes().getLength(); i++) { - String tag = String.format("Limit%d", i+1); + String tag = String.format("Limit%d", i + 1); this.zoneLimits.add(getNodeAttributeDouble(zoneLimitsList, tag)); } @@ -440,61 +527,60 @@ public class XMLParser { if (currentBoat.getNodeName().equals("Boat")) { // Boat boat = new Boat(currentBoat); Yacht boat = new Yacht(getNodeAttributeString(currentBoat, "Type"), - getNodeAttributeInt(currentBoat, "SourceID"), - getNodeAttributeString(currentBoat, "HullNum"), - getNodeAttributeString(currentBoat, "ShortName"), - getNodeAttributeString(currentBoat, "BoatName"), - getNodeAttributeString(currentBoat, "Country")); + getNodeAttributeInt(currentBoat, "SourceID"), + getNodeAttributeString(currentBoat, "HullNum"), + getNodeAttributeString(currentBoat, "ShortName"), + getNodeAttributeString(currentBoat, "BoatName"), + getNodeAttributeString(currentBoat, "Country")); this.boats.add(boat); if (boat.getBoatType().equals("Yacht")) { competingBoats.put(boat.getSourceID(), boat); } } - //System.out.println(this.getBoats()); } } - public String getLastModified() { return lastModified; } - public Integer getVersion() { return version; } - public String getBoatType() { return boatType; } - public Double getBoatLength() { return boatLength; } - public Double getHullLength() { return hullLength; } - public Double getMarkZoneSize() { return markZoneSize; } - public Double getCourseZoneSize() { return courseZoneSize; } - public ArrayList getZoneLimits() { return zoneLimits; } - public ArrayList getBoats() { return boats; } + public String getLastModified() { + return lastModified; + } + + public Integer getVersion() { + return version; + } + + public String getBoatType() { + return boatType; + } + + public Double getBoatLength() { + return boatLength; + } + + public Double getHullLength() { + return hullLength; + } + + public Double getMarkZoneSize() { + return markZoneSize; + } + + public Double getCourseZoneSize() { + return courseZoneSize; + } + + public ArrayList getZoneLimits() { + return zoneLimits; + } + + public ArrayList getBoats() { + return boats; + } + public Map getCompetingBoats() { return competingBoats; } -// public class Boat { -// -// private String boatType; -// private Integer sourceID; -// private String hullID; //matches HullNum in the XML spec. -// private String shortName; -// private String boatName; -// private String country; -// -// Boat(Node boatNode) { -// this.boatType = getNodeAttributeString(boatNode, "Type"); -// this.sourceID = getNodeAttributeInt(boatNode, "SourceID"); -// this.hullID = getNodeAttributeString(boatNode, "HullNum"); -// this.shortName = getNodeAttributeString(boatNode, "ShortName"); -// this.boatName = getNodeAttributeString(boatNode, "BoatName"); -// this.country = getNodeAttributeString(boatNode, "Country"); -// } -// -// public String getBoatType() { return boatType; } -// public Integer getSourceID() { return sourceID; } -// public String getHullID() { return hullID; } -// public String getShortName() { return shortName; } -// public String getBoatName() { return boatName; } -// public String getCountry() { return country; } -// -// } - } } \ No newline at end of file From 5d6b356602a993d592e82057dc2030bf6987d033 Mon Sep 17 00:00:00 2001 From: Alistair McIntyre Date: Thu, 18 May 2017 18:02:25 +1200 Subject: [PATCH 4/9] all marks displaying except currently gate marks are displaying as a single dot #story[923] #pair[ajm412, ptg19] --- src/main/java/seng302/App.java | 2 +- .../seng302/controllers/CanvasController.java | 51 +++++++++++++++---- src/main/java/seng302/models/mark/Mark.java | 4 +- .../java/seng302/models/mark/MarkGroup.java | 12 ++--- .../seng302/models/stream/StreamParser.java | 45 +++++++++++----- .../java/seng302/models/stream/XMLParser.java | 8 ++- 6 files changed, 83 insertions(+), 39 deletions(-) diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index ac264db6..28d7e923 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -63,7 +63,7 @@ public class App extends Application { //Change the StreamReceiver in this else block to change the default data source. 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(); diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index ff7a294f..c7fbcb6e 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -1,6 +1,11 @@ package seng302.controllers; -import javafx.animation.*; +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; import javafx.geometry.Point2D; @@ -10,15 +15,18 @@ import javafx.scene.canvas.GraphicsContext; import javafx.scene.layout.AnchorPane; import javafx.scene.paint.Color; import javafx.scene.text.Font; -import seng302.models.*; -import seng302.models.mark.*; +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.stream.StreamParser; -import seng302.models.stream.packets.BoatPositionPacket; import seng302.models.stream.XMLParser; import seng302.models.stream.XMLParser.RaceXMLObject.Limit; -import seng302.models.mark.Mark; -import java.util.*; -import java.util.concurrent.PriorityBlockingQueue; +import seng302.models.stream.packets.BoatPositionPacket; /** * Created by ptg19 on 15/03/17. @@ -96,6 +104,7 @@ public class CanvasController { // TODO: 1/05/17 wmu16 - Change this call to now draw the marks as from the xml initializeBoats(); + initializeMarks(); timer = new AnimationTimer() { @Override @@ -179,8 +188,8 @@ public class CanvasController { boatGroup.move(); } for (MarkGroup markGroup : markGroups) { - for (int id : markGroup.getRaceIds()) { - if (StreamParser.boatPositions.containsKey(id)) { + for (long id : markGroup.getRaceIds()) { + if (StreamParser.markPositions.containsKey(id)) { UpdateMarkGroup(id, markGroup); } } @@ -214,8 +223,8 @@ public class CanvasController { } } - void UpdateMarkGroup (int raceId, MarkGroup markGroup) { - PriorityBlockingQueue movementQueue = StreamParser.boatPositions.get(raceId); + void UpdateMarkGroup (long raceId, MarkGroup markGroup) { + PriorityBlockingQueue movementQueue = StreamParser.markPositions.get(raceId); if (movementQueue.size() > 0){ try { BoatPositionPacket positionPacket = movementQueue.take(); @@ -244,6 +253,26 @@ public class CanvasController { group.getChildren().addAll(boatGroups); } + private void initializeMarks() { + Map allMarks = StreamParser.getXmlObject().getRaceXML().getCompoundMarks(); + + for (Mark mark : allMarks.values()) { + if (mark.getMarkType() == MarkType.SINGLE_MARK) { + SingleMark sMark = (SingleMark) mark; + + MarkGroup markGroup = new MarkGroup(mark, findScaledXY(sMark)); + markGroups.add(markGroup); + } else { + GateMark gMark = (GateMark) mark; + + MarkGroup markGroup = new MarkGroup(mark, findScaledXY(gMark.getSingleMark1()), + findScaledXY(gMark.getSingleMark2())); //should be 2 objects in the list. + markGroups.add(markGroup); + } + } + group.getChildren().addAll(markGroups); + } + class ResizableCanvas extends Canvas { ResizableCanvas() { diff --git a/src/main/java/seng302/models/mark/Mark.java b/src/main/java/seng302/models/mark/Mark.java index ce5a6f4a..1ca1f608 100644 --- a/src/main/java/seng302/models/mark/Mark.java +++ b/src/main/java/seng302/models/mark/Mark.java @@ -10,7 +10,7 @@ public abstract class Mark { private MarkType markType; private double latitude; private double longitude; - private int id; + private long id; /** * Create a mark instance by passing its name and type @@ -125,7 +125,7 @@ public abstract class Mark { return longitude; } - public int getId() { + public long getId() { return id; } diff --git a/src/main/java/seng302/models/mark/MarkGroup.java b/src/main/java/seng302/models/mark/MarkGroup.java index 0e886abc..bdd1491d 100644 --- a/src/main/java/seng302/models/mark/MarkGroup.java +++ b/src/main/java/seng302/models/mark/MarkGroup.java @@ -1,14 +1,12 @@ package seng302.models.mark; +import java.util.ArrayList; +import java.util.List; import javafx.geometry.Point2D; import javafx.scene.Group; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Line; -import javafx.scene.transform.Rotate; - -import java.util.ArrayList; -import java.util.List; /** * Created by CJIRWIN on 26/04/2017. @@ -72,7 +70,7 @@ public class MarkGroup extends Group { } } - public void moveMarkTo (double x, double y, int raceId) + public void moveMarkTo (double x, double y, long raceId) { if (mainMark.getMarkType() == MarkType.SINGLE_MARK) { Circle markCircle = (Circle) super.getChildren().get(0); @@ -104,8 +102,8 @@ public class MarkGroup extends Group { return false; } - public int[] getRaceIds () { - int[] idArray = new int[marks.size()]; + public long[] getRaceIds () { + long[] idArray = new long[marks.size()]; int i = 0; for (Mark mark : marks) idArray[i++] = mark.getId(); diff --git a/src/main/java/seng302/models/stream/StreamParser.java b/src/main/java/seng302/models/stream/StreamParser.java index f7093306..0b685da2 100644 --- a/src/main/java/seng302/models/stream/StreamParser.java +++ b/src/main/java/seng302/models/stream/StreamParser.java @@ -1,6 +1,23 @@ package seng302.models.stream; +import java.io.IOException; +import java.io.StringReader; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Date; +import java.util.Map; +import java.util.TimeZone; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.PriorityBlockingQueue; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; @@ -8,19 +25,6 @@ import seng302.models.Yacht; import seng302.models.stream.packets.BoatPositionPacket; import seng302.models.stream.packets.StreamPacket; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.IOException; -import java.io.StringReader; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.concurrent.PriorityBlockingQueue; -import seng302.models.stream.XMLParser; - /** * The purpose of this class is to take in the stream of divided packets so they can be read * and parsed in by turning the byte arrays into useful data. There are two public static hashmaps @@ -29,6 +33,7 @@ import seng302.models.stream.XMLParser; */ public class StreamParser extends Thread{ + public static ConcurrentHashMap> markPositions = new ConcurrentHashMap<>(); public static ConcurrentHashMap> boatPositions = new ConcurrentHashMap<>(); private String threadName; private Thread t; @@ -400,6 +405,20 @@ public class StreamParser extends Thread{ })); } boatPositions.get(boatId).put(boatPacket); + } else if (deviceType == 3){ + BoatPositionPacket markPacket = new BoatPositionPacket(boatId, timeValid, lat, lon, heading, groundSpeed); + + //add a new priority que to the boatPositions HashMap + if (!markPositions.containsKey(boatId)) { + markPositions.put(boatId, + new PriorityBlockingQueue<>(256, new Comparator() { + @Override + public int compare(BoatPositionPacket p1, BoatPositionPacket p2) { + return (int) (p1.getTimeValid() - p2.getTimeValid()); + } + })); + } + markPositions.get(boatId).put(markPacket); } } diff --git a/src/main/java/seng302/models/stream/XMLParser.java b/src/main/java/seng302/models/stream/XMLParser.java index 43595cea..53bb0889 100644 --- a/src/main/java/seng302/models/stream/XMLParser.java +++ b/src/main/java/seng302/models/stream/XMLParser.java @@ -1,6 +1,9 @@ package seng302.models.stream; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -9,10 +12,6 @@ import seng302.models.Yacht; import seng302.models.mark.GateMark; import seng302.models.mark.Mark; import seng302.models.mark.MarkType; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; import seng302.models.mark.SingleMark; /** @@ -349,7 +348,6 @@ public class XMLParser { } } - System.out.println(marksList.size()); if (marksList.size() == 1) { return marksList.get(0); } else if (marksList.size() == 2) { From b692ddcbe609598a8993fee15687452d06f936b7 Mon Sep 17 00:00:00 2001 From: Alistair McIntyre Date: Thu, 18 May 2017 18:39:23 +1200 Subject: [PATCH 5/9] Marks and gates correctly displaying from XML messages and mark(boat) position packets. Will need a little polishing but marks and gates are moving around. #story[923] #pair[ajm412, ptg19] --- .../seng302/controllers/CanvasController.java | 7 +- .../java/seng302/models/mark/MarkGroup.java | 92 +++++++++++-------- 2 files changed, 57 insertions(+), 42 deletions(-) diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index c7fbcb6e..40642f41 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -223,7 +223,7 @@ public class CanvasController { } } - void UpdateMarkGroup (long raceId, MarkGroup markGroup) { + private void UpdateMarkGroup (long raceId, MarkGroup markGroup) { PriorityBlockingQueue movementQueue = StreamParser.markPositions.get(raceId); if (movementQueue.size() > 0){ try { @@ -260,13 +260,12 @@ public class CanvasController { if (mark.getMarkType() == MarkType.SINGLE_MARK) { SingleMark sMark = (SingleMark) mark; - MarkGroup markGroup = new MarkGroup(mark, findScaledXY(sMark)); + MarkGroup markGroup = new MarkGroup(sMark, findScaledXY(sMark)); markGroups.add(markGroup); } else { GateMark gMark = (GateMark) mark; - MarkGroup markGroup = new MarkGroup(mark, findScaledXY(gMark.getSingleMark1()), - findScaledXY(gMark.getSingleMark2())); //should be 2 objects in the list. + MarkGroup markGroup = new MarkGroup(gMark, findScaledXY(gMark.getSingleMark1()), findScaledXY(gMark.getSingleMark2())); //should be 2 objects in the list. markGroups.add(markGroup); } } diff --git a/src/main/java/seng302/models/mark/MarkGroup.java b/src/main/java/seng302/models/mark/MarkGroup.java index bdd1491d..ecb0cdc7 100644 --- a/src/main/java/seng302/models/mark/MarkGroup.java +++ b/src/main/java/seng302/models/mark/MarkGroup.java @@ -21,7 +21,12 @@ public class MarkGroup extends Group { private List marks = new ArrayList<>(); private Mark mainMark; - public MarkGroup (Mark mark, Point2D... points) { + /** + * Constructor for singleMark groups + * @param mark + * @param points + */ + public MarkGroup (SingleMark mark, Point2D points) { marks.add(mark); mainMark = mark; Color color = Color.BLACK; @@ -31,43 +36,54 @@ public class MarkGroup extends Group { color = Color.RED; } Circle markCircle; - if (mark.getMarkType() == MarkType.SINGLE_MARK) { - markCircle = new Circle( - points[0].getX(), - points[0].getY(), - MARK_RADIUS, - color - ); - super.getChildren().add(markCircle); - } else { - markCircle = new Circle( - points[0].getX(), - points[0].getY(), - MARK_RADIUS, - color - ); - super.getChildren().add(markCircle); + markCircle = new Circle( + points.getX(), + points.getY(), + MARK_RADIUS, + color + ); + super.getChildren().add(markCircle); + } - markCircle = new Circle( - points[1].getX(), - points[1].getY(), - MARK_RADIUS, - color - ); - super.getChildren().add(markCircle); - Line line = new Line( - points[0].getX(), - points[0].getY(), - points[1].getX(), - points[1].getY() - ); - line.setStrokeWidth(LINE_THICKNESS); - line.setStroke(color); - if (mark.getMarkType() == MarkType.OPEN_GATE) { - line.getStrokeDashArray().addAll(DASHED_GAP_LEN, DASHED_LINE_LEN); - } - super.getChildren().add(line); + public MarkGroup(GateMark mark, Point2D points1, Point2D points2) { + marks.add(mark.getSingleMark1()); + marks.add(mark.getSingleMark2()); + mainMark = mark; + Color color = Color.BLACK; + if (mark.getName().equals("Start")){ + color = Color.GREEN; + } else if (mark.getName().equals("Finish")){ + color = Color.RED; } + Circle markCircle; + markCircle = new Circle( + points1.getX(), + points1.getY(), + MARK_RADIUS, + color + ); + super.getChildren().add(markCircle); + + markCircle = new Circle( + points2.getX(), + points2.getY(), + MARK_RADIUS, + color + ); + super.getChildren().add(markCircle); + Line line = new Line( + points1.getX(), + points1.getY(), + points2.getX(), + points2.getY() + ); + line.setStrokeWidth(LINE_THICKNESS); + line.setStroke(color); + if (mark.getMarkType() == MarkType.OPEN_GATE) { + line.getStrokeDashArray().addAll(DASHED_GAP_LEN, DASHED_LINE_LEN); + } + super.getChildren().add(line); + } public void moveMarkTo (double x, double y, long raceId) @@ -80,12 +96,12 @@ public class MarkGroup extends Group { Circle markCircle1 = (Circle) super.getChildren().get(0); Circle markCircle2 = (Circle) super.getChildren().get(1); Line connectingLine = (Line) super.getChildren().get(2); - if (marks.get(1).getId() == raceId) { + if (marks.get(0).getId() == raceId) { markCircle1.setCenterX(x); markCircle1.setCenterY(y); connectingLine.setStartX(markCircle1.getCenterX()); connectingLine.setStartY(markCircle1.getCenterY()); - } else if (marks.get(2).getId() == raceId) { + } else if (marks.get(1).getId() == raceId) { markCircle2.setCenterX(x); markCircle2.setCenterY(y); connectingLine.setEndX(markCircle2.getCenterX()); From be633c0e60b4b5a73c3eb25c94abac8700c60bd0 Mon Sep 17 00:00:00 2001 From: alistairjmcintyre Date: Mon, 22 May 2017 13:22:55 +1200 Subject: [PATCH 6/9] Marks display correctly on the canvas, no double ups or anything like that left. #[issue10] --- src/main/java/seng302/App.java | 2 +- .../seng302/controllers/CanvasController.java | 3 ++- .../java/seng302/models/mark/GateMark.java | 2 -- .../java/seng302/models/mark/MarkGroup.java | 1 + .../java/seng302/models/mark/SingleMark.java | 1 - .../java/seng302/models/stream/XMLParser.java | 19 ++++++++++++++++--- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index 28d7e923..c7a764c0 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -63,7 +63,7 @@ public class App extends Application { //Change the StreamReceiver in this else block to change the default data source. else{ // sr = new StreamReceiver("localhost", 4949, "RaceStream"); - sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream"); + sr = new StreamReceiver("localhost", 4949, "RaceStream"); } sr.start(); diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 40642f41..43c4b40a 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -255,7 +255,7 @@ public class CanvasController { private void initializeMarks() { Map allMarks = StreamParser.getXmlObject().getRaceXML().getCompoundMarks(); - + System.out.println(allMarks); for (Mark mark : allMarks.values()) { if (mark.getMarkType() == MarkType.SINGLE_MARK) { SingleMark sMark = (SingleMark) mark; @@ -270,6 +270,7 @@ public class CanvasController { } } group.getChildren().addAll(markGroups); + System.out.println(group.getChildren()); } class ResizableCanvas extends Canvas { diff --git a/src/main/java/seng302/models/mark/GateMark.java b/src/main/java/seng302/models/mark/GateMark.java index ffcf2b51..79943114 100644 --- a/src/main/java/seng302/models/mark/GateMark.java +++ b/src/main/java/seng302/models/mark/GateMark.java @@ -39,12 +39,10 @@ public class GateMark extends Mark { } public double getLatitude(){ - //return (this.getSingleMark1().getLatitude() + this.getSingleMark2().getLatitude()) / 2; return (this.getSingleMark1().getLatitude()); } public double getLongitude(){ - //return (this.getSingleMark1().getLongitude() + this.getSingleMark2().getLongitude()) / 2; return (this.getSingleMark1().getLongitude()); } diff --git a/src/main/java/seng302/models/mark/MarkGroup.java b/src/main/java/seng302/models/mark/MarkGroup.java index ecb0cdc7..c87ae174 100644 --- a/src/main/java/seng302/models/mark/MarkGroup.java +++ b/src/main/java/seng302/models/mark/MarkGroup.java @@ -90,6 +90,7 @@ public class MarkGroup extends Group { { if (mainMark.getMarkType() == MarkType.SINGLE_MARK) { Circle markCircle = (Circle) super.getChildren().get(0); + markCircle.setCenterX(x); markCircle.setCenterY(y); } else { diff --git a/src/main/java/seng302/models/mark/SingleMark.java b/src/main/java/seng302/models/mark/SingleMark.java index d4b4f3f2..9239552a 100644 --- a/src/main/java/seng302/models/mark/SingleMark.java +++ b/src/main/java/seng302/models/mark/SingleMark.java @@ -11,7 +11,6 @@ public class SingleMark extends Mark { private String name; private int id; - /** * Represents a marker * diff --git a/src/main/java/seng302/models/stream/XMLParser.java b/src/main/java/seng302/models/stream/XMLParser.java index 53bb0889..19f9b9db 100644 --- a/src/main/java/seng302/models/stream/XMLParser.java +++ b/src/main/java/seng302/models/stream/XMLParser.java @@ -239,6 +239,9 @@ public class XMLParser { private ArrayList compoundMarkSequence; private ArrayList courseLimit; + // ensures there's no duplicate marks. + private List seenSourceIDs = new ArrayList(); + /** * Constructor for a RaceXMLObject. * Takes the information from a Document object and creates a more usable format. @@ -312,6 +315,7 @@ public class XMLParser { private Map createCompoundMarks(Element docEle) { Map cMarks = new HashMap<>(); + NodeList cMarkList = docEle.getElementsByTagName("Course").item(0).getChildNodes(); for (int i = 0; i < cMarkList.getLength(); i++) { Node cMarkNode = cMarkList.item(i); @@ -319,14 +323,15 @@ public class XMLParser { if (cMarkNode.getNodeName().equals("CompoundMark")) { Integer markID = getNodeAttributeInt(cMarkNode, "CompoundMarkID"); Mark mark = createMark(cMarkNode); - - cMarks.put(markID, mark); + if (mark != null) { + cMarks.put(markID, mark); + } } } - return cMarks; } + private Mark createMark(Node compoundMark) { List marksList = new ArrayList<>(); @@ -348,6 +353,14 @@ public class XMLParser { } } + for (SingleMark mark : marksList) { + if (seenSourceIDs.contains(mark.getId())) { + return null; + } else { + seenSourceIDs.add(mark.getId()); + } + } + if (marksList.size() == 1) { return marksList.get(0); } else if (marksList.size() == 2) { From 78573fa837863fdb286416b33df165f773402ec8 Mon Sep 17 00:00:00 2001 From: Alistair McIntyre Date: Mon, 22 May 2017 15:10:05 +1200 Subject: [PATCH 7/9] Made start/finish lines a different color. #story[923] --- src/main/java/seng302/App.java | 2 +- .../seng302/controllers/CanvasController.java | 5 ++--- .../java/seng302/models/stream/XMLParser.java | 18 ++++++++++-------- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index c7a764c0..28d7e923 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -63,7 +63,7 @@ public class App extends Application { //Change the StreamReceiver in this else block to change the default data source. else{ // sr = new StreamReceiver("localhost", 4949, "RaceStream"); - sr = new StreamReceiver("localhost", 4949, "RaceStream"); + sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream"); } sr.start(); diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 43c4b40a..398cc712 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -254,9 +254,9 @@ public class CanvasController { } private void initializeMarks() { - Map allMarks = StreamParser.getXmlObject().getRaceXML().getCompoundMarks(); + ArrayList allMarks = StreamParser.getXmlObject().getRaceXML().getCompoundMarks(); System.out.println(allMarks); - for (Mark mark : allMarks.values()) { + for (Mark mark : allMarks) { if (mark.getMarkType() == MarkType.SINGLE_MARK) { SingleMark sMark = (SingleMark) mark; @@ -270,7 +270,6 @@ public class CanvasController { } } group.getChildren().addAll(markGroups); - System.out.println(group.getChildren()); } class ResizableCanvas extends Canvas { diff --git a/src/main/java/seng302/models/stream/XMLParser.java b/src/main/java/seng302/models/stream/XMLParser.java index 19f9b9db..97dfe37a 100644 --- a/src/main/java/seng302/models/stream/XMLParser.java +++ b/src/main/java/seng302/models/stream/XMLParser.java @@ -235,7 +235,7 @@ public class XMLParser { //Non atomic race attributes private ArrayList participants; - private Map course; + private ArrayList course; private ArrayList compoundMarkSequence; private ArrayList courseLimit; @@ -312,22 +312,24 @@ public class XMLParser { } - private Map createCompoundMarks(Element docEle) { - Map cMarks = new HashMap<>(); - + private ArrayList createCompoundMarks(Element docEle) { + ArrayList cMarks = new ArrayList<>(); NodeList cMarkList = docEle.getElementsByTagName("Course").item(0).getChildNodes(); for (int i = 0; i < cMarkList.getLength(); i++) { Node cMarkNode = cMarkList.item(i); - if (cMarkNode.getNodeName().equals("CompoundMark")) { - Integer markID = getNodeAttributeInt(cMarkNode, "CompoundMarkID"); Mark mark = createMark(cMarkNode); if (mark != null) { - cMarks.put(markID, mark); + cMarks.add(mark); } } } + + // This is awful but it works. + cMarks.get(0).setName("Start"); + cMarks.get(cMarks.size()-1).setName("Finish"); + return cMarks; } @@ -397,7 +399,7 @@ public class XMLParser { return participants; } - public Map getCompoundMarks() { + public ArrayList getCompoundMarks() { return course; } From c30629542be84df83ebc3b735a72e4cc77715015 Mon Sep 17 00:00:00 2001 From: Alistair McIntyre Date: Mon, 22 May 2017 15:27:23 +1200 Subject: [PATCH 8/9] Merged develop into issue10 branch. Fixed merge issues and completed manual testing before merge request. #story[923] --- src/main/java/seng302/controllers/CanvasController.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 4850b4f4..2884de27 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -189,8 +189,8 @@ public class CanvasController { boatGroup.move(); } for (MarkGroup markGroup : markGroups) { - for (int id : markGroup.getRaceIds()) { - if (StreamParser.boatPositions.containsKey(id)) { + for (Long id : markGroup.getRaceIds()) { + if (StreamParser.markPositions.containsKey(id)) { updateMarkGroup(id, markGroup); } } @@ -224,8 +224,8 @@ public class CanvasController { } } - void updateMarkGroup (int raceId, MarkGroup markGroup) { - PriorityBlockingQueue movementQueue = StreamParser.boatPositions.get(raceId); + void updateMarkGroup (long raceId, MarkGroup markGroup) { + PriorityBlockingQueue movementQueue = StreamParser.markPositions.get(raceId); if (movementQueue.size() > 0){ try { BoatPositionPacket positionPacket = movementQueue.take(); @@ -256,7 +256,6 @@ public class CanvasController { private void initializeMarks() { ArrayList allMarks = StreamParser.getXmlObject().getRaceXML().getCompoundMarks(); - System.out.println(allMarks); for (Mark mark : allMarks) { if (mark.getMarkType() == MarkType.SINGLE_MARK) { SingleMark sMark = (SingleMark) mark; From e51c9669691141c6bbc9a5c3d85ff2703a3567b8 Mon Sep 17 00:00:00 2001 From: Alistair McIntyre Date: Mon, 22 May 2017 16:05:24 +1200 Subject: [PATCH 9/9] Made sure only boats in participant list are replaced. Also removed mark coloring as it wasn't as accurate as was necessary. #story[923] --- src/main/java/seng302/App.java | 2 +- .../seng302/controllers/CanvasController.java | 17 +++++++++++++---- .../seng302/models/stream/StreamParser.java | 1 + .../java/seng302/models/stream/XMLParser.java | 4 ---- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/main/java/seng302/App.java b/src/main/java/seng302/App.java index 28d7e923..ac264db6 100644 --- a/src/main/java/seng302/App.java +++ b/src/main/java/seng302/App.java @@ -63,7 +63,7 @@ public class App extends Application { //Change the StreamReceiver in this else block to change the default data source. else{ // sr = new StreamReceiver("localhost", 4949, "RaceStream"); - sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream"); + sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream"); } sr.start(); diff --git a/src/main/java/seng302/controllers/CanvasController.java b/src/main/java/seng302/controllers/CanvasController.java index 2884de27..0bdeae25 100644 --- a/src/main/java/seng302/controllers/CanvasController.java +++ b/src/main/java/seng302/controllers/CanvasController.java @@ -26,6 +26,7 @@ import seng302.models.mark.SingleMark; 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; /** @@ -244,11 +245,19 @@ public class CanvasController { Map boats = StreamParser.getBoats(); Group boatAnnotations = new Group(); + ArrayList participants = StreamParser.getXmlObject().getRaceXML().getParticipants(); + ArrayList participantIDs = new ArrayList<>(); + for (Participant p : participants) { + participantIDs.add(p.getsourceID()); + } + for (Yacht boat : boats.values()) { - boat.setColour(Colors.getColor()); - BoatGroup boatGroup = new BoatGroup(boat, boat.getColour()); - boatGroups.add(boatGroup); - boatAnnotations.getChildren().add(boatGroup.getLowPriorityAnnotations()); + if (participantIDs.contains(boat.getSourceID())) { + boat.setColour(Colors.getColor()); + BoatGroup boatGroup = new BoatGroup(boat, boat.getColour()); + boatGroups.add(boatGroup); + boatAnnotations.getChildren().add(boatGroup.getLowPriorityAnnotations()); + } } group.getChildren().add(boatAnnotations); group.getChildren().addAll(boatGroups); diff --git a/src/main/java/seng302/models/stream/StreamParser.java b/src/main/java/seng302/models/stream/StreamParser.java index 0b685da2..f800379c 100644 --- a/src/main/java/seng302/models/stream/StreamParser.java +++ b/src/main/java/seng302/models/stream/StreamParser.java @@ -307,6 +307,7 @@ public class StreamParser extends Thread{ boats = xmlObject.getBoatXML().getCompetingBoats(); } if (messageType == 6) { //6 is race info xml + newRaceXmlReceived = true; } } diff --git a/src/main/java/seng302/models/stream/XMLParser.java b/src/main/java/seng302/models/stream/XMLParser.java index 97dfe37a..674a2611 100644 --- a/src/main/java/seng302/models/stream/XMLParser.java +++ b/src/main/java/seng302/models/stream/XMLParser.java @@ -326,10 +326,6 @@ public class XMLParser { } } - // This is awful but it works. - cMarks.get(0).setName("Start"); - cMarks.get(cMarks.size()-1).setName("Finish"); - return cMarks; }