shared.dataInput:
Added shared.enums.XMLFileType, which is used to specify if a string contains a file path or file contents. Updated the XML readers to use it. Testing: Moved the networking tests and resources into racevisionGame module. Moved the remaining tests from visualiser into racevisionGame, and added a few empty tests to implement later.
This commit is contained in:
@@ -8,6 +8,7 @@ import network.Messages.LatestMessages;
|
||||
import network.Messages.XMLMessage;
|
||||
import org.xml.sax.SAXException;
|
||||
import shared.dataInput.*;
|
||||
import shared.enums.XMLFileType;
|
||||
import shared.exceptions.InvalidBoatDataException;
|
||||
import shared.exceptions.InvalidRaceDataException;
|
||||
import shared.exceptions.InvalidRegattaDataException;
|
||||
@@ -61,9 +62,9 @@ public class Event {
|
||||
sendXMLs();
|
||||
|
||||
//Parse the XML files into data sources.
|
||||
RaceDataSource raceDataSource = new RaceXMLReader(this.raceXML);
|
||||
BoatDataSource boatDataSource = new BoatXMLReader(this.boatXML);
|
||||
RegattaDataSource regattaDataSource = new RegattaXMLReader(this.regattaXML);
|
||||
RaceDataSource raceDataSource = new RaceXMLReader(this.raceXML, XMLFileType.ResourcePath);
|
||||
BoatDataSource boatDataSource = new BoatXMLReader(this.boatXML, XMLFileType.ResourcePath);
|
||||
RegattaDataSource regattaDataSource = new RegattaXMLReader(this.regattaXML, XMLFileType.ResourcePath);
|
||||
|
||||
//Create and start race.
|
||||
MockRace newRace = new MockRace(boatDataSource, raceDataSource, regattaDataSource, this.latestMessages, this.boatPolars, Constants.RaceTimeScale);
|
||||
|
||||
@@ -2,6 +2,7 @@ package shared.dataInput;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import shared.enums.XMLFileType;
|
||||
import shared.exceptions.InvalidBoatDataException;
|
||||
import shared.exceptions.XMLReaderException;
|
||||
import shared.model.Boat;
|
||||
@@ -32,11 +33,12 @@ public class BoatXMLReader extends XMLReader implements BoatDataSource {
|
||||
* Constructor for Boat XML using a file read as a resource.
|
||||
*
|
||||
* @param fileContents Contents of xml file.
|
||||
* @param type How to read the file - e.g., load as resource.
|
||||
* @throws XMLReaderException Thrown if the file cannot be parsed.
|
||||
* @throws InvalidBoatDataException Thrown if the file cannot be parsed correctly.
|
||||
*/
|
||||
public BoatXMLReader(String fileContents) throws XMLReaderException, InvalidBoatDataException {
|
||||
super(fileContents);
|
||||
public BoatXMLReader(String fileContents, XMLFileType type) throws XMLReaderException, InvalidBoatDataException {
|
||||
super(fileContents, type);
|
||||
|
||||
//Attempt to read boat xml file.
|
||||
try {
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import shared.enums.XMLFileType;
|
||||
import shared.exceptions.InvalidRaceDataException;
|
||||
import shared.exceptions.XMLReaderException;
|
||||
import shared.model.*;
|
||||
@@ -83,12 +84,13 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
|
||||
/**
|
||||
* Constructor for Streamed Race XML
|
||||
* @param fileContents Contents of xml file.
|
||||
* @param type How to read the file - e.g., load as resource.
|
||||
* @throws XMLReaderException Thrown if an XML reader cannot be constructed for the given file.
|
||||
* @throws InvalidRaceDataException Thrown if the XML file is invalid in some way.
|
||||
*/
|
||||
public RaceXMLReader(String fileContents) throws XMLReaderException, InvalidRaceDataException {
|
||||
public RaceXMLReader(String fileContents, XMLFileType type) throws XMLReaderException, InvalidRaceDataException {
|
||||
|
||||
super(fileContents);
|
||||
super(fileContents, type);
|
||||
|
||||
|
||||
//Attempt to read race xml file.
|
||||
|
||||
@@ -4,6 +4,7 @@ import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.SAXException;
|
||||
import shared.dataInput.XMLReader;
|
||||
import shared.enums.XMLFileType;
|
||||
import shared.exceptions.InvalidRegattaDataException;
|
||||
import shared.exceptions.XMLReaderException;
|
||||
import shared.model.GPSCoordinate;
|
||||
@@ -67,11 +68,12 @@ public class RegattaXMLReader extends XMLReader implements RegattaDataSource {
|
||||
* Constructor for Regatta XML using a file read as a resource.
|
||||
*
|
||||
* @param fileContents Contents of xml file.
|
||||
* @param type How to read the file - e.g., load as resource.
|
||||
* @throws XMLReaderException Thrown if the file cannot be parsed.
|
||||
* @throws InvalidRegattaDataException Thrown if the file cannot be parsed correctly.
|
||||
*/
|
||||
public RegattaXMLReader(String fileContents) throws XMLReaderException, InvalidRegattaDataException {
|
||||
super(fileContents);
|
||||
public RegattaXMLReader(String fileContents, XMLFileType type) throws XMLReaderException, InvalidRegattaDataException {
|
||||
super(fileContents, type);
|
||||
|
||||
//Attempt to read boat xml file.
|
||||
try {
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import shared.enums.XMLFileType;
|
||||
import shared.exceptions.XMLReaderException;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
@@ -27,20 +28,43 @@ public abstract class XMLReader {
|
||||
|
||||
protected Document doc;
|
||||
|
||||
/**
|
||||
* Read an XML file.
|
||||
* @param fileContents Contents of the xml file.
|
||||
* @throws XMLReaderException Thrown if the file cannot be parsed.
|
||||
*/
|
||||
public XMLReader(String fileContents) throws XMLReaderException {
|
||||
|
||||
//Wrap file contents in input stream.
|
||||
InputStream xmlInputStream = new ByteArrayInputStream(fileContents.getBytes(StandardCharsets.UTF_8));
|
||||
/**
|
||||
* Reads an XML file.
|
||||
* @param file The file to read.
|
||||
* @param type How to read the file - e.g., load as resource.
|
||||
* @throws XMLReaderException Throw if the file cannot be parsed.
|
||||
*/
|
||||
public XMLReader(String file, XMLFileType type) throws XMLReaderException {
|
||||
|
||||
|
||||
InputStream xmlInputStream = null;
|
||||
|
||||
//Create an input stream. Method depends on type parameter.
|
||||
|
||||
if (type == XMLFileType.Contents) {
|
||||
//Wrap file contents in input stream.
|
||||
xmlInputStream = new ByteArrayInputStream(file.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
} else if (type == XMLFileType.ResourcePath) {
|
||||
xmlInputStream = XMLReader.class.getClassLoader().getResourceAsStream(file);
|
||||
|
||||
} else if (type == XMLFileType.FilePath) {
|
||||
try {
|
||||
xmlInputStream = new FileInputStream(file);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new XMLReaderException("Could not open file " + file, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.doc = parseInputStream(xmlInputStream);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads an XML file from an input stream.
|
||||
* @param xmlInputStream The input stream to parse.
|
||||
@@ -58,7 +82,7 @@ public abstract class XMLReader {
|
||||
* @return The parsed document.
|
||||
* @throws XMLReaderException Thrown when a document builder cannot be constructed, or the stream cannot be parsed.
|
||||
*/
|
||||
private Document parseInputStream(InputStream inputStream) throws XMLReaderException {
|
||||
private static Document parseInputStream(InputStream inputStream) throws XMLReaderException {
|
||||
|
||||
//Create document builder.
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
@@ -142,18 +166,15 @@ public abstract class XMLReader {
|
||||
* @param path path of the XML
|
||||
* @param encoding encoding of the xml
|
||||
* @return A string containing the contents of the specified file.
|
||||
* @throws IOException No file etc
|
||||
* @throws ParserConfigurationException Issue with the XML formatting
|
||||
* @throws SAXException Issue with XML formatting
|
||||
* @throws TransformerException Issue with the XML format
|
||||
* @throws XMLReaderException Thrown if file cannot be read for some reason.
|
||||
*/
|
||||
public static String readXMLFileToString(String path, Charset encoding) throws IOException, ParserConfigurationException, SAXException, TransformerException {
|
||||
public static String readXMLFileToString(String path, Charset encoding) throws TransformerException, XMLReaderException {
|
||||
|
||||
InputSource fileSource = new InputSource(XMLReader.class.getClassLoader().getResourceAsStream(path));
|
||||
InputStream fileStream = XMLReader.class.getClassLoader().getResourceAsStream(path);
|
||||
|
||||
Document doc = XMLReader.parseInputStream(fileStream);
|
||||
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
Document doc = dBuilder.parse(fileSource);
|
||||
doc.getDocumentElement().normalize();
|
||||
|
||||
return XMLReader.getContents(doc);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package shared.enums;
|
||||
|
||||
/**
|
||||
* Represents the various ways in which we want to open/read an xml file - e.g., a string may contain the file contents, or the file path.
|
||||
*/
|
||||
public enum XMLFileType {
|
||||
|
||||
/**
|
||||
* This means that a provided string contains the contents of an XML file.
|
||||
*/
|
||||
Contents,
|
||||
|
||||
/**
|
||||
* This means that a provided string contains the path to an XML file.
|
||||
*/
|
||||
FilePath,
|
||||
|
||||
/**
|
||||
* This means that a provided string contains the path, to be loaded as a resource, of an XML file.
|
||||
*/
|
||||
ResourcePath;
|
||||
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import javafx.scene.paint.Color;
|
||||
import network.Messages.Enums.RaceStatusEnum;
|
||||
import network.Messages.LatestMessages;
|
||||
import shared.dataInput.*;
|
||||
import shared.enums.XMLFileType;
|
||||
import shared.exceptions.InvalidBoatDataException;
|
||||
import shared.exceptions.InvalidRaceDataException;
|
||||
import shared.exceptions.InvalidRegattaDataException;
|
||||
@@ -115,9 +116,9 @@ public class StartController extends Controller implements Observer {
|
||||
private void startRace(LatestMessages latestMessages) throws XMLReaderException, InvalidRaceDataException, InvalidBoatDataException, InvalidRegattaDataException {
|
||||
|
||||
//Create data sources from latest messages for the race.
|
||||
RaceDataSource raceDataSource = new RaceXMLReader(latestMessages.getRaceXMLMessage().getXmlMessage());
|
||||
BoatDataSource boatDataSource = new BoatXMLReader(latestMessages.getBoatXMLMessage().getXmlMessage());
|
||||
RegattaDataSource regattaDataSource = new RegattaXMLReader(latestMessages.getRegattaXMLMessage().getXmlMessage());
|
||||
RaceDataSource raceDataSource = new RaceXMLReader(latestMessages.getRaceXMLMessage().getXmlMessage(), XMLFileType.ResourcePath);
|
||||
BoatDataSource boatDataSource = new BoatXMLReader(latestMessages.getBoatXMLMessage().getXmlMessage(), XMLFileType.ResourcePath);
|
||||
RegattaDataSource regattaDataSource = new RegattaXMLReader(latestMessages.getRegattaXMLMessage().getXmlMessage(), XMLFileType.ResourcePath);
|
||||
|
||||
//Create race.
|
||||
this.visualiserRace = new VisualiserRace(boatDataSource, raceDataSource, regattaDataSource, latestMessages, this.colors);
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,119 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<BoatConfig>
|
||||
<Modified>2017-04-19T15:49:40+1200</Modified>
|
||||
<Version>1</Version>
|
||||
<Settings>
|
||||
<RaceBoatType Type="AC45" />
|
||||
<BoatDimension BoatLength="14.019" HullLength="13.449" />
|
||||
<ZoneSize MarkZoneSize="40.347" CourseZoneSize="40.347" />
|
||||
<ZoneLimits Limit1="200" Limit2="100" Limit3="40.347" Limit4="0" Limit5="-100" />
|
||||
</Settings>
|
||||
<BoatShapes>
|
||||
<BoatShape ShapeID="0">
|
||||
<Vertices>
|
||||
<Vtx Seq="1" Y="0" X="-2.659" />
|
||||
<Vtx Seq="2" Y="18.359" X="-2.659" />
|
||||
<Vtx Seq="3" Y="18.359" X="2.659" />
|
||||
<Vtx Seq="4" Y="0" X="2.659" />
|
||||
</Vertices>
|
||||
</BoatShape>
|
||||
<BoatShape ShapeID="1">
|
||||
<Vertices>
|
||||
<Vtx Seq="1" Y="0" X="-1.278" />
|
||||
<Vtx Seq="2" Y="8.876" X="-1.278" />
|
||||
<Vtx Seq="3" Y="8.876" X="1.278" />
|
||||
<Vtx Seq="4" Y="0" X="1.278" />
|
||||
</Vertices>
|
||||
</BoatShape>
|
||||
<BoatShape ShapeID="2">
|
||||
<Vertices>
|
||||
<Vtx Seq="1" Y="0" X="-1.1" />
|
||||
<Vtx Seq="2" Y="8.3" X="-1.1" />
|
||||
<Vtx Seq="3" Y="8.3" X="1.1" />
|
||||
<Vtx Seq="4" Y="0" X="1.1" />
|
||||
</Vertices>
|
||||
</BoatShape>
|
||||
<BoatShape ShapeID="3">
|
||||
<Vertices>
|
||||
<Vtx Seq="1" Y="0" X="-0.75" />
|
||||
<Vtx Seq="2" Y="3" X="-0.75" />
|
||||
<Vtx Seq="3" Y="3" X="0.75" />
|
||||
<Vtx Seq="4" Y="0" X="0.75" />
|
||||
</Vertices>
|
||||
</BoatShape>
|
||||
<BoatShape ShapeID="4">
|
||||
<Vertices>
|
||||
<Vtx Seq="1" Y="0" X="-3.46" />
|
||||
<Vtx Seq="2" Y="13.449" X="-3.46" />
|
||||
<Vtx Seq="3" Y="14.019" X="0" />
|
||||
<Vtx Seq="4" Y="13.449" X="3.46" />
|
||||
<Vtx Seq="5" Y="0" X="3.46" />
|
||||
</Vertices>
|
||||
<Catamaran>
|
||||
<Vtx Seq="1" Y="1.769" X="-2.752" />
|
||||
<Vtx Seq="2" Y="0" X="-2.813" />
|
||||
<Vtx Seq="3" Y="0" X="-3.34" />
|
||||
<Vtx Seq="4" Y="5.351" X="-3.46" />
|
||||
<Vtx Seq="5" Y="10.544" X="-3.387" />
|
||||
<Vtx Seq="6" Y="13.449" X="-3.075" />
|
||||
<Vtx Seq="7" Y="10.851" X="-2.793" />
|
||||
<Vtx Seq="8" Y="6.669" X="-2.699" />
|
||||
<Vtx Seq="9" Y="6.669" X="2.699" />
|
||||
<Vtx Seq="10" Y="10.851" X="2.793" />
|
||||
<Vtx Seq="11" Y="13.449" X="3.075" />
|
||||
<Vtx Seq="12" Y="10.544" X="3.387" />
|
||||
<Vtx Seq="13" Y="5.351" X="3.46" />
|
||||
<Vtx Seq="14" Y="0" X="3.34" />
|
||||
<Vtx Seq="15" Y="0" X="2.813" />
|
||||
<Vtx Seq="16" Y="1.769" X="2.752" />
|
||||
</Catamaran>
|
||||
<Bowsprit>
|
||||
<Vtx Seq="1" Y="6.669" X="-0.2" />
|
||||
<Vtx Seq="2" Y="11.377" X="-0.2" />
|
||||
<Vtx Seq="3" Y="14.019" X="0" />
|
||||
<Vtx Seq="4" Y="11.377" X="0.2" />
|
||||
<Vtx Seq="5" Y="6.669" X="0.2" />
|
||||
</Bowsprit>
|
||||
<Trampoline>
|
||||
<Vtx Seq="1" Y="2" X="-2.699" />
|
||||
<Vtx Seq="2" Y="6.438" X="-2.699" />
|
||||
<Vtx Seq="3" Y="6.438" X="2.699" />
|
||||
<Vtx Seq="4" Y="2" X="2.699" />
|
||||
</Trampoline>
|
||||
</BoatShape>
|
||||
<BoatShape ShapeID="5" />
|
||||
</BoatShapes>
|
||||
<Boats>>
|
||||
<Boat Type="Yacht" SourceID="101" ShapeID="4" HullNum="AC4501" ShortName="USA"
|
||||
BoatName="ORACLE TEAM USA" Country="USA">
|
||||
<GPSposition Z="1.738" Y="0.625" X="0.001" />
|
||||
<MastTop Z="21.496" Y="4.233" X="0.000" />
|
||||
</Boat>
|
||||
<Boat Type="Yacht" SourceID="102" ShapeID="4" HullNum="AC4502" ShortName="GBR"
|
||||
BoatName="Land Rover BAR" Country="United Kingdom">
|
||||
<GPSposition Z="1.738" Y="0.625" X="0.001" />
|
||||
<MastTop Z="21.496" Y="4.233" X="0.000" />
|
||||
</Boat>
|
||||
<Boat Type="Yacht" SourceID="103" ShapeID="4" HullNum="AC4503" ShortName="JPN"
|
||||
BoatName="SoftBank Team Japan" Country="Japan">
|
||||
<GPSposition Z="1.738" Y="0.625" X="0.001" />
|
||||
<MastTop Z="21.496" Y="4.233" X="0.000" />
|
||||
</Boat>
|
||||
<Boat Type="Yacht" SourceID="104" ShapeID="4" HullNum="AC4504" ShortName="FRA"
|
||||
BoatName="Groupama Team France" Country="France">
|
||||
<GPSposition Z="1.738" Y="0.625" X="0.001" />
|
||||
<MastTop Z="21.496" Y="4.233" X="0.000" />
|
||||
</Boat>
|
||||
<Boat Type="Yacht" SourceID="105" ShapeID="4" HullNum="AC4505" ShortName="SWE"
|
||||
BoatName="Artemis Racing" Country="Sweden">
|
||||
<GPSposition Z="1.738" Y="0.625" X="0.001" />
|
||||
<MastTop Z="21.496" Y="4.233" X="0.000" />
|
||||
</Boat>
|
||||
<Boat Type="Yacht" SourceID="106" ShapeID="4" HullNum="AC4506" ShortName="NZL"
|
||||
BoatName="Emirates Team New Zealand" Country="New Zealand">
|
||||
<GPSposition Z="1.738" Y="0.625" X="0.001" />
|
||||
<MastTop Z="21.496" Y="4.233" X="0.000" />
|
||||
</Boat>
|
||||
</Boats>
|
||||
</BoatConfig>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Race>
|
||||
<RaceID>17041901</RaceID>
|
||||
<RaceType>Fleet</RaceType>
|
||||
<CreationTimeDate>2017-04-19T15:30:00+1200</CreationTimeDate >
|
||||
<RaceStartTime Time="2019-06-01T13:30:00-0400" Postpone="false" />
|
||||
<Participants>
|
||||
<Yacht SourceID="001" Entry="Port" />
|
||||
<Yacht SourceID="002" Entry="Port" />
|
||||
<Yacht SourceID="003" Entry="Port" />
|
||||
<Yacht SourceID="004" Entry="Port" />
|
||||
<Yacht SourceID="005" Entry="Port" />
|
||||
<Yacht SourceID="006" Entry="Port" />
|
||||
</Participants>
|
||||
<Course>
|
||||
<CompoundMark CompoundMarkID="1" Name="StartLine">
|
||||
<Mark SeqID="1" Name="PRO" TargetLat="32.296577" TargetLng="-64.854304" SourceID="101" />
|
||||
<Mark SeqID="2" Name="PIN" TargetLat="32.293771" TargetLng="-64.855242" SourceID="102" />
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="2" Name="M1">
|
||||
<Mark Name="M1" TargetLat="32.293039" TargetLng="-64.843983" SourceID="103" />
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="3" Name="WindwardGate">
|
||||
<Mark SeqID="1" Name="G1" TargetLat="32.284680" TargetLng="-64.850045" SourceID="104" />
|
||||
<Mark SeqID="2" Name="G2" TargetLat="32.280164" TargetLng="-64.847591" SourceID="105" />
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="4" Name="LeewardGate">
|
||||
<Mark SeqID="1" Name="G1" TargetLat="32.309693" TargetLng="-64.835249" SourceID="106" />
|
||||
<Mark SeqID="2" Name="G2" TargetLat="32.308046" TargetLng="-64.831785" SourceID="107" />
|
||||
</CompoundMark>
|
||||
<CompoundMark CompoundMarkID="5" Name="FinishLine">
|
||||
<Mark SeqID="1" Name="PRO" TargetLat="32.317379" TargetLng="-64.839291" SourceID="108" />
|
||||
<Mark SeqID="2" Name="PIN" TargetLat="32.317257" TargetLng="-64.836260" SourceID="109" />
|
||||
</CompoundMark>
|
||||
</Course>
|
||||
<CompoundMarkSequence>
|
||||
<Corner SeqID="1" CompoundMarkID="1" Rounding="SP" ZoneSize="3" />
|
||||
<Corner SeqID="2" CompoundMarkID="2" Rounding="Port" ZoneSize="3" />
|
||||
<Corner SeqID="3" CompoundMarkID="3" Rounding="Port" ZoneSize="3" />
|
||||
<Corner SeqID="4" CompoundMarkID="4" Rounding="Port" ZoneSize="3" />
|
||||
<Corner SeqID="3" CompoundMarkID="3" Rounding="Port" ZoneSize="3" />
|
||||
<Corner SeqID="5" CompoundMarkID="5" Rounding="SP" ZoneSize="3"/>
|
||||
</CompoundMarkSequence>
|
||||
<CourseLimit>
|
||||
<Limit SeqID="1" Lat="32.313922" Lon="-64.837168"/>
|
||||
<Limit SeqID="2" Lat="32.317379" Lon="-64.839291"/>
|
||||
<Limit SeqID="3" Lat="32.317911" Lon="-64.836996"/>
|
||||
<Limit SeqID="4" Lat="32.317257" Lon="-64.836260"/>
|
||||
<Limit SeqID="5" Lat="32.304273" Lon="-64.822834"/>
|
||||
|
||||
<Limit SeqID="6" Lat="32.279097" Lon="-64.841545"/>
|
||||
<Limit SeqID="7" Lat="32.279604" Lon="-64.849871"/>
|
||||
<Limit SeqID="8" Lat="32.289545" Lon="-64.854162"/>
|
||||
<Limit SeqID="9" Lat="32.290198" Lon="-64.858711"/>
|
||||
<Limit SeqID="10" Lat="32.297164" Lon="-64.856394"/>
|
||||
<Limit SeqID="11" Lat="32.296148" Lon="-64.849184"/>
|
||||
</CourseLimit>
|
||||
</Race>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<RegattaConfig>
|
||||
<RegattaID>1</RegattaID>
|
||||
<RegattaName>Seng302 Mock Test</RegattaName>
|
||||
<CourseName>Bermuda AC35</CourseName>
|
||||
<CentralLatitude>-32.296577</CentralLatitude>
|
||||
<CentralLongitude>64.854304</CentralLongitude>
|
||||
<CentralAltitude>0.00</CentralAltitude>
|
||||
<UtcOffset>-4</UtcOffset>
|
||||
<MagneticVariation>-14.78</MagneticVariation>
|
||||
</RegattaConfig>
|
||||
Reference in New Issue
Block a user