Merge branch 'splitIntoTwoModules' of https://eng-git.canterbury.ac.nz/seng302-2017/team-7 into splitIntoTwoModules
This commit is contained in:
@@ -16,4 +16,5 @@
|
|||||||
# https://www.kernel.org/pub/software/scm/git/docs/git-shortlog.html
|
# https://www.kernel.org/pub/software/scm/git/docs/git-shortlog.html
|
||||||
# http://stacktoheap.com/blog/2013/01/06/using-mailmap-to-fix-authors-list-in-git/
|
# http://stacktoheap.com/blog/2013/01/06/using-mailmap-to-fix-authors-list-in-git/
|
||||||
Erika Savell <[email protected]>
|
Erika Savell <[email protected]>
|
||||||
Connor Taylor-Brown <[email protected]> <[email protected]>
|
Connor Taylor-Brown <[email protected]> <[email protected]>
|
||||||
|
Fraser Cope <[email protected]>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import seng302.Model.Event;
|
|||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
public class App extends Application {
|
public class App extends Application {
|
||||||
|
|
||||||
@@ -25,9 +26,10 @@ public class App extends Application {
|
|||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) {
|
public void start(Stage primaryStage) {
|
||||||
try {
|
try {
|
||||||
|
OutputStream outputStream = System.out;//TEMP currently using System.out, but should replace this with tcp socket we are sending over.
|
||||||
RaceDataSource raceData = new RaceXMLReader("raceXML/bermuda_AC35.xml");
|
RaceDataSource raceData = new RaceXMLReader("raceXML/bermuda_AC35.xml");
|
||||||
RegattaDataSource regattaData = new RegattaXMLReader("mockXML/regattaTest.xml");
|
RegattaDataSource regattaData = new RegattaXMLReader("mockXML/regattaTest.xml");
|
||||||
Event raceEvent = new Event(raceData, regattaData);
|
Event raceEvent = new Event(raceData, regattaData, outputStream);
|
||||||
raceEvent.start();
|
raceEvent.start();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ public class Constants {
|
|||||||
|
|
||||||
public static final int NMToMetersConversion = 1852; // 1 nautical mile = 1852 meters
|
public static final int NMToMetersConversion = 1852; // 1 nautical mile = 1852 meters
|
||||||
|
|
||||||
|
//Knots x this = meters per second.
|
||||||
|
public static final double KnotsToMetersPerSecondConversionFactor = 0.514444;
|
||||||
|
|
||||||
public static final GPSCoordinate startLineMarker1 = new GPSCoordinate(32.296577, -64.854304);
|
public static final GPSCoordinate startLineMarker1 = new GPSCoordinate(32.296577, -64.854304);
|
||||||
public static final GPSCoordinate startLineMarker2 = new GPSCoordinate(32.293771, -64.855242);
|
public static final GPSCoordinate startLineMarker2 = new GPSCoordinate(32.293771, -64.855242);
|
||||||
public static final GPSCoordinate mark1 = new GPSCoordinate(32.293039, -64.843983);
|
public static final GPSCoordinate mark1 = new GPSCoordinate(32.293039, -64.843983);
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import javax.xml.transform.TransformerException;
|
|||||||
import javax.xml.transform.TransformerFactory;
|
import javax.xml.transform.TransformerFactory;
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -47,7 +48,7 @@ public class RaceData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void createXML() {
|
public String createXML() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||||
@@ -148,14 +149,13 @@ public class RaceData {
|
|||||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||||
Transformer transformer = transformerFactory.newTransformer();
|
Transformer transformer = transformerFactory.newTransformer();
|
||||||
DOMSource source = new DOMSource(doc);
|
DOMSource source = new DOMSource(doc);
|
||||||
StreamResult result = new StreamResult(System.out);
|
|
||||||
|
|
||||||
// Output to console for testing
|
//Serialize document.
|
||||||
// StreamResult result = new StreamResult(System.out);
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
StreamResult result = new StreamResult(stringWriter);
|
||||||
|
transformer.transform(source,result);
|
||||||
|
|
||||||
transformer.transform(source, result);
|
return stringWriter.toString();
|
||||||
|
|
||||||
System.out.println("File saved!");
|
|
||||||
|
|
||||||
|
|
||||||
} catch (ParserConfigurationException pce) {
|
} catch (ParserConfigurationException pce) {
|
||||||
@@ -164,6 +164,7 @@ public class RaceData {
|
|||||||
tfe.printStackTrace();
|
tfe.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return "";//TEMP this is probably bad. This shouldn't really be reached, but seems necessary due to the use of catches above.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package seng302.Exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by f123 on 25-Apr-17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An exception thrown when we cannot generate Boats.xml and send an XML message.
|
||||||
|
*/
|
||||||
|
public class InvalidBoatDataException extends RuntimeException
|
||||||
|
{
|
||||||
|
|
||||||
|
public InvalidBoatDataException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidBoatDataException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package seng302.Exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by f123 on 25-Apr-17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown when we cannot generate Race.xml data, and send an XML message.
|
||||||
|
*/
|
||||||
|
public class InvalidRaceDataException extends RuntimeException
|
||||||
|
{
|
||||||
|
public InvalidRaceDataException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidRaceDataException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package seng302.Exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by f123 on 25-Apr-17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An exception thrown when a Regatta.xml message cannot be generated and sent.
|
||||||
|
*/
|
||||||
|
public class InvalidRegattaDataException extends RuntimeException
|
||||||
|
{
|
||||||
|
public InvalidRegattaDataException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidRegattaDataException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,9 @@ public class BoatInRace extends Boat {
|
|||||||
private StringProperty position;
|
private StringProperty position;
|
||||||
private double heading;
|
private double heading;
|
||||||
|
|
||||||
|
///While generating BoatLocationMessages, each one needs a sequence number relating to each boat.
|
||||||
|
private long sequenceNumber = 0;
|
||||||
|
|
||||||
private boolean trackVisible = true;
|
private boolean trackVisible = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -263,4 +266,18 @@ public class BoatInRace extends Boat {
|
|||||||
this.position.set(position);
|
this.position.set(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current sequence number, and increments the internal value, such that that next call will return a value 1 larger than the current call.
|
||||||
|
* @return Current sequence number.
|
||||||
|
*/
|
||||||
|
public long getNextSequenceNumber(){
|
||||||
|
//Make a copy of current value.
|
||||||
|
long oldNumber = this.sequenceNumber;
|
||||||
|
//Increment.
|
||||||
|
this.sequenceNumber += 1;
|
||||||
|
//Return the previous value.
|
||||||
|
return oldNumber;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,24 @@ import org.w3c.dom.Element;
|
|||||||
import seng302.Data.RaceData;
|
import seng302.Data.RaceData;
|
||||||
import seng302.Mock.Regatta;
|
import seng302.Mock.Regatta;
|
||||||
import seng302.Mock.RegattaDataSource;
|
import seng302.Mock.RegattaDataSource;
|
||||||
|
import seng302.Exceptions.InvalidBoatDataException;
|
||||||
|
import seng302.Exceptions.InvalidRaceDataException;
|
||||||
|
import seng302.Exceptions.InvalidRegattaDataException;
|
||||||
import seng302.Model.Race;
|
import seng302.Model.Race;
|
||||||
import seng302.RaceDataSource;
|
import seng302.RaceDataSource;
|
||||||
|
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.transform.Transformer;
|
import javax.xml.transform.Transformer;
|
||||||
|
import javax.xml.transform.TransformerConfigurationException;
|
||||||
|
import javax.xml.transform.TransformerException;
|
||||||
import javax.xml.transform.TransformerFactory;
|
import javax.xml.transform.TransformerFactory;
|
||||||
import javax.xml.transform.dom.DOMSource;
|
import javax.xml.transform.dom.DOMSource;
|
||||||
import javax.xml.transform.stream.StreamResult;
|
import javax.xml.transform.stream.StreamResult;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,34 +33,50 @@ public class Event {
|
|||||||
|
|
||||||
RaceDataSource raceDataSource;
|
RaceDataSource raceDataSource;
|
||||||
RegattaDataSource regattaDataSource;
|
RegattaDataSource regattaDataSource;
|
||||||
|
///The stream to which we send all data.
|
||||||
|
private OutputStream outputStream;
|
||||||
|
|
||||||
public Event(RaceDataSource raceData, RegattaDataSource regattaData) {
|
public Event(RaceDataSource raceData, RegattaDataSource regattaData, OutputStream outputStream) {
|
||||||
this.raceDataSource = raceData;
|
this.raceDataSource = raceData;
|
||||||
this.regattaDataSource = regattaData;
|
this.regattaDataSource = regattaData;
|
||||||
|
this.outputStream = outputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start()
|
||||||
|
{
|
||||||
|
System.out.println("\nREGATTA DATA\n");//TEMP REMOVE debug
|
||||||
sendRegattaData();
|
sendRegattaData();
|
||||||
|
System.out.println("\nRACE DATA\n");//TEMP REMOVE debug
|
||||||
sendRaceData();
|
sendRaceData();
|
||||||
|
System.out.println("\nBOAT DATA\n");//TEMP REMOVE debug
|
||||||
sendBoatData();
|
sendBoatData();
|
||||||
|
|
||||||
Race newRace = new Race(raceDataSource, 15);
|
System.out.println("RACE STARTING!!\n\n");//TEMP REMOVE debug
|
||||||
|
|
||||||
|
Race newRace = new Race(raceDataSource, 15, this.outputStream);
|
||||||
new Thread((newRace)).start();
|
new Thread((newRace)).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void sendRegattaData() {
|
public void sendRegattaData() throws InvalidRegattaDataException {
|
||||||
try {
|
|
||||||
|
|
||||||
Regatta regatta = regattaDataSource.getRegatta();
|
Regatta regatta = regattaDataSource.getRegatta();
|
||||||
|
|
||||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
DocumentBuilder docBuilder = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
docBuilder = docFactory.newDocumentBuilder();
|
||||||
|
}
|
||||||
|
catch (ParserConfigurationException e)
|
||||||
|
{
|
||||||
|
throw new InvalidRegattaDataException();
|
||||||
|
}
|
||||||
|
|
||||||
//root element
|
//root element
|
||||||
Document doc = docBuilder.newDocument();
|
Document doc = docBuilder.newDocument();
|
||||||
Element rootElement = doc.createElement("RegattaConfig");
|
Element rootElement = doc.createElement("RegattaConfig");
|
||||||
doc.appendChild(rootElement);
|
doc.appendChild(rootElement);
|
||||||
|
|
||||||
//regattaID element
|
//regattaID element
|
||||||
Element regattaID = doc.createElement("RegattaID");
|
Element regattaID = doc.createElement("RegattaID");
|
||||||
@@ -93,120 +118,198 @@ public class Event {
|
|||||||
magneticVariation.appendChild(doc.createTextNode(Double.toString(regatta.getMagneticVariation())));
|
magneticVariation.appendChild(doc.createTextNode(Double.toString(regatta.getMagneticVariation())));
|
||||||
rootElement.appendChild(magneticVariation);
|
rootElement.appendChild(magneticVariation);
|
||||||
|
|
||||||
TransformerFactory trasformerFactory = TransformerFactory.newInstance();
|
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||||
Transformer transformer = trasformerFactory.newTransformer();
|
Transformer transformer = null;
|
||||||
DOMSource source = new DOMSource(doc);
|
try
|
||||||
|
{
|
||||||
|
transformer = transformerFactory.newTransformer();
|
||||||
|
}
|
||||||
|
catch (TransformerConfigurationException e)
|
||||||
|
{
|
||||||
|
throw new InvalidRegattaDataException();
|
||||||
|
}
|
||||||
|
DOMSource source = new DOMSource(doc);
|
||||||
|
|
||||||
//print XML object to check for correctness
|
|
||||||
StreamResult result = new StreamResult(System.out);
|
|
||||||
|
//Serialize document.
|
||||||
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
StreamResult result = new StreamResult(stringWriter);
|
||||||
|
try
|
||||||
|
{
|
||||||
transformer.transform(source,result);
|
transformer.transform(source,result);
|
||||||
|
}
|
||||||
|
catch (TransformerException e)
|
||||||
|
{
|
||||||
|
throw new InvalidRegattaDataException();
|
||||||
|
}
|
||||||
|
//TODO now we should place in XML message object.
|
||||||
|
//TODO now we should serialize xml message object.
|
||||||
|
//TODO now we should write serialized xml message over this.outputStream.
|
||||||
|
|
||||||
} catch (Exception e){
|
try
|
||||||
e.printStackTrace();
|
{
|
||||||
|
this.outputStream.write(stringWriter.toString().getBytes());//TEMP currently we output the XML doc, not the serialized message.
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new InvalidRegattaDataException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendRaceData() {
|
public void sendRaceData() throws InvalidRaceDataException
|
||||||
|
{
|
||||||
RaceData raceData = new RaceData(raceDataSource);
|
RaceData raceData = new RaceData(raceDataSource);
|
||||||
raceData.createXML();
|
//Serialize race data to an XML as a string.
|
||||||
|
String xmlString = raceData.createXML();
|
||||||
|
|
||||||
|
//TODO now we should place in XML message object.
|
||||||
|
//TODO now we should serialize xml message object.
|
||||||
|
//TODO now we should write serialized xml message over this.outputStream.
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.outputStream.write(xmlString.getBytes());//TEMP currently we output the XML doc, not the serialized message.
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new InvalidRaceDataException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendBoatData() {
|
public void sendBoatData() throws InvalidBoatDataException
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
List<BoatInRace> boatData = raceDataSource.getBoats();
|
List<BoatInRace> boatData = raceDataSource.getBoats();
|
||||||
try {
|
|
||||||
|
|
||||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
|
||||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
|
||||||
|
|
||||||
//root element
|
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||||
Document doc = docBuilder.newDocument();
|
DocumentBuilder docBuilder = null;
|
||||||
Element rootElement = doc.createElement("BoatConfig");
|
|
||||||
doc.appendChild(rootElement);
|
|
||||||
|
|
||||||
//Boats element
|
try
|
||||||
Element boats = doc.createElement("Boats");
|
{
|
||||||
rootElement.appendChild(boats);
|
docBuilder = docFactory.newDocumentBuilder();
|
||||||
|
|
||||||
for (int i=0; i < boatData.size(); i++) {
|
|
||||||
|
|
||||||
//Boat element
|
|
||||||
Element boat = doc.createElement("Boat");
|
|
||||||
|
|
||||||
//Type attribute
|
|
||||||
Attr attrType = doc.createAttribute("Type");
|
|
||||||
attrType.setValue("Mark");
|
|
||||||
boat.setAttributeNode(attrType);
|
|
||||||
|
|
||||||
//SourceID attribute
|
|
||||||
Attr attrSourceID = doc.createAttribute("SourceID");
|
|
||||||
attrSourceID.setValue(Integer.toString(boatData.get(i).getSourceID()));
|
|
||||||
boat.setAttributeNode(attrSourceID);
|
|
||||||
|
|
||||||
//ShapeID attribute
|
|
||||||
Attr attrShapeID = doc.createAttribute("ShapeID");
|
|
||||||
attrShapeID.setValue("0");
|
|
||||||
boat.setAttributeNode(attrShapeID);
|
|
||||||
|
|
||||||
//HullNum attribute
|
|
||||||
Attr attrHullNum = doc.createAttribute("HullNum");
|
|
||||||
attrHullNum.setValue("RG01");
|
|
||||||
boat.setAttributeNode(attrHullNum);
|
|
||||||
|
|
||||||
//StoweName attribute
|
|
||||||
Attr attrStoweName = doc.createAttribute("StoweName");
|
|
||||||
attrStoweName.setValue(boatData.get(i).getAbbrev());
|
|
||||||
boat.setAttributeNode(attrStoweName);
|
|
||||||
|
|
||||||
//ShortName attribute
|
|
||||||
Attr attrShortName = doc.createAttribute("ShortName");
|
|
||||||
attrShortName.setValue(boatData.get(i).getAbbrev());
|
|
||||||
boat.setAttributeNode(attrShortName);
|
|
||||||
|
|
||||||
//BoatName attribute
|
|
||||||
Attr attrBoatName = doc.createAttribute("BoatName");
|
|
||||||
attrBoatName.setValue(boatData.get(i).toString());
|
|
||||||
boat.setAttributeNode(attrBoatName);
|
|
||||||
|
|
||||||
//GPSCoord for element
|
|
||||||
Element GPSCoord = doc.createElement("GPSposition");
|
|
||||||
|
|
||||||
//Z axis attribute
|
|
||||||
Attr attrZCoord = doc.createAttribute("Z");
|
|
||||||
attrZCoord.setValue("0");
|
|
||||||
GPSCoord.setAttributeNode(attrZCoord);
|
|
||||||
|
|
||||||
//Y axis attribute
|
|
||||||
Attr attrYCoord = doc.createAttribute("Y");
|
|
||||||
attrYCoord.setValue(Double.toString(boatData.get(i).getCurrentPosition().getLatitude()));
|
|
||||||
GPSCoord.setAttributeNode(attrYCoord);
|
|
||||||
|
|
||||||
//X axis attribute
|
|
||||||
Attr attrXCoord = doc.createAttribute("X");
|
|
||||||
attrXCoord.setValue(Double.toString(boatData.get(i).getCurrentPosition().getLongitude()));
|
|
||||||
GPSCoord.setAttributeNode(attrXCoord);
|
|
||||||
|
|
||||||
//Write GPSCoord to boat
|
|
||||||
boat.appendChild(GPSCoord);
|
|
||||||
|
|
||||||
//Write boat to boats
|
|
||||||
boats.appendChild(boat);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TransformerFactory trasformerFactory = TransformerFactory.newInstance();
|
|
||||||
Transformer transformer = trasformerFactory.newTransformer();
|
|
||||||
DOMSource source = new DOMSource(doc);
|
|
||||||
|
|
||||||
//print XML object to check for correctness
|
|
||||||
StreamResult result = new StreamResult(System.out);
|
|
||||||
transformer.transform(source,result);
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
catch (ParserConfigurationException e)
|
||||||
|
{
|
||||||
|
throw new InvalidBoatDataException();
|
||||||
|
}
|
||||||
|
|
||||||
|
//root element
|
||||||
|
Document doc = docBuilder.newDocument();
|
||||||
|
Element rootElement = doc.createElement("BoatConfig");
|
||||||
|
doc.appendChild(rootElement);
|
||||||
|
|
||||||
|
//Boats element
|
||||||
|
Element boats = doc.createElement("Boats");
|
||||||
|
rootElement.appendChild(boats);
|
||||||
|
|
||||||
|
for (int i=0; i < boatData.size(); i++) {
|
||||||
|
|
||||||
|
//Boat element
|
||||||
|
Element boat = doc.createElement("Boat");
|
||||||
|
|
||||||
|
//Type attribute
|
||||||
|
Attr attrType = doc.createAttribute("Type");
|
||||||
|
attrType.setValue("Mark");
|
||||||
|
boat.setAttributeNode(attrType);
|
||||||
|
|
||||||
|
//SourceID attribute
|
||||||
|
Attr attrSourceID = doc.createAttribute("SourceID");
|
||||||
|
attrSourceID.setValue(Integer.toString(boatData.get(i).getSourceID()));
|
||||||
|
boat.setAttributeNode(attrSourceID);
|
||||||
|
|
||||||
|
//ShapeID attribute
|
||||||
|
Attr attrShapeID = doc.createAttribute("ShapeID");
|
||||||
|
attrShapeID.setValue("0");
|
||||||
|
boat.setAttributeNode(attrShapeID);
|
||||||
|
|
||||||
|
//HullNum attribute
|
||||||
|
Attr attrHullNum = doc.createAttribute("HullNum");
|
||||||
|
attrHullNum.setValue("RG01");
|
||||||
|
boat.setAttributeNode(attrHullNum);
|
||||||
|
|
||||||
|
//StoweName attribute
|
||||||
|
Attr attrStoweName = doc.createAttribute("StoweName");
|
||||||
|
attrStoweName.setValue(boatData.get(i).getAbbrev());
|
||||||
|
boat.setAttributeNode(attrStoweName);
|
||||||
|
|
||||||
|
//ShortName attribute
|
||||||
|
Attr attrShortName = doc.createAttribute("ShortName");
|
||||||
|
attrShortName.setValue(boatData.get(i).getAbbrev());
|
||||||
|
boat.setAttributeNode(attrShortName);
|
||||||
|
|
||||||
|
//BoatName attribute
|
||||||
|
Attr attrBoatName = doc.createAttribute("BoatName");
|
||||||
|
attrBoatName.setValue(boatData.get(i).toString());
|
||||||
|
boat.setAttributeNode(attrBoatName);
|
||||||
|
|
||||||
|
//GPSCoord for element
|
||||||
|
Element GPSCoord = doc.createElement("GPSposition");
|
||||||
|
|
||||||
|
//Z axis attribute
|
||||||
|
Attr attrZCoord = doc.createAttribute("Z");
|
||||||
|
attrZCoord.setValue("0");
|
||||||
|
GPSCoord.setAttributeNode(attrZCoord);
|
||||||
|
|
||||||
|
//Y axis attribute
|
||||||
|
Attr attrYCoord = doc.createAttribute("Y");
|
||||||
|
attrYCoord.setValue(Double.toString(boatData.get(i).getCurrentPosition().getLatitude()));
|
||||||
|
GPSCoord.setAttributeNode(attrYCoord);
|
||||||
|
|
||||||
|
//X axis attribute
|
||||||
|
Attr attrXCoord = doc.createAttribute("X");
|
||||||
|
attrXCoord.setValue(Double.toString(boatData.get(i).getCurrentPosition().getLongitude()));
|
||||||
|
GPSCoord.setAttributeNode(attrXCoord);
|
||||||
|
|
||||||
|
//Write GPSCoord to boat
|
||||||
|
boat.appendChild(GPSCoord);
|
||||||
|
|
||||||
|
//Write boat to boats
|
||||||
|
boats.appendChild(boat);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TransformerFactory trasformerFactory = TransformerFactory.newInstance();
|
||||||
|
Transformer transformer = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
transformer = trasformerFactory.newTransformer();
|
||||||
|
}
|
||||||
|
catch (TransformerConfigurationException e)
|
||||||
|
{
|
||||||
|
throw new InvalidBoatDataException();
|
||||||
|
}
|
||||||
|
DOMSource source = new DOMSource(doc);
|
||||||
|
|
||||||
|
|
||||||
|
//Serialize document.
|
||||||
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
StreamResult result = new StreamResult(stringWriter);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
transformer.transform(source,result);
|
||||||
|
}
|
||||||
|
catch (TransformerException e)
|
||||||
|
{
|
||||||
|
throw new InvalidBoatDataException();
|
||||||
|
}
|
||||||
|
//TODO now we should place in XML message object.
|
||||||
|
//TODO now we should serialize xml message object.
|
||||||
|
//TODO now we should write serialized xml message over this.outputStream.
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.outputStream.write(stringWriter.toString().getBytes());//TEMP currently we output the XML doc, not the serialized message.
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new InvalidBoatDataException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,12 @@ import org.geotools.referencing.GeodeticCalculator;
|
|||||||
import seng302.Constants;
|
import seng302.Constants;
|
||||||
import seng302.GPSCoordinate;
|
import seng302.GPSCoordinate;
|
||||||
import seng302.RaceDataSource;
|
import seng302.RaceDataSource;
|
||||||
|
import seng302.RaceEventMessages.BoatLocationMessage;
|
||||||
|
|
||||||
|
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -38,26 +41,33 @@ public class Race implements Runnable {
|
|||||||
|
|
||||||
protected int PRERACE_TIME = 120000; //time in milliseconds to pause during pre-race
|
protected int PRERACE_TIME = 120000; //time in milliseconds to pause during pre-race
|
||||||
|
|
||||||
|
//Outputstream to write messages to.
|
||||||
|
private OutputStream outputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initailiser for Race
|
* Initailiser for Race
|
||||||
*
|
*
|
||||||
* @param boats Takes in an array of boats that are participating in the race.
|
* @param boats Takes in an array of boats that are participating in the race.
|
||||||
* @param legs Number of marks in order that the boats pass in order to complete the race.
|
* @param legs Number of marks in order that the boats pass in order to complete the race.
|
||||||
* @param scaleFactor for race
|
* @param scaleFactor for race
|
||||||
|
* @param outputStream Outputstream to write messages to.
|
||||||
*/
|
*/
|
||||||
public Race(List<BoatInRace> boats, List<Leg> legs, int scaleFactor) {
|
public Race(List<BoatInRace> boats, List<Leg> legs, int scaleFactor, OutputStream outputStream) {
|
||||||
|
|
||||||
this.startingBoats = FXCollections.observableArrayList(boats);
|
this.startingBoats = FXCollections.observableArrayList(boats);
|
||||||
this.legs = legs;
|
this.legs = legs;
|
||||||
this.legs.add(new Leg("Finish", this.legs.size()));
|
this.legs.add(new Leg("Finish", this.legs.size()));
|
||||||
this.scaleFactor = scaleFactor;
|
this.scaleFactor = scaleFactor;
|
||||||
|
this.outputStream = outputStream;
|
||||||
|
|
||||||
if (startingBoats != null && startingBoats.size() > 0) {
|
if (startingBoats != null && startingBoats.size() > 0) {
|
||||||
initialiseBoats();
|
initialiseBoats();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Race(RaceDataSource raceData, int scaleFactor) {
|
public Race(RaceDataSource raceData, int scaleFactor, OutputStream outputStream) {
|
||||||
this(raceData.getBoats(), raceData.getLegs(), scaleFactor);
|
this(raceData.getBoats(), raceData.getLegs(), scaleFactor, outputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -158,20 +168,70 @@ public class Race implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
new AnimationTimer() {
|
new AnimationTimer() {
|
||||||
|
//Start time of loop.
|
||||||
long timeRaceStarted = System.currentTimeMillis(); //start time of loop
|
long timeRaceStarted = System.currentTimeMillis();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(long arg0) {
|
public void handle(long arg0) {
|
||||||
if (boatsFinished < startingBoats.size()) {
|
if (boatsFinished < startingBoats.size()) {
|
||||||
totalTimeElapsed = System.currentTimeMillis() - timeRaceStarted;
|
//Get the current time.
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
//Update the total elapsed time.
|
||||||
|
totalTimeElapsed = currentTime - timeRaceStarted;
|
||||||
|
|
||||||
|
//For each boat, we update it's position, and generate a BoatLocationMessage.
|
||||||
for (BoatInRace boat : startingBoats) {
|
for (BoatInRace boat : startingBoats) {
|
||||||
if (boat != null && !boat.isFinished()) {
|
if (boat != null && !boat.isFinished()) {
|
||||||
|
//Update position.
|
||||||
updatePosition(boat, Math.round(1000 / lastFPS) > 20 ? 15 : Math.round(1000 / lastFPS));
|
updatePosition(boat, Math.round(1000 / lastFPS) > 20 ? 15 : Math.round(1000 / lastFPS));
|
||||||
checkPosition(boat, totalTimeElapsed);
|
checkPosition(boat, totalTimeElapsed);
|
||||||
|
|
||||||
|
|
||||||
|
//Generate a boat location message for the updated boat.
|
||||||
|
BoatLocationMessage boatLocationMessage = new BoatLocationMessage();
|
||||||
|
boatLocationMessage.setTime(currentTime);
|
||||||
|
boatLocationMessage.setSourceID(boat.getSourceID());
|
||||||
|
boatLocationMessage.setSequenceNumber(boat.getNextSequenceNumber());
|
||||||
|
boatLocationMessage.setDeviceType(BoatLocationMessage.RacingYacht);
|
||||||
|
|
||||||
|
boatLocationMessage.setLatitude(BoatLocationMessage.convertCoordinateDoubleToInt(boat.getCurrentPosition().getLatitude()));
|
||||||
|
boatLocationMessage.setLongitude(BoatLocationMessage.convertCoordinateDoubleToInt(boat.getCurrentPosition().getLongitude()));
|
||||||
|
|
||||||
|
boatLocationMessage.setAltitude(0);//Junk value.
|
||||||
|
boatLocationMessage.setHeading(BoatLocationMessage.convertHeadingDoubleToInt(boat.getHeading()));
|
||||||
|
|
||||||
|
boatLocationMessage.setPitch((short)0);//Junk value.
|
||||||
|
boatLocationMessage.setRoll((short)0);//Junk value.
|
||||||
|
|
||||||
|
boatLocationMessage.setBoatSpeed(BoatLocationMessage.convertBoatSpeedDoubleToInt(boat.getVelocity()));
|
||||||
|
boatLocationMessage.setBoatCOG(0);//Junk value.
|
||||||
|
boatLocationMessage.setBoatSOG(0);//Junk value.
|
||||||
|
|
||||||
|
boatLocationMessage.setApparentWindSpeed(0);//Junk value.
|
||||||
|
boatLocationMessage.setApparentWindAngle((short)0);//Junk value.
|
||||||
|
boatLocationMessage.setTrueWindSpeed(0);//Junk value.
|
||||||
|
boatLocationMessage.setTrueWindAngle((short)0);//Junk value.
|
||||||
|
|
||||||
|
boatLocationMessage.setCurrentDrift(0);//Junk value.
|
||||||
|
boatLocationMessage.setCurrentSet(0);//Junk value.
|
||||||
|
boatLocationMessage.setRudderAngle((short)0);//Junk value.
|
||||||
|
|
||||||
|
//We have finished creating the message.
|
||||||
|
//TODO at this point, we need to send the event to the visualiser.
|
||||||
|
//System.out.println(boatLocationMessage);//TEMP debug print
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//TODO we should actually serialize the boat message before writing to output.
|
||||||
|
outputStream.write(boatLocationMessage.toString().getBytes());
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Race is over");
|
System.out.println("Race is over");//TEMP debug print
|
||||||
//raceFinish = true;
|
//raceFinish = true;
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
@@ -194,7 +254,7 @@ public class Race implements Runnable {
|
|||||||
boat.setPosition("-");
|
boat.setPosition("-");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("=====");
|
System.out.println("=====");//TEMP debug print
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialiseBoats() {
|
public void initialiseBoats() {
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ package seng302.RaceEventMessages;
|
|||||||
* Created by f123 on 21-Apr-17.
|
* Created by f123 on 21-Apr-17.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import seng302.Constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the information in a boat location message (AC streaming spec: 4.9).
|
* Represents the information in a boat location message (AC streaming spec: 4.9).
|
||||||
*/
|
*/
|
||||||
@@ -442,4 +444,112 @@ public class BoatLocationMessage
|
|||||||
return angleShort;
|
return angleShort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a double representing the speed of a boat in knots to an int in millimeters per second, as required by the streaming spec format.
|
||||||
|
* @param speed Speed in knots, stored as a double.
|
||||||
|
* @return Speed in millimeters per second, stored as an int (using only the two least significant bytes).
|
||||||
|
*/
|
||||||
|
public static int convertBoatSpeedDoubleToInt(double speed)
|
||||||
|
{
|
||||||
|
//Calculate meters per second.
|
||||||
|
double metersPerSecond = speed * Constants.KnotsToMetersPerSecondConversionFactor;
|
||||||
|
|
||||||
|
//Calculate millimeters per second.
|
||||||
|
double millimetersPerSecond = metersPerSecond * 1000.0;
|
||||||
|
|
||||||
|
//Convert to an int.
|
||||||
|
int millimetersPerSecondInt = (int)Math.round(millimetersPerSecond);
|
||||||
|
|
||||||
|
return millimetersPerSecondInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an int representing the speed of a boat in millimeters per second to a double in knots, as required by the streaming spec format.
|
||||||
|
* @param speed Speed in millimeters per second, stored as an int.
|
||||||
|
* @return Speed in knots, stored as a double.
|
||||||
|
*/
|
||||||
|
public static double convertBoatSpeedIntToDouble(int speed)
|
||||||
|
{
|
||||||
|
//Calculate meters per second.
|
||||||
|
double metersPerSecond = speed / 1000.0;
|
||||||
|
|
||||||
|
//Calculate knots.
|
||||||
|
double knots = metersPerSecond / Constants.KnotsToMetersPerSecondConversionFactor;
|
||||||
|
|
||||||
|
return knots;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
builder.append("Message version number: ");
|
||||||
|
builder.append(this.getMessageVersionNumber());
|
||||||
|
|
||||||
|
builder.append("\nTime: ");
|
||||||
|
builder.append(this.getTime());
|
||||||
|
|
||||||
|
builder.append("\nSource ID: ");
|
||||||
|
builder.append(this.getSourceID());
|
||||||
|
|
||||||
|
builder.append("\nSequence number: ");
|
||||||
|
builder.append(this.getSequenceNumber());
|
||||||
|
|
||||||
|
builder.append("\nDevice type: ");
|
||||||
|
builder.append(this.getDeviceType());
|
||||||
|
|
||||||
|
builder.append("\nLatitude: ");
|
||||||
|
builder.append(this.getLatitude());
|
||||||
|
|
||||||
|
builder.append("\nLongitude: ");
|
||||||
|
builder.append(this.getLongitude());
|
||||||
|
|
||||||
|
builder.append("\nAltitude: ");
|
||||||
|
builder.append(this.getAltitude());
|
||||||
|
|
||||||
|
builder.append("\nHeading: ");
|
||||||
|
builder.append(this.getHeading());
|
||||||
|
|
||||||
|
builder.append("\nPitch: ");
|
||||||
|
builder.append(this.getPitch());
|
||||||
|
|
||||||
|
builder.append("\nRoll: ");
|
||||||
|
builder.append(this.getRoll());
|
||||||
|
|
||||||
|
builder.append("\nBoat speed (mm/sec): ");
|
||||||
|
builder.append(this.getBoatSpeed());
|
||||||
|
|
||||||
|
builder.append("\nBoat COG: ");
|
||||||
|
builder.append(this.getBoatCOG());
|
||||||
|
|
||||||
|
builder.append("\nBoat SOG: ");
|
||||||
|
builder.append(this.getBoatSOG());
|
||||||
|
|
||||||
|
builder.append("\nApparent wind speed: ");
|
||||||
|
builder.append(this.getApparentWindSpeed());
|
||||||
|
|
||||||
|
builder.append("\nApparent wind angle: ");
|
||||||
|
builder.append(this.getApparentWindAngle());
|
||||||
|
|
||||||
|
builder.append("\nTrue wind speed: ");
|
||||||
|
builder.append(this.getTrueWindSpeed());
|
||||||
|
|
||||||
|
builder.append("\nTrue wind angle: ");
|
||||||
|
builder.append(this.getTrueWindAngle());
|
||||||
|
|
||||||
|
builder.append("\nCurrent drift: ");
|
||||||
|
builder.append(this.getCurrentDrift());
|
||||||
|
|
||||||
|
builder.append("\nCurrent set: ");
|
||||||
|
builder.append(this.getCurrentSet());
|
||||||
|
|
||||||
|
builder.append("\nRudder angle: ");
|
||||||
|
builder.append(this.getRudderAngle());
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user