Merge remote-tracking branch 'origin/develop' into 38b_LayLines

This commit is contained in:
William Muir
2017-05-22 18:15:58 +12:00
9 changed files with 482 additions and 309 deletions
-2
View File
@@ -21,7 +21,6 @@ public class App extends Application {
primaryStage.setScene(new Scene(root)); primaryStage.setScene(new Scene(root));
primaryStage.setMaximized(true); primaryStage.setMaximized(true);
primaryStage.show(); primaryStage.show();
primaryStage.setOnCloseRequest(e -> { primaryStage.setOnCloseRequest(e -> {
StreamParser.appClose(); StreamParser.appClose();
@@ -68,7 +67,6 @@ public class App extends Application {
else { else {
// sr = new StreamReceiver("localhost", 4949, "RaceStream"); // sr = new StreamReceiver("localhost", 4949, "RaceStream");
sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream"); sr = new StreamReceiver("livedata.americascup.com", 4941, "RaceStream");
// sr = new StreamReceiver("csse-s302staff.canterbury.ac.nz", 4941, "RaceStream");
} }
sr.start(); sr.start();
@@ -1,6 +1,11 @@
package seng302.controllers; 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.beans.property.SimpleDoubleProperty;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.geometry.Point2D; import javafx.geometry.Point2D;
@@ -10,15 +15,19 @@ import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.text.Font; import javafx.scene.text.Font;
import seng302.models.*; import seng302.models.BoatGroup;
import seng302.models.mark.*; 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.StreamParser;
import seng302.models.stream.packets.BoatPositionPacket;
import seng302.models.stream.XMLParser; import seng302.models.stream.XMLParser;
import seng302.models.stream.XMLParser.RaceXMLObject.Limit; import seng302.models.stream.XMLParser.RaceXMLObject.Limit;
import seng302.models.mark.Mark; import seng302.models.stream.XMLParser.RaceXMLObject.Participant;
import java.util.*; import seng302.models.stream.packets.BoatPositionPacket;
import java.util.concurrent.PriorityBlockingQueue;
/** /**
* Created by ptg19 on 15/03/17. * Created by ptg19 on 15/03/17.
@@ -97,6 +106,7 @@ public class CanvasController {
// TODO: 1/05/17 wmu16 - Change this call to now draw the marks as from the xml // TODO: 1/05/17 wmu16 - Change this call to now draw the marks as from the xml
initializeBoats(); initializeBoats();
initializeMarks();
timer = new AnimationTimer() { timer = new AnimationTimer() {
@Override @Override
@@ -118,6 +128,7 @@ public class CanvasController {
} }
// TODO: 1/05/17 cir27 - Make the RaceObjects update on the actual delay. // TODO: 1/05/17 cir27 - Make the RaceObjects update on the actual delay.
elapsedNanos = 1000 / 60;
updateGroups(); updateGroups();
if (StreamParser.isRaceFinished()) { if (StreamParser.isRaceFinished()) {
this.stop(); this.stop();
@@ -179,8 +190,8 @@ public class CanvasController {
boatGroup.move(); boatGroup.move();
} }
for (MarkGroup markGroup : markGroups) { for (MarkGroup markGroup : markGroups) {
for (int id : markGroup.getRaceIds()) { for (Long id : markGroup.getRaceIds()) {
if (StreamParser.boatPositions.containsKey(id)) { if (StreamParser.markPositions.containsKey(id)) {
updateMarkGroup(id, markGroup); updateMarkGroup(id, markGroup);
} }
} }
@@ -214,8 +225,8 @@ public class CanvasController {
} }
} }
void updateMarkGroup (int raceId, MarkGroup markGroup) { void updateMarkGroup (long raceId, MarkGroup markGroup) {
PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.boatPositions.get(raceId); PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.markPositions.get(raceId);
if (movementQueue.size() > 0){ if (movementQueue.size() > 0){
try { try {
BoatPositionPacket positionPacket = movementQueue.take(); BoatPositionPacket positionPacket = movementQueue.take();
@@ -234,16 +245,42 @@ public class CanvasController {
Map<Integer, Yacht> boats = StreamParser.getBoats(); Map<Integer, Yacht> boats = StreamParser.getBoats();
Group boatAnnotations = new Group(); Group boatAnnotations = new Group();
ArrayList<Participant> participants = StreamParser.getXmlObject().getRaceXML().getParticipants();
ArrayList<Integer> participantIDs = new ArrayList<>();
for (Participant p : participants) {
participantIDs.add(p.getsourceID());
}
for (Yacht boat : boats.values()) { for (Yacht boat : boats.values()) {
if (participantIDs.contains(boat.getSourceID())) {
boat.setColour(Colors.getColor()); boat.setColour(Colors.getColor());
BoatGroup boatGroup = new BoatGroup(boat, boat.getColour()); BoatGroup boatGroup = new BoatGroup(boat, boat.getColour());
boatGroups.add(boatGroup); boatGroups.add(boatGroup);
boatAnnotations.getChildren().add(boatGroup.getLowPriorityAnnotations()); boatAnnotations.getChildren().add(boatGroup.getLowPriorityAnnotations());
} }
}
group.getChildren().add(boatAnnotations); group.getChildren().add(boatAnnotations);
group.getChildren().addAll(boatGroups); group.getChildren().addAll(boatGroups);
} }
private void initializeMarks() {
ArrayList<Mark> allMarks = StreamParser.getXmlObject().getRaceXML().getCompoundMarks();
for (Mark mark : allMarks) {
if (mark.getMarkType() == MarkType.SINGLE_MARK) {
SingleMark sMark = (SingleMark) mark;
MarkGroup markGroup = new MarkGroup(sMark, findScaledXY(sMark));
markGroups.add(markGroup);
} else {
GateMark gMark = (GateMark) mark;
MarkGroup markGroup = new MarkGroup(gMark, findScaledXY(gMark.getSingleMark1()), findScaledXY(gMark.getSingleMark2())); //should be 2 objects in the list.
markGroups.add(markGroup);
}
}
group.getChildren().addAll(markGroups);
}
class ResizableCanvas extends Canvas { class ResizableCanvas extends Canvas {
ResizableCanvas() { ResizableCanvas() {
+61 -49
View File
@@ -18,13 +18,14 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
/** /**
* BoatGroup is a javafx group that by default contains a graphical objects for representing a 2 dimensional boat. * BoatGroup is a javafx group that by default contains a graphical objects for representing a 2
* It contains a single polygon for the boat, a group of lines to show it's path, a wake object and two text labels to * dimensional boat. It contains a single polygon for the boat, a group of lines to show it's path,
* annotate the boat teams name and the boats velocity. The boat will update it's position onscreen everytime * a wake object and two text labels to annotate the boat teams name and the boats velocity. The
* UpdatePosition is called unless the window is minimized in which case it attempts to store animations and apply them * boat will update it's position onscreen everytime UpdatePosition is called unless the window is
* when the window is maximised. * minimized in which case it attempts to store animations and apply them when the window is
* maximised.
*/ */
public class BoatGroup extends Group{ public class BoatGroup extends Group {
//Constants for drawing //Constants for drawing
private static final double TEAMNAME_X_OFFSET = 10d; private static final double TEAMNAME_X_OFFSET = 10d;
@@ -62,36 +63,40 @@ public class BoatGroup extends Group{
/** /**
* Creates a BoatGroup with the default triangular boat polygon. * Creates a BoatGroup with the default triangular boat polygon.
* @param boat The boat that the BoatGroup will represent. Must contain an ID which will be used to tell which *
* BoatGroup to update. * @param boat The boat that the BoatGroup will represent. Must contain an ID which will be used
* to tell which BoatGroup to update.
* @param color The colour of the boat polygon and the trailing line. * @param color The colour of the boat polygon and the trailing line.
*/ */
public BoatGroup (Yacht boat, Color color){ public BoatGroup(Yacht boat, Color color) {
this.boat = boat; this.boat = boat;
initChildren(color); initChildren(color);
this.textColor = color; this.textColor = color;
} }
/** /**
* Creates a BoatGroup with the boat being the default polygon. The head of the boat should be at point (0,0). * Creates a BoatGroup with the boat being the default polygon. The head of the boat should be
* @param boat The boat that the BoatGroup will represent. Must contain an ID which will be used to tell which * at point (0,0).
* BoatGroup to update. *
* @param boat The boat that the BoatGroup will represent. Must contain an ID which will be used
* to tell which BoatGroup to update.
* @param color The colour of the boat polygon and the trailing line. * @param color The colour of the boat polygon and the trailing line.
* @param points An array of co-ordinates x1,y1,x2,y2,x3,y3... that will make up the boat polygon. * @param points An array of co-ordinates x1,y1,x2,y2,x3,y3... that will make up the boat
* polygon.
*/ */
public BoatGroup (Yacht boat, Color color, double... points) public BoatGroup(Yacht boat, Color color, double... points) {
{
this.boat = boat; this.boat = boat;
initChildren(color, points); initChildren(color, points);
} }
/** /**
* Return a text object with caching and a color applied * Return a text object with caching and a color applied
*
* @param defaultText The default text to display * @param defaultText The default text to display
* @param fill The text fill color * @param fill The text fill color
* @return The text object * @return The text object
*/ */
private Text getTextObject(String defaultText, Color fill){ private Text getTextObject(String defaultText, Color fill) {
Text text = new Text(defaultText); Text text = new Text(defaultText);
text.setFill(fill); text.setFill(fill);
@@ -103,10 +108,12 @@ public class BoatGroup extends Group{
/** /**
* Creates the javafx objects that will be the in the group by default. * Creates the javafx objects that will be the in the group by default.
*
* @param color The colour of the boat polygon and the trailing line. * @param color The colour of the boat polygon and the trailing line.
* @param points An array of co-ordinates x1,y1,x2,y2,x3,y3... that will make up the boat polygon. * @param points An array of co-ordinates x1,y1,x2,y2,x3,y3... that will make up the boat
* polygon.
*/ */
private void initChildren (Color color, double... points) { private void initChildren(Color color, double... points) {
textColor = color; textColor = color;
destinationSet = false; destinationSet = false;
@@ -132,14 +139,14 @@ public class BoatGroup extends Group{
updateLastMarkRoundingTime(); updateLastMarkRoundingTime();
updateTimeTillNextMark(); updateTimeTillNextMark();
if (estTimeToNextMarkObject != null){ if (estTimeToNextMarkObject != null) {
estTimeToNextMarkObject.setX(ESTTIMETONEXTMARK_X_OFFSET); estTimeToNextMarkObject.setX(ESTTIMETONEXTMARK_X_OFFSET);
estTimeToNextMarkObject.setY(ESTTIMETONEXTMARK_Y_OFFSET); estTimeToNextMarkObject.setY(ESTTIMETONEXTMARK_Y_OFFSET);
estTimeToNextMarkObject estTimeToNextMarkObject
.relocate(estTimeToNextMarkObject.getX(), estTimeToNextMarkObject.getY()); .relocate(estTimeToNextMarkObject.getX(), estTimeToNextMarkObject.getY());
} }
if (legTimeObject != null){ if (legTimeObject != null) {
legTimeObject.setX(LEGTIME_X_OFFSET); legTimeObject.setX(LEGTIME_X_OFFSET);
legTimeObject.setY(LEGTIME_Y_OFFSET); legTimeObject.setY(LEGTIME_Y_OFFSET);
legTimeObject.relocate(legTimeObject.getX(), legTimeObject.getY()); legTimeObject.relocate(legTimeObject.getX(), legTimeObject.getY());
@@ -154,9 +161,10 @@ public class BoatGroup extends Group{
/** /**
* Creates the javafx objects that will be the in the group by default. * Creates the javafx objects that will be the in the group by default.
*
* @param color The colour of the boat polygon and the trailing line. * @param color The colour of the boat polygon and the trailing line.
*/ */
private void initChildren (Color color) { private void initChildren(Color color) {
initChildren(color, initChildren(color,
-BOAT_WIDTH / 2, BOAT_HEIGHT / 2, -BOAT_WIDTH / 2, BOAT_HEIGHT / 2,
0.0, -BOAT_HEIGHT / 2, 0.0, -BOAT_HEIGHT / 2,
@@ -164,7 +172,9 @@ public class BoatGroup extends Group{
} }
/** /**
* Moves the boat and its children annotations from its current coordinates by specified amounts. * Moves the boat and its children annotations from its current coordinates by specified
* amounts.
*
* @param dx The amount to move the X coordinate by * @param dx The amount to move the X coordinate by
* @param dy The amount to move the Y coordinate by * @param dy The amount to move the Y coordinate by
*/ */
@@ -186,6 +196,7 @@ public class BoatGroup extends Group{
/** /**
* Moves the boat and its children annotations to coordinates specified * Moves the boat and its children annotations to coordinates specified
*
* @param x The X coordinate to move the boat to * @param x The X coordinate to move the boat to
* @param y The Y coordinate to move the boat to * @param y The Y coordinate to move the boat to
*/ */
@@ -213,11 +224,11 @@ public class BoatGroup extends Group{
/** /**
* Updates the time until next mark label, will create a label if one doesn't exist * Updates the time until next mark label, will create a label if one doesn't exist
*/ */
private void updateTimeTillNextMark(){ private void updateTimeTillNextMark() {
if (estTimeToNextMarkObject == null){ if (estTimeToNextMarkObject == null) {
estTimeToNextMarkObject = getTextObject("", textColor); estTimeToNextMarkObject = getTextObject("Next mark: -", textColor);
} }
if (boat.getEstimateTimeAtNextMark() != null){ if (boat.getEstimateTimeAtNextMark() != null) {
DateFormat format = new SimpleDateFormat("mm:ss"); DateFormat format = new SimpleDateFormat("mm:ss");
String timeToNextMark = format String timeToNextMark = format
.format(boat.getEstimateTimeAtNextMark() - StreamParser.getCurrentTimeLong()); .format(boat.getEstimateTimeAtNextMark() - StreamParser.getCurrentTimeLong());
@@ -230,18 +241,17 @@ public class BoatGroup extends Group{
/** /**
* Updates the time since last mark rounding, will create a label if one doesn't exist * Updates the time since last mark rounding, will create a label if one doesn't exist
*/ */
private void updateLastMarkRoundingTime(){ private void updateLastMarkRoundingTime() {
if (legTimeObject == null){ if (legTimeObject == null) {
legTimeObject = getTextObject("", textColor); legTimeObject = getTextObject("Last mark: -", textColor);
} }
if (boat.getMarkRoundingTime() != null){ if (boat.getMarkRoundingTime() != null) {
DateFormat format = new SimpleDateFormat("mm:ss"); DateFormat format = new SimpleDateFormat("mm:ss");
String elapsedTime = format String elapsedTime = format
.format(StreamParser.getCurrentTimeLong() - boat.getMarkRoundingTime()); .format(StreamParser.getCurrentTimeLong() - boat.getMarkRoundingTime());
legTimeObject.setText("Last mark: " + elapsedTime); legTimeObject.setText("Last mark: " + elapsedTime);
} } else {
else{
legTimeObject.setText("Last mark: -"); legTimeObject.setText("Last mark: -");
} }
@@ -255,14 +265,14 @@ public class BoatGroup extends Group{
moveGroupBy(xIncrement, yIncrement); moveGroupBy(xIncrement, yIncrement);
framesToMove = framesToMove - 1; framesToMove = framesToMove - 1;
if (framesToMove <= 0){ if (framesToMove <= 0) {
isStopped = true; isStopped = true;
} }
if (distanceTravelled > 70){ if (distanceTravelled > 70) {
distanceTravelled = 0d; distanceTravelled = 0d;
if (lastPoint != null){ if (lastPoint != null) {
Line l = new Line( Line l = new Line(
lastPoint.getX(), lastPoint.getX(),
lastPoint.getY(), lastPoint.getY(),
@@ -276,18 +286,19 @@ public class BoatGroup extends Group{
lineGroup.getChildren().add(l); lineGroup.getChildren().add(l);
} }
if (destinationSet){ if (destinationSet) {
lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY()); lastPoint = new Point2D(boatPoly.getLayoutX(), boatPoly.getLayoutY());
} }
} }
wake.updatePosition(1000/60); wake.updatePosition(1000 / 60);
} }
/** /**
* Calculates the rotational velocity required to reach the rotationalGoal from the currentRotation. * Calculates the rotational velocity required to reach the rotationalGoal from the
* currentRotation.
*/ */
protected Double calculateRotationalVelocity (Double rotationalGoal) { protected Double calculateRotationalVelocity(Double rotationalGoal) {
Double rotationalVelocity = 0.0; Double rotationalVelocity = 0.0;
if (Math.abs(rotationalGoal - lastRotation) > 180) { if (Math.abs(rotationalGoal - lastRotation) > 180) {
@@ -310,22 +321,24 @@ public class BoatGroup extends Group{
/** /**
* Sets the destination of the boat and the headng it should have once it reaches * Sets the destination of the boat and the headng it should have once it reaches
*
* @param newXValue The X co-ordinate the boat needs to move to. * @param newXValue The X co-ordinate the boat needs to move to.
* @param newYValue The Y co-ordinate the boat needs to move to. * @param newYValue The Y co-ordinate the boat needs to move to.
* @param rotation Rotation to move graphics to. * @param rotation Rotation to move graphics to.
* @param timeValid the time the position values are valid for * @param timeValid the time the position values are valid for
*/ */
public void setDestination (double newXValue, double newYValue, double rotation, double groundSpeed, long timeValid, double frameRate, long id) { public void setDestination(double newXValue, double newYValue, double rotation,
if (lastTimeValid == 0){ double groundSpeed, long timeValid, double frameRate, long id) {
if (lastTimeValid == 0) {
lastTimeValid = timeValid - 200; lastTimeValid = timeValid - 200;
moveTo(newXValue, newYValue, rotation); moveTo(newXValue, newYValue, rotation);
} }
framesToMove = Math.round((frameRate/(1000.0f/(timeValid-lastTimeValid)))); framesToMove = Math.round((frameRate / (1000.0f / (timeValid - lastTimeValid))));
double dx = newXValue - boatPoly.getLayoutX(); double dx = newXValue - boatPoly.getLayoutX();
double dy = newYValue - boatPoly.getLayoutY(); double dy = newYValue - boatPoly.getLayoutY();
xIncrement = dx/framesToMove; xIncrement = dx / framesToMove;
yIncrement = dy/framesToMove; yIncrement = dy / framesToMove;
destinationSet = true; destinationSet = true;
@@ -361,7 +374,6 @@ public class BoatGroup extends Group{
} }
public void setTeamNameObjectVisible(Boolean visible) { public void setTeamNameObjectVisible(Boolean visible) {
teamNameObject.setVisible(visible); teamNameObject.setVisible(visible);
} }
@@ -400,13 +412,13 @@ public class BoatGroup extends Group{
} }
/** /**
* Due to javaFX limitations annotations associated with a boat that you want to appear below all boats in the * Due to javaFX limitations annotations associated with a boat that you want to appear below
* Z-axis need to be pulled out of the BoatGroup and added to the parent group of the BoatGroups. This function * all boats in the Z-axis need to be pulled out of the BoatGroup and added to the parent group
* returns these annotations as a group. * of the BoatGroups. This function returns these annotations as a group.
* *
* @return A group containing low priority annotations. * @return A group containing low priority annotations.
*/ */
public Group getLowPriorityAnnotations () { public Group getLowPriorityAnnotations() {
Group group = new Group(); Group group = new Group();
group.getChildren().addAll(wake, lineGroup); group.getChildren().addAll(wake, lineGroup);
return group; return group;
@@ -39,12 +39,10 @@ public class GateMark extends Mark {
} }
public double getLatitude(){ public double getLatitude(){
//return (this.getSingleMark1().getLatitude() + this.getSingleMark2().getLatitude()) / 2;
return (this.getSingleMark1().getLatitude()); return (this.getSingleMark1().getLatitude());
} }
public double getLongitude(){ public double getLongitude(){
//return (this.getSingleMark1().getLongitude() + this.getSingleMark2().getLongitude()) / 2;
return (this.getSingleMark1().getLongitude()); return (this.getSingleMark1().getLongitude());
} }
+2 -3
View File
@@ -10,7 +10,7 @@ public abstract class Mark {
private MarkType markType; private MarkType markType;
private double latitude; private double latitude;
private double longitude; private double longitude;
private int id; private long id;
/** /**
* Create a mark instance by passing its name and type * Create a mark instance by passing its name and type
@@ -125,12 +125,11 @@ public abstract class Mark {
return longitude; return longitude;
} }
public int getId() { public long getId() {
return id; return id;
} }
public void setId(int id) { public void setId(int id) {
this.id = id; this.id = id;
} }
} }
@@ -1,14 +1,12 @@
package seng302.models.mark; package seng302.models.mark;
import java.util.ArrayList;
import java.util.List;
import javafx.geometry.Point2D; import javafx.geometry.Point2D;
import javafx.scene.Group; import javafx.scene.Group;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.shape.Circle; import javafx.scene.shape.Circle;
import javafx.scene.shape.Line; 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. * Created by CJIRWIN on 26/04/2017.
@@ -23,7 +21,12 @@ public class MarkGroup extends Group {
private List<Mark> marks = new ArrayList<>(); private List<Mark> marks = new ArrayList<>();
private Mark mainMark; 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); marks.add(mark);
mainMark = mark; mainMark = mark;
Color color = Color.BLACK; Color color = Color.BLACK;
@@ -33,35 +36,46 @@ public class MarkGroup extends Group {
color = Color.RED; color = Color.RED;
} }
Circle markCircle; Circle markCircle;
if (mark.getMarkType() == MarkType.SINGLE_MARK) {
markCircle = new Circle( markCircle = new Circle(
points[0].getX(), points.getX(),
points[0].getY(), points.getY(),
MARK_RADIUS, MARK_RADIUS,
color color
); );
super.getChildren().add(markCircle); super.getChildren().add(markCircle);
} else { }
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( markCircle = new Circle(
points[0].getX(), points1.getX(),
points[0].getY(), points1.getY(),
MARK_RADIUS, MARK_RADIUS,
color color
); );
super.getChildren().add(markCircle); super.getChildren().add(markCircle);
markCircle = new Circle( markCircle = new Circle(
points[1].getX(), points2.getX(),
points[1].getY(), points2.getY(),
MARK_RADIUS, MARK_RADIUS,
color color
); );
super.getChildren().add(markCircle); super.getChildren().add(markCircle);
Line line = new Line( Line line = new Line(
points[0].getX(), points1.getX(),
points[0].getY(), points1.getY(),
points[1].getX(), points2.getX(),
points[1].getY() points2.getY()
); );
line.setStrokeWidth(LINE_THICKNESS); line.setStrokeWidth(LINE_THICKNESS);
line.setStroke(color); line.setStroke(color);
@@ -69,25 +83,26 @@ public class MarkGroup extends Group {
line.getStrokeDashArray().addAll(DASHED_GAP_LEN, DASHED_LINE_LEN); line.getStrokeDashArray().addAll(DASHED_GAP_LEN, DASHED_LINE_LEN);
} }
super.getChildren().add(line); super.getChildren().add(line);
}
} }
public void moveMarkTo (double x, double y, int raceId) public void moveMarkTo (double x, double y, long raceId)
{ {
if (mainMark.getMarkType() == MarkType.SINGLE_MARK) { if (mainMark.getMarkType() == MarkType.SINGLE_MARK) {
Circle markCircle = (Circle) super.getChildren().get(0); Circle markCircle = (Circle) super.getChildren().get(0);
markCircle.setCenterX(x); markCircle.setCenterX(x);
markCircle.setCenterY(y); markCircle.setCenterY(y);
} else { } else {
Circle markCircle1 = (Circle) super.getChildren().get(0); Circle markCircle1 = (Circle) super.getChildren().get(0);
Circle markCircle2 = (Circle) super.getChildren().get(1); Circle markCircle2 = (Circle) super.getChildren().get(1);
Line connectingLine = (Line) super.getChildren().get(2); Line connectingLine = (Line) super.getChildren().get(2);
if (marks.get(1).getId() == raceId) { if (marks.get(0).getId() == raceId) {
markCircle1.setCenterX(x); markCircle1.setCenterX(x);
markCircle1.setCenterY(y); markCircle1.setCenterY(y);
connectingLine.setStartX(markCircle1.getCenterX()); connectingLine.setStartX(markCircle1.getCenterX());
connectingLine.setStartY(markCircle1.getCenterY()); connectingLine.setStartY(markCircle1.getCenterY());
} else if (marks.get(2).getId() == raceId) { } else if (marks.get(1).getId() == raceId) {
markCircle2.setCenterX(x); markCircle2.setCenterX(x);
markCircle2.setCenterY(y); markCircle2.setCenterY(y);
connectingLine.setEndX(markCircle2.getCenterX()); connectingLine.setEndX(markCircle2.getCenterX());
@@ -104,8 +119,8 @@ public class MarkGroup extends Group {
return false; return false;
} }
public int[] getRaceIds () { public long[] getRaceIds () {
int[] idArray = new int[marks.size()]; long[] idArray = new long[marks.size()];
int i = 0; int i = 0;
for (Mark mark : marks) for (Mark mark : marks)
idArray[i++] = mark.getId(); idArray[i++] = mark.getId();
@@ -11,7 +11,6 @@ public class SingleMark extends Mark {
private String name; private String name;
private int id; private int id;
/** /**
* Represents a marker * Represents a marker
* *
@@ -1,6 +1,23 @@
package seng302.models.stream; 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.w3c.dom.Document;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
@@ -8,19 +25,6 @@ import seng302.models.Yacht;
import seng302.models.stream.packets.BoatPositionPacket; import seng302.models.stream.packets.BoatPositionPacket;
import seng302.models.stream.packets.StreamPacket; 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 * 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 * 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 class StreamParser extends Thread{
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> markPositions = new ConcurrentHashMap<>();
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> boatPositions = new ConcurrentHashMap<>(); public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> boatPositions = new ConcurrentHashMap<>();
private String threadName; private String threadName;
private Thread t; private Thread t;
@@ -302,6 +307,7 @@ public class StreamParser extends Thread{
boats = xmlObject.getBoatXML().getCompetingBoats(); boats = xmlObject.getBoatXML().getCompetingBoats();
} }
if (messageType == 6) { //6 is race info xml if (messageType == 6) { //6 is race info xml
newRaceXmlReceived = true; newRaceXmlReceived = true;
} }
} }
@@ -400,6 +406,20 @@ public class StreamParser extends Thread{
})); }));
} }
boatPositions.get(boatId).put(boatPacket); 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<BoatPositionPacket>() {
@Override
public int compare(BoatPositionPacket p1, BoatPositionPacket p2) {
return (int) (p1.getTimeValid() - p2.getTimeValid());
}
}));
}
markPositions.get(boatId).put(markPacket);
} }
} }
+234 -139
View File
@@ -1,15 +1,18 @@
package seng302.models.stream; 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.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import seng302.models.Yacht; import seng302.models.Yacht;
import seng302.models.mark.GateMark;
import seng302.models.mark.Mark;
import seng302.models.mark.MarkType; import seng302.models.mark.MarkType;
import seng302.models.mark.SingleMark;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/** /**
* Class to create an XML object from the XML Packet Messages. * Class to create an XML object from the XML Packet Messages.
@@ -21,7 +24,6 @@ import java.util.Map;
* *
* xmlP = new XMLParser(doc, xmlMessageType); * xmlP = new XMLParser(doc, xmlMessageType);
* RegattaXMLObject rXmlObj = xmlP.createRegattaXML(); // creates a regattaXML object. * RegattaXMLObject rXmlObj = xmlP.createRegattaXML(); // creates a regattaXML object.
*
*/ */
public class XMLParser { public class XMLParser {
@@ -31,10 +33,12 @@ public class XMLParser {
private RegattaXMLObject regattaXML; private RegattaXMLObject regattaXML;
private BoatXMLObject boatXML; private BoatXMLObject boatXML;
public XMLParser() {} public XMLParser() {
}
/** /**
* Constructor for XMLParser * Constructor for XMLParser
*
* @param doc Document to create XML object. * @param doc Document to create XML object.
* @param messageType Defines if a message is a RegattaXML(5), RaceXML(6), BoatXML(7). * @param messageType Defines if a message is a RegattaXML(5), RaceXML(6), BoatXML(7).
*/ */
@@ -53,13 +57,22 @@ public class XMLParser {
} }
} }
public RaceXMLObject getRaceXML() { return raceXML; } public RaceXMLObject getRaceXML() {
public RegattaXMLObject getRegattaXML() { return regattaXML; } return raceXML;
public BoatXMLObject getBoatXML() { return boatXML; } }
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. * Returns the text content of a given child element tag, assuming it exists, as an Integer.
*
* @param ele Document Element with child elements. * @param ele Document Element with child elements.
* @param tag Tag to find in document elements child elements. * @param tag Tag to find in document elements child elements.
* @return Text content from tag if found, null otherwise. * @return Text content from tag if found, null otherwise.
@@ -75,6 +88,7 @@ public class XMLParser {
/** /**
* Returns the text content of a given child element tag, assuming it exists, as an String. * Returns the text content of a given child element tag, assuming it exists, as an String.
*
* @param ele Document Element with child elements. * @param ele Document Element with child elements.
* @param tag Tag to find in document elements child elements. * @param tag Tag to find in document elements child elements.
* @return Text content from tag if found, null otherwise. * @return Text content from tag if found, null otherwise.
@@ -90,6 +104,7 @@ public class XMLParser {
/** /**
* Returns the text content of a given child element tag, assuming it exists, as a Double. * Returns the text content of a given child element tag, assuming it exists, as a Double.
*
* @param ele Document Element with child elements. * @param ele Document Element with child elements.
* @param tag Tag to find in document elements child elements. * @param tag Tag to find in document elements child elements.
* @return Text content from tag if found, null otherwise. * @return Text content from tag if found, null otherwise.
@@ -105,9 +120,11 @@ public class XMLParser {
/** /**
* Returns the text content of an attribute of a given Node, assuming it exists, as a String. * 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 n A node object that should have some attributes
* @param attr The attribute you want to get from the given node. * @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) { private static String getNodeAttributeString(Node n, String attr) {
Node attrItem = n.getAttributes().getNamedItem(attr); Node attrItem = n.getAttributes().getNamedItem(attr);
@@ -120,9 +137,11 @@ public class XMLParser {
/** /**
* Returns the text content of an attribute of a given Node, assuming it exists, as an Integer. * 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 n A node object that should have some attributes
* @param attr The attribute you want to get from the given node. * @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) { private static Integer getNodeAttributeInt(Node n, String attr) {
Node attrItem = n.getAttributes().getNamedItem(attr); Node attrItem = n.getAttributes().getNamedItem(attr);
@@ -135,9 +154,11 @@ public class XMLParser {
/** /**
* Returns the text content of an attribute of a given Node, assuming it exists, as a Double. * 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 n A node object that should have some attributes
* @param attr The attribute you want to get from the given node. * @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) { private static Double getNodeAttributeDouble(Node n, String attr) {
Node attrItem = n.getAttributes().getNamedItem(attr); Node attrItem = n.getAttributes().getNamedItem(attr);
@@ -149,6 +170,7 @@ public class XMLParser {
} }
public class RegattaXMLObject { public class RegattaXMLObject {
//Regatta Info //Regatta Info
private Integer regattaID; private Integer regattaID;
private String regattaName; private String regattaName;
@@ -160,6 +182,7 @@ public class XMLParser {
/** /**
* Constructor for a RegattaXMLObject. * Constructor for a RegattaXMLObject.
* Takes the information from a Document object and creates a more usable format. * Takes the information from a Document object and creates a more usable format.
*
* @param doc XML Document Object * @param doc XML Document Object
*/ */
RegattaXMLObject(Document doc) { RegattaXMLObject(Document doc) {
@@ -173,12 +196,29 @@ public class XMLParser {
this.utcOffset = getElementInt(docEle, "UtcOffset"); this.utcOffset = getElementInt(docEle, "UtcOffset");
} }
public Integer getRegattaID() { return regattaID; } public Integer getRegattaID() {
public String getRegattaName() { return regattaName; } return regattaID;
public String getCourseName() { return courseName; } }
public Double getCentralLat() { return centralLat; }
public Double getCentralLng() { return centralLng; } public String getRegattaName() {
public Integer getUtcOffset() { return utcOffset; } return regattaName;
}
public String getCourseName() {
return courseName;
}
public Double getCentralLat() {
return centralLat;
}
public Double getCentralLng() {
return centralLng;
}
public Integer getUtcOffset() {
return utcOffset;
}
} }
@@ -195,13 +235,17 @@ public class XMLParser {
//Non atomic race attributes //Non atomic race attributes
private ArrayList<Participant> participants; private ArrayList<Participant> participants;
private ArrayList<CompoundMark> course; private ArrayList<Mark> course;
private ArrayList<Corner> compoundMarkSequence; private ArrayList<Corner> compoundMarkSequence;
private ArrayList<Limit> courseLimit; private ArrayList<Limit> courseLimit;
// ensures there's no duplicate marks.
private List<Long> seenSourceIDs = new ArrayList<Long>();
/** /**
* Constructor for a RaceXMLObject. * Constructor for a RaceXMLObject.
* Takes the information from a Document object and creates a more usable format. * Takes the information from a Document object and creates a more usable format.
*
* @param doc XML Document Object * @param doc XML Document Object
*/ */
RaceXMLObject(Document doc) { RaceXMLObject(Document doc) {
@@ -213,8 +257,9 @@ public class XMLParser {
this.creationTimeDate = getElementString(docEle, "CreationTimeDate"); this.creationTimeDate = getElementString(docEle, "CreationTimeDate");
Node raceStart = docEle.getElementsByTagName("RaceStartTime").item(0); Node raceStart = docEle.getElementsByTagName("RaceStartTime").item(0);
this.raceStartTime = getNodeAttributeString(raceStart, "Start") ; this.raceStartTime = getNodeAttributeString(raceStart, "Start");
this.postponeStatus = Boolean.parseBoolean(getNodeAttributeString(raceStart, "Postpone")); this.postponeStatus = Boolean
.parseBoolean(getNodeAttributeString(raceStart, "Postpone"));
//Participants //Participants
participants = new ArrayList<>(); participants = new ArrayList<>();
@@ -238,21 +283,13 @@ public class XMLParser {
} }
//Course //Course
course = new ArrayList<>(); course = createCompoundMarks(docEle);
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 Mark Sequence //Course Mark Sequence
compoundMarkSequence = new ArrayList<>(); 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++) { for (int i = 0; i < cornerList.getLength(); i++) {
Node cornerNode = cornerList.item(i); Node cornerNode = cornerList.item(i);
if (cornerNode.getNodeName().equals("Corner")) { if (cornerNode.getNodeName().equals("Corner")) {
@@ -274,18 +311,104 @@ 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<Participant> getParticipants() { return participants; } private ArrayList<Mark> createCompoundMarks(Element docEle) {
public ArrayList<CompoundMark> getCompoundMarks() { return course; } ArrayList<Mark> cMarks = new ArrayList<>();
public ArrayList<Corner> getCompoundMarkSequence() { return compoundMarkSequence; }
public ArrayList<Limit> getCourseLimit() { return courseLimit; } 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")) {
Mark mark = createMark(cMarkNode);
if (mark != null) {
cMarks.add(mark);
}
}
}
return cMarks;
}
private Mark createMark(Node compoundMark) {
List<SingleMark> 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);
}
}
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) {
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<Participant> getParticipants() {
return participants;
}
public ArrayList<Mark> getCompoundMarks() {
return course;
}
public ArrayList<Corner> getCompoundMarkSequence() {
return compoundMarkSequence;
}
public ArrayList<Limit> getCourseLimit() {
return courseLimit;
}
public class Participant { public class Participant {
Integer sourceID; Integer sourceID;
String entry; String entry;
@@ -294,65 +417,17 @@ public class XMLParser {
this.entry = entry; this.entry = entry;
} }
public Integer getsourceID() { return sourceID; } public Integer getsourceID() {
public String getEntry() { return entry; } return sourceID;
} }
public class CompoundMark { public String getEntry() {
private Integer markID; return entry;
private String cMarkName;
private MarkType markType;
private ArrayList<Mark> 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 getMarkID() { return markID; }
public String getcMarkName() { return cMarkName; }
public MarkType getMarkType() { return markType; }
public ArrayList<Mark> 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 class Corner { public class Corner {
private Integer seqID; private Integer seqID;
private Integer compoundMarkID; private Integer compoundMarkID;
private String rounding; private String rounding;
@@ -365,13 +440,25 @@ public class XMLParser {
this.zoneSize = getNodeAttributeInt(cornerNode, "ZoneSize"); this.zoneSize = getNodeAttributeInt(cornerNode, "ZoneSize");
} }
public Integer getSeqID() { return seqID; } public Integer getSeqID() {
public Integer getCompoundMarkID() { return compoundMarkID; } return seqID;
public String getRounding() { return rounding; } }
public Integer getZoneSize() { return zoneSize; }
public Integer getCompoundMarkID() {
return compoundMarkID;
}
public String getRounding() {
return rounding;
}
public Integer getZoneSize() {
return zoneSize;
}
} }
public class Limit { public class Limit {
private Integer seqID; private Integer seqID;
private Double lat; private Double lat;
private Double lng; private Double lng;
@@ -382,9 +469,17 @@ public class XMLParser {
this.lng = getNodeAttributeDouble(limitNode, "Lon"); this.lng = getNodeAttributeDouble(limitNode, "Lon");
} }
public Integer getSeqID() { return seqID; } public Integer getSeqID() {
public Double getLat() { return lat; } return seqID;
public Double getLng() { return lng; } }
public Double getLat() {
return lat;
}
public Double getLng() {
return lng;
}
} }
} }
@@ -410,6 +505,7 @@ public class XMLParser {
/** /**
* Constructor for a BoatXMLObject. * Constructor for a BoatXMLObject.
* Takes the information from a Document object and creates a more usable format. * Takes the information from a Document object and creates a more usable format.
*
* @param doc XML Document Object * @param doc XML Document Object
*/ */
BoatXMLObject(Document doc) { BoatXMLObject(Document doc) {
@@ -429,7 +525,7 @@ public class XMLParser {
Node zoneLimitsList = settingsList.item(7); Node zoneLimitsList = settingsList.item(7);
this.zoneLimits = new ArrayList<>(); this.zoneLimits = new ArrayList<>();
for (int i = 0; i < zoneLimitsList.getAttributes().getLength(); i++) { 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)); this.zoneLimits.add(getNodeAttributeDouble(zoneLimitsList, tag));
} }
@@ -450,51 +546,50 @@ public class XMLParser {
competingBoats.put(boat.getSourceID(), boat); competingBoats.put(boat.getSourceID(), boat);
} }
} }
//System.out.println(this.getBoats());
} }
} }
public String getLastModified() { return lastModified; } public String getLastModified() {
public Integer getVersion() { return version; } return lastModified;
public String getBoatType() { return boatType; } }
public Double getBoatLength() { return boatLength; }
public Double getHullLength() { return hullLength; } public Integer getVersion() {
public Double getMarkZoneSize() { return markZoneSize; } return version;
public Double getCourseZoneSize() { return courseZoneSize; } }
public ArrayList<Double> getZoneLimits() { return zoneLimits; }
public ArrayList<Yacht> getBoats() { return boats; } 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<Double> getZoneLimits() {
return zoneLimits;
}
public ArrayList<Yacht> getBoats() {
return boats;
}
public Map<Integer, Yacht> getCompetingBoats() { public Map<Integer, Yacht> getCompetingBoats() {
return competingBoats; 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; }
//
// }
} }
} }