Merge branch 'isolatingMock' of https://eng-git.canterbury.ac.nz/seng302-2017/team-7 into isolatingMock
This commit is contained in:
@@ -16,4 +16,5 @@
|
||||
# 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/
|
||||
Erika Savell <[email protected]>
|
||||
Connor Taylor-Brown <[email protected]> <[email protected]>
|
||||
Connor Taylor-Brown <[email protected]> <[email protected]>
|
||||
Fraser Cope <[email protected]>
|
||||
|
||||
@@ -4,12 +4,14 @@ package seng302;
|
||||
import javafx.application.Application;
|
||||
import javafx.stage.Stage;
|
||||
import org.xml.sax.SAXException;
|
||||
import seng302.Mock.RaceDataSource;
|
||||
import seng302.Mock.RegattaDataSource;
|
||||
import seng302.Mock.RegattaXMLReader;
|
||||
import seng302.Model.Event;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class App extends Application {
|
||||
|
||||
@@ -25,9 +27,10 @@ public class App extends Application {
|
||||
@Override
|
||||
public void start(Stage primaryStage) {
|
||||
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");
|
||||
RegattaDataSource regattaData = new RegattaXMLReader("mockXML/regattaTest.xml");
|
||||
Event raceEvent = new Event(raceData, regattaData);
|
||||
Event raceEvent = new Event(raceData, regattaData, outputStream);
|
||||
raceEvent.start();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -11,6 +11,9 @@ public class Constants {
|
||||
|
||||
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 startLineMarker2 = new GPSCoordinate(32.293771, -64.855242);
|
||||
public static final GPSCoordinate mark1 = new GPSCoordinate(32.293039, -64.843983);
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
package seng302.Data;
|
||||
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import seng302.GPSCoordinate;
|
||||
import seng302.Model.Boat;
|
||||
import seng302.Model.BoatInRace;
|
||||
import seng302.Model.Leg;
|
||||
import seng302.Model.Marker;
|
||||
import seng302.RaceDataSource;
|
||||
import seng302.Mock.RaceDataSource;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
@@ -18,6 +15,7 @@ import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.StringWriter;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@@ -47,7 +45,7 @@ public class RaceData {
|
||||
}
|
||||
|
||||
|
||||
public void createXML() {
|
||||
public String createXML() {
|
||||
|
||||
try {
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
@@ -148,14 +146,13 @@ public class RaceData {
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
DOMSource source = new DOMSource(doc);
|
||||
StreamResult result = new StreamResult(System.out);
|
||||
|
||||
// Output to console for testing
|
||||
// StreamResult result = new StreamResult(System.out);
|
||||
//Serialize document.
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
StreamResult result = new StreamResult(stringWriter);
|
||||
transformer.transform(source,result);
|
||||
|
||||
transformer.transform(source, result);
|
||||
|
||||
System.out.println("File saved!");
|
||||
return stringWriter.toString();
|
||||
|
||||
|
||||
} catch (ParserConfigurationException pce) {
|
||||
@@ -164,6 +161,7 @@ public class RaceData {
|
||||
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,110 @@
|
||||
package seng302.Data;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import seng302.Exceptions.InvalidRegattaDataException;
|
||||
import seng302.Mock.Regatta;
|
||||
import seng302.Mock.RegattaDataSource;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* Created by esa46 on 25/04/17.
|
||||
*/
|
||||
public class RegattaData {
|
||||
|
||||
|
||||
private RegattaDataSource regattaDataSource;
|
||||
|
||||
|
||||
public RegattaData(RegattaDataSource regattaDataSource) {
|
||||
this.regattaDataSource = regattaDataSource;
|
||||
}
|
||||
|
||||
public String createXML() {
|
||||
|
||||
|
||||
Regatta regatta = regattaDataSource.getRegatta();
|
||||
|
||||
try {
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||
|
||||
//root element
|
||||
Document doc = docBuilder.newDocument();
|
||||
Element rootElement = doc.createElement("RegattaConfig");
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
//regattaID element
|
||||
Element regattaID = doc.createElement("RegattaID");
|
||||
regattaID.appendChild(doc.createTextNode(Integer.toString(regatta.getRegattaID())));
|
||||
rootElement.appendChild(regattaID);
|
||||
|
||||
//regattaName element
|
||||
Element regattaName = doc.createElement("RegattaName");
|
||||
regattaName.appendChild(doc.createTextNode(regatta.getRegattaName()));
|
||||
rootElement.appendChild(regattaName);
|
||||
|
||||
//courseName element
|
||||
Element courseName = doc.createElement("CourseName");
|
||||
courseName.appendChild(doc.createTextNode(regatta.getCourseName()));
|
||||
rootElement.appendChild(courseName);
|
||||
|
||||
//centralLatitude element
|
||||
Element centralLat = doc.createElement("CentralLatitude");
|
||||
centralLat.appendChild(doc.createTextNode(Double.toString(regatta.getCentralLatitude())));
|
||||
rootElement.appendChild(centralLat);
|
||||
|
||||
//centralLongitude element
|
||||
Element centralLong = doc.createElement("CentralLongitude");
|
||||
centralLong.appendChild(doc.createTextNode(Double.toString(regatta.getCentralLongitude())));
|
||||
rootElement.appendChild(centralLong);
|
||||
|
||||
//centralAltitude element
|
||||
Element centralAlt = doc.createElement("CentralAltitude");
|
||||
centralAlt.appendChild(doc.createTextNode(Double.toString(regatta.getCentralAltitude())));
|
||||
rootElement.appendChild(centralAlt);
|
||||
|
||||
//utcOffset element
|
||||
Element utcOffset = doc.createElement("UtcOffset");
|
||||
utcOffset.appendChild(doc.createTextNode(Double.toString(regatta.getUtcOffset())));
|
||||
rootElement.appendChild(utcOffset);
|
||||
|
||||
//magneticVariation element
|
||||
Element magneticVariation = doc.createElement("MagneticVariation");
|
||||
magneticVariation.appendChild(doc.createTextNode(Double.toString(regatta.getMagneticVariation())));
|
||||
rootElement.appendChild(magneticVariation);
|
||||
|
||||
// write the content into xml file
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
DOMSource source = new DOMSource(doc);
|
||||
|
||||
//Serialize document.
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
StreamResult result = new StreamResult(stringWriter);
|
||||
transformer.transform(source,result);
|
||||
|
||||
return stringWriter.toString();
|
||||
|
||||
|
||||
} catch (ParserConfigurationException pce) {
|
||||
pce.printStackTrace();
|
||||
} catch (TransformerException tfe) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
package seng302;
|
||||
package seng302.Mock;
|
||||
|
||||
import seng302.GPSCoordinate;
|
||||
import seng302.Model.BoatInRace;
|
||||
import seng302.Model.Leg;
|
||||
import seng302.Model.Marker;
|
||||
@@ -29,6 +29,9 @@ public class BoatInRace extends Boat {
|
||||
private StringProperty position;
|
||||
private double heading;
|
||||
|
||||
///While generating BoatLocationMessages, each one needs a sequence number relating to each boat.
|
||||
private long sequenceNumber = 0;
|
||||
|
||||
private boolean trackVisible = true;
|
||||
|
||||
/**
|
||||
@@ -263,4 +266,18 @@ public class BoatInRace extends Boat {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,17 +4,26 @@ import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import seng302.Data.RaceData;
|
||||
import seng302.Data.RegattaData;
|
||||
import seng302.Mock.Regatta;
|
||||
import seng302.Mock.RegattaDataSource;
|
||||
import seng302.Model.Race;
|
||||
import seng302.RaceDataSource;
|
||||
import seng302.Exceptions.InvalidBoatDataException;
|
||||
import seng302.Exceptions.InvalidRaceDataException;
|
||||
import seng302.Exceptions.InvalidRegattaDataException;
|
||||
import seng302.Mock.RaceDataSource;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -24,189 +33,201 @@ public class Event {
|
||||
|
||||
RaceDataSource raceDataSource;
|
||||
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.regattaDataSource = regattaData;
|
||||
this.outputStream = outputStream;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
public void start()
|
||||
{
|
||||
System.out.println("\nREGATTA DATA\n");//TEMP REMOVE debug
|
||||
sendRegattaData();
|
||||
System.out.println("\nRACE DATA\n");//TEMP REMOVE debug
|
||||
sendRaceData();
|
||||
System.out.println("\nBOAT DATA\n");//TEMP REMOVE debug
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
public void sendRegattaData() {
|
||||
try {
|
||||
public void sendRegattaData() throws InvalidRegattaDataException {
|
||||
|
||||
Regatta regatta = regattaDataSource.getRegatta();
|
||||
RegattaData regattaData = new RegattaData(regattaDataSource);
|
||||
String xmlString = regattaData.createXML();
|
||||
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||
//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.
|
||||
|
||||
//root element
|
||||
Document doc = docBuilder.newDocument();
|
||||
Element rootElement = doc.createElement("RegattaConfig");
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
//regattaID element
|
||||
Element regattaID = doc.createElement("RegattaID");
|
||||
regattaID.appendChild(doc.createTextNode(Integer.toString(regatta.getRegattaID())));
|
||||
rootElement.appendChild(regattaID);
|
||||
|
||||
//regattaName element
|
||||
Element regattaName = doc.createElement("RegattaName");
|
||||
regattaName.appendChild(doc.createTextNode(regatta.getRegattaName()));
|
||||
rootElement.appendChild(regattaName);
|
||||
|
||||
//courseName element
|
||||
Element courseName = doc.createElement("CourseName");
|
||||
courseName.appendChild(doc.createTextNode(regatta.getCourseName()));
|
||||
rootElement.appendChild(courseName);
|
||||
|
||||
//centralLatitude element
|
||||
Element centralLat = doc.createElement("CentralLatitude");
|
||||
centralLat.appendChild(doc.createTextNode(Double.toString(regatta.getCentralLatitude())));
|
||||
rootElement.appendChild(centralLat);
|
||||
|
||||
//centralLongitude element
|
||||
Element centralLong = doc.createElement("CentralLongitude");
|
||||
centralLong.appendChild(doc.createTextNode(Double.toString(regatta.getCentralLongitude())));
|
||||
rootElement.appendChild(centralLong);
|
||||
|
||||
//centralAltitude element
|
||||
Element centralAlt = doc.createElement("CentralAltitude");
|
||||
centralAlt.appendChild(doc.createTextNode(Double.toString(regatta.getCentralAltitude())));
|
||||
rootElement.appendChild(centralAlt);
|
||||
|
||||
//utcOffset element
|
||||
Element utcOffset = doc.createElement("UtcOffset");
|
||||
utcOffset.appendChild(doc.createTextNode(Double.toString(regatta.getUtcOffset())));
|
||||
rootElement.appendChild(utcOffset);
|
||||
|
||||
//magneticVariation element
|
||||
Element magneticVariation = doc.createElement("MagneticVariation");
|
||||
magneticVariation.appendChild(doc.createTextNode(Double.toString(regatta.getMagneticVariation())));
|
||||
rootElement.appendChild(magneticVariation);
|
||||
|
||||
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();
|
||||
try
|
||||
{
|
||||
this.outputStream.write(xmlString.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.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();
|
||||
try {
|
||||
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||
|
||||
//root element
|
||||
Document doc = docBuilder.newDocument();
|
||||
Element rootElement = doc.createElement("BoatConfig");
|
||||
doc.appendChild(rootElement);
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = null;
|
||||
|
||||
//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 = 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();
|
||||
try
|
||||
{
|
||||
docBuilder = docFactory.newDocumentBuilder();
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package seng302.Model;
|
||||
|
||||
|
||||
import com.sun.org.apache.xpath.internal.SourceTree;
|
||||
import javafx.animation.AnimationTimer;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
@@ -10,12 +9,14 @@ import javafx.collections.ObservableList;
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
import seng302.Constants;
|
||||
import seng302.GPSCoordinate;
|
||||
import seng302.RaceDataSource;
|
||||
import seng302.Mock.RaceDataSource;
|
||||
import seng302.RaceEventMessages.BoatLocationMessage;
|
||||
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -38,26 +39,33 @@ public class Race implements Runnable {
|
||||
|
||||
protected int PRERACE_TIME = 120000; //time in milliseconds to pause during pre-race
|
||||
|
||||
//Outputstream to write messages to.
|
||||
private OutputStream outputStream;
|
||||
|
||||
/**
|
||||
* Initailiser for 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 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.legs = legs;
|
||||
this.legs.add(new Leg("Finish", this.legs.size()));
|
||||
this.scaleFactor = scaleFactor;
|
||||
this.outputStream = outputStream;
|
||||
|
||||
if (startingBoats != null && startingBoats.size() > 0) {
|
||||
initialiseBoats();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Race(RaceDataSource raceData, int scaleFactor) {
|
||||
this(raceData.getBoats(), raceData.getLegs(), scaleFactor);
|
||||
public Race(RaceDataSource raceData, int scaleFactor, OutputStream outputStream) {
|
||||
this(raceData.getBoats(), raceData.getLegs(), scaleFactor, outputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,20 +166,70 @@ public class Race implements Runnable {
|
||||
}
|
||||
|
||||
new AnimationTimer() {
|
||||
|
||||
long timeRaceStarted = System.currentTimeMillis(); //start time of loop
|
||||
//Start time of loop.
|
||||
long timeRaceStarted = System.currentTimeMillis();
|
||||
|
||||
@Override
|
||||
public void handle(long arg0) {
|
||||
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) {
|
||||
if (boat != null && !boat.isFinished()) {
|
||||
//Update position.
|
||||
updatePosition(boat, Math.round(1000 / lastFPS) > 20 ? 15 : Math.round(1000 / lastFPS));
|
||||
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 {
|
||||
System.out.println("Race is over");
|
||||
System.out.println("Race is over");//TEMP debug print
|
||||
//raceFinish = true;
|
||||
stop();
|
||||
}
|
||||
@@ -194,7 +252,7 @@ public class Race implements Runnable {
|
||||
boat.setPosition("-");
|
||||
}
|
||||
}
|
||||
System.out.println("=====");
|
||||
System.out.println("=====");//TEMP debug print
|
||||
}
|
||||
|
||||
public void initialiseBoats() {
|
||||
|
||||
@@ -4,6 +4,8 @@ package seng302.RaceEventMessages;
|
||||
* Created by f123 on 21-Apr-17.
|
||||
*/
|
||||
|
||||
import seng302.Constants;
|
||||
|
||||
/**
|
||||
* Represents the information in a boat location message (AC streaming spec: 4.9).
|
||||
*/
|
||||
@@ -442,4 +444,112 @@ public class BoatLocationMessage
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import javafx.scene.paint.Color;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
import seng302.Mock.RaceDataSource;
|
||||
import seng302.Model.BoatInRace;
|
||||
import seng302.Model.Leg;
|
||||
import seng302.Model.Marker;
|
||||
|
||||
Reference in New Issue
Block a user