mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 14:28:43 +00:00
Boat and race XML now generated dynamically
- Removed course from XML Generator as it was not needed - Boat and race XML added - Method names in Yacht class updated to follow JavaBean standard so they can be read by the template engine Tags: #story[984]
This commit is contained in:
@@ -320,7 +320,7 @@ public class CanvasController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Yacht boat : boats.values()) {
|
for (Yacht boat : boats.values()) {
|
||||||
if (participantIDs.contains(boat.getSourceID())) {
|
if (participantIDs.contains(boat.getSourceId())) {
|
||||||
boat.setColour(Colors.getColor());
|
boat.setColour(Colors.getColor());
|
||||||
BoatGroup boatGroup = new BoatGroup(boat, boat.getColour());
|
BoatGroup boatGroup = new BoatGroup(boat, boat.getColour());
|
||||||
boatGroups.add(boatGroup);
|
boatGroups.add(boatGroup);
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class FinishScreenViewController implements Initializable {
|
|||||||
|
|
||||||
// add data to table
|
// add data to table
|
||||||
for (Yacht boat : StreamParser.getBoatsPos().values()) {
|
for (Yacht boat : StreamParser.getBoatsPos().values()) {
|
||||||
if (participantIDs.contains(boat.getSourceID())) {
|
if (participantIDs.contains(boat.getSourceId())) {
|
||||||
data.add(boat);
|
data.add(boat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
*/
|
*/
|
||||||
void updateSparkLine(){
|
void updateSparkLine(){
|
||||||
// Collect the racing boats that aren't already in the chart
|
// Collect the racing boats that aren't already in the chart
|
||||||
ArrayList<Yacht> sparkLineCandidates = startingBoats.stream().filter(yacht -> !sparkLineData.containsKey(yacht.getSourceID())
|
ArrayList<Yacht> sparkLineCandidates = startingBoats.stream().filter(yacht -> !sparkLineData.containsKey(yacht.getSourceId())
|
||||||
&& yacht.getPosition() != null & yacht.getPosition() != "-").collect(Collectors.toCollection(ArrayList::new));
|
&& yacht.getPosition() != null & yacht.getPosition() != "-").collect(Collectors.toCollection(ArrayList::new));
|
||||||
|
|
||||||
// Obtain the qualifying boats to set the max on the Y axis
|
// Obtain the qualifying boats to set the max on the Y axis
|
||||||
@@ -214,7 +214,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
Series<String, Double> yachtData = new Series<>();
|
Series<String, Double> yachtData = new Series<>();
|
||||||
yachtData.setName(yacht.getBoatName());
|
yachtData.setName(yacht.getBoatName());
|
||||||
yachtData.getData().add(new XYChart.Data<>(Integer.toString(yacht.getLegNumber()), 1 + racingBoats.size() - Double.parseDouble(yacht.getPosition())));
|
yachtData.getData().add(new XYChart.Data<>(Integer.toString(yacht.getLegNumber()), 1 + racingBoats.size() - Double.parseDouble(yacht.getPosition())));
|
||||||
sparkLineData.put(yacht.getSourceID(), yachtData);
|
sparkLineData.put(yacht.getSourceId(), yachtData);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Lambda function to sort the series in order of leg (later legs shown more to the right)
|
// Lambda function to sort the series in order of leg (later legs shown more to the right)
|
||||||
@@ -244,7 +244,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
* @param legNumber the leg number that the position will be assigned to
|
* @param legNumber the leg number that the position will be assigned to
|
||||||
*/
|
*/
|
||||||
public static void updateYachtPositionSparkline(Yacht yacht, Integer legNumber){
|
public static void updateYachtPositionSparkline(Yacht yacht, Integer legNumber){
|
||||||
XYChart.Series<String, Double> positionData = sparkLineData.get(yacht.getSourceID());
|
XYChart.Series<String, Double> positionData = sparkLineData.get(yacht.getSourceId());
|
||||||
positionData.getData().add(new XYChart.Data<>(Integer.toString(legNumber), 1 + racingBoats.size() - Double.parseDouble(yacht.getPosition())));
|
positionData.getData().add(new XYChart.Data<>(Integer.toString(legNumber), 1 + racingBoats.size() - Double.parseDouble(yacht.getPosition())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,7 +381,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
|
|
||||||
if (StreamParser.isRaceStarted()) {
|
if (StreamParser.isRaceStarted()) {
|
||||||
for (Yacht boat : StreamParser.getBoatsPos().values()) {
|
for (Yacht boat : StreamParser.getBoatsPos().values()) {
|
||||||
if (participantIDs.contains(boat.getSourceID())) { // check if the boat is racing
|
if (participantIDs.contains(boat.getSourceId())) { // check if the boat is racing
|
||||||
if (boat.getBoatStatus() == 3) { // 3 is finish status
|
if (boat.getBoatStatus() == 3) { // 3 is finish status
|
||||||
Text textToAdd = new Text(boat.getPosition() + ". " +
|
Text textToAdd = new Text(boat.getPosition() + ". " +
|
||||||
boat.getShortName() + " (Finished)");
|
boat.getShortName() + " (Finished)");
|
||||||
@@ -399,7 +399,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (Yacht boat : StreamParser.getBoats().values()) {
|
for (Yacht boat : StreamParser.getBoats().values()) {
|
||||||
if (participantIDs.contains(boat.getSourceID())) { // check if the boat is racing
|
if (participantIDs.contains(boat.getSourceId())) { // check if the boat is racing
|
||||||
Text textToAdd = new Text(boat.getPosition() + ". " +
|
Text textToAdd = new Text(boat.getPosition() + ". " +
|
||||||
boat.getShortName() + " ");
|
boat.getShortName() + " ");
|
||||||
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
textToAdd.setFill(Paint.valueOf("#d3d3d3"));
|
||||||
@@ -613,7 +613,7 @@ public class RaceViewController extends Thread implements ImportantAnnotationDel
|
|||||||
for (BoatGroup bg : includedCanvasController.getBoatGroups()) {
|
for (BoatGroup bg : includedCanvasController.getBoatGroups()) {
|
||||||
//We need to iterate over all race groups to get the matching boat group belonging to this boat if we
|
//We need to iterate over all race groups to get the matching boat group belonging to this boat if we
|
||||||
//are to toggle its annotations, there is no other backwards knowledge of a yacht to its boatgroup.
|
//are to toggle its annotations, there is no other backwards knowledge of a yacht to its boatgroup.
|
||||||
if (bg.getBoat().getHullID().equals(yacht.getHullID())) {
|
if (bg.getBoat().getHullId().equals(yacht.getHullId())) {
|
||||||
updateLaylines(bg);
|
updateLaylines(bg);
|
||||||
bg.setIsSelected(true);
|
bg.setIsSelected(true);
|
||||||
selectedBoat = yacht;
|
selectedBoat = yacht;
|
||||||
|
|||||||
@@ -316,7 +316,7 @@ public class BoatGroup extends Group {
|
|||||||
* @return An array containing all ID's associated with this RaceObject.
|
* @return An array containing all ID's associated with this RaceObject.
|
||||||
*/
|
*/
|
||||||
public long getRaceId() {
|
public long getRaceId() {
|
||||||
return boat.getSourceID();
|
return boat.getSourceId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Group getWake () {
|
public Group getWake () {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public class GameServerThread implements Runnable, Observer, ClientConnectionDel
|
|||||||
thereAreBoatsNotFinished = true;
|
thereAreBoatsNotFinished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
BoatSubMessage m = new BoatSubMessage(y.getSourceID(), boatStatus, y.getLastMarkRounded().getId(), 0, 0, 1234l, 1234l);
|
BoatSubMessage m = new BoatSubMessage(y.getSourceId(), boatStatus, y.getLastMarkRounded().getId(), 0, 0, 1234l, 1234l);
|
||||||
boatSubMessages.add(m);
|
boatSubMessages.add(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,15 @@ package seng302.gameServerWithThreading;
|
|||||||
|
|
||||||
import seng302.gameServer.GameStages;
|
import seng302.gameServer.GameStages;
|
||||||
import seng302.gameServer.GameState;
|
import seng302.gameServer.GameState;
|
||||||
|
import seng302.models.Yacht;
|
||||||
import seng302.models.mark.Mark;
|
import seng302.models.mark.Mark;
|
||||||
import seng302.models.mark.MarkType;
|
import seng302.models.mark.MarkType;
|
||||||
|
import seng302.models.mark.SingleMark;
|
||||||
import seng302.models.stream.PacketBufferDelegate;
|
import seng302.models.stream.PacketBufferDelegate;
|
||||||
import seng302.models.stream.StreamParser;
|
import seng302.models.stream.StreamParser;
|
||||||
import seng302.models.stream.packets.StreamPacket;
|
import seng302.models.stream.packets.StreamPacket;
|
||||||
|
import seng302.models.xml.Boats;
|
||||||
|
import seng302.models.xml.Race;
|
||||||
import seng302.models.xml.Regatta;
|
import seng302.models.xml.Regatta;
|
||||||
import seng302.models.xml.XMLGenerator;
|
import seng302.models.xml.XMLGenerator;
|
||||||
|
|
||||||
@@ -53,8 +57,19 @@ public class MainServerThread extends Thread implements PacketBufferDelegate{
|
|||||||
|
|
||||||
g.setRegatta(r);
|
g.setRegatta(r);
|
||||||
|
|
||||||
|
Race b = new Race();
|
||||||
|
b.addBoat(new Yacht("SomeType", 123, "hid", "NZL",
|
||||||
|
"Emirates Team New Zealand", "NZL"));
|
||||||
|
|
||||||
|
g.setRace(b);
|
||||||
|
|
||||||
|
System.out.println("g.getBoatsAsXml() = " + g.getBoatsAsXml());
|
||||||
|
g.getBoatsAsXml();
|
||||||
|
|
||||||
System.out.println("g.getRegattaAsXml() = " + g.getRegattaAsXml());
|
System.out.println("g.getRegattaAsXml() = " + g.getRegattaAsXml());
|
||||||
|
|
||||||
|
System.out.println("g.ragce() = " + g.getRaceAsXml());
|
||||||
|
|
||||||
//You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app.
|
//You should handle interrupts in some way, so that the thread won't keep on forever if you exit the app.
|
||||||
while (!isInterrupted()) {
|
while (!isInterrupted()) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -85,11 +85,11 @@ public class Yacht {
|
|||||||
return boatType;
|
return boatType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getSourceID() {
|
public Integer getSourceId() {
|
||||||
return sourceID;
|
return sourceID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHullID() {
|
public String getHullId() {
|
||||||
return hullID;
|
return hullID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,6 +207,7 @@ public class Yacht {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Double getLat() {
|
public Double getLat() {
|
||||||
|
if (lat == null) return 0d;
|
||||||
return lat;
|
return lat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,6 +216,8 @@ public class Yacht {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Double getLon() {
|
public Double getLon() {
|
||||||
|
|
||||||
|
if (lon == null) return 0d;
|
||||||
return lon;
|
return lon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -558,7 +558,7 @@ public class XMLParser {
|
|||||||
getNodeAttributeString(currentBoat, "Country"));
|
getNodeAttributeString(currentBoat, "Country"));
|
||||||
this.boats.add(boat);
|
this.boats.add(boat);
|
||||||
if (boat.getBoatType().equals("Yacht")) {
|
if (boat.getBoatType().equals("Yacht")) {
|
||||||
competingBoats.put(boat.getSourceID(), boat);
|
competingBoats.put(boat.getSourceId(), boat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,11 @@
|
|||||||
package seng302.models.xml;
|
package seng302.models.xml;
|
||||||
|
|
||||||
import seng302.models.mark.Mark;
|
import seng302.models.Yacht;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class Boats {
|
public class Boats {
|
||||||
private List<Mark> marks;
|
|
||||||
|
|
||||||
public Boats(){
|
|
||||||
marks = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addMark(Mark m){
|
|
||||||
marks.add(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Mark> getMarks(){
|
|
||||||
return this.marks;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,23 @@
|
|||||||
package seng302.models.xml;
|
package seng302.models.xml;
|
||||||
|
|
||||||
public class Race {
|
import seng302.models.Yacht;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Race {
|
||||||
|
private List<Yacht> yachts;
|
||||||
|
|
||||||
|
public Race(){
|
||||||
|
yachts = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBoat(Yacht yacht){
|
||||||
|
yachts.add(yacht);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Yacht> getBoats(){
|
||||||
|
return Collections.unmodifiableList(yachts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,11 @@ import java.net.URISyntaxException;
|
|||||||
public class XMLGenerator {
|
public class XMLGenerator {
|
||||||
private static final String XML_TEMPLATE_DIR = "/server_config/xml_templates";
|
private static final String XML_TEMPLATE_DIR = "/server_config/xml_templates";
|
||||||
private static final String REGATTA_TEMPLATE_NAME = "regatta.ftlh";
|
private static final String REGATTA_TEMPLATE_NAME = "regatta.ftlh";
|
||||||
|
private static final String BOATS_TEMPLATE_NAME = "boats.ftlh";
|
||||||
|
private static final String RACE_TEMPLATE_NAME = "race.ftlh";
|
||||||
private Configuration configuration;
|
private Configuration configuration;
|
||||||
private Regatta regatta;
|
private Regatta regatta;
|
||||||
|
private Race race;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set up a configuration instance for Apache Freemake
|
* Set up a configuration instance for Apache Freemake
|
||||||
@@ -39,6 +42,10 @@ public class XMLGenerator {
|
|||||||
this.regatta = regatta;
|
this.regatta = regatta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRace(Race race){
|
||||||
|
this.race = race;
|
||||||
|
}
|
||||||
|
|
||||||
private String parseToXmlString(String templateName, XMLMessageSubType type) throws IOException, TemplateException {
|
private String parseToXmlString(String templateName, XMLMessageSubType type) throws IOException, TemplateException {
|
||||||
Template template;
|
Template template;
|
||||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
@@ -52,11 +59,11 @@ public class XMLGenerator {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BOAT:
|
case BOAT:
|
||||||
template.process(regatta, writer);
|
template.process(race, writer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RACE:
|
case RACE:
|
||||||
template.process(regatta, writer);
|
template.process(race, writer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -88,5 +95,35 @@ public class XMLGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getBoatsAsXml() {
|
||||||
|
String result = null;
|
||||||
|
|
||||||
|
if (race == null) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = parseToXmlString(BOATS_TEMPLATE_NAME, XMLMessageSubType.BOAT);
|
||||||
|
} catch (TemplateException e) {
|
||||||
|
System.out.println("[FATAL] Error parsing boats");
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("[FATAL] Error reading boats");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRaceAsXml() {
|
||||||
|
String result = null;
|
||||||
|
|
||||||
|
if (race == null) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = parseToXmlString(RACE_TEMPLATE_NAME, XMLMessageSubType.RACE);
|
||||||
|
} catch (TemplateException e) {
|
||||||
|
System.out.println("[FATAL] Error parsing race");
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("[FATAL] Error reading race");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -16,20 +16,12 @@
|
|||||||
</BoatShapes>
|
</BoatShapes>
|
||||||
|
|
||||||
<Boats>
|
<Boats>
|
||||||
<#list marks as mark>
|
|
||||||
<Boat Type="Mark" SourceID="${mark.sourceId}" ShapeID="1" HullNum="${mark.hullNumber}" StoweName="${mark.stoweName}" ShortName="${mark.shortName}"
|
|
||||||
BoatName="${mark.boatName}">
|
|
||||||
<GPSposition Z="${mark.zpos}" Y="${mark.ypos}" X="${mark.xpos}" />
|
|
||||||
<FlagPosition Z="${mark.zpos}" Y="${mark.ypos}" X="${mark.xpos}" />
|
|
||||||
</Boat>
|
|
||||||
</#list>
|
|
||||||
|
|
||||||
<#list boats as boat>
|
<#list boats as boat>
|
||||||
<Boat Type="Yacht" SourceID="${boat.sourceId}" ShapeID="4" HullNum="${boat.hullNumber}" StoweName="${boat.stoweName}" ShortName="${boat.shortName}"
|
<Boat Type="Yacht" SourceID="${boat.sourceId}" ShapeID="4" HullNum="${boat.hullId}" StoweName="${boat.shortName}" ShortName="${boat.shortName}"
|
||||||
BoatName="${boat.boatName}" Country="${boat.country}">
|
BoatName="${boat.boatName}" Country="${boat.country}">
|
||||||
|
|
||||||
<GPSposition Z="${boat.zpos}" Y="${boat.ypos}" X="${boat.xpos}" />
|
<GPSposition Z="0" Y="${boat.lat}" X="${boat.lon}" />
|
||||||
<MastTop Z="${boat.zpos}" Y="${boat.ypos}" X="${boat.xpos}"/>
|
<MastTop Z="0" Y="${boat.lat}" X="${boat.lon}" />
|
||||||
</Boat>
|
</Boat>
|
||||||
</#list>
|
</#list>
|
||||||
</Boats>
|
</Boats>
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Race>
|
||||||
|
<CreationTimeDate>2015-08-29T11:27:15+02:00</CreationTimeDate>
|
||||||
|
<RaceStartTime Start="2015-08-29T13:10:00+02:00" Postpone="False" />
|
||||||
|
<RaceID>15082901</RaceID>
|
||||||
|
<RaceType>Fleet</RaceType>
|
||||||
|
|
||||||
|
<Participants>
|
||||||
|
<#list boats as boat>
|
||||||
|
<Yacht SourceID="${boat.sourceId}"/>
|
||||||
|
</#list>
|
||||||
|
</Participants>
|
||||||
|
|
||||||
|
<Course>
|
||||||
|
<CompoundMark CompoundMarkID="1" Name="Mark0">
|
||||||
|
<Mark SeqID="1" Name="Start Line 1" TargetLat="57.6703330" TargetLng="11.8278330" SourceID="122" />
|
||||||
|
<Mark SeqID="2" Name="Start Line 2" TargetLat="57.6703330" TargetLng="11.8278330" SourceID="123" />
|
||||||
|
</CompoundMark>
|
||||||
|
<CompoundMark CompoundMarkID="2" Name="Mark1">
|
||||||
|
<Mark SeqID="1" Name="Mark1" TargetLat="57.6675700" TargetLng="11.8359880" SourceID="131" />
|
||||||
|
</CompoundMark>
|
||||||
|
<CompoundMark CompoundMarkID="3" Name="Mark2">
|
||||||
|
<Mark SeqID="1" Name="Lee Gate 1" TargetLat="57.6708220" TargetLng="11.8433900" SourceID="124" />
|
||||||
|
<Mark SeqID="2" Name="Lee Gate 2" TargetLat="57.6708220" TargetLng="11.8433900" SourceID="125" />
|
||||||
|
</CompoundMark>
|
||||||
|
<CompoundMark CompoundMarkID="4" Name="Mark3">
|
||||||
|
<Mark SeqID="1" Name="Wind Gate 1" TargetLat="57.6650170" TargetLng="11.8279170" SourceID="126" />
|
||||||
|
<Mark SeqID="2" Name="Wind Gate 2" TargetLat="57.6650170" TargetLng="11.8279170" SourceID="127" />
|
||||||
|
</CompoundMark>
|
||||||
|
<CompoundMark CompoundMarkID="5" Name="Mark2">
|
||||||
|
<Mark SeqID="1" Name="Lee Gate 1" TargetLat="57.6708220" TargetLng="11.8433900" SourceID="124" />
|
||||||
|
<Mark SeqID="2" Name="Lee Gate 2" TargetLat="57.6708220" TargetLng="11.8433900" SourceID="125" />
|
||||||
|
</CompoundMark>
|
||||||
|
<CompoundMark CompoundMarkID="6" Name="Mark3">
|
||||||
|
<Mark SeqID="1" Name="Wind Gate 1" TargetLat="57.6650170" TargetLng="11.8279170" SourceID="126" />
|
||||||
|
<Mark SeqID="2" Name="Wind Gate 2" TargetLat="57.6650170" TargetLng="11.8279170" SourceID="127" />
|
||||||
|
</CompoundMark>
|
||||||
|
<CompoundMark CompoundMarkID="7" Name="Mark2">
|
||||||
|
<Mark SeqID="1" Name="Lee Gate 1" TargetLat="57.6708220" TargetLng="11.8433900" SourceID="124" />
|
||||||
|
<Mark SeqID="2" Name="Lee Gate 2" TargetLat="57.6708220" TargetLng="11.8433900" SourceID="125" />
|
||||||
|
</CompoundMark>
|
||||||
|
<CompoundMark CompoundMarkID="8" Name="Mark3">
|
||||||
|
<Mark SeqID="1" Name="Wind Gate 1" TargetLat="57.6650170" TargetLng="11.8279170" SourceID="126" />
|
||||||
|
<Mark SeqID="2" Name="Wind Gate 2" TargetLat="57.6650170" TargetLng="11.8279170" SourceID="127" />
|
||||||
|
</CompoundMark>
|
||||||
|
<CompoundMark CompoundMarkID="9" Name="Mark2">
|
||||||
|
<Mark SeqID="1" Name="Lee Gate 1" TargetLat="57.6708220" TargetLng="11.8433900" SourceID="124" />
|
||||||
|
<Mark SeqID="2" Name="Lee Gate 2" TargetLat="57.6708220" TargetLng="11.8433900" SourceID="125" />
|
||||||
|
</CompoundMark>
|
||||||
|
<CompoundMark CompoundMarkID="10" Name="Mark3">
|
||||||
|
<Mark SeqID="1" Name="Wind Gate 1" TargetLat="57.6650170" TargetLng="11.8279170" SourceID="126" />
|
||||||
|
<Mark SeqID="2" Name="Wind Gate 2" TargetLat="57.6650170" TargetLng="11.8279170" SourceID="127" />
|
||||||
|
</CompoundMark>
|
||||||
|
<CompoundMark CompoundMarkID="11" Name="Mark4">
|
||||||
|
<Mark SeqID="1" Name="Finish Line 1" TargetLat="57.6715240" TargetLng="11.8444950" SourceID="128" />
|
||||||
|
<Mark SeqID="2" Name="Finish Line 2" TargetLat="57.6715240" TargetLng="11.8444950" SourceID="129" />
|
||||||
|
</CompoundMark>
|
||||||
|
</Course>
|
||||||
|
<CompoundMarkSequence>
|
||||||
|
<Corner SeqID="1" CompoundMarkID="1" Rounding="PS" ZoneSize="3" />
|
||||||
|
<Corner SeqID="2" CompoundMarkID="2" Rounding="Port" ZoneSize="3" />
|
||||||
|
<Corner SeqID="3" CompoundMarkID="3" Rounding="SP" ZoneSize="3" />
|
||||||
|
<Corner SeqID="4" CompoundMarkID="4" Rounding="PS" ZoneSize="3" />
|
||||||
|
<Corner SeqID="5" CompoundMarkID="5" Rounding="SP" ZoneSize="3" />
|
||||||
|
<Corner SeqID="6" CompoundMarkID="6" Rounding="PS" ZoneSize="3" />
|
||||||
|
<Corner SeqID="7" CompoundMarkID="7" Rounding="SP" ZoneSize="3" />
|
||||||
|
<Corner SeqID="8" CompoundMarkID="8" Rounding="PS" ZoneSize="3" />
|
||||||
|
<Corner SeqID="9" CompoundMarkID="9" Rounding="SP" ZoneSize="3" />
|
||||||
|
<Corner SeqID="10" CompoundMarkID="10" Rounding="PS" ZoneSize="3" />
|
||||||
|
<Corner SeqID="11" CompoundMarkID="11" Rounding="PS" ZoneSize="3" />
|
||||||
|
</CompoundMarkSequence>
|
||||||
|
<CourseLimit>
|
||||||
|
<Limit SeqID="1" Lat="57.6739450" Lon="11.8417100" />
|
||||||
|
<Limit SeqID="2" Lat="57.6709520" Lon="11.8485010" />
|
||||||
|
<Limit SeqID="3" Lat="57.6690260" Lon="11.8472790" />
|
||||||
|
<Limit SeqID="4" Lat="57.6693140" Lon="11.8457610" />
|
||||||
|
<Limit SeqID="5" Lat="57.6665370" Lon="11.8432910" />
|
||||||
|
<Limit SeqID="6" Lat="57.6641400" Lon="11.8385840" />
|
||||||
|
<Limit SeqID="7" Lat="57.6629430" Lon="11.8332030" />
|
||||||
|
<Limit SeqID="8" Lat="57.6629480" Lon="11.8249660" />
|
||||||
|
<Limit SeqID="9" Lat="57.6686890" Lon="11.8250920" />
|
||||||
|
<Limit SeqID="10" Lat="57.6692230" Lon="11.8231430" />
|
||||||
|
<Limit SeqID="11" Lat="57.6725370" Lon="11.8272480" />
|
||||||
|
<Limit SeqID="12" Lat="57.6708220" Lon="11.8321340" />
|
||||||
|
</CourseLimit>
|
||||||
|
</Race>
|
||||||
Reference in New Issue
Block a user