mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Merge branch 'issue#10_unifying_marks' into 'develop'
Issue#10 unifying marks Marks work properly, reading boat position packets and moving. First and last marks are colored green and red respectively. See merge request !35
This commit is contained in:
@@ -18,7 +18,6 @@ public class App extends Application {
|
||||
primaryStage.setScene(new Scene(root));
|
||||
primaryStage.setMaximized(true);
|
||||
|
||||
|
||||
primaryStage.show();
|
||||
primaryStage.setOnCloseRequest(e -> {
|
||||
StreamParser.appClose();
|
||||
@@ -65,7 +64,6 @@ public class App extends Application {
|
||||
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();
|
||||
|
||||
@@ -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,19 @@ 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.XMLParser.RaceXMLObject.Participant;
|
||||
import seng302.models.stream.packets.BoatPositionPacket;
|
||||
|
||||
/**
|
||||
* 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
|
||||
initializeBoats();
|
||||
initializeMarks();
|
||||
timer = new AnimationTimer() {
|
||||
|
||||
@Override
|
||||
@@ -118,6 +128,7 @@ public class CanvasController {
|
||||
}
|
||||
|
||||
// TODO: 1/05/17 cir27 - Make the RaceObjects update on the actual delay.
|
||||
elapsedNanos = 1000 / 60;
|
||||
updateGroups();
|
||||
if (StreamParser.isRaceFinished()) {
|
||||
this.stop();
|
||||
@@ -179,8 +190,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 +225,8 @@ public class CanvasController {
|
||||
}
|
||||
}
|
||||
|
||||
void updateMarkGroup (int raceId, MarkGroup markGroup) {
|
||||
PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.boatPositions.get(raceId);
|
||||
void updateMarkGroup (long raceId, MarkGroup markGroup) {
|
||||
PriorityBlockingQueue<BoatPositionPacket> movementQueue = StreamParser.markPositions.get(raceId);
|
||||
if (movementQueue.size() > 0){
|
||||
try {
|
||||
BoatPositionPacket positionPacket = movementQueue.take();
|
||||
@@ -234,16 +245,42 @@ public class CanvasController {
|
||||
Map<Integer, Yacht> boats = StreamParser.getBoats();
|
||||
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()) {
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
ResizableCanvas() {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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,12 +125,11 @@ public abstract class Mark {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -23,7 +21,12 @@ public class MarkGroup extends Group {
|
||||
private List<Mark> 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;
|
||||
@@ -33,61 +36,73 @@ 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[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);
|
||||
}
|
||||
markCircle = new Circle(
|
||||
points.getX(),
|
||||
points.getY(),
|
||||
MARK_RADIUS,
|
||||
color
|
||||
);
|
||||
super.getChildren().add(markCircle);
|
||||
}
|
||||
|
||||
public void moveMarkTo (double x, double y, int raceId)
|
||||
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)
|
||||
{
|
||||
if (mainMark.getMarkType() == MarkType.SINGLE_MARK) {
|
||||
Circle markCircle = (Circle) super.getChildren().get(0);
|
||||
|
||||
markCircle.setCenterX(x);
|
||||
markCircle.setCenterY(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) {
|
||||
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());
|
||||
@@ -104,8 +119,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();
|
||||
|
||||
@@ -11,7 +11,6 @@ public class SingleMark extends Mark {
|
||||
private String name;
|
||||
private int id;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a marker
|
||||
*
|
||||
|
||||
@@ -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<Long, PriorityBlockingQueue<BoatPositionPacket>> markPositions = new ConcurrentHashMap<>();
|
||||
public static ConcurrentHashMap<Long, PriorityBlockingQueue<BoatPositionPacket>> boatPositions = new ConcurrentHashMap<>();
|
||||
private String threadName;
|
||||
private Thread t;
|
||||
@@ -302,6 +307,7 @@ public class StreamParser extends Thread{
|
||||
boats = xmlObject.getBoatXML().getCompetingBoats();
|
||||
}
|
||||
if (messageType == 6) { //6 is race info xml
|
||||
|
||||
newRaceXmlReceived = true;
|
||||
}
|
||||
}
|
||||
@@ -400,6 +406,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<BoatPositionPacket>() {
|
||||
@Override
|
||||
public int compare(BoatPositionPacket p1, BoatPositionPacket p2) {
|
||||
return (int) (p1.getTimeValid() - p2.getTimeValid());
|
||||
}
|
||||
}));
|
||||
}
|
||||
markPositions.get(boatId).put(markPacket);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
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;
|
||||
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 +33,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 +57,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 +88,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 +104,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 +120,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 +137,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 +154,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 +170,7 @@ public class XMLParser {
|
||||
}
|
||||
|
||||
public class RegattaXMLObject {
|
||||
|
||||
//Regatta Info
|
||||
private Integer regattaID;
|
||||
private String regattaName;
|
||||
@@ -160,6 +182,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 +196,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 +235,17 @@ public class XMLParser {
|
||||
|
||||
//Non atomic race attributes
|
||||
private ArrayList<Participant> participants;
|
||||
private ArrayList<CompoundMark> course;
|
||||
private ArrayList<Mark> course;
|
||||
private ArrayList<Corner> compoundMarkSequence;
|
||||
private ArrayList<Limit> courseLimit;
|
||||
|
||||
// ensures there's no duplicate marks.
|
||||
private List<Long> seenSourceIDs = new ArrayList<Long>();
|
||||
|
||||
/**
|
||||
* 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 +257,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 +283,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 +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; }
|
||||
public ArrayList<CompoundMark> getCompoundMarks() { return course; }
|
||||
public ArrayList<Corner> getCompoundMarkSequence() { return compoundMarkSequence; }
|
||||
public ArrayList<Limit> getCourseLimit() { return courseLimit; }
|
||||
private ArrayList<Mark> createCompoundMarks(Element docEle) {
|
||||
ArrayList<Mark> 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")) {
|
||||
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 {
|
||||
|
||||
Integer sourceID;
|
||||
String entry;
|
||||
|
||||
@@ -294,65 +417,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<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 getsourceID() {
|
||||
return sourceID;
|
||||
}
|
||||
|
||||
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 String getEntry() {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
public class Corner {
|
||||
|
||||
private Integer seqID;
|
||||
private Integer compoundMarkID;
|
||||
private String rounding;
|
||||
@@ -365,13 +440,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 +469,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 +505,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 +525,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 +536,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<Double> getZoneLimits() { return zoneLimits; }
|
||||
public ArrayList<Yacht> 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<Double> getZoneLimits() {
|
||||
return zoneLimits;
|
||||
}
|
||||
|
||||
public ArrayList<Yacht> getBoats() {
|
||||
return boats;
|
||||
}
|
||||
|
||||
public Map<Integer, Yacht> 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; }
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user