mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-15 00:30:58 +00:00
Merge remote-tracking branch 'origin/master' into ribdashboard
This commit is contained in:
commit
5bbb80891e
18 files changed
+1087
-97
No files matched your search
+14
-4
@@ -17,14 +17,12 @@ import com.sap.sse.common.TimePoint;
|
||||
public class TracTracStartTimeUpdateHandler extends UpdateHandler implements StartTimeChangedListener {
|
||||
|
||||
private static final String ACTION = "update_race_start_time";
|
||||
private final TracTracStartTimeResetHandler resetHandler;
|
||||
|
||||
private final static Logger logger = Logger.getLogger(TracTracStartTimeUpdateHandler.class.getName());
|
||||
private final static String FIELD_RACE_START_TIME = "race_start_time";
|
||||
|
||||
public TracTracStartTimeUpdateHandler(URI updateURI, String tracTracUsername, String tracTracPassword, Serializable tracTracEventId, Serializable raceId) {
|
||||
super(updateURI, ACTION, tracTracUsername, tracTracPassword, tracTracEventId, raceId);
|
||||
resetHandler = new TracTracStartTimeResetHandler(updateURI, tracTracUsername, tracTracPassword, tracTracEventId, raceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -34,8 +32,20 @@ public class TracTracStartTimeUpdateHandler extends UpdateHandler implements Sta
|
||||
}
|
||||
|
||||
if (newStartTime == null) {
|
||||
// reset start time with TracTrac
|
||||
resetHandler.startTimeChanged(null);
|
||||
/*
|
||||
* Do not reset start time based on request by Jorge from TracTrac:
|
||||
*
|
||||
* """
|
||||
* We have detected that when you want to update the race start time your
|
||||
* system sends before a message to reset the race start time. When your
|
||||
* system invokes the first service our system changes the race start time
|
||||
* to null and this value causes some secondary effects in our side.
|
||||
*
|
||||
* Can you just send the update_race_start_time without the
|
||||
* reset_race_start_time? The reset_race_start_time service has to be used
|
||||
* if you want to set the value to null.
|
||||
* """
|
||||
*/
|
||||
} else {
|
||||
HashMap<String, String> additionalParameters = new HashMap<String, String>();
|
||||
additionalParameters.put(FIELD_RACE_START_TIME, String.valueOf(newStartTime.asMillis()));
|
||||
|
||||
+1
-1
@@ -674,7 +674,7 @@ public class RaceMap extends AbsolutePanel implements TimeListener, CompetitorSe
|
||||
WindTrackInfoDTO windTrackInfoDTO = windInfo.windTrackInfoByWindSource.get(windSource);
|
||||
switch (windSource.getType()) {
|
||||
case EXPEDITION:
|
||||
// we filter out measured wind sources with a very little confidence
|
||||
// we filter out measured wind sources with vary low confidence
|
||||
if (windTrackInfoDTO.minWindConfidence > 0.0001) {
|
||||
windSourcesToShow.add(new com.sap.sse.common.Util.Pair<WindSource, WindTrackInfoDTO>(windSource, windTrackInfoDTO));
|
||||
}
|
||||
|
||||
+9
-6
@@ -82,7 +82,7 @@ public class TestWindEstimationFromManeuversOnAFew505Races extends OnlineTracTra
|
||||
CreateModelException, NotEnoughDataHasBeenAddedException {
|
||||
setUp("OBMR 2012", "event_20121031_OBMR-OBMR_2012_VR_Fr_Fleet_1_2");
|
||||
Wind average = getManeuverBasedAverageWind();
|
||||
assertEquals(222, average.getFrom().getDegrees(), 5.0); // wind in this race was from 075deg on average
|
||||
assertEquals(222, average.getFrom().getDegrees(), 5.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -91,7 +91,7 @@ public class TestWindEstimationFromManeuversOnAFew505Races extends OnlineTracTra
|
||||
CreateModelException, NotEnoughDataHasBeenAddedException {
|
||||
setUp("event_20110609_KielerWoch-505_Race_2");
|
||||
Wind average = getManeuverBasedAverageWind();
|
||||
assertEquals(235, average.getFrom().getDegrees(), 5.0); // wind in this race was from 075deg on average
|
||||
assertEquals(235, average.getFrom().getDegrees(), 5.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -100,7 +100,7 @@ public class TestWindEstimationFromManeuversOnAFew505Races extends OnlineTracTra
|
||||
CreateModelException, NotEnoughDataHasBeenAddedException {
|
||||
setUp("event_20110609_KielerWoch-505_Race_3");
|
||||
Wind average = getManeuverBasedAverageWind();
|
||||
assertEquals(245, average.getFrom().getDegrees(), 5.0); // wind in this race was from 075deg on average
|
||||
assertEquals(245, average.getFrom().getDegrees(), 5.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -109,7 +109,7 @@ public class TestWindEstimationFromManeuversOnAFew505Races extends OnlineTracTra
|
||||
CreateModelException, NotEnoughDataHasBeenAddedException {
|
||||
setUp("event_20110609_KielerWoch-505_race_4");
|
||||
Wind average = getManeuverBasedAverageWind();
|
||||
assertEquals(275, average.getFrom().getDegrees(), 5.0); // wind in this race was from 075deg on average
|
||||
assertEquals(270, average.getFrom().getDegrees(), 5.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -139,8 +139,11 @@ public class TestWindEstimationFromManeuversOnAFew505Races extends OnlineTracTra
|
||||
.sorted((c1, c2) -> (int) -Math.signum(getAverageLikelihood(c1, ManeuverType.TACK)
|
||||
- getAverageLikelihood(c2, ManeuverType.TACK))).collect(Collectors.toList());
|
||||
// expecting a wind direction that is from around 245deg, +/- 10deg
|
||||
assertEquals(245., windTrack.getWeightedAverageMiddleManeuverCOGDeg(clustersSortedByAverageTackLikelihood.get(0), ManeuverType.TACK).getDegrees(), 10.);
|
||||
assertEquals(245., windTrack.getWeightedAverageMiddleManeuverCOGDeg(clustersSortedByAverageTackLikelihood.get(1), ManeuverType.TACK).getDegrees(), 10.);
|
||||
assertEquals(
|
||||
245., windTrack.getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(
|
||||
clustersSortedByAverageTackLikelihood.get(0), ManeuverType.TACK).getA().getDegrees(), 10.);
|
||||
assertEquals(245., windTrack.getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(
|
||||
clustersSortedByAverageTackLikelihood.get(1), ManeuverType.TACK).getA().getDegrees(), 10.);
|
||||
}
|
||||
|
||||
private double getAverageLikelihood(
|
||||
|
||||
+208
-60
@@ -70,26 +70,59 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
* for another cluster to be a cluster's opposite tack cluster is determined by first computing the
|
||||
* {@link #getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(Cluster, double, Bearing) angular
|
||||
* distance}. For each so many degrees of distance as specified by this constant, the likelihood of the cluster to be the
|
||||
* opposite tack cluster is halved.
|
||||
* opposite tack cluster is halved. This constant can also be used to assign likelihoods for other cluster types
|
||||
* based on their distance from an expected configuration of maneuver angle and middle COG.
|
||||
*/
|
||||
private static final double ANGULAR_DISTANCE_FOR_HALF_CONFIDENCE_FOR_OPPOSITE_TACK_CLUSTER_DEG = 20.;
|
||||
|
||||
/**
|
||||
* When one or two jibe clusters have been found whose
|
||||
* {@link #getLikelihoodOfBeingJibeCluster(Speed, Stream, BoatClass, Set) likelihood of being a jibe cluster} is 100%,
|
||||
* this is the boost factor by which the base likelihood for the tack cluster candidate will be increased (up to a
|
||||
* maximum of 1.0).
|
||||
*/
|
||||
private static final double BOOST_FACTOR_FOR_FULL_JIBE_CLUSTER_LIKELIHOOD = 0.2;
|
||||
|
||||
/**
|
||||
* When one or two head-up / bear-away clusters on the two tacks adjacent to the middle upwind COG have been found
|
||||
* whose {@link #getLikelihoodOfClusterBasedOnDistanceFromExpected(double, Bearing, Cluster) likelihood of being
|
||||
* such a cluster} is 100%, this is the boost factor by which the base likelihood for the tack cluster candidate
|
||||
* will be increased (up to a maximum of 1.0).
|
||||
*/
|
||||
private static final double BOOST_FACTOR_FOR_FULL_HEAD_UP_BEAR_AWAY_CLUSTER_LIKELIHOOD = 0.1;
|
||||
|
||||
/**
|
||||
* When looking for the head-up/bear-away clusters, which average maneuver angle should be expected? This is a bit
|
||||
* fuzzy because in some cases the head-up and bear-away maneuvers may be grouped into one cluster, resulting in an
|
||||
* average maneuver angle that is close to zero whereas in other cases they may form two clusters, one with positive
|
||||
* and the other with negative maneuver angles of somewhere between 10-20deg, typically.
|
||||
*/
|
||||
private static final double EXPECTED_AVERAGE_HEAD_UP_AND_BEAR_AWAY_MANEUVER_ANGLE_DEG = 10.;
|
||||
|
||||
/**
|
||||
* We're trying to find the jibe cluster based on a candidate for the tack cluster. This constant tells how many degrees
|
||||
* the jibe cluster may be off from the reversed tack cluster's centroid in order to be accepted as jibe cluster candidate.
|
||||
*/
|
||||
private static final double THRESHOLD_JIBE_CLUSTER_DIFFERENCE_DEGREES = 20;
|
||||
|
||||
/**
|
||||
* For judging the likelihood of a cluster being a speed cluster, the speed ratio of the tack cluster candidate and
|
||||
* the jibe cluster candidate is computed and compared to what the polar service predicts. The basic likelihood of the
|
||||
* jibe cluster candidate (based on the maneuver angles relative to their speeds) is boosted by this factor for a perfect
|
||||
* speed ratio match.
|
||||
*/
|
||||
private static final double BOOST_FACTOR_FOR_JIBE_TACK_SPEED_RATIO_LIKELIHOOD = 0;
|
||||
|
||||
private final PolarDataService polarService;
|
||||
|
||||
private final TrackedRace trackedRace;
|
||||
|
||||
/**
|
||||
* Caches the {@link #getWeightedAverageMiddleManeuverCOGDeg(Cluster, ManeuverType)} results because these values are required several times to
|
||||
* Caches the {@link #getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(Cluster, ManeuverType)} results because these values are required several times to
|
||||
* determine the likelihood with which a cluster is a cluster of tacks or a cluster of jibes. Note that the un-weighted averages can simply be obtained
|
||||
* by asking the cluster for its {@link Cluster#getCentroid() centroid}.
|
||||
*/
|
||||
private final Map<Pair<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>, ManeuverType>, Bearing>
|
||||
private final Map<Pair<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>, ManeuverType>, Pair<Bearing, Double>>
|
||||
weightedAverageMiddleCOGForManeuverType;
|
||||
|
||||
/**
|
||||
@@ -308,17 +341,16 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
* There are usually no other maneuvers with similar middle COG because boats can't sail straight against the wind.
|
||||
* <p>
|
||||
*
|
||||
* We evaluate each cluster's likelihood of being the tack cluster by for each of its maneuvers adding up the
|
||||
* likelihood of that maneuver being a tack, solely based on its maneuver angle, as judged by the polar service. If
|
||||
* a cluster exists that has approximately the opposite average middle COG (the jibe cluster candidate), the
|
||||
* likelihoods for its maneuvers being a jibe are added. (TODO adding is statistically not adequate here; however,
|
||||
* multiplying hundreds if not thousands of probability values would easily lead to a double value going to 0.0
|
||||
* quickly. But is adding adequate to estimate the cluster having the maximum likelihood of being the tack cluster?
|
||||
* We'd only need a monotonous function.) Finally, the resulting likelihood is multiplied by how likely the speed
|
||||
* ratio between the tack and jibe cluster candidates is, based on the polar diagram. For this task, the cluster's
|
||||
* maneuvers' average speed (weighted by each maneuver's likelihood of being a tack) is divided by that of the jibe
|
||||
* cluster's maneuvers' average speed (weighted by each maneuver's likelihood of being a jibe) and assigned a
|
||||
* likelihood by the polar service.
|
||||
* We evaluate each cluster's likelihood of being the tack cluster by computing the average across all its maneuvers
|
||||
* for that maneuver being a tack, solely based on its speed and maneuver angle, as
|
||||
* {@link PolarDataService#getManeuverLikelihoodAndTwsTwa(BoatClass, Speed, double, ManeuverType) judged by the
|
||||
* polar service}. If a cluster exists that has approximately the opposite average middle COG (the jibe cluster
|
||||
* candidate), the {@link #getLikelihoodOfBeingJibeCluster(Speed, Stream, BoatClass, Set) likelihood for its maneuvers
|
||||
* being jibes} are determined and may result in a "boost" for the basic probability of up to 20%. Finally, the
|
||||
* resulting likelihood is multiplied by how likely the speed ratio between the tack and jibe cluster candidates is,
|
||||
* based on the polar diagram. For this task, the cluster's maneuvers' average speed (weighted by each maneuver's
|
||||
* likelihood of being a tack) is divided by that of the jibe cluster's maneuvers' average speed (weighted by each
|
||||
* maneuver's likelihood of being a jibe) and assigned a likelihood by the polar service.
|
||||
* <p>
|
||||
*
|
||||
* The cluster that has the highest likelihood of being the tack cluster is selected. The confidence of the choice
|
||||
@@ -361,21 +393,22 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
final Map<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>, Double>
|
||||
likelihoodOfBeingTackCluster = new HashMap<>();
|
||||
for (Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble> c : clusters) {
|
||||
likelihoodOfBeingTackCluster.put(c, getLikelihoodOfBeingTackCluster(c, clusters));
|
||||
likelihoodOfBeingTackCluster.put(c,
|
||||
getLikelihoodOfBeingTackCluster(c, clusters));
|
||||
}
|
||||
// The first two clusters in the resulting list are now our best bet for the tack clusters, assuming that the likelihood for the third element
|
||||
// in the list is already much lower. Should there be a significant degradation of likelihood between the first and the second cluster, we
|
||||
// will only use the first, particularly if the average middle COGs of the first two clusters differ significantly.
|
||||
final List<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>> tackClusters =
|
||||
clusters.stream()
|
||||
.sorted((c1, c2) -> (int) -Math.signum(likelihoodOfBeingTackCluster.get(c1) // TODO cache result of getLikelihoodOfBeingTackCluster
|
||||
.sorted((c1, c2) -> (int) -Math.signum(likelihoodOfBeingTackCluster.get(c1)
|
||||
- likelihoodOfBeingTackCluster.get(c2))).limit(2).collect(Collectors.toList());
|
||||
addWindFixes(tackClusters.stream(), ManeuverType.TACK);
|
||||
Bearing estimatedJibeMiddleCOG =
|
||||
tackClusters.isEmpty() ? null
|
||||
: (tackClusters.size() == 1 ? getWeightedAverageMiddleManeuverCOGDeg(tackClusters.get(0), ManeuverType.TACK)
|
||||
: new ScalableBearing(getWeightedAverageMiddleManeuverCOGDeg(tackClusters.get(0), ManeuverType.TACK)).add(
|
||||
new ScalableBearing(getWeightedAverageMiddleManeuverCOGDeg(tackClusters.get(1), ManeuverType.TACK))).
|
||||
: (tackClusters.size() == 1 ? getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(tackClusters.get(0), ManeuverType.TACK).getA()
|
||||
: new ScalableBearing(getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(tackClusters.get(0), ManeuverType.TACK).getA()).add(
|
||||
new ScalableBearing(getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(tackClusters.get(1), ManeuverType.TACK).getA())).
|
||||
divide(2)).reverse();
|
||||
final List<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>> jibeClusters =
|
||||
getJibeClusters(estimatedJibeMiddleCOG, clusters).collect(Collectors.toList());
|
||||
@@ -402,12 +435,14 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
/**
|
||||
* Determines the likelihood of <code>cluster</code> being a cluster of tacks, based on the average likelihood of
|
||||
* the maneuver classifications in <code>cluster</code> to be maneuvers of type {@link ManeuverType#TACK TACK}, in
|
||||
* turn based on what the {@link #polarService} thinks that this likelihood is and based on whether we find other
|
||||
* <code>clusters</code> that support this hypothesis. The likelihood is positively affected
|
||||
* turn based on what the {@link #polarService} thinks that this
|
||||
* {@link PolarDataService#getManeuverLikelihoodAndTwsTwa(BoatClass, Speed, double, ManeuverType) likelihood} is and
|
||||
* based on whether we find other <code>clusters</code> that support this hypothesis. The likelihood is positively
|
||||
* affected
|
||||
*
|
||||
* <ul>
|
||||
* <li>if a second cluster with similar average middle COG and a similar average maneuver angle with opposite sign
|
||||
* is found that also has a high average likelihood of the maneuvers contained being tacks</li>
|
||||
* is found that also has a high average likelihood of its maneuvers being tacks</li>
|
||||
* <li>if other clusters are found that for the average true wind speed estimated from the maneuvers in
|
||||
* <code>cluster</code> seem like head-up/bear-away clusters on port/starboard tack with an average middle COG that
|
||||
* is half the tacking angle for that wind speed away from the tack cluster's average middle COG</li>
|
||||
@@ -423,7 +458,14 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
* apart from the tacks even if they have similar maneuver angles.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return a likelihood between 0..1 (inclusive)
|
||||
* @return a likelihood between 0..1 (inclusive), obtained by multiplying the based likelihood of the
|
||||
* <code>cluster</code> to hold tacks, based on the maneuver angles and their speed and how likely the
|
||||
* {@link #polarService} considers this to be a tack; with boost factors added for the likelihood of having
|
||||
* found a good jibe cluster and boost factors for the likelihoods of having found starboard and port tack
|
||||
* clusters that hold the head-up/bear-away maneuvers. These boosts can add as much as
|
||||
* {@link #BOOST_FACTOR_FOR_FULL_JIBE_CLUSTER_LIKELIHOOD} + 2*
|
||||
* {@link #BOOST_FACTOR_FOR_FULL_HEAD_UP_BEAR_AWAY_CLUSTER_LIKELIHOOD} of the original value but will be
|
||||
* capped at the maximum likelihood of 1.0.
|
||||
*
|
||||
* @see ManeuverClassification#getLikelihoodAndTWSBasedOnSpeedAndAngle(ManeuverType)
|
||||
* @see PolarDataService#getManeuverLikelihoodAndTwsTwa(BoatClass, Speed, double, ManeuverType)
|
||||
@@ -433,8 +475,7 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
Set<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>> clusters) {
|
||||
// start with the average of all of the cluster's maneuvers' likelihood to be a tack
|
||||
double averageTackLikelihood = getAverageLikelihoodOfBeingManeuver(ManeuverType.TACK, cluster.stream());
|
||||
final Bearing approximateMiddleCOG = getWeightedAverageMiddleManeuverCOGDeg(cluster, ManeuverType.TACK);
|
||||
final Bearing approximateMiddleCOGForJibes = approximateMiddleCOG.reverse();
|
||||
final Bearing approximateMiddleCOG = getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(cluster, ManeuverType.TACK).getA();
|
||||
// search for the opposite tack cluster by finding the one that has the smallest angular distance to the expected
|
||||
// middle COG (same as for the candidate cluster) and expected maneuver angle (the cluster's average maneuver angle with inverted sign)
|
||||
final Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble> oppositeTackCluster =
|
||||
@@ -442,11 +483,29 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(a, -cluster.getCentroid().getB(), approximateMiddleCOG)-
|
||||
getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(b, -cluster.getCentroid().getB(), approximateMiddleCOG))).
|
||||
orElse(null);
|
||||
final double likelihoodOfOppositeCluster = getLikelihoodOfOppositeTackCluster(-cluster.getCentroid().getB(), approximateMiddleCOG, oppositeTackCluster);
|
||||
|
||||
// TODO search for head-up/bear-away cluster(s) to port and to starboard of cluster's weighted middle COG
|
||||
// if the opposite tack cluster is empty, it's pretty unlikely that it's a tack cluster; assign a low default probability of 10%
|
||||
final double likelihoodOfOppositeCluster = oppositeTackCluster.isEmpty() ? 0.1 :
|
||||
getLikelihoodOfClusterBasedOnDistanceFromExpected(-cluster.getCentroid().getB(), approximateMiddleCOG, oppositeTackCluster);
|
||||
// compute weighted averages across the current candidate cluster and its supposed opposite tack cluster where the latter
|
||||
// is weighted by the likelihoodOfOppositeCluster whereas the candidate cluster is always weighed as 1.0 for this purpose
|
||||
final double averageTackingAngleDeg = (Math.abs(getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(cluster, ManeuverType.TACK).getB()) +
|
||||
likelihoodOfOppositeCluster*Math.abs(getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(oppositeTackCluster, ManeuverType.TACK).getB()))
|
||||
/ (1+likelihoodOfOppositeCluster);
|
||||
final Bearing averageUpwindCOG = new ScalableBearing(
|
||||
getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(cluster, ManeuverType.TACK).getA()).add(new ScalableBearing(
|
||||
getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(oppositeTackCluster, ManeuverType.TACK).getA()).
|
||||
multiply(likelihoodOfOppositeCluster)).divide(1+likelihoodOfOppositeCluster);
|
||||
|
||||
// Now search for head-up/bear-away cluster(s) to port and to starboard of cluster's weighted middle COG
|
||||
final Bearing expectedUpwindStarboardTackCOG = averageUpwindCOG.add(new DegreeBearingImpl(-averageTackingAngleDeg/2.));
|
||||
double starboardHeadUpBearAwayClusterLikelihood = getLikelihoodOfBestFittingHeadUpBearAwayCluster(
|
||||
clusters.stream().filter(c->c!=cluster), expectedUpwindStarboardTackCOG);
|
||||
final Bearing expectedUpwindPortTackCOG = averageUpwindCOG.add(new DegreeBearingImpl(averageTackingAngleDeg/2.));
|
||||
double portHeadUpBearAwayClusterLikelihood = getLikelihoodOfBestFittingHeadUpBearAwayCluster(
|
||||
clusters.stream().filter(c->c!=cluster), expectedUpwindPortTackCOG);
|
||||
|
||||
// under the assumption that cluster holds tacks, find the clusters that then most likely hold the jibes
|
||||
final Bearing approximateMiddleCOGForJibes = averageUpwindCOG.reverse();
|
||||
Stream<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>> jibeClusters =
|
||||
getJibeClusters(approximateMiddleCOGForJibes, clusters);
|
||||
// increase cluster's score if "good" jibe clusters are found; quality is defined by how well the angle matches and how well the speed ratio fits
|
||||
@@ -455,12 +514,14 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
if (tackClusterWeightedAverageSpeed != null) {
|
||||
// find out how likely the speed ratio is between the candidate tack cluster and the corresponding
|
||||
// hypothetical jibe clusters
|
||||
double tackJibeLikelihoodBasedOnSpeedRatioAndAverageManeuverAngle = getLikelihoodOfBeingJibeCluster(
|
||||
double jibeClusterLikelihood = getLikelihoodOfBeingJibeCluster(
|
||||
tackClusterWeightedAverageSpeed, jibeClusters.map((jc) -> jc.stream()).reduce(Stream::concat)
|
||||
.orElse(Stream.empty()), getBoatClass());
|
||||
.orElse(Stream.empty()), getBoatClass(), clusters);
|
||||
// Likely jibe clusters may raise the general likelihood by up to 20% of the value so far, but not to over 1.0
|
||||
result = Math.min(1.0, averageTackLikelihood * likelihoodOfOppositeCluster *
|
||||
(1.0 + 0.2 * tackJibeLikelihoodBasedOnSpeedRatioAndAverageManeuverAngle));
|
||||
(1.0 + BOOST_FACTOR_FOR_FULL_JIBE_CLUSTER_LIKELIHOOD * jibeClusterLikelihood +
|
||||
BOOST_FACTOR_FOR_FULL_HEAD_UP_BEAR_AWAY_CLUSTER_LIKELIHOOD * starboardHeadUpBearAwayClusterLikelihood +
|
||||
BOOST_FACTOR_FOR_FULL_HEAD_UP_BEAR_AWAY_CLUSTER_LIKELIHOOD * portHeadUpBearAwayClusterLikelihood));
|
||||
} else {
|
||||
result = .1; // no elements in the cluster, therefore no average speed; low propability that this would be a tack cluster
|
||||
}
|
||||
@@ -468,28 +529,86 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells how likely it is that the two clusters are opposite tack clusters. This is determined by looking at the
|
||||
* {@link #getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(Cluster, double, Bearing) angular distance}
|
||||
* between the two clusters regarding their middle COG and their average maneuver angles. The likelihood decreases exponentially
|
||||
* with increasing angle differences. It is 1.0 for an exact match and reaches 0.5 for an angular distance of 20deg.
|
||||
* Determines a likelihood for <code>cluster</code> being a head-up/bear-away cluster for the
|
||||
* <code>expectedMiddleCOG</code>.
|
||||
*
|
||||
* @return a value between 0..1 (exclusive)
|
||||
* @see #getLikelihoodOfClusterBasedOnDistanceFromExpected(double, Bearing, Cluster)
|
||||
*/
|
||||
private double getLikelihoodOfOppositeTackCluster(
|
||||
private double getLikelihoodOfBestFittingHeadUpBearAwayCluster(
|
||||
Stream<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>> clusters,
|
||||
final Bearing expectedAverageMiddleCOG) {
|
||||
final Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble> starboardTackHeadUpAndBearAwayCluster =
|
||||
clusters.max((a, b)->(int) Math.signum(
|
||||
getLikelihoodOfClusterBasedOnDistanceFromExpected(EXPECTED_AVERAGE_HEAD_UP_AND_BEAR_AWAY_MANEUVER_ANGLE_DEG, expectedAverageMiddleCOG, a)-
|
||||
getLikelihoodOfClusterBasedOnDistanceFromExpected(EXPECTED_AVERAGE_HEAD_UP_AND_BEAR_AWAY_MANEUVER_ANGLE_DEG, expectedAverageMiddleCOG, b))).
|
||||
orElse(null);
|
||||
double starboardHeadUpBearAwayClusterLikelihood = starboardTackHeadUpAndBearAwayCluster == null ? 0.0 :
|
||||
getLikelihoodOfClusterBasedOnDistanceFromExpected(
|
||||
EXPECTED_AVERAGE_HEAD_UP_AND_BEAR_AWAY_MANEUVER_ANGLE_DEG, expectedAverageMiddleCOG, starboardTackHeadUpAndBearAwayCluster);
|
||||
return starboardHeadUpBearAwayClusterLikelihood;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a likelihood to a cluster based on its
|
||||
* {@link #getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(Cluster, double, Bearing)
|
||||
* "angular distance"} from an expected average middle COG and Tells how likely it is that the two clusters are opposite tack clusters. This is determined
|
||||
* by looking at the
|
||||
* {@link #getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(Cluster, double, Bearing)
|
||||
* angular distance} between the two clusters regarding their middle COG and their average maneuver angles. The
|
||||
* likelihood decreases exponentially with increasing angle differences. It is 1.0 for an exact match and reaches
|
||||
* 0.5 for an angular distance of 20deg.
|
||||
*/
|
||||
private double getLikelihoodOfClusterBasedOnDistanceFromExpected(
|
||||
double expectedManeuverAngleDeg, Bearing expectedApproximateMiddleCOG,
|
||||
Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble> oppositeTackCluster) {
|
||||
return Math.exp(Math.log(0.5) * (getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(
|
||||
oppositeTackCluster, expectedManeuverAngleDeg, expectedApproximateMiddleCOG) / ANGULAR_DISTANCE_FOR_HALF_CONFIDENCE_FOR_OPPOSITE_TACK_CLUSTER_DEG));
|
||||
final double clusterDistanceFromExpected = getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(
|
||||
oppositeTackCluster, expectedManeuverAngleDeg, expectedApproximateMiddleCOG);
|
||||
return getLikelihoodOfClusterBasedOnDistanceFromExpected(clusterDistanceFromExpected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a likelihood to a cluster based on its
|
||||
* {@link #getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(Cluster, double, Bearing)
|
||||
* "angular distance"} from an expected average middle COG and Tells how likely it is that the two clusters are
|
||||
* opposite tack clusters. This is determined by looking at the
|
||||
* {@link #getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(Cluster, double, Bearing)
|
||||
* angular distance} between the two clusters regarding their middle COG and their average maneuver angles. The
|
||||
* likelihood decreases exponentially with increasing angle differences. It is 1.0 for an exact match and reaches
|
||||
* 0.5 for an angular distance of 20deg (see
|
||||
* {@link #ANGULAR_DISTANCE_FOR_HALF_CONFIDENCE_FOR_OPPOSITE_TACK_CLUSTER_DEG}).
|
||||
*
|
||||
* @param clusterDistanceFromExpected
|
||||
* an angular distance as computed by {@link #getClusterDistance(double, Bearing, double, Bearing)} and
|
||||
* {@link #getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(Cluster, double, Bearing)}
|
||||
* .
|
||||
*/
|
||||
private double getLikelihoodOfClusterBasedOnDistanceFromExpected(final double clusterDistanceFromExpected) {
|
||||
return Math.exp(Math.log(0.5) * (clusterDistanceFromExpected / ANGULAR_DISTANCE_FOR_HALF_CONFIDENCE_FOR_OPPOSITE_TACK_CLUSTER_DEG));
|
||||
}
|
||||
|
||||
/**
|
||||
* A euklidian degree distance based on the two degree distances between the maneuver angles and the
|
||||
* middle COGs. The expected pair is passed as <code>expcetedManeuverAngleDeg</code> and <code>expectedApproximateMiddleCOG</code> whereas
|
||||
* the actuals are determined by computing the {@link ManeuverType#TACK}-weighted average for those values from <code>cluster</code>.
|
||||
*/
|
||||
private double getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(
|
||||
Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble> cluster,
|
||||
double expectedManeuverAngleDeg, Bearing expectedApproximateMiddleCOG) {
|
||||
final Pair<Bearing, Double> weightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg = getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(cluster, ManeuverType.TACK);
|
||||
final Bearing weightedAverageMiddleCOG = weightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg.getA();
|
||||
final Double weightedAverageManeuverAngle = weightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg.getB();
|
||||
return getClusterDistance(expectedManeuverAngleDeg, expectedApproximateMiddleCOG, weightedAverageManeuverAngle, weightedAverageMiddleCOG);
|
||||
}
|
||||
|
||||
/**
|
||||
* A euklidian degree distance based on the two degree distances between the maneuver angles and the
|
||||
* middle COGs.
|
||||
*/
|
||||
private double getClusterDistanceBasedOnAverageManeuverLikelihoodAndWeightedAverageMiddleCOG(
|
||||
Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble> cluster,
|
||||
double expectedManeuverAngleDeg, Bearing expectedApproximateMiddleCOG) {
|
||||
final Bearing approximateMiddleCOG = getWeightedAverageMiddleManeuverCOGDeg(cluster, ManeuverType.TACK);
|
||||
double middleCOGDiff = approximateMiddleCOG.getDifferenceTo(expectedApproximateMiddleCOG).getDegrees();
|
||||
double maneuverAngleDiff = cluster.getCentroid().getB() - expectedManeuverAngleDeg;
|
||||
private double getClusterDistance(double expectedManeuverAngleDeg, Bearing expectedApproximateMiddleCOG,
|
||||
final double weightedAverageManeuverAngle, final Bearing weightedAverageMiddleCOG) {
|
||||
double middleCOGDiff = weightedAverageMiddleCOG.getDifferenceTo(expectedApproximateMiddleCOG).getDegrees();
|
||||
double maneuverAngleDiff = weightedAverageManeuverAngle - expectedManeuverAngleDeg;
|
||||
return Math.sqrt(middleCOGDiff*middleCOGDiff + maneuverAngleDiff*maneuverAngleDiff);
|
||||
}
|
||||
|
||||
@@ -508,7 +627,7 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
|
||||
/**
|
||||
* Returns at most two clusters that hold maneuvers with the highest average probability of being a jibe and whose
|
||||
* {@link #getWeightedAverageMiddleManeuverCOGDeg(Cluster, ManeuverType) weighted average middle COG} fits that of
|
||||
* {@link #getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(Cluster, ManeuverType) weighted average middle COG} fits that of
|
||||
* the expected value (<code>approximateMiddleCOGForJibes</code>) within
|
||||
* {@link #THRESHOLD_JIBE_CLUSTER_DIFFERENCE_DEGREES} degrees.
|
||||
*/
|
||||
@@ -519,17 +638,17 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
return clusters.stream().sorted((a, b)->
|
||||
(int) -Math.signum(getAverageLikelihoodOfBeingManeuver(ManeuverType.JIBE, a.stream()) -
|
||||
getAverageLikelihoodOfBeingManeuver(ManeuverType.JIBE, b.stream()))).filter(
|
||||
(jibeClusterCandidate)->Math.abs(getWeightedAverageMiddleManeuverCOGDeg(jibeClusterCandidate, ManeuverType.JIBE).
|
||||
(jibeClusterCandidate)->Math.abs(getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(jibeClusterCandidate, ManeuverType.JIBE).getA().
|
||||
getDifferenceTo(approximateMiddleCOGForJibes).getDegrees()) < THRESHOLD_JIBE_CLUSTER_DIFFERENCE_DEGREES).
|
||||
limit(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* By looking at the weighted speeds over ground averages, and based on the {@link #polarService} determines how
|
||||
* likely it is that the jibe cluster contents are actually jibes. This is based on the idea that if for the most
|
||||
* likely wind speeds the jibes have a different (usually significantly higher) entry speed than the tacks then this
|
||||
* difference show show in the cluster elements. If they don't, then this should give a penalty for the cluster
|
||||
* likelihoods.
|
||||
* {@link PolarDataService#getManeuverLikelihoodAndTwsTwa(BoatClass, Speed, double, ManeuverType) likely} it is that
|
||||
* the jibe cluster contents are actually jibes. This is based on the idea that if for the most likely wind speeds
|
||||
* the jibes have a different (usually significantly higher) entry speed than the tacks then this difference should
|
||||
* show in the cluster elements. If they don't, then this should give a penalty for the cluster likelihoods.
|
||||
* <p>
|
||||
*
|
||||
* The weight of a maneuver for computing the weighted speed average is determined to be the
|
||||
@@ -539,26 +658,48 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
private double getLikelihoodOfBeingJibeCluster(
|
||||
Speed tackClusterWeightedAverageSpeed,
|
||||
Stream<ManeuverClassification> jibeClustersContent,
|
||||
BoatClass boatClass) {
|
||||
BoatClass boatClass, Set<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>> clusters) {
|
||||
final int[] count = new int[1];
|
||||
final double[] likelihoodSum = new double[1];
|
||||
final ScalableBearing[] scaledAverageDownwindCOG = new ScalableBearing[1];
|
||||
final double[] scaledAbsJibingAngleSum = new double[1];
|
||||
Stream<ManeuverClassification> jibeClustersContentPeeker = jibeClustersContent.peek((mc)->{
|
||||
count[0]++;
|
||||
likelihoodSum[0] += mc.getLikelihoodAndTWSBasedOnSpeedAndAngle(ManeuverType.JIBE).getA();
|
||||
final double likelihood = mc.getLikelihoodAndTWSBasedOnSpeedAndAngle(ManeuverType.JIBE).getA();
|
||||
likelihoodSum[0] += likelihood;
|
||||
final ScalableBearing scaledCOG = new ScalableBearing(mc.getMiddleManeuverCourse()).multiply(likelihood);
|
||||
if (scaledAverageDownwindCOG[0] == null) {
|
||||
scaledAverageDownwindCOG[0] = scaledCOG;
|
||||
} else {
|
||||
scaledAverageDownwindCOG[0] = scaledAverageDownwindCOG[0].add(scaledCOG);
|
||||
}
|
||||
scaledAbsJibingAngleSum[0] += likelihood * Math.abs(mc.getManeuverAngleDeg());
|
||||
});
|
||||
Speed jibeClusterWeightedAverageSpeed = getWeightedAverageSpeed(jibeClustersContentPeeker, ManeuverType.JIBE);
|
||||
Bearing averageDownwindCOG = scaledAverageDownwindCOG[0] == null ? null : scaledAverageDownwindCOG[0].divide(likelihoodSum[0]);
|
||||
double absWeightedAverageJibingAbgle = scaledAbsJibingAngleSum[0] / likelihoodSum[0];
|
||||
final double result;
|
||||
if (jibeClusterWeightedAverageSpeed != null) {
|
||||
double tackJibeSpeedRatioLikelihood = polarService.getConfidenceForTackJibeSpeedRatio(
|
||||
tackClusterWeightedAverageSpeed, jibeClusterWeightedAverageSpeed, boatClass);
|
||||
if (count[0] > 0) {
|
||||
double averageJibeLikelihood = likelihoodSum[0] / count[0];
|
||||
result = averageJibeLikelihood * tackJibeSpeedRatioLikelihood;
|
||||
// Now search for head-up/bear-away cluster(s) to port and to starboard of cluster's weighted middle COG
|
||||
final Bearing expectedDownwindStarboardTackCOG = averageDownwindCOG.add(new DegreeBearingImpl(+absWeightedAverageJibingAbgle/2.));
|
||||
double starboardHeadUpBearAwayClusterLikelihood = getLikelihoodOfBestFittingHeadUpBearAwayCluster(
|
||||
clusters.stream(), expectedDownwindStarboardTackCOG);
|
||||
final Bearing expectedDownwindPortTackCOG = averageDownwindCOG.add(new DegreeBearingImpl(-absWeightedAverageJibingAbgle/2.));
|
||||
double portHeadUpBearAwayClusterLikelihood = getLikelihoodOfBestFittingHeadUpBearAwayCluster(
|
||||
clusters.stream(), expectedDownwindPortTackCOG);
|
||||
result = Math.min(1.0, averageJibeLikelihood
|
||||
* (1.0 + BOOST_FACTOR_FOR_JIBE_TACK_SPEED_RATIO_LIKELIHOOD * tackJibeSpeedRatioLikelihood +
|
||||
BOOST_FACTOR_FOR_FULL_HEAD_UP_BEAR_AWAY_CLUSTER_LIKELIHOOD * starboardHeadUpBearAwayClusterLikelihood +
|
||||
BOOST_FACTOR_FOR_FULL_HEAD_UP_BEAR_AWAY_CLUSTER_LIKELIHOOD * portHeadUpBearAwayClusterLikelihood));
|
||||
} else {
|
||||
throw new RuntimeException("Internal error: no maneuvers in jibe cluster candidate but still a valid weighted average speed "+jibeClusterWeightedAverageSpeed);
|
||||
}
|
||||
} else {
|
||||
result = 0.5; // no maneuvers in the jibe clusters; could be but may also not be a jibe cluster
|
||||
result = 0.1; // no maneuvers in the jibe clusters; could be but may also not be a jibe cluster
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -606,28 +747,35 @@ public class ManeuverBasedWindEstimationTrackImpl extends WindTrackImpl {
|
||||
|
||||
/**
|
||||
* For a cluster of maneuver classifications, clustered two-dimensionally by middle COG and maneuver angle, computes the
|
||||
* weighted average of the middle COG where as the weight of each maneuver the likelihood that the maneuver was of type
|
||||
* weighted average of the middle COG and maneuver angle where as the weight of each maneuver the likelihood that the maneuver was of type
|
||||
* <code>maneuverType</code> is used.<p>
|
||||
*
|
||||
* The method has default package scope to allow tests in the same package in the test fragment to use it.
|
||||
*
|
||||
* @return the weighted average middle COG
|
||||
*/
|
||||
Bearing getWeightedAverageMiddleManeuverCOGDeg(
|
||||
Pair<Bearing, Double> getWeightedAverageMiddleManeuverCOGDegAndManeuverAngleDeg(
|
||||
Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble> cluster,
|
||||
ManeuverType maneuverType) {
|
||||
Pair<Cluster<ManeuverClassification, Pair<ScalableBearing, ScalableDouble>, Pair<Bearing, Double>, ScalableBearingAndScalableDouble>, ManeuverType> key = new Pair<>(
|
||||
cluster, maneuverType);
|
||||
Bearing result = weightedAverageMiddleCOGForManeuverType.get(key);
|
||||
Pair<Bearing, Double> result = weightedAverageMiddleCOGForManeuverType.get(key);
|
||||
if (result == null) {
|
||||
ConfidenceBasedAverager<DoublePair, Bearing, Void> averager = ConfidenceFactory.INSTANCE
|
||||
ConfidenceBasedAverager<DoublePair, Bearing, Void> middleCOGAverager = ConfidenceFactory.INSTANCE
|
||||
.createAverager(/* weigher */null);
|
||||
HasConfidence<DoublePair, Bearing, Void> average = averager.getAverage(
|
||||
HasConfidence<DoublePair, Bearing, Void> average = middleCOGAverager.getAverage(
|
||||
cluster.stream()
|
||||
.map(new ManeuverClassificationToHasConfidenceAndIsScalableAdapter<DoublePair, Bearing>(
|
||||
maneuverType, (mc) -> new ScalableBearing(mc.getMiddleManeuverCourse()),
|
||||
polarService)).iterator(), /* at */null);
|
||||
result = average.getObject();
|
||||
ConfidenceBasedAverager<Double, Double, Void> maneuverAngleAverager = ConfidenceFactory.INSTANCE
|
||||
.createAverager(/* weigher */null);
|
||||
HasConfidence<Double, Double, Void> maneuverAngleAverageDeg = maneuverAngleAverager.getAverage(
|
||||
cluster.stream()
|
||||
.map(new ManeuverClassificationToHasConfidenceAndIsScalableAdapter<Double, Double>(
|
||||
maneuverType, (mc) -> new ScalableDouble(mc.getManeuverAngleDeg()),
|
||||
polarService)).iterator(), /* at */null);
|
||||
result = new Pair<>(average.getObject(), maneuverAngleAverageDeg.getObject());
|
||||
weightedAverageMiddleCOGForManeuverType.put(key, result);
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="resources"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.sap.sailing.xmlexport.test</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,12 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
@@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
pluginProject.extensions=false
|
||||
resolve.requirebundle=false
|
||||
@@ -0,0 +1,12 @@
|
||||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Test
|
||||
Bundle-SymbolicName: com.sap.sailing.xmlexport.test
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Fragment-Host: com.sap.sailing.xmlexport
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Require-Bundle: org.junit4;bundle-version="4.8.2",
|
||||
com.sap.sse.common,
|
||||
com.sap.sailing.domain.test;bundle-version="1.0.0",
|
||||
com.tractrac.clientmodule;bundle-version="3.0.7"
|
||||
@@ -0,0 +1,5 @@
|
||||
source.. = src/,\
|
||||
resources/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>root</artifactId>
|
||||
<groupId>com.sap.sailing</groupId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>com.sap.sailing.xmlexport.test</artifactId>
|
||||
<packaging>eclipse-test-plugin</packaging>
|
||||
</project>
|
||||
Binary file not shown.
@@ -0,0 +1,643 @@
|
||||
stored-uri:event_20141001_ESSNice-Race_1.mtb
|
||||
StartReplay:1
|
||||
|
||||
// Input from params_static:
|
||||
|
||||
// Input from event_parameters:
|
||||
|
||||
DefaultPanel:
|
||||
ReCalcDirAndSpeed:1
|
||||
CompMarkerUUID:2dee0384-2c45-11e4-a9f6-14dae9614d7b
|
||||
CodanIsSponsor:0
|
||||
DefaultTailLength:60
|
||||
APzoomChangeTime:2500
|
||||
disableAutoProduce:0
|
||||
autoProduce:0
|
||||
APstartLineShowOfLeg:0.25
|
||||
APsideOfStartLine:0.30
|
||||
APstartSwitch:0.8
|
||||
APwholeLegBehindMarks:0.15
|
||||
APmarkSwitch:0.13
|
||||
APmarkZoomBehindMarks:0.10
|
||||
APmarkZoomInFrontOfMarks:0.20
|
||||
PopupMarkerUUID:84199024-2c45-11e4-a9f6-14dae9614d7b
|
||||
ManualUrl:http://www.tractrac.com/files/userguide_sailing.pdf
|
||||
//live-uri:tcp://192.168.1.203:4400
|
||||
//stored-uri:tcp://192.168.1.203:4401
|
||||
Marker1UUID:2dee0384-2c45-11e4-a9f6-14dae9614d7b
|
||||
Marker1Type:RGBMarkerFactory
|
||||
Marker1Directional:1
|
||||
Marker1Image:markers/boat_FF0000_big.png
|
||||
Marker1Length:5
|
||||
Marker1MinPixelSize:30
|
||||
Startlocation:7.269026586914038,43.68669104379883
|
||||
MaxDiffTime:1200
|
||||
MaxMetersPerSecond:20
|
||||
PrecisionMeters:20
|
||||
ShortAvgTime:180
|
||||
LongAvgTime:900
|
||||
TimeZone:2
|
||||
CompMarkerTimeout:60
|
||||
FramesPerSecond:8
|
||||
replayspeedup:5
|
||||
MatchRaceClock:0
|
||||
MatchRaceClockNo:3
|
||||
MatchRaceClockSpacing:300
|
||||
Minimap:1
|
||||
MinimapUseLayers:2
|
||||
Minimapgeorect:7.241326904296898,43.705766636035165,7.296516491699208,43.67209091170523
|
||||
MinimapMarkerUUID:84199024-2c45-11e4-a9f6-14dae9614d7b
|
||||
Marker4UUID:84199024-2c45-11e4-a9f6-14dae9614d7b
|
||||
Marker4Type:RGBmarkerFactory
|
||||
Marker4Directional:1
|
||||
Marker4Image:markers/boat_FF0000_small.png
|
||||
MetersPerPixel:18
|
||||
MetersPerPixelMax:30
|
||||
MetersPerPixelMin:0.2
|
||||
isMatchRace:0
|
||||
DefaultDistanceUnits:meters
|
||||
weatherEnabled:0
|
||||
DefaultSpeedUnits:KmH
|
||||
showRaceClock:1
|
||||
BackGroundImage:graphics/background.jpg
|
||||
DisableRotation:0
|
||||
ControlPointMarkerRadius:13
|
||||
disableselection:0
|
||||
disableleaderline:0
|
||||
DisableChangeRace:0
|
||||
PopUpRow1Name:
|
||||
PopUpRow1Type:Name
|
||||
PopUpRow2Name:Knots
|
||||
PopUpRow2Type:BoatSpeed
|
||||
PopUpRow3Name:Ranking
|
||||
PopUpRow3Type:RowNumber
|
||||
PopUpRow4Name:Sail
|
||||
PopUpRow4Type:Ini
|
||||
PopUpRow5Name:After
|
||||
PopUpRow5Type:BoatAfter
|
||||
WindEstimator:0
|
||||
MapUrl:http://tile.traclive.dk/ttm
|
||||
ResultColumn1Name:#
|
||||
ResultColumn1Size:20
|
||||
ResultColumn1Type:RowNumber
|
||||
ResultColumn2Name:sail
|
||||
ResultColumn2Size:45
|
||||
ResultColumn2Type:Ini
|
||||
ResultColumn3Name:name
|
||||
ResultColumn3Size:110
|
||||
ResultColumn3Type:Name
|
||||
ResultColumn4Name:after
|
||||
ResultColumn4Size:45
|
||||
ResultColumn4Type:BoatAfter
|
||||
ResultColumn5Name:kts
|
||||
ResultColumn5Size:40
|
||||
ResultColumn5Type:BoatSpeed
|
||||
DisableLeaderboard:0
|
||||
DisableAnalysis:0
|
||||
TableFontSize:11
|
||||
compInitialsFontSize:11
|
||||
AutoRotate:0
|
||||
MassStart:0
|
||||
SegmentFile:segments.php
|
||||
StartType:Mass
|
||||
RaceHandicapSystem:NONE
|
||||
TeamCompetitionType:NONE
|
||||
LiveDelaySecs: 6
|
||||
|
||||
//-------- AUTO GENERATED PARAMETERS START ----------------
|
||||
|
||||
EventID:8638bc00-2aad-0132-18bc-448a5b8481d8
|
||||
EventName:ESS Nice 2014
|
||||
EventDB:event_20141001_ESSNice
|
||||
EventStartTime:2014-09-30 22:00:00
|
||||
EventEndTime:2014-10-05 21:00:00
|
||||
EventType:a1b74ca0-fdd8-11dc-8811-005056c00008
|
||||
|
||||
RaceID:09f4b690-2bc6-0132-1eef-10b11c4ed8fd
|
||||
RaceName:Race 1
|
||||
RaceStartTime:2014-10-02 12:02:00
|
||||
RaceEndTime:
|
||||
RaceTrackingStartTime:2014-10-02 11:58:14
|
||||
RaceTrackingEndTime:2014-10-02 12:17:02
|
||||
RaceDefaultRouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
RaceHandicapSystem:NONE
|
||||
|
||||
Image1UUID:64a7b348-83db-11e2-88c0-10bf48d758ce
|
||||
Image1Type:Logo
|
||||
Image1Description:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/SUI.gif
|
||||
Image1Image:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/SUI.gif
|
||||
|
||||
Image2UUID:64c3a8fa-83db-11e2-88c0-10bf48d758ce
|
||||
Image2Type:Logo
|
||||
Image2Description:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/NZL.gif
|
||||
Image2Image:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/NZL.gif
|
||||
|
||||
Image3UUID:651130a2-83db-11e2-88c0-10bf48d758ce
|
||||
Image3Type:Logo
|
||||
Image3Description:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/KOR.gif
|
||||
Image3Image:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/KOR.gif
|
||||
|
||||
Image4UUID:653c1ab0-83db-11e2-88c0-10bf48d758ce
|
||||
Image4Type:Logo
|
||||
Image4Description:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/AUT.gif
|
||||
Image4Image:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/AUT.gif
|
||||
|
||||
Image5UUID:65637da8-83db-11e2-88c0-10bf48d758ce
|
||||
Image5Type:Logo
|
||||
Image5Description:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/DEN.gif
|
||||
Image5Image:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/DEN.gif
|
||||
|
||||
Image6UUID:65875138-83db-11e2-88c0-10bf48d758ce
|
||||
Image6Type:Logo
|
||||
Image6Description:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/OMN.gif
|
||||
Image6Image:http://germanmaster.traclive.dk/events/event_20100806_SailforGol/images/OMN.gif
|
||||
|
||||
Class1UUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Class1Name:Extreme40
|
||||
|
||||
Team1UUID:649f1dbe-83db-11e2-88c0-10bf48d758ce
|
||||
Team1Name:TeamA
|
||||
Team1Comp1UUID:648bd4f2-83db-11e2-88c0-10bf48d758ce
|
||||
|
||||
Team2UUID:64bf0854-83db-11e2-88c0-10bf48d758ce
|
||||
Team2Name:TeamB
|
||||
Team2Comp1UUID:64bbff7e-83db-11e2-88c0-10bf48d758ce
|
||||
|
||||
Team3UUID:64dd7988-83db-11e2-88c0-10bf48d758ce
|
||||
Team3Name:TeamC
|
||||
Team3Comp1UUID:64da7c24-83db-11e2-88c0-10bf48d758ce
|
||||
|
||||
Team4UUID:64ffc402-83db-11e2-88c0-10bf48d758ce
|
||||
Team4Name:TeamD
|
||||
|
||||
Team5UUID:65351d82-83db-11e2-88c0-10bf48d758ce
|
||||
Team5Name:TeamE
|
||||
Team5Comp1UUID:65322500-83db-11e2-88c0-10bf48d758ce
|
||||
|
||||
Team6UUID:655ed82a-83db-11e2-88c0-10bf48d758ce
|
||||
Team6Name:TeamF
|
||||
Team6Comp1UUID:655bd56c-83db-11e2-88c0-10bf48d758ce
|
||||
|
||||
Team7UUID:65829fa8-83db-11e2-88c0-10bf48d758ce
|
||||
Team7Name:TeamG
|
||||
Team7Comp1UUID:657fa5a0-83db-11e2-88c0-10bf48d758ce
|
||||
|
||||
Team8UUID:e4459a20-83db-11e2-88c0-10bf48d758ce
|
||||
Team8Name:TeamH
|
||||
|
||||
Team9UUID:a73aabc0-d6d6-0130-8be2-60a44ce903c3
|
||||
Team9Name:TeamI
|
||||
Team9Comp1UUID:93085e80-7ad9-0131-e5b3-60a44ce903c3
|
||||
|
||||
Team10UUID:bbf81f60-d6d6-0130-8be3-60a44ce903c3
|
||||
Team10Name:TeamJ
|
||||
Team10Comp1UUID:f097f4f0-7ad9-0131-e5b4-60a44ce903c3
|
||||
|
||||
Team11UUID:65659280-eda3-0130-c5c0-10b11c4ed8fd
|
||||
Team11Name:TeamK
|
||||
Team11Comp1UUID:19dc3eb0-7ada-0131-e5b5-60a44ce903c3
|
||||
|
||||
Team12UUID:9ee14560-77af-0131-e5af-60a44ce903c3
|
||||
Team12Name:TeamL
|
||||
Team12Comp1UUID:5e15e7c0-7ada-0131-e5b6-60a44ce903c3
|
||||
|
||||
Team13UUID:b9677300-7ad7-0131-e5b0-60a44ce903c3
|
||||
Team13Name:TeamM
|
||||
Team13Comp1UUID:84e68b70-7ada-0131-e5b7-60a44ce903c3
|
||||
|
||||
Team14UUID:c9689a00-7ad7-0131-e5b1-60a44ce903c3
|
||||
Team14Name:TeamN
|
||||
|
||||
Team15UUID:d5712f30-7ad7-0131-e5b2-60a44ce903c3
|
||||
Team15Name:TeamO
|
||||
|
||||
Comp1UUID:648bd4f2-83db-11e2-88c0-10bf48d758ce
|
||||
Comp1Name:Alinghi
|
||||
Comp1NameShort:Alinghi
|
||||
Comp1Color:00FF00
|
||||
Comp1Nationality:SUI
|
||||
Comp1Description:
|
||||
Comp1Handicap:1.0000000000
|
||||
Comp1HandicapDistance:0.00000
|
||||
Comp1StartTime:2014-10-02 12:02:00
|
||||
Comp1PictureUUID:64a7b348-83db-11e2-88c0-10bf48d758ce
|
||||
Comp1ClassUUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Comp1RouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
|
||||
Comp2UUID:64bbff7e-83db-11e2-88c0-10bf48d758ce
|
||||
Comp2Name:GAC Pindar
|
||||
Comp2NameShort:GAC Pindar
|
||||
Comp2Color:000080
|
||||
Comp2Nationality:AUS
|
||||
Comp2Description:
|
||||
Comp2Handicap:1.0000000000
|
||||
Comp2HandicapDistance:0.00000
|
||||
Comp2StartTime:2014-10-02 12:02:00
|
||||
Comp2PictureUUID:64c3a8fa-83db-11e2-88c0-10bf48d758ce
|
||||
Comp2ClassUUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Comp2RouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
|
||||
Comp3UUID:64da7c24-83db-11e2-88c0-10bf48d758ce
|
||||
Comp3Name:Realteam by Realstone
|
||||
Comp3NameShort:Realstone
|
||||
Comp3Color:000000
|
||||
Comp3Nationality:AFG
|
||||
Comp3Description:
|
||||
Comp3Handicap:1.0000000000
|
||||
Comp3HandicapDistance:0.00000
|
||||
Comp3StartTime:2014-10-02 12:02:00
|
||||
Comp3PictureUUID:64a7b348-83db-11e2-88c0-10bf48d758ce
|
||||
Comp3ClassUUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Comp3RouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
|
||||
Comp4UUID:65322500-83db-11e2-88c0-10bf48d758ce
|
||||
Comp4Name:Red Bull Sailing Team
|
||||
Comp4NameShort:Red Bull
|
||||
Comp4Color:008080
|
||||
Comp4Nationality:AUT
|
||||
Comp4Description:
|
||||
Comp4Handicap:1.0000000000
|
||||
Comp4HandicapDistance:0.00000
|
||||
Comp4StartTime:2014-10-02 12:02:00
|
||||
Comp4PictureUUID:653c1ab0-83db-11e2-88c0-10bf48d758ce
|
||||
Comp4ClassUUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Comp4RouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
|
||||
Comp5UUID:655bd56c-83db-11e2-88c0-10bf48d758ce
|
||||
Comp5Name:SAP Extreme Sailing Team
|
||||
Comp5NameShort:SAP
|
||||
Comp5Color:FFFFFF
|
||||
Comp5Nationality:DEN
|
||||
Comp5Description:
|
||||
Comp5Handicap:1.0000000000
|
||||
Comp5HandicapDistance:0.00000
|
||||
Comp5StartTime:2014-10-02 12:02:00
|
||||
Comp5PictureUUID:65637da8-83db-11e2-88c0-10bf48d758ce
|
||||
Comp5ClassUUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Comp5RouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
|
||||
Comp6UUID:657fa5a0-83db-11e2-88c0-10bf48d758ce
|
||||
Comp6Name:The Wave, Muscat
|
||||
Comp6NameShort:The Wave
|
||||
Comp6Color:800080
|
||||
Comp6Nationality:OMA
|
||||
Comp6Description:
|
||||
Comp6Handicap:1.0000000000
|
||||
Comp6HandicapDistance:0.00000
|
||||
Comp6StartTime:2014-10-02 12:02:00
|
||||
Comp6PictureUUID:65875138-83db-11e2-88c0-10bf48d758ce
|
||||
Comp6ClassUUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Comp6RouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
|
||||
Comp7UUID:93085e80-7ad9-0131-e5b3-60a44ce903c3
|
||||
Comp7Name:Emirates Team New Zealand
|
||||
Comp7NameShort:Emirates NZ
|
||||
Comp7Color:CC9900
|
||||
Comp7Nationality:NZL
|
||||
Comp7Description:
|
||||
Comp7Handicap:1.0000000000
|
||||
Comp7HandicapDistance:0.00000
|
||||
Comp7StartTime:2014-10-02 12:02:00
|
||||
Comp7PictureUUID:64c3a8fa-83db-11e2-88c0-10bf48d758ce
|
||||
Comp7ClassUUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Comp7RouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
|
||||
Comp8UUID:f097f4f0-7ad9-0131-e5b4-60a44ce903c3
|
||||
Comp8Name:Gazprom Team Russia
|
||||
Comp8NameShort:Team Russia
|
||||
Comp8Color:999900
|
||||
Comp8Nationality:RUS
|
||||
Comp8Description:
|
||||
Comp8Handicap:1.0000000000
|
||||
Comp8HandicapDistance:0.00000
|
||||
Comp8StartTime:2014-10-02 12:02:00
|
||||
Comp8ClassUUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Comp8RouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
|
||||
Comp9UUID:19dc3eb0-7ada-0131-e5b5-60a44ce903c3
|
||||
Comp9Name:Groupama sailing team
|
||||
Comp9NameShort:Groupama
|
||||
Comp9Color:33CC00
|
||||
Comp9Nationality:AFG
|
||||
Comp9Description:
|
||||
Comp9Handicap:1.0000000000
|
||||
Comp9HandicapDistance:0.00000
|
||||
Comp9StartTime:2014-10-02 12:02:00
|
||||
Comp9ClassUUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Comp9RouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
|
||||
Comp10UUID:5e15e7c0-7ada-0131-e5b6-60a44ce903c3
|
||||
Comp10Name:J.P. Morgan BAR
|
||||
Comp10NameShort:J.P. Morgan
|
||||
Comp10Color:CCFF00
|
||||
Comp10Nationality:GBR
|
||||
Comp10Description:
|
||||
Comp10Handicap:1.0000000000
|
||||
Comp10HandicapDistance:0.00000
|
||||
Comp10StartTime:2014-10-02 12:02:00
|
||||
Comp10ClassUUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Comp10RouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
|
||||
Comp11UUID:84e68b70-7ada-0131-e5b7-60a44ce903c3
|
||||
Comp11Name:Oman Air
|
||||
Comp11NameShort:Oman Air
|
||||
Comp11Color:CCFF99
|
||||
Comp11Nationality:OMA
|
||||
Comp11Description:
|
||||
Comp11Handicap:1.0000000000
|
||||
Comp11HandicapDistance:0.00000
|
||||
Comp11StartTime:2014-10-02 12:02:00
|
||||
Comp11PictureUUID:65875138-83db-11e2-88c0-10bf48d758ce
|
||||
Comp11ClassUUID:648ee25a-83db-11e2-88c0-10bf48d758ce
|
||||
Comp11RouteUUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
|
||||
ControlPoint1UUID:1100ea60-7adb-0131-e5b8-60a44ce903c3
|
||||
ControlPoint1Name:Red-Green
|
||||
ControlPoint1HasTwoPoints:1
|
||||
ControlPoint1ShortName:RG
|
||||
ControlPoint1DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Red###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Name=Red###BREAKLINE###P1.UUID=5427c7d2-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Green###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Green###BREAKLINE###P2.UUID=785c3e44-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint1Mark1Lon:7.273181
|
||||
ControlPoint1Mark1Lat:43.688370
|
||||
ControlPoint1Mark2Lon:7.272257
|
||||
ControlPoint1Mark2Lat:43.687305
|
||||
|
||||
ControlPoint2UUID:1286f15e-83be-11e2-88c0-10bf48d758ce
|
||||
ControlPoint2Name:Blue
|
||||
ControlPoint2HasTwoPoints:0
|
||||
ControlPoint2ShortName:Bl
|
||||
ControlPoint2DataSheet:Name=Blue###BREAKLINE###Type=Buoy###BREAKLINE###Color=Blue###BREAKLINE###Shape=Conical
|
||||
ControlPoint2Mark1Lon:7.269418
|
||||
ControlPoint2Mark1Lat:43.687290
|
||||
|
||||
ControlPoint3UUID:1a94c6a0-7adc-0131-e5f4-60a44ce903c3
|
||||
ControlPoint3Name:Black Conical-Blue
|
||||
ControlPoint3HasTwoPoints:1
|
||||
ControlPoint3ShortName:BB
|
||||
ControlPoint3DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Black###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Pattern=Checkered###BREAKLINE###P1.Name=Black Conical###BREAKLINE###P1.UUID=d78695ea-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Blue###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Blue###BREAKLINE###P2.UUID=1286f15e-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint3Mark1Lon:7.272432
|
||||
ControlPoint3Mark1Lat:43.692131
|
||||
ControlPoint3Mark2Lon:7.269418
|
||||
ControlPoint3Mark2Lat:43.687290
|
||||
|
||||
ControlPoint4UUID:2ce99970-2c47-0132-20ce-10b11c4ed8fd
|
||||
ControlPoint4Name:Black Conical-White P
|
||||
ControlPoint4HasTwoPoints:1
|
||||
ControlPoint4ShortName:F
|
||||
ControlPoint4DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Black###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Pattern=Checkered###BREAKLINE###P1.Name=Black Conical###BREAKLINE###P1.UUID=d78695ea-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=White###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=White P###BREAKLINE###P2.UUID=e9ec42f8-83bd-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint4Mark1Lon:7.272432
|
||||
ControlPoint4Mark1Lat:43.692131
|
||||
ControlPoint4Mark2Lon:7.271063
|
||||
ControlPoint4Mark2Lat:43.691803
|
||||
|
||||
ControlPoint5UUID:2dc7d9d0-7b84-0131-b9c3-10b11c4ed8fd
|
||||
ControlPoint5Name:Black Cylinder - Black Conical
|
||||
ControlPoint5HasTwoPoints:1
|
||||
ControlPoint5ShortName:BB
|
||||
ControlPoint5DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Black###BREAKLINE###P1.Shape=Cylinder###BREAKLINE###P1.Pattern=Checkered###BREAKLINE###P1.Name=Black Cylinder###BREAKLINE###P1.UUID=b153dfd6-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Black###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Pattern=Checkered###BREAKLINE###P2.Name=Black Conical###BREAKLINE###P2.UUID=d78695ea-83be-11e2-88c0-10bf48d758ce
|
||||
ControlPoint5Mark1Lon:7.269445
|
||||
ControlPoint5Mark1Lat:43.687302
|
||||
ControlPoint5Mark2Lon:7.272432
|
||||
ControlPoint5Mark2Lat:43.692131
|
||||
|
||||
ControlPoint6UUID:2e37b410-7adc-0131-e5fe-60a44ce903c3
|
||||
ControlPoint6Name:Black Conical-Yellow (white S)
|
||||
ControlPoint6HasTwoPoints:1
|
||||
ControlPoint6ShortName:BY
|
||||
ControlPoint6DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Black###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Pattern=Checkered###BREAKLINE###P1.Name=Black Conical###BREAKLINE###P1.UUID=d78695ea-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Yellow###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Yellow###BREAKLINE###P2.UUID=3fdd2402-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint6Mark1Lon:7.272432
|
||||
ControlPoint6Mark1Lat:43.692131
|
||||
ControlPoint6Mark2Lon:7.269320
|
||||
ControlPoint6Mark2Lat:43.687366
|
||||
|
||||
ControlPoint7UUID:3240586c-83c0-11e2-88c0-10bf48d758ce
|
||||
ControlPoint7Name:Finish Pole
|
||||
ControlPoint7HasTwoPoints:0
|
||||
ControlPoint7ShortName:F
|
||||
ControlPoint7DataSheet:Color=Black###BREAKLINE###Type=Landmark###BREAKLINE###Name=Finish Pole
|
||||
ControlPoint7Mark1Lon:7.271467
|
||||
ControlPoint7Mark1Lat:43.694897
|
||||
|
||||
ControlPoint8UUID:37cb36e0-7adb-0131-e5c2-60a44ce903c3
|
||||
ControlPoint8Name:Red-Blue
|
||||
ControlPoint8HasTwoPoints:1
|
||||
ControlPoint8ShortName:RB
|
||||
ControlPoint8DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Red###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Name=Red###BREAKLINE###P1.UUID=5427c7d2-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Blue###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Blue###BREAKLINE###P2.UUID=1286f15e-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint8Mark1Lon:7.273181
|
||||
ControlPoint8Mark1Lat:43.688370
|
||||
ControlPoint8Mark2Lon:7.269418
|
||||
ControlPoint8Mark2Lat:43.687290
|
||||
|
||||
ControlPoint9UUID:3e6c1c94-83bf-11e2-88c0-10bf48d758ce
|
||||
ControlPoint9Name:Race Committee
|
||||
ControlPoint9HasTwoPoints:0
|
||||
ControlPoint9ShortName:RC
|
||||
ControlPoint9DataSheet:Type=StartBoat###BREAKLINE###Name=Race Committee
|
||||
ControlPoint9Mark1Lon:7.267022
|
||||
ControlPoint9Mark1Lat:43.691895
|
||||
|
||||
ControlPoint10UUID:3fdd2402-83be-11e2-88c0-10bf48d758ce
|
||||
ControlPoint10Name:Yellow
|
||||
ControlPoint10HasTwoPoints:0
|
||||
ControlPoint10ShortName:Y
|
||||
ControlPoint10DataSheet:Type=Buoy###BREAKLINE###Color=Yellow###BREAKLINE###Shape=Conical###BREAKLINE###Name=Yellow
|
||||
ControlPoint10Mark1Lon:7.269320
|
||||
ControlPoint10Mark1Lat:43.687366
|
||||
|
||||
ControlPoint11UUID:4c304720-7adc-0131-e608-60a44ce903c3
|
||||
ControlPoint11Name:Black Conical-Red
|
||||
ControlPoint11HasTwoPoints:1
|
||||
ControlPoint11ShortName:BR
|
||||
ControlPoint11DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Black###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Pattern=Checkered###BREAKLINE###P1.Name=Black Conical###BREAKLINE###P1.UUID=d78695ea-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Red###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Red###BREAKLINE###P2.UUID=5427c7d2-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint11Mark1Lon:7.272432
|
||||
ControlPoint11Mark1Lat:43.692131
|
||||
ControlPoint11Mark2Lon:7.273181
|
||||
ControlPoint11Mark2Lat:43.688370
|
||||
|
||||
ControlPoint12UUID:4e0c2a90-7adb-0131-e5cc-60a44ce903c3
|
||||
ControlPoint12Name:Red-Yellow
|
||||
ControlPoint12HasTwoPoints:1
|
||||
ControlPoint12ShortName:RY
|
||||
ControlPoint12DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Red###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Name=Red###BREAKLINE###P1.UUID=5427c7d2-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Yellow###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Yellow###BREAKLINE###P2.UUID=3fdd2402-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint12Mark1Lon:7.273181
|
||||
ControlPoint12Mark1Lat:43.688370
|
||||
ControlPoint12Mark2Lon:7.269320
|
||||
ControlPoint12Mark2Lat:43.687366
|
||||
|
||||
ControlPoint13UUID:5427c7d2-83be-11e2-88c0-10bf48d758ce
|
||||
ControlPoint13Name:Red
|
||||
ControlPoint13HasTwoPoints:0
|
||||
ControlPoint13ShortName:R
|
||||
ControlPoint13DataSheet:Type=Buoy###BREAKLINE###Color=Red###BREAKLINE###Shape=Conical###BREAKLINE###Name=Red
|
||||
ControlPoint13Mark1Lon:7.273181
|
||||
ControlPoint13Mark1Lat:43.688370
|
||||
|
||||
ControlPoint14UUID:621831d0-7adc-0131-e612-60a44ce903c3
|
||||
ControlPoint14Name:Black Conical-Green
|
||||
ControlPoint14HasTwoPoints:1
|
||||
ControlPoint14ShortName:BG
|
||||
ControlPoint14DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Black###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Pattern=Checkered###BREAKLINE###P1.Name=Black Conical###BREAKLINE###P1.UUID=d78695ea-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Green###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Green###BREAKLINE###P2.UUID=785c3e44-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint14Mark1Lon:7.272432
|
||||
ControlPoint14Mark1Lat:43.692131
|
||||
ControlPoint14Mark2Lon:7.272257
|
||||
ControlPoint14Mark2Lat:43.687305
|
||||
|
||||
ControlPoint15UUID:77b9e620-7adb-0131-e5d6-60a44ce903c3
|
||||
ControlPoint15Name:Green-Blue
|
||||
ControlPoint15HasTwoPoints:1
|
||||
ControlPoint15ShortName:GB
|
||||
ControlPoint15DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Green###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Name=Green###BREAKLINE###P1.UUID=785c3e44-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Blue###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Blue###BREAKLINE###P2.UUID=1286f15e-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint15Mark1Lon:7.272257
|
||||
ControlPoint15Mark1Lat:43.687305
|
||||
ControlPoint15Mark2Lon:7.269418
|
||||
ControlPoint15Mark2Lat:43.687290
|
||||
|
||||
ControlPoint16UUID:785c3e44-83be-11e2-88c0-10bf48d758ce
|
||||
ControlPoint16Name:Green
|
||||
ControlPoint16HasTwoPoints:0
|
||||
ControlPoint16ShortName:G
|
||||
ControlPoint16DataSheet:Type=Buoy###BREAKLINE###Color=Green###BREAKLINE###Shape=Conical###BREAKLINE###Name=Green
|
||||
ControlPoint16Mark1Lon:7.272257
|
||||
ControlPoint16Mark1Lat:43.687305
|
||||
|
||||
ControlPoint17UUID:7d9d1730-b3e8-0131-1d10-10b11c4ed8fd
|
||||
ControlPoint17Name:Race Committee - Finish Pole
|
||||
ControlPoint17HasTwoPoints:1
|
||||
ControlPoint17ShortName:RF
|
||||
ControlPoint17DataSheet:P1.Type=StartBoat###BREAKLINE###P1.Name=Race Committee###BREAKLINE###P1.UUID=3e6c1c94-83bf-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Color=Black###BREAKLINE###P2.Type=Landmark###BREAKLINE###P2.Name=Finish Pole###BREAKLINE###P2.UUID=3240586c-83c0-11e2-88c0-10bf48d758ce
|
||||
ControlPoint17Mark1Lon:7.267022
|
||||
ControlPoint17Mark1Lat:43.691895
|
||||
ControlPoint17Mark2Lon:7.271342
|
||||
ControlPoint17Mark2Lat:43.694851
|
||||
|
||||
ControlPoint18UUID:88ef6d40-7adc-0131-e61c-60a44ce903c3
|
||||
ControlPoint18Name:Finish Pole-Cylinder
|
||||
ControlPoint18HasTwoPoints:1
|
||||
ControlPoint18ShortName:F
|
||||
ControlPoint18DataSheet:P1.Color=Black###BREAKLINE###P1.Type=Landmark###BREAKLINE###P1.Name=Finish Pole###BREAKLINE###P1.UUID=3240586c-83c0-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Black###BREAKLINE###P2.Shape=Cylinder###BREAKLINE###P2.Pattern=Checkered###BREAKLINE###P2.Name=Black Cylinder###BREAKLINE###P2.UUID=b153dfd6-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint18Mark1Lon:7.271342
|
||||
ControlPoint18Mark1Lat:43.694851
|
||||
ControlPoint18Mark2Lon:7.269445
|
||||
ControlPoint18Mark2Lat:43.687302
|
||||
|
||||
ControlPoint19UUID:8f9a4ee0-7adb-0131-e5e0-60a44ce903c3
|
||||
ControlPoint19Name:Green-Yellow
|
||||
ControlPoint19HasTwoPoints:1
|
||||
ControlPoint19ShortName:GY
|
||||
ControlPoint19DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Green###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Name=Green###BREAKLINE###P1.UUID=785c3e44-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Yellow###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Yellow###BREAKLINE###P2.UUID=3fdd2402-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint19Mark1Lon:7.272257
|
||||
ControlPoint19Mark1Lat:43.687305
|
||||
ControlPoint19Mark2Lon:7.269320
|
||||
ControlPoint19Mark2Lat:43.687366
|
||||
|
||||
ControlPoint20UUID:a0f71190-7adb-0131-e5ea-60a44ce903c3
|
||||
ControlPoint20Name:Blue-Yellow
|
||||
ControlPoint20HasTwoPoints:1
|
||||
ControlPoint20ShortName:BY
|
||||
ControlPoint20DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Blue###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Name=Blue###BREAKLINE###P1.UUID=1286f15e-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Yellow###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Yellow###BREAKLINE###P2.UUID=3fdd2402-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint20Mark1Lon:7.269418
|
||||
ControlPoint20Mark1Lat:43.687290
|
||||
ControlPoint20Mark2Lon:7.269320
|
||||
ControlPoint20Mark2Lat:43.687366
|
||||
|
||||
ControlPoint21UUID:a68c6350-7adc-0131-e626-60a44ce903c3
|
||||
ControlPoint21Name:RC-Black Conical
|
||||
ControlPoint21HasTwoPoints:1
|
||||
ControlPoint21ShortName:S
|
||||
ControlPoint21DataSheet:P1.Type=StartBoat###BREAKLINE###P1.Name=Race Committee###BREAKLINE###P1.UUID=3e6c1c94-83bf-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Black###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Pattern=Checkered###BREAKLINE###P2.Name=Black Conical###BREAKLINE###P2.UUID=d78695ea-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint21Mark1Lon:7.267022
|
||||
ControlPoint21Mark1Lat:43.691895
|
||||
ControlPoint21Mark2Lon:7.272432
|
||||
ControlPoint21Mark2Lat:43.692131
|
||||
|
||||
ControlPoint22UUID:b153dfd6-83be-11e2-88c0-10bf48d758ce
|
||||
ControlPoint22Name:Black Cylinder
|
||||
ControlPoint22HasTwoPoints:0
|
||||
ControlPoint22ShortName:B
|
||||
ControlPoint22DataSheet:Type=Buoy###BREAKLINE###Color=Black###BREAKLINE###Shape=Cylinder###BREAKLINE###Pattern=Checkered###BREAKLINE###Name=Black Cylinder
|
||||
ControlPoint22Mark1Lon:7.269445
|
||||
ControlPoint22Mark1Lat:43.687302
|
||||
|
||||
ControlPoint23UUID:b62e0bf0-7adc-0131-e630-60a44ce903c3
|
||||
ControlPoint23Name:RC-Black Cylinder
|
||||
ControlPoint23HasTwoPoints:1
|
||||
ControlPoint23ShortName:S
|
||||
ControlPoint23DataSheet:P1.Type=StartBoat###BREAKLINE###P1.Name=Race Committee###BREAKLINE###P1.UUID=3e6c1c94-83bf-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Black###BREAKLINE###P2.Shape=Cylinder###BREAKLINE###P2.Pattern=Checkered###BREAKLINE###P2.Name=Black Cylinder###BREAKLINE###P2.UUID=b153dfd6-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint23Mark1Lon:7.267022
|
||||
ControlPoint23Mark1Lat:43.691895
|
||||
ControlPoint23Mark2Lon:7.269445
|
||||
ControlPoint23Mark2Lat:43.687302
|
||||
|
||||
ControlPoint24UUID:bd1fc330-7c10-0131-9c24-10b11c4ed8fd
|
||||
ControlPoint24Name:Black Cylinder-Yellow
|
||||
ControlPoint24HasTwoPoints:1
|
||||
ControlPoint24ShortName:S
|
||||
ControlPoint24DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=Black###BREAKLINE###P1.Shape=Cylinder###BREAKLINE###P1.Pattern=Checkered###BREAKLINE###P1.Name=Black Cylinder###BREAKLINE###P1.UUID=b153dfd6-83be-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Yellow###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Yellow###BREAKLINE###P2.UUID=3fdd2402-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint24Mark1Lon:7.269445
|
||||
ControlPoint24Mark1Lat:43.687302
|
||||
ControlPoint24Mark2Lon:7.269320
|
||||
ControlPoint24Mark2Lat:43.687366
|
||||
|
||||
ControlPoint25UUID:bf6777e6-83bd-11e2-88c0-10bf48d758ce
|
||||
ControlPoint25Name:White S
|
||||
ControlPoint25HasTwoPoints:0
|
||||
ControlPoint25ShortName:W
|
||||
ControlPoint25DataSheet:Type=Buoy###BREAKLINE###Color=White###BREAKLINE###Shape=Conical###BREAKLINE###Name=White S
|
||||
ControlPoint25Mark1Lon:7.268352
|
||||
ControlPoint25Mark1Lat:43.691936
|
||||
|
||||
ControlPoint26UUID:cd3c1dc0-7c11-0131-9c2e-10b11c4ed8fd
|
||||
ControlPoint26Name:Finish Pole-Conical
|
||||
ControlPoint26HasTwoPoints:1
|
||||
ControlPoint26ShortName:S
|
||||
ControlPoint26DataSheet:P1.Color=Black###BREAKLINE###P1.Type=Landmark###BREAKLINE###P1.Name=Finish Pole###BREAKLINE###P1.UUID=3240586c-83c0-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Black###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Pattern=Checkered###BREAKLINE###P2.Name=Black Conical###BREAKLINE###P2.UUID=d78695ea-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint26Mark1Lon:7.271342
|
||||
ControlPoint26Mark1Lat:43.694851
|
||||
ControlPoint26Mark2Lon:7.272432
|
||||
ControlPoint26Mark2Lat:43.692131
|
||||
|
||||
ControlPoint27UUID:d39a0d00-7adc-0131-e63a-60a44ce903c3
|
||||
ControlPoint27Name:White Gate
|
||||
ControlPoint27HasTwoPoints:1
|
||||
ControlPoint27ShortName:W
|
||||
ControlPoint27DataSheet:P1.Type=Buoy###BREAKLINE###P1.Color=White###BREAKLINE###P1.Shape=Conical###BREAKLINE###P1.Name=White S###BREAKLINE###P1.UUID=bf6777e6-83bd-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=White###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=White P###BREAKLINE###P2.UUID=e9ec42f8-83bd-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint27Mark1Lon:7.268352
|
||||
ControlPoint27Mark1Lat:43.691936
|
||||
ControlPoint27Mark2Lon:7.271063
|
||||
ControlPoint27Mark2Lat:43.691803
|
||||
|
||||
ControlPoint28UUID:d78695ea-83be-11e2-88c0-10bf48d758ce
|
||||
ControlPoint28Name:Black Conical
|
||||
ControlPoint28HasTwoPoints:0
|
||||
ControlPoint28ShortName:B
|
||||
ControlPoint28DataSheet:Type=Buoy###BREAKLINE###Color=Black###BREAKLINE###Shape=Conical###BREAKLINE###Pattern=Checkered###BREAKLINE###Name=Black Conical
|
||||
ControlPoint28Mark1Lon:7.272432
|
||||
ControlPoint28Mark1Lat:43.692131
|
||||
|
||||
ControlPoint29UUID:e9ec42f8-83bd-11e2-88c0-10bf48d758ce
|
||||
ControlPoint29Name:White P
|
||||
ControlPoint29HasTwoPoints:0
|
||||
ControlPoint29ShortName:W
|
||||
ControlPoint29DataSheet:Type=Buoy###BREAKLINE###Color=White###BREAKLINE###Shape=Conical###BREAKLINE###Name=White P
|
||||
ControlPoint29Mark1Lon:7.271063
|
||||
ControlPoint29Mark1Lat:43.691803
|
||||
|
||||
ControlPoint30UUID:eff23330-7b84-0131-b9d2-10b11c4ed8fd
|
||||
ControlPoint30Name:RC-Red
|
||||
ControlPoint30HasTwoPoints:1
|
||||
ControlPoint30ShortName:S
|
||||
ControlPoint30DataSheet:P1.Type=StartBoat###BREAKLINE###P1.Name=Race Committee###BREAKLINE###P1.UUID=3e6c1c94-83bf-11e2-88c0-10bf48d758ce###BREAKLINE###P2.Type=Buoy###BREAKLINE###P2.Color=Red###BREAKLINE###P2.Shape=Conical###BREAKLINE###P2.Name=Red###BREAKLINE###P2.UUID=5427c7d2-83be-11e2-88c0-10bf48d758ce###BREAKLINE###
|
||||
ControlPoint30Mark1Lon:7.267022
|
||||
ControlPoint30Mark1Lat:43.691895
|
||||
ControlPoint30Mark2Lon:7.273181
|
||||
ControlPoint30Mark2Lat:43.688370
|
||||
|
||||
SegmentFile:segments.php
|
||||
Route1UUID:09f125d0-2bc6-0132-1eee-10b11c4ed8fd
|
||||
Route1Description:Race 1
|
||||
Route1Length:0
|
||||
Route1DataSheet:CourseDiagram=Course###BREAKLINE###Seq.1=Line###BREAKLINE###Seq.2=Port###BREAKLINE###Seq.3=Gate###BREAKLINE###Seq.4=Port###BREAKLINE###Seq.5=Line###BREAKLINE###
|
||||
Route1ControlPoint1UUID:d39a0d00-7adc-0131-e63a-60a44ce903c3
|
||||
Route1ControlPoint2UUID:785c3e44-83be-11e2-88c0-10bf48d758ce
|
||||
Route1ControlPoint3UUID:2ce99970-2c47-0132-20ce-10b11c4ed8fd
|
||||
|
||||
//-------- AUTO GENERATED PARAMETERS END ------------------
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package com.sap.sailing.xmlexport.test;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.WindSourceImpl;
|
||||
import com.sap.sailing.domain.leaderboard.FlexibleLeaderboard;
|
||||
import com.sap.sailing.domain.leaderboard.impl.FlexibleLeaderboardImpl;
|
||||
import com.sap.sailing.domain.leaderboard.impl.HighPointFirstGets10LastBreaksTie;
|
||||
import com.sap.sailing.domain.leaderboard.impl.ThresholdBasedResultDiscardingRuleImpl;
|
||||
import com.sap.sailing.domain.test.OnlineTracTracBasedTest;
|
||||
import com.sap.sailing.domain.tracking.impl.WindImpl;
|
||||
import com.sap.sailing.domain.tractracadapter.ReceiverType;
|
||||
import com.sap.sailing.xmlexport.LeaderboardData;
|
||||
|
||||
public class XMLExportTest extends OnlineTracTracBasedTest {
|
||||
|
||||
public XMLExportTest() throws MalformedURLException, URISyntaxException {
|
||||
super();
|
||||
}
|
||||
|
||||
private void setUpESS2014Nice(String raceNumber) {
|
||||
URI storedUri;
|
||||
try {
|
||||
storedUri = new URI("file:///" + new File("resources/" + getFileName() + raceNumber + ".mtb").getCanonicalPath().replace('\\', '/'));
|
||||
super.setUp(new URL("file:///" + new File("resources/" + getFileName() + raceNumber + ".txt").getCanonicalPath()),
|
||||
/* liveUri */null, /* storedUri */storedUri,
|
||||
new ReceiverType[] { ReceiverType.MARKPASSINGS, ReceiverType.RACECOURSE, ReceiverType.MARKPOSITIONS, ReceiverType.RAWPOSITIONS });
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
boolean result = getTrackedRace().recordWind(new WindImpl(/* position */null, getTrackedRace().getStartOfRace(), new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(65))),
|
||||
new WindSourceImpl(WindSourceType.WEB));
|
||||
assert result==true;
|
||||
|
||||
}
|
||||
|
||||
protected String getExpectedEventName() {
|
||||
return "ESS Nice 2014";
|
||||
}
|
||||
|
||||
protected String getFileName() {
|
||||
return "event_20141001_ESSNice-Race_";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExportingESSNice2014() {
|
||||
setUpESS2014Nice("1");
|
||||
FlexibleLeaderboard leaderboard = new FlexibleLeaderboardImpl("ESS 2014 Nice", new ThresholdBasedResultDiscardingRuleImpl(new int[] {0}), new HighPointFirstGets10LastBreaksTie(),
|
||||
null);
|
||||
leaderboard.addRace(getTrackedRace(), "R1", false);
|
||||
LeaderboardData leaderboardData = new LeaderboardData(leaderboard);
|
||||
try {
|
||||
leaderboardData.perform();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
fail("No exception should occur");
|
||||
}
|
||||
String resultData = leaderboardData.getResultXML();
|
||||
assertNotNull(resultData);
|
||||
assertTrue(resultData.length()>261000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.sap.sailing.xmlexport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.List;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -41,11 +42,21 @@ public abstract class ExportAction {
|
||||
private HttpServletResponse res;
|
||||
|
||||
private RacingEventService service;
|
||||
|
||||
private Leaderboard leaderboard;
|
||||
protected final boolean useProvidedLeaderboard;
|
||||
private String resultingXMLData;
|
||||
|
||||
public ExportAction(HttpServletRequest req, HttpServletResponse res, RacingEventService service) {
|
||||
this.req = req;
|
||||
this.res = res;
|
||||
this.service = service;
|
||||
this.leaderboard = null;
|
||||
this.useProvidedLeaderboard = false;
|
||||
}
|
||||
|
||||
public ExportAction(Leaderboard leaderboard) {
|
||||
this.leaderboard = leaderboard;
|
||||
this.useProvidedLeaderboard = true;
|
||||
}
|
||||
|
||||
public String getAttribute(String name) {
|
||||
@@ -55,15 +66,21 @@ public abstract class ExportAction {
|
||||
public RacingEventService getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public String getResultXML() {
|
||||
return resultingXMLData;
|
||||
}
|
||||
|
||||
public Leaderboard getLeaderboard() throws IOException, ServletException {
|
||||
final String leaderboardName = getAttribute("name");
|
||||
if (leaderboardName == null) {
|
||||
throw new ServletException("Use the name= parameter to specify the leaderboard");
|
||||
}
|
||||
final Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
if (leaderboard == null) {
|
||||
throw new ServletException("Leaderboard " + leaderboardName + " not found.");
|
||||
if (!useProvidedLeaderboard) {
|
||||
final String leaderboardName = getAttribute("name");
|
||||
if (leaderboardName == null) {
|
||||
throw new ServletException("Use the name= parameter to specify the leaderboard");
|
||||
}
|
||||
leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
if (leaderboard == null) {
|
||||
throw new ServletException("Leaderboard " + leaderboardName + " not found.");
|
||||
}
|
||||
}
|
||||
return leaderboard;
|
||||
}
|
||||
@@ -315,13 +332,22 @@ public abstract class ExportAction {
|
||||
format.setEncoding("UTF-8");
|
||||
XMLOutputter xmlOutputter = new XMLOutputter(format);
|
||||
|
||||
res.setContentType("text/xml");
|
||||
res.addHeader("Content-Disposition", "attachment; filename=" + fileName);
|
||||
|
||||
try {
|
||||
xmlOutputter.output(element, res.getOutputStream());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
if (!useProvidedLeaderboard) {
|
||||
res.setContentType("text/xml");
|
||||
res.addHeader("Content-Disposition", "attachment; filename=" + fileName);
|
||||
try {
|
||||
xmlOutputter.output(element, res.getOutputStream());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
StringWriter resultStringWriter = new StringWriter();
|
||||
try {
|
||||
xmlOutputter.output(element, resultStringWriter);
|
||||
resultingXMLData = resultStringWriter.toString();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,10 @@ public class LeaderboardData extends ExportAction {
|
||||
public LeaderboardData(HttpServletRequest req, HttpServletResponse res, RacingEventService service) {
|
||||
super(req, res, service);
|
||||
}
|
||||
|
||||
public LeaderboardData(Leaderboard leaderboard) {
|
||||
super(leaderboard);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates XML for a leaderboard. Expects a list of generated competitors and races XML elements that are associated with the leaderboard.
|
||||
@@ -907,6 +911,7 @@ public class LeaderboardData extends ExportAction {
|
||||
}
|
||||
}
|
||||
log.info("Finished XML export of leaderboard " + leaderboard.getName() + " in " + MillisecondsTimePoint.now().minus(timeSpent.asMillis()).asMillis() + " milliseconds");
|
||||
sendDocument(createLeaderboardXML(leaderboard, competitorElements, racesElements, leaderboardConfidenceAndErrorMessages), leaderboard.getName() + ".xml");
|
||||
Element dataToExport = createLeaderboardXML(leaderboard, competitorElements, racesElements, leaderboardConfidenceAndErrorMessages);
|
||||
sendDocument(dataToExport, leaderboard.getName() + ".xml");
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,7 @@
|
||||
<module>com.sap.sailing.www</module>
|
||||
<module>com.sap.sailing.www.events</module>
|
||||
<module>com.sap.sailing.xmlexport</module>
|
||||
<module>com.sap.sailing.xmlexport.test</module>
|
||||
<module>com.google.gwt.osgi</module>
|
||||
<module>com.tractrac.clientmodule</module>
|
||||
<module>org.json.simple</module>
|
||||
|
||||
Reference in new issue
Block a user