mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-22 03:53:56 +00:00
Merge branch 'master' into bug2564
This commit is contained in:
commit
4465088111
309 files changed
+8100
-3929
No files matched your search
+1
-1
@@ -161,7 +161,7 @@ public class StartAnalysisCard extends Composite implements HasWidgets, StartAna
|
||||
final RaceMapSettings raceMapSettings = new RaceMapSettings(raceMapZoomSettings, getHelpLineSettings(),
|
||||
defaultRaceMapSettings.getTransparentHoverlines(), defaultRaceMapSettings.getHoverlineStrokeWeight(),
|
||||
startAnalysisDTO.tailLenghtInMilliseconds, defaultRaceMapSettings.isWindUp(),
|
||||
defaultRaceMapSettings.getBuoyZoneRadiusInMeters(), defaultRaceMapSettings.isShowOnlySelectedCompetitors(),
|
||||
defaultRaceMapSettings.getBuoyZoneRadius(), defaultRaceMapSettings.isShowOnlySelectedCompetitors(),
|
||||
defaultRaceMapSettings.isShowSelectedCompetitorsInfo(), defaultRaceMapSettings.isShowWindStreamletColors(),
|
||||
defaultRaceMapSettings.isShowWindStreamletOverlay(), defaultRaceMapSettings.isShowSimulationOverlay(),
|
||||
defaultRaceMapSettings.isShowMapControls(), defaultRaceMapSettings.getManeuverTypesToShow(),
|
||||
|
||||
+6
@@ -2,6 +2,9 @@ package com.sap.sailing.datamining.shared;
|
||||
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.common.impl.CentralAngleDistance;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||
@@ -16,6 +19,9 @@ public final class SailingDataMiningSerializationDummy implements SerializationD
|
||||
private CentralAngleDistance centralAngleDistance;
|
||||
private MeterDistance meterDistance;
|
||||
private NauticalMileDistance nauticalMileDistance;
|
||||
private ManeuverType maneuverType;
|
||||
private Tack tack;
|
||||
private NauticalSide nauticalSide;
|
||||
|
||||
private SailingDataMiningSerializationDummy() { }
|
||||
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sse.datamining.data.Cluster;
|
||||
import com.sap.sse.datamining.impl.data.ClusterWithLowerAndUpperBoundaries;
|
||||
import com.sap.sse.datamining.impl.data.ClusterWithSingleBoundary;
|
||||
import com.sap.sse.datamining.impl.data.ComparableClusterBoundary;
|
||||
import com.sap.sse.datamining.impl.data.ComparisonStrategy;
|
||||
|
||||
// TODO Move to sse bundle, after 49er analysis
|
||||
public class TestLinearDoubleClusterGroup {
|
||||
|
||||
private LinearDoubleClusterGroup hardPercentageClusterGroup;
|
||||
private LinearDoubleClusterGroup softLinearClusterGroup;
|
||||
|
||||
@Before
|
||||
public void initialize() {
|
||||
hardPercentageClusterGroup = new LinearDoubleClusterGroup(0.0, 1.0, 0.1, true);
|
||||
softLinearClusterGroup = new LinearDoubleClusterGroup(0, 100, 10, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetClusterForValueOutOfBounds() {
|
||||
Cluster<Double> cluster = hardPercentageClusterGroup.getClusterFor(-0.01);
|
||||
assertThat(cluster, nullValue());
|
||||
|
||||
cluster = hardPercentageClusterGroup.getClusterFor(1.01);
|
||||
assertThat(cluster, nullValue());
|
||||
|
||||
cluster = softLinearClusterGroup.getClusterFor(-0.1);
|
||||
Cluster<Double> expectedCluster = createCluster(softLinearClusterGroup.getStepSize(), ComparisonStrategy.LOWER_THAN);
|
||||
assertThat(cluster, is(expectedCluster));
|
||||
|
||||
cluster = softLinearClusterGroup.getClusterFor(100.1);
|
||||
expectedCluster = createCluster(softLinearClusterGroup.getUpperGroupBound() - softLinearClusterGroup.getStepSize(), ComparisonStrategy.GREATER_EQUALS_THAN);
|
||||
assertThat(cluster, is(expectedCluster));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetClusterForBoundaryValues() {
|
||||
Cluster<Double> cluster = hardPercentageClusterGroup.getClusterFor(0.0);
|
||||
Cluster<Double> expectedCluster = createCluster(hardPercentageClusterGroup.getLowerGroupBound(), ComparisonStrategy.GREATER_EQUALS_THAN,
|
||||
hardPercentageClusterGroup.getLowerGroupBound() + hardPercentageClusterGroup.getStepSize(), ComparisonStrategy.LOWER_THAN);
|
||||
assertThat(cluster, is(expectedCluster));
|
||||
|
||||
cluster = hardPercentageClusterGroup.getClusterFor(1.0);
|
||||
expectedCluster = createCluster(hardPercentageClusterGroup.getUpperGroupBound() - hardPercentageClusterGroup.getStepSize(), ComparisonStrategy.GREATER_EQUALS_THAN,
|
||||
hardPercentageClusterGroup.getUpperGroupBound(), ComparisonStrategy.LOWER_EQUALS_THAN);
|
||||
assertThat(cluster, is(expectedCluster));
|
||||
|
||||
cluster = softLinearClusterGroup.getClusterFor(0.0);
|
||||
expectedCluster = createCluster(softLinearClusterGroup.getStepSize(), ComparisonStrategy.LOWER_THAN);
|
||||
assertThat(cluster, is(expectedCluster));
|
||||
|
||||
cluster = softLinearClusterGroup.getClusterFor(100.0);
|
||||
expectedCluster = createCluster(softLinearClusterGroup.getUpperGroupBound() - softLinearClusterGroup.getStepSize(), ComparisonStrategy.GREATER_EQUALS_THAN);
|
||||
assertThat(cluster, is(expectedCluster));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetClusterFor() {
|
||||
LinearDoubleClusterGroup clusterGroup = softLinearClusterGroup;
|
||||
double value = (clusterGroup.getUpperGroupBound() + clusterGroup.getStepSize()) / 2;
|
||||
Cluster<Double> cluster = clusterGroup.getClusterFor(value);
|
||||
Cluster<Double> expectedCluster = createCluster(clusterGroup.getUpperGroupBound() / 2, ComparisonStrategy.GREATER_EQUALS_THAN,
|
||||
(clusterGroup.getUpperGroupBound() / 2) + clusterGroup.getStepSize(), ComparisonStrategy.LOWER_THAN);
|
||||
assertThat(cluster, is(expectedCluster));
|
||||
}
|
||||
|
||||
private Cluster<Double> createCluster(double lowerBoundValue, ComparisonStrategy lowerComparisonStrategy, double upperBoundValue, ComparisonStrategy upperComparisonStrategy) {
|
||||
ComparableClusterBoundary<Double> lowerBound = new ComparableClusterBoundary<>(lowerBoundValue, lowerComparisonStrategy);
|
||||
ComparableClusterBoundary<Double> upperBound = new ComparableClusterBoundary<>(upperBoundValue, upperComparisonStrategy);
|
||||
return new ClusterWithLowerAndUpperBoundaries<>(lowerBound, upperBound);
|
||||
}
|
||||
|
||||
private Cluster<Double> createCluster(double boundValue, ComparisonStrategy comparisonStrategy) {
|
||||
return new ClusterWithSingleBoundary<>(new ComparableClusterBoundary<>(boundValue, comparisonStrategy));
|
||||
}
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sse.datamining.data.Cluster;
|
||||
import com.sap.sse.datamining.data.ClusterGroup;
|
||||
|
||||
public class TestPercentageClusterFormatter {
|
||||
|
||||
private ClusterGroup<Double> percentageClusterGroup;
|
||||
private PercentageClusterFormatter formatter;
|
||||
|
||||
@Before
|
||||
public void initialize() {
|
||||
percentageClusterGroup = new LinearDoubleClusterGroup(0.0, 1.0, 0.1, true);
|
||||
formatter = new PercentageClusterFormatter();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormat() {
|
||||
Cluster<Double> cluster = percentageClusterGroup.getClusterFor(0.05);
|
||||
String formattedCluster = formatter.format(cluster);
|
||||
assertThat(formattedCluster, is("[0% - 10%["));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//resources/stringmessages/Sailing_StringMessages_ja.properties=UTF-8
|
||||
encoding//resources/stringmessages/Sailing_StringMessages_ru.properties=UTF-8
|
||||
encoding//resources/stringmessages/Sailing_StringMessages_zh.properties=UTF-8
|
||||
encoding//resources/stringmessages/Sailing_StringMessages_zh_CN.properties=UTF-8
|
||||
+28
-6
@@ -16,6 +16,7 @@ Race=Race
|
||||
Competitor=Competitor
|
||||
Boat=Boat
|
||||
Team=Team
|
||||
CompetitorSearchTag=Competitor Search Tag
|
||||
LeaderboardSailingDomainRetrieverChain=Leaderboards
|
||||
RaceSailingDomainRetrieverChain=Races
|
||||
LegSailingDomainRetrieverChain=Legs
|
||||
@@ -23,12 +24,14 @@ GPSFixSailingDomainRetrieverChain=GPS-Fixes
|
||||
MarkPassingSailingDomainRetrieverChain=Mark Passings
|
||||
RaceResultSailingDomainRetrieverChain=Race Results
|
||||
RaceOfCompetitorSailingDomainRetrieverChain=Races of Competitors
|
||||
ManeuverSailingDomainRetrieverChain=Maneuver
|
||||
LeaderboardGroup=Leaderboard Group
|
||||
Leaderboard=Leaderboard
|
||||
Leg=Leg
|
||||
MarkPassing=Mark Passing
|
||||
LegOfCompetitor=Leg of competitor
|
||||
GpsFix=GPS-Fix
|
||||
Maneuver=Maneuver
|
||||
WindStrengthInBeaufort=Wind Strength in Beaufort
|
||||
Bft0=Calm
|
||||
Bft1=Light air
|
||||
@@ -43,11 +46,14 @@ Bft9=Strong gale
|
||||
Bft10=Storm
|
||||
Bft11=Violent storm
|
||||
Bft12=Hurricane
|
||||
RelativeScoreInRace=Relative score in race (0 best; 1 worst)
|
||||
WindSpeedInBeaufort=Wind speed in Bft
|
||||
DistanceAtStart=Distance to start at start
|
||||
SpeedWhenStarting=Speed when starting
|
||||
SpeedTenSecondsBeforeStart=Speed 10s before start
|
||||
RelativeScore=Relative Score (0 best; 1 worst)
|
||||
RelativeScoreInPercent=Relative Score in %
|
||||
RelativeScoreInRaceInPercent=Relative Score in Race in %
|
||||
AbsoluteRank=Absolute Rank
|
||||
WindSpeedInBeaufort=Wind Speed in Bft
|
||||
DistanceAtStart=Distance to Start at Start
|
||||
SpeedWhenStarting=Speed at Start
|
||||
SpeedTenSecondsBeforeStart=Speed 10s Before Start
|
||||
RankAtFirstMark=Rank at First Mark
|
||||
NumberOfManeuvers=Number of Maneuvers
|
||||
NumberOfTacks=Number of Tacks
|
||||
@@ -60,4 +66,20 @@ NumberOfWins=Number of Wins
|
||||
RankGainsOrLossesBetweenFirstMarkAndFinish=Rank Gains or Losses (1st Mark -> Finish)
|
||||
IsTracked=Is Tracked
|
||||
NumberOfCompetitorFixes=Number of Competitor Fixes
|
||||
NumberOfMarkFixes=Number of Mark Fixes
|
||||
NumberOfMarkFixes=Number of Mark Fixes
|
||||
ManeuverType=Maneuver Type
|
||||
Tack=Tack
|
||||
SpeedBefore=Speed Before Maneuver
|
||||
SpeedAfter=Speed After Maneuver
|
||||
DirectionChange=Direction Change in Degrees
|
||||
ManeuverLoss=Maneuver Loss
|
||||
Waypoint=Waypoint
|
||||
PassingSide=Passing Side
|
||||
TackAtStart=Tack at Start
|
||||
SpeedTenSecondsAfterStart=Speed 10s After Start
|
||||
RankThirtySecondsAfterStart=Rank 30s After Start
|
||||
WindwardDistanceToAdvantageousEndOfLine=Windward Distance to Advantageous End of Line
|
||||
RankAfterHalfOfTheFirstLeg=Rank after the half of the first leg
|
||||
AdvantageousEndOfLine=Advantageous End of Line
|
||||
TimeSpentInSeconds=Time Spent in Seconds
|
||||
MedalRace=Medal Race
|
||||
+24
-2
@@ -3,6 +3,7 @@ DistanceTraveled=zur
|
||||
Boat=Boot
|
||||
Team=Team
|
||||
Name=Name
|
||||
CompetitorSearchTag=Teilnehmer Such-Tag
|
||||
Nationality=Nationalitäts
|
||||
Acronym=Abkürzung
|
||||
SailID=Segelnummer
|
||||
@@ -21,12 +22,14 @@ GPSFixSailingDomainRetrieverChain=GPS-Fixes
|
||||
MarkPassingSailingDomainRetrieverChain=Tonnenrundungen
|
||||
RaceResultSailingDomainRetrieverChain=Rennergebnisse
|
||||
RaceOfCompetitorSailingDomainRetrieverChain=Rennen eines Teilnehmers
|
||||
ManeuverSailingDomainRetrieverChain=Manöver
|
||||
LeaderboardGroup=Ranglisten Gruppe
|
||||
Leaderboard=Rangliste
|
||||
Leg=Schenkel
|
||||
MarkPassing=Tonnenrundung
|
||||
LegOfCompetitor=Schenkel eines Teilnehmers
|
||||
GpsFix=GPS-Fix
|
||||
Maneuver=Manöver
|
||||
Speed=Geschwindigkeit
|
||||
SpeedTenSecondsBefore=Geschwindigkeit 10s vorher
|
||||
WindStrengthInBeaufort=Windstärke in Beaufort
|
||||
@@ -43,7 +46,10 @@ Bft9=Sturm
|
||||
Bft10=schwerer Sturm
|
||||
Bft11=orkanartiger Sturm
|
||||
Bft12=Orkan
|
||||
RelativeScoreInRace=Relative Wertung im Rennen (0 am besten; 1 am schlechtesten)
|
||||
RelativeScore=Relative Wertung (0 am besten; 1 am schlechtesten)
|
||||
RelativeScoreInPercent=Relative Wertung in %
|
||||
RelativeScoreInRaceInPercent=Relative Wertung im Rennen in %
|
||||
AbsoluteRank=Absolute Platzierung
|
||||
WindSpeedInBeaufort=Windgeschwindigkeit in Bft.
|
||||
DistanceAtStart=Distanz zur Startlinie zum Startzeitpunkt
|
||||
SpeedWhenStarting=Geschwindigkeit beim Überqueren der Startlinie
|
||||
@@ -60,4 +66,20 @@ NumberOfWins=Anzahl der Siege
|
||||
RankGainsOrLossesBetweenFirstMarkAndFinish=Positions-Verluste oder -Gewinne (1ter Wegpunkt -> Ziel)
|
||||
IsTracked=Ist getracked
|
||||
NumberOfCompetitorFixes=Anzahl der Teilnehmer-Fixes
|
||||
NumberOfMarkFixes=Anzahl der Tonnen-Fixes
|
||||
NumberOfMarkFixes=Anzahl der Tonnen-Fixes
|
||||
ManeuverType=Art des Manövers
|
||||
Tack=Bug
|
||||
SpeedBefore=Geschwindigkeit bevor dem Manöver
|
||||
SpeedAfter=Geschwindigkeit nach dem Manöver
|
||||
DirectionChange=Richtungsänderung in Grad
|
||||
ManeuverLoss=Manöververlust
|
||||
Waypoint=Wegpunkt
|
||||
PassingSide=Passierende Seite
|
||||
TackAtStart=Startbug
|
||||
SpeedTenSecondsAfterStart=Geschwindigkeit 10s nach dem Startzeitpunkt
|
||||
RankThirtySecondsAfterStart=Absolute Platzierung 30s nach dem Startzeitpunkt
|
||||
WindwardDistanceToAdvantageousEndOfLine=Windwärtige Distanz zum Bevorteilten Ende der Startlinie
|
||||
RankAfterHalfOfTheFirstLeg=Platzierung nach der Hälfte des ersten Schenkels
|
||||
AdvantageousEndOfLine=Bevorteiltes Ende der Startlinie
|
||||
TimeSpentInSeconds=Benötigte Zeit in Sekunden
|
||||
MedalRace=Medaillenrennen
|
||||
+26
-4
@@ -1,5 +1,5 @@
|
||||
Speed=速力
|
||||
SpeedTenSecondsBefore=10 秒前の速力
|
||||
SpeedTenSecondsBefore=10 秒前の艇速
|
||||
DistanceTraveled=移動した距離
|
||||
Name=名称
|
||||
LegType=レグタイプ
|
||||
@@ -16,6 +16,7 @@ Race=レース
|
||||
Competitor=競技者
|
||||
Boat=艇
|
||||
Team=チーム
|
||||
CompetitorSearchTag=競技者検索タグ
|
||||
LeaderboardSailingDomainRetrieverChain=リーダーボード
|
||||
RaceSailingDomainRetrieverChain=レース
|
||||
LegSailingDomainRetrieverChain=レグ
|
||||
@@ -23,12 +24,14 @@ GPSFixSailingDomainRetrieverChain=GPS フィックス
|
||||
MarkPassingSailingDomainRetrieverChain=マーク通過
|
||||
RaceResultSailingDomainRetrieverChain=レース結果
|
||||
RaceOfCompetitorSailingDomainRetrieverChain=競技者のレース
|
||||
ManeuverSailingDomainRetrieverChain=マニューバー
|
||||
LeaderboardGroup=リーダーボードグループ
|
||||
Leaderboard=リーダーボード
|
||||
Leg=レグ
|
||||
MarkPassing=マーク通過
|
||||
LegOfCompetitor=競技者のレグ
|
||||
GpsFix=GPS フィックス
|
||||
Maneuver=マニューバー
|
||||
WindStrengthInBeaufort=ビューフォート風力
|
||||
Bft0=平穏
|
||||
Bft1=至軽風
|
||||
@@ -43,11 +46,14 @@ Bft9=大強風
|
||||
Bft10=全強風
|
||||
Bft11=暴風
|
||||
Bft12=颶風 (ぐふう)
|
||||
RelativeScoreInRace=レース中の相対スコア (0 が最高、1 が最低)
|
||||
RelativeScore=相対スコア (0 が最高、1 が最低)
|
||||
RelativeScoreInPercent=相対スコア (%)
|
||||
RelativeScoreInRaceInPercent=レース中の相対スコア (%)
|
||||
AbsoluteRank=絶対順位
|
||||
WindSpeedInBeaufort=風速 (Bft)
|
||||
DistanceAtStart=スタート時のスタートラインまでの距離
|
||||
SpeedWhenStarting=スタート時の速力
|
||||
SpeedTenSecondsBeforeStart=スタート 10 秒前の速力
|
||||
SpeedWhenStarting=スタート時の艇速
|
||||
SpeedTenSecondsBeforeStart=スタート 10 秒前の艇速
|
||||
RankAtFirstMark=第一マークでのランク
|
||||
NumberOfManeuvers=マニューバー回数
|
||||
NumberOfTacks=タック回数
|
||||
@@ -61,3 +67,19 @@ RankGainsOrLossesBetweenFirstMarkAndFinish=ランク上下 (第一マーク ->
|
||||
IsTracked=追跡済
|
||||
NumberOfCompetitorFixes=競技者フィックスの数
|
||||
NumberOfMarkFixes=マークフィックスの数
|
||||
ManeuverType=マニューバータイプ
|
||||
Tack=タック
|
||||
SpeedBefore=マニューバー前の艇速
|
||||
SpeedAfter=マニューバー後の艇速
|
||||
DirectionChange=方向転換 (度)
|
||||
ManeuverLoss=マニューバーロス
|
||||
Waypoint=変針点
|
||||
PassingSide=通過サイド
|
||||
TackAtStart=スタート時のタック
|
||||
SpeedTenSecondsAfterStart=スタート 10 秒後の艇速
|
||||
RankThirtySecondsAfterStart=スタート 30 秒後の順位
|
||||
WindwardDistanceToAdvantageousEndOfLine=ラインの有利な端までの風上距離
|
||||
RankAfterHalfOfTheFirstLeg=第一レグ中間点の順位
|
||||
AdvantageousEndOfLine=ラインの有利な端
|
||||
TimeSpentInSeconds=所要時間 (秒)
|
||||
MedalRace=メダルレース
|
||||
+23
-1
@@ -16,6 +16,7 @@ Race=Гонка
|
||||
Competitor=Участник
|
||||
Boat=Лодка
|
||||
Team=Команда
|
||||
CompetitorSearchTag=Тег поиска участника
|
||||
LeaderboardSailingDomainRetrieverChain=Таблицы лидеров
|
||||
RaceSailingDomainRetrieverChain=Гонки
|
||||
LegSailingDomainRetrieverChain=Отрезки
|
||||
@@ -23,12 +24,14 @@ GPSFixSailingDomainRetrieverChain=Замеры GPS
|
||||
MarkPassingSailingDomainRetrieverChain=Прохождения отметок
|
||||
RaceResultSailingDomainRetrieverChain=Результаты гонки
|
||||
RaceOfCompetitorSailingDomainRetrieverChain=Гонки участников
|
||||
ManeuverSailingDomainRetrieverChain=Маневр
|
||||
LeaderboardGroup=Группа таблиц лидеров
|
||||
Leaderboard=Таблица лидеров
|
||||
Leg=Отрезок
|
||||
MarkPassing=Прохождение отметки
|
||||
LegOfCompetitor=Отрезок участника
|
||||
GpsFix=Замер GPS
|
||||
Maneuver=Маневр
|
||||
WindStrengthInBeaufort=Сила ветра по шкале Бофорта
|
||||
Bft0=Штиль
|
||||
Bft1=Тихий
|
||||
@@ -43,7 +46,10 @@ Bft9=Шторм
|
||||
Bft10=Сильный шторм
|
||||
Bft11=Жестокий шторм
|
||||
Bft12=Ураган
|
||||
RelativeScoreInRace=Относительная оценка в гонке (0 лучшая; 1 худшая)
|
||||
RelativeScore=Относительная оценка (0 лучшая; 1 худшая)
|
||||
RelativeScoreInPercent=Относительная оценка (%)
|
||||
RelativeScoreInRaceInPercent=Относительная оценка в гонке (%)
|
||||
AbsoluteRank=Абсолютный ранг
|
||||
WindSpeedInBeaufort=Скорость ветра по шкале Бофорта
|
||||
DistanceAtStart=Дистанция до старта при старте
|
||||
SpeedWhenStarting=Скорость при старте
|
||||
@@ -61,3 +67,19 @@ RankGainsOrLossesBetweenFirstMarkAndFinish=Повышения или пониж
|
||||
IsTracked=Отслеживается
|
||||
NumberOfCompetitorFixes=Число замеров участника
|
||||
NumberOfMarkFixes=Число замеров отметки
|
||||
ManeuverType=Тип маневра
|
||||
Tack=Оверштаг
|
||||
SpeedBefore=Скорость до маневра
|
||||
SpeedAfter=Скорость после маневра
|
||||
DirectionChange=Изменение направления в градусах
|
||||
ManeuverLoss=Потеря маневра
|
||||
Waypoint=Путевая точка
|
||||
PassingSide=Сторона прохождения
|
||||
TackAtStart=Оверштаг при старте
|
||||
SpeedTenSecondsAfterStart=Скорость через 10 с после старта
|
||||
RankThirtySecondsAfterStart=Ранг через 30 с после старта
|
||||
WindwardDistanceToAdvantageousEndOfLine=Дистанция по ветру до выгодного конца линии
|
||||
RankAfterHalfOfTheFirstLeg=Ранг после половины первого этапа
|
||||
AdvantageousEndOfLine=Выгодный конец линии
|
||||
TimeSpentInSeconds=Затраченное время в секундах
|
||||
MedalRace=Гонка на медали
|
||||
+23
-1
@@ -16,6 +16,7 @@ Race=比赛轮次
|
||||
Competitor=参赛队
|
||||
Boat=船只
|
||||
Team=团队
|
||||
CompetitorSearchTag=参赛队搜索标记
|
||||
LeaderboardSailingDomainRetrieverChain=积分榜
|
||||
RaceSailingDomainRetrieverChain=比赛轮次
|
||||
LegSailingDomainRetrieverChain=航段
|
||||
@@ -23,12 +24,14 @@ GPSFixSailingDomainRetrieverChain=GPS 修复
|
||||
MarkPassingSailingDomainRetrieverChain=绕标
|
||||
RaceResultSailingDomainRetrieverChain=比赛轮次结果
|
||||
RaceOfCompetitorSailingDomainRetrieverChain=参赛队的比赛轮次
|
||||
ManeuverSailingDomainRetrieverChain=操作
|
||||
LeaderboardGroup=积分榜分组
|
||||
Leaderboard=积分榜
|
||||
Leg=航段
|
||||
MarkPassing=绕标
|
||||
LegOfCompetitor=参赛队的航段
|
||||
GpsFix=GPS 修复
|
||||
Maneuver=操作
|
||||
WindStrengthInBeaufort=风力(蒲福风级)
|
||||
Bft0=无风
|
||||
Bft1=软风
|
||||
@@ -43,7 +46,10 @@ Bft9=烈风
|
||||
Bft10=暴风
|
||||
Bft11=飓风
|
||||
Bft12=台风
|
||||
RelativeScoreInRace=比赛轮次中的相对得分(0 最佳;1 最差)
|
||||
RelativeScore=相对得分(0 最佳;1 最差)
|
||||
RelativeScoreInPercent=相对得分 (%)
|
||||
RelativeScoreInRaceInPercent=比赛轮次中的相对得分 (%)
|
||||
AbsoluteRank=绝对名次
|
||||
WindSpeedInBeaufort=风速(单位:Bft)
|
||||
DistanceAtStart=起航前与起航线的距离
|
||||
SpeedWhenStarting=起航时的速度
|
||||
@@ -61,3 +67,19 @@ RankGainsOrLossesBetweenFirstMarkAndFinish=名次进阶或落后(第一个标
|
||||
IsTracked=是否跟踪
|
||||
NumberOfCompetitorFixes=参赛队修复次数
|
||||
NumberOfMarkFixes=标志修复次数
|
||||
ManeuverType=操作类型
|
||||
Tack=迎风转向
|
||||
SpeedBefore=操作前的速度
|
||||
SpeedAfter=操作后的速度
|
||||
DirectionChange=风向变化角度
|
||||
ManeuverLoss=操作损失
|
||||
Waypoint=航路点
|
||||
PassingSide=绕标侧
|
||||
TackAtStart=起航时迎风转向
|
||||
SpeedTenSecondsAfterStart=起航后 10 秒的速度
|
||||
RankThirtySecondsAfterStart=起航后 30 秒的名次
|
||||
WindwardDistanceToAdvantageousEndOfLine=与有利航线终点的上风距离
|
||||
RankAfterHalfOfTheFirstLeg=第一航段过半后的名次
|
||||
AdvantageousEndOfLine=有利航线终点
|
||||
TimeSpentInSeconds=所用时间(秒)
|
||||
MedalRace=奖牌轮
|
||||
+75
-9
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file datatype="javapropertyresourcebundle" original="/usr/sap/ljs/app/Converter_6482944262098570487/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties" source-language="en">
|
||||
<file datatype="javapropertyresourcebundle" original="/usr/sap/ljs/app/Converter_2566045106627533633/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties" source-language="en">
|
||||
<header>
|
||||
<skl>
|
||||
<internal-file crc="2476e2fa472ba5cb7a43d465af58c5c7" form="base64">H4sIAAAAAAAAAIVVTW8aMRC9+1fMpVJyiATptypXAiIIFfkQoEY9mt0BLBYb2SaU/vrO2Muuk0b04p1582zPjO23sx1iKWc8ijjO0cywsKb0fVxahykG3Y6HRQTEjfZBmQLnTj1jRbNPAJwQca+2KHkQE1zNjzuU9AU2xEzpanwj+QP3++0CnfiFykkemJ2wyK/D9ypoa1Slw1FmtugVzprjVtZfMcWVCkHJ+isGdu889hwqmUxgW/StCoNKeS/ZgmiKYYUYZBzFVBUoeaAVtjsMOlgnWzMuEOeKOaqt5IESVyW6hVWu5Mq0Wd3YrdJmisFpfEY3WJMnM5qP+5wjc9xzS86vuPJi9Dgb6t/naMS4Igqtd6fc5pFKJua5CUyDmpdSnaLfV+F/CUOipSkPy7Zt/60U7BJaus9bOnJ2v8ubBxHJKXmUe8aNyWt9URAT8tzibaPti/aQRztP/Tr1TTxpU86CQ7MK67Hpo9rTUwiSYTjhoA2cIqK/DB05UNWWra6c6NU6gNKO3evaXTjEP8jIezlCEyrMoA/yzlJBKuTgRzl06NcZ8knS9tasMuizvKXl4UC5sftFjlQVA19P3FUNdDuEWJdy7Mqf2laUBvgGu5a3e+d0oQzS86ro8T3jrCARGJv0SmoMPIPcAMd34KJDWuHDN+jCgY4yXKb+sZC8bp6P6sKdW4ZGWXphFhQxGmEJlpIiBFRIRtKqpzWJFbt8wEmnDgQlCp/zm4qW1n4ta/W6U2U2vTDUlDXfGMk+7xoRYEgkWXpY3lFX9nSHvUwI36AGa1hzVWxyRvSb6A9Njcqi0W+ij0hSF44D7YrqBa0OQB2JWY/oJfkHN7HeEzfmHSGwDhLYKrflHiS10uWb7W4IwAy4eMfbTuI9v2zzs6Xeb4faaL/Os4swJDwrhw48L4LdfzPvYzggmuYEeqasN3irJLjo1scCV9/rHS/F2NOfqNjQr2nsoTabLNpnHwUxS6iNQNLK9qTd5jU57plofwGIogiCRAcAAA==</internal-file>
|
||||
<internal-file crc="f38aaa3e2ebfcee22c5187ca5b77bc00" form="base64">H4sIAAAAAAAAAIVWS28jKRC+8yu4jJQcRopn9qkVKznJ2vHKeci2Ntoj7i53o7TBApys59dvVdEP7Ew8F7rq4wOKetHLHUCpljQKHldgl1A4W4Zr2DgPaU6OroJcMyBuTYjaFrDy+hUaXN0BskPEg96CokHMoVoddqDwK0kQS22a2a2ij3zYb9fgxb+gvaKB2Aljfjv9oKNxVjcmHlQmi3HhnT1sVfsVC6h0jFq1X3Hj9j7A2INWSZQki2un402jQ1AkSRbFpAGIikex0AUoGnCH7Q6iic6rQeQNeK1Ygd4qGjLmEu9R1CtdZUtkAiWieEVdgl877UvygbHVrdtqYxcQvYFX8Dc1aiqjBbboHJnmAznv/I5VENOn5cT8d46GjM9Iwf3utX95Qucg89wCosmWl0xdQNg38UcGy0RLSx43mQd/dFPpNnKgk6EW9kg5b2Xi5P6ferff5Z6WjOSUfJYcTF7MHXN0eyLkF+EkRluLIXemu4DO7ZzcWz6Y92xsuYwebBXrmb0Gvceai4pg2eHSWNnNiOtNvFI3utmSNFJzU9VRauNJ/dKqaw/wDQj5qqZgYwMZ9JO6d3hFHXPwZzXxEOoM+UXh8c5WGfSrusPt5RvaRupvaqobnvi941YtMLpCxPlk40j9Y1yDZsjQY1/U3d57U6AbsI4brPJXWBbUfjpNsiovrrANhfiHHMk3jH28PKbP7BP4Avc+XYcu+3RKpWQ6t4CzlBeO18E1+wgLbV9Up0jSUsCoRb6LFvdNCtUm9j1zHJdRI6NvmdFJRiS2IhZSF36usQ2TSjmWdjomnLbptO3QqxPariBDx3Fi0F+Ur4p02o8RSZBIvfZx0yViUAmh/O2xnrXSxUvOYL2f/dtgiLJZ1vvZJ8D+HQ83xhfNEa2dkO0MWz3F2g2Pfu5CQC7bzZDEpprA4TlydNnUWE35oadToRNDXnyiY+dcU5eDfa40++3EWBPq3DqGZcKz62Cs80uQ+t7ya4hvALaPwNiW7QHfu5K8GLVhkZ//bE+8FLOAz2vxgu/tLMhW7K0Ymg737syg7BVKbX2ItH85JfOZXfdPQefXu1PSE07RVjSkVDz6T2jzru9njI43EXtcIrA8zN8aDwW96dimbQWq12UCqIBuocKeM5hEXhpMIk0868POGaziThDdy4WBVq3MUWfru+Qg+cPCYktP6yqZP5TVqjY+Ht6v4Lh+PVlAfeEN029I2XH5qm3UFbh9+MuWj5u5saA6nsyTN6dK5HLuGuqXVN10yp1uNlibNXCe0WuVCp0tiDXIGgm0jOQN136Dz9n3bfjwuJXZAvrDxlnnKEWQZIzC1aLiHkrd8M8US9xOxf+VN8i0cAoAAA==</internal-file>
|
||||
</skl>
|
||||
<phase-group>
|
||||
<phase company-name="SAP AG" date="2016-09-23T09:24:36Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
<phase company-name="SAP AG" date="2016-11-04T21:01:36Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
</phase-group>
|
||||
<tool tool-company="SAP AG" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter" tool-name="TEW: Javascript .properties Flexible File Converter" tool-version="1.1.0"/>
|
||||
</header>
|
||||
@@ -65,6 +65,9 @@
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Team" resname="Team">
|
||||
<source>Team</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="CompetitorSearchTag" resname="CompetitorSearchTag">
|
||||
<source>Competitor Search Tag</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LeaderboardSailingDomainRetrieverChain" resname="LeaderboardSailingDomainRetrieverChain">
|
||||
<source>Leaderboards</source>
|
||||
</trans-unit>
|
||||
@@ -86,6 +89,9 @@
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RaceOfCompetitorSailingDomainRetrieverChain" resname="RaceOfCompetitorSailingDomainRetrieverChain">
|
||||
<source>Races of Competitors</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverSailingDomainRetrieverChain" resname="ManeuverSailingDomainRetrieverChain">
|
||||
<source>Maneuver</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LeaderboardGroup" resname="LeaderboardGroup">
|
||||
<source>Leaderboard Group</source>
|
||||
</trans-unit>
|
||||
@@ -104,6 +110,9 @@
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="GpsFix" resname="GpsFix">
|
||||
<source>GPS-Fix</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Maneuver" resname="Maneuver">
|
||||
<source>Maneuver</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindStrengthInBeaufort" resname="WindStrengthInBeaufort">
|
||||
<source>Wind Strength in Beaufort</source>
|
||||
</trans-unit>
|
||||
@@ -146,20 +155,29 @@
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft12" resname="Bft12">
|
||||
<source>Hurricane</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInRace" resname="RelativeScoreInRace">
|
||||
<source>Relative score in race (0 best; 1 worst)</source>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScore" resname="RelativeScore">
|
||||
<source>Relative Score (0 best; 1 worst)</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInPercent" resname="RelativeScoreInPercent">
|
||||
<source>Relative Score in %</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInRaceInPercent" resname="RelativeScoreInRaceInPercent">
|
||||
<source>Relative Score in Race in %</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="AbsoluteRank" resname="AbsoluteRank">
|
||||
<source>Absolute Rank</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindSpeedInBeaufort" resname="WindSpeedInBeaufort">
|
||||
<source>Wind speed in Bft</source>
|
||||
<source>Wind Speed in Bft</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="DistanceAtStart" resname="DistanceAtStart">
|
||||
<source>Distance to start at start</source>
|
||||
<source>Distance to Start at Start</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedWhenStarting" resname="SpeedWhenStarting">
|
||||
<source>Speed when starting</source>
|
||||
<source>Speed at Start</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedTenSecondsBeforeStart" resname="SpeedTenSecondsBeforeStart">
|
||||
<source>Speed 10s before start</source>
|
||||
<source>Speed 10s Before Start</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankAtFirstMark" resname="RankAtFirstMark">
|
||||
<source>Rank at First Mark</source>
|
||||
@@ -200,6 +218,54 @@
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="NumberOfMarkFixes" resname="NumberOfMarkFixes">
|
||||
<source>Number of Mark Fixes</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverType" resname="ManeuverType">
|
||||
<source>Maneuver Type</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Tack" resname="Tack">
|
||||
<source>Tack</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedBefore" resname="SpeedBefore">
|
||||
<source>Speed Before Maneuver</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedAfter" resname="SpeedAfter">
|
||||
<source>Speed After Maneuver</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="DirectionChange" resname="DirectionChange">
|
||||
<source>Direction Change in Degrees</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverLoss" resname="ManeuverLoss">
|
||||
<source>Maneuver Loss</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Waypoint" resname="Waypoint">
|
||||
<source>Waypoint</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="PassingSide" resname="PassingSide">
|
||||
<source>Passing Side</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="TackAtStart" resname="TackAtStart">
|
||||
<source>Tack at Start</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedTenSecondsAfterStart" resname="SpeedTenSecondsAfterStart">
|
||||
<source>Speed 10s After Start</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankThirtySecondsAfterStart" resname="RankThirtySecondsAfterStart">
|
||||
<source>Rank 30s After Start</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindwardDistanceToAdvantageousEndOfLine" resname="WindwardDistanceToAdvantageousEndOfLine">
|
||||
<source>Windward Distance to Advantageous End of Line</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankAfterHalfOfTheFirstLeg" resname="RankAfterHalfOfTheFirstLeg">
|
||||
<source>Rank after the half of the first leg</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="AdvantageousEndOfLine" resname="AdvantageousEndOfLine">
|
||||
<source>Advantageous End of Line</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="TimeSpentInSeconds" resname="TimeSpentInSeconds">
|
||||
<source>Time Spent in Seconds</source>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="MedalRace" resname="MedalRace">
|
||||
<source>Medal Race</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
+104
-16
@@ -1,23 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-09-29T12:16:25Z" original="/usr/sap/ljs/app/Converter_5483050776164983/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties" source-language="en" target-language="ja">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-11-09T11:19:08Z" original="/usr/sap/ljs/app/Converter_2566045106627533633/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties" source-language="en" target-language="ja">
|
||||
<header>
|
||||
<skl>
|
||||
<internal-file crc="2476e2fa472ba5cb7a43d465af58c5c7" form="base64">H4sIAAAAAAAAAIVVTW8aMRC9+1fMpVJyiATptypXAiIIFfkQoEY9mt0BLBYb2SaU/vrO2Muuk0b04p1582zPjO23sx1iKWc8ijjO0cywsKb0fVxahykG3Y6HRQTEjfZBmQLnTj1jRbNPAJwQca+2KHkQE1zNjzuU9AU2xEzpanwj+QP3++0CnfiFykkemJ2wyK/D9ypoa1Slw1FmtugVzprjVtZfMcWVCkHJ+isGdu889hwqmUxgW/StCoNKeS/ZgmiKYYUYZBzFVBUoeaAVtjsMOlgnWzMuEOeKOaqt5IESVyW6hVWu5Mq0Wd3YrdJmisFpfEY3WJMnM5qP+5wjc9xzS86vuPJi9Dgb6t/naMS4Igqtd6fc5pFKJua5CUyDmpdSnaLfV+F/CUOipSkPy7Zt/60U7BJaus9bOnJ2v8ubBxHJKXmUe8aNyWt9URAT8tzibaPti/aQRztP/Tr1TTxpU86CQ7MK67Hpo9rTUwiSYTjhoA2cIqK/DB05UNWWra6c6NU6gNKO3evaXTjEP8jIezlCEyrMoA/yzlJBKuTgRzl06NcZ8knS9tasMuizvKXl4UC5sftFjlQVA19P3FUNdDuEWJdy7Mqf2laUBvgGu5a3e+d0oQzS86ro8T3jrCARGJv0SmoMPIPcAMd34KJDWuHDN+jCgY4yXKb+sZC8bp6P6sKdW4ZGWXphFhQxGmEJlpIiBFRIRtKqpzWJFbt8wEmnDgQlCp/zm4qW1n4ta/W6U2U2vTDUlDXfGMk+7xoRYEgkWXpY3lFX9nSHvUwI36AGa1hzVWxyRvSb6A9Njcqi0W+ij0hSF44D7YrqBa0OQB2JWY/oJfkHN7HeEzfmHSGwDhLYKrflHiS10uWb7W4IwAy4eMfbTuI9v2zzs6Xeb4faaL/Os4swJDwrhw48L4LdfzPvYzggmuYEeqasN3irJLjo1scCV9/rHS/F2NOfqNjQr2nsoTabLNpnHwUxS6iNQNLK9qTd5jU57plofwGIogiCRAcAAA==</internal-file>
|
||||
<internal-file crc="f38aaa3e2ebfcee22c5187ca5b77bc00" form="base64">H4sIAAAAAAAAAIVWS28jKRC+8yu4jJQcRopn9qkVKznJ2vHKeci2Ntoj7i53o7TBApys59dvVdEP7Ew8F7rq4wOKetHLHUCpljQKHldgl1A4W4Zr2DgPaU6OroJcMyBuTYjaFrDy+hUaXN0BskPEg96CokHMoVoddqDwK0kQS22a2a2ij3zYb9fgxb+gvaKB2Aljfjv9oKNxVjcmHlQmi3HhnT1sVfsVC6h0jFq1X3Hj9j7A2INWSZQki2un402jQ1AkSRbFpAGIikex0AUoGnCH7Q6iic6rQeQNeK1Ygd4qGjLmEu9R1CtdZUtkAiWieEVdgl877UvygbHVrdtqYxcQvYFX8Dc1aiqjBbboHJnmAznv/I5VENOn5cT8d46GjM9Iwf3utX95Qucg89wCosmWl0xdQNg38UcGy0RLSx43mQd/dFPpNnKgk6EW9kg5b2Xi5P6ferff5Z6WjOSUfJYcTF7MHXN0eyLkF+EkRluLIXemu4DO7ZzcWz6Y92xsuYwebBXrmb0Gvceai4pg2eHSWNnNiOtNvFI3utmSNFJzU9VRauNJ/dKqaw/wDQj5qqZgYwMZ9JO6d3hFHXPwZzXxEOoM+UXh8c5WGfSrusPt5RvaRupvaqobnvi941YtMLpCxPlk40j9Y1yDZsjQY1/U3d57U6AbsI4brPJXWBbUfjpNsiovrrANhfiHHMk3jH28PKbP7BP4Avc+XYcu+3RKpWQ6t4CzlBeO18E1+wgLbV9Up0jSUsCoRb6LFvdNCtUm9j1zHJdRI6NvmdFJRiS2IhZSF36usQ2TSjmWdjomnLbptO3QqxPariBDx3Fi0F+Ur4p02o8RSZBIvfZx0yViUAmh/O2xnrXSxUvOYL2f/dtgiLJZ1vvZJ8D+HQ83xhfNEa2dkO0MWz3F2g2Pfu5CQC7bzZDEpprA4TlydNnUWE35oadToRNDXnyiY+dcU5eDfa40++3EWBPq3DqGZcKz62Cs80uQ+t7ya4hvALaPwNiW7QHfu5K8GLVhkZ//bE+8FLOAz2vxgu/tLMhW7K0Ymg737syg7BVKbX2ItH85JfOZXfdPQefXu1PSE07RVjSkVDz6T2jzru9njI43EXtcIrA8zN8aDwW96dimbQWq12UCqIBuocKeM5hEXhpMIk0868POGaziThDdy4WBVq3MUWfru+Qg+cPCYktP6yqZP5TVqjY+Ht6v4Lh+PVlAfeEN029I2XH5qm3UFbh9+MuWj5u5saA6nsyTN6dK5HLuGuqXVN10yp1uNlibNXCe0WuVCp0tiDXIGgm0jOQN136Dz9n3bfjwuJXZAvrDxlnnKEWQZIzC1aLiHkrd8M8US9xOxf+VN8i0cAoAAA==</internal-file>
|
||||
</skl>
|
||||
<phase-group>
|
||||
<phase company-name="SAP AG" date="2016-05-11T12:28:06Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
<phase company-name="SAP AG" date="2016-11-04T21:01:36Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
</phase-group>
|
||||
<tool tool-company="SAP AG" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter" tool-name="TEW: Javascript .properties Flexible File Converter" tool-version="1.1.0"/>
|
||||
</header>
|
||||
<body>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Speed" resname="Speed">
|
||||
<source>Speed</source>
|
||||
<target state="signed-off">速力</target>
|
||||
<target state="translated">速力</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedTenSecondsBefore" resname="SpeedTenSecondsBefore">
|
||||
<source>Speed 10s before</source>
|
||||
<target state="signed-off">10 秒前の速力</target>
|
||||
<target state="translated">10 秒前の艇速</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="DistanceTraveled" resname="DistanceTraveled">
|
||||
<source>Distance Traveled</source>
|
||||
@@ -83,6 +83,10 @@
|
||||
<source>Team</source>
|
||||
<target state="signed-off">チーム</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="CompetitorSearchTag" resname="CompetitorSearchTag">
|
||||
<source>Competitor Search Tag</source>
|
||||
<target>競技者検索タグ</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LeaderboardSailingDomainRetrieverChain" resname="LeaderboardSailingDomainRetrieverChain">
|
||||
<source>Leaderboards</source>
|
||||
<target state="signed-off">リーダーボード</target>
|
||||
@@ -111,6 +115,10 @@
|
||||
<source>Races of Competitors</source>
|
||||
<target state="signed-off">競技者のレース</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverSailingDomainRetrieverChain" resname="ManeuverSailingDomainRetrieverChain">
|
||||
<source>Maneuver</source>
|
||||
<target state="translated">マニューバー</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LeaderboardGroup" resname="LeaderboardGroup">
|
||||
<source>Leaderboard Group</source>
|
||||
<target state="signed-off">リーダーボードグループ</target>
|
||||
@@ -135,6 +143,10 @@
|
||||
<source>GPS-Fix</source>
|
||||
<target state="signed-off">GPS フィックス</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Maneuver" resname="Maneuver">
|
||||
<source>Maneuver</source>
|
||||
<target state="translated">マニューバー</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindStrengthInBeaufort" resname="WindStrengthInBeaufort">
|
||||
<source>Wind Strength in Beaufort</source>
|
||||
<target state="signed-off">ビューフォート風力</target>
|
||||
@@ -191,25 +203,37 @@
|
||||
<source>Hurricane</source>
|
||||
<target state="signed-off">颶風 (ぐふう)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInRace" resname="RelativeScoreInRace">
|
||||
<source>Relative score in race (0 best; 1 worst)</source>
|
||||
<target state="signed-off">レース中の相対スコア (0 が最高、1 が最低)</target>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScore" resname="RelativeScore">
|
||||
<source>Relative Score (0 best; 1 worst)</source>
|
||||
<target>相対スコア (0 が最高、1 が最低)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInPercent" resname="RelativeScoreInPercent">
|
||||
<source>Relative Score in %</source>
|
||||
<target>相対スコア (%)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInRaceInPercent" resname="RelativeScoreInRaceInPercent">
|
||||
<source>Relative Score in Race in %</source>
|
||||
<target>レース中の相対スコア (%)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="AbsoluteRank" resname="AbsoluteRank">
|
||||
<source>Absolute Rank</source>
|
||||
<target>絶対順位</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindSpeedInBeaufort" resname="WindSpeedInBeaufort">
|
||||
<source>Wind speed in Bft</source>
|
||||
<target state="signed-off">風速 (Bft)</target>
|
||||
<source>Wind Speed in Bft</source>
|
||||
<target state="translated">風速 (Bft)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="DistanceAtStart" resname="DistanceAtStart">
|
||||
<source>Distance to start at start</source>
|
||||
<target state="signed-off">スタート時のスタートラインまでの距離</target>
|
||||
<source>Distance to Start at Start</source>
|
||||
<target state="translated">スタート時のスタートラインまでの距離</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedWhenStarting" resname="SpeedWhenStarting">
|
||||
<source>Speed when starting</source>
|
||||
<target state="signed-off">スタート時の速力</target>
|
||||
<source>Speed at Start</source>
|
||||
<target state="translated">スタート時の艇速</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedTenSecondsBeforeStart" resname="SpeedTenSecondsBeforeStart">
|
||||
<source>Speed 10s before start</source>
|
||||
<target state="signed-off">スタート 10 秒前の速力</target>
|
||||
<source>Speed 10s Before Start</source>
|
||||
<target state="translated">スタート 10 秒前の艇速</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankAtFirstMark" resname="RankAtFirstMark">
|
||||
<source>Rank at First Mark</source>
|
||||
@@ -263,6 +287,70 @@
|
||||
<source>Number of Mark Fixes</source>
|
||||
<target state="signed-off">マークフィックスの数</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverType" resname="ManeuverType">
|
||||
<source>Maneuver Type</source>
|
||||
<target>マニューバータイプ</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Tack" resname="Tack">
|
||||
<source>Tack</source>
|
||||
<target state="translated">タック</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedBefore" resname="SpeedBefore">
|
||||
<source>Speed Before Maneuver</source>
|
||||
<target>マニューバー前の艇速</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedAfter" resname="SpeedAfter">
|
||||
<source>Speed After Maneuver</source>
|
||||
<target>マニューバー後の艇速</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="DirectionChange" resname="DirectionChange">
|
||||
<source>Direction Change in Degrees</source>
|
||||
<target>方向転換 (度)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverLoss" resname="ManeuverLoss">
|
||||
<source>Maneuver Loss</source>
|
||||
<target>マニューバーロス</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Waypoint" resname="Waypoint">
|
||||
<source>Waypoint</source>
|
||||
<target state="translated">変針点</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="PassingSide" resname="PassingSide">
|
||||
<source>Passing Side</source>
|
||||
<target>通過サイド</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="TackAtStart" resname="TackAtStart">
|
||||
<source>Tack at Start</source>
|
||||
<target>スタート時のタック</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedTenSecondsAfterStart" resname="SpeedTenSecondsAfterStart">
|
||||
<source>Speed 10s After Start</source>
|
||||
<target>スタート 10 秒後の艇速</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankThirtySecondsAfterStart" resname="RankThirtySecondsAfterStart">
|
||||
<source>Rank 30s After Start</source>
|
||||
<target>スタート 30 秒後の順位</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindwardDistanceToAdvantageousEndOfLine" resname="WindwardDistanceToAdvantageousEndOfLine">
|
||||
<source>Windward Distance to Advantageous End of Line</source>
|
||||
<target>ラインの有利な端までの風上距離</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankAfterHalfOfTheFirstLeg" resname="RankAfterHalfOfTheFirstLeg">
|
||||
<source>Rank after the half of the first leg</source>
|
||||
<target>第一レグ中間点の順位</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="AdvantageousEndOfLine" resname="AdvantageousEndOfLine">
|
||||
<source>Advantageous End of Line</source>
|
||||
<target>ラインの有利な端</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="TimeSpentInSeconds" resname="TimeSpentInSeconds">
|
||||
<source>Time Spent in Seconds</source>
|
||||
<target>所要時間 (秒)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="MedalRace" resname="MedalRace">
|
||||
<source>Medal Race</source>
|
||||
<target state="translated">メダルレース</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
+99
-11
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-09-29T12:16:25Z" original="/usr/sap/ljs/app/Converter_5483050776164983/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties" source-language="en" target-language="ru">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-11-09T11:21:16Z" original="/usr/sap/ljs/app/Converter_2566045106627533633/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties" source-language="en" target-language="ru">
|
||||
<header>
|
||||
<skl>
|
||||
<internal-file crc="2476e2fa472ba5cb7a43d465af58c5c7" form="base64">H4sIAAAAAAAAAIVVTW8aMRC9+1fMpVJyiATptypXAiIIFfkQoEY9mt0BLBYb2SaU/vrO2Muuk0b04p1582zPjO23sx1iKWc8ijjO0cywsKb0fVxahykG3Y6HRQTEjfZBmQLnTj1jRbNPAJwQca+2KHkQE1zNjzuU9AU2xEzpanwj+QP3++0CnfiFykkemJ2wyK/D9ypoa1Slw1FmtugVzprjVtZfMcWVCkHJ+isGdu889hwqmUxgW/StCoNKeS/ZgmiKYYUYZBzFVBUoeaAVtjsMOlgnWzMuEOeKOaqt5IESVyW6hVWu5Mq0Wd3YrdJmisFpfEY3WJMnM5qP+5wjc9xzS86vuPJi9Dgb6t/naMS4Igqtd6fc5pFKJua5CUyDmpdSnaLfV+F/CUOipSkPy7Zt/60U7BJaus9bOnJ2v8ubBxHJKXmUe8aNyWt9URAT8tzibaPti/aQRztP/Tr1TTxpU86CQ7MK67Hpo9rTUwiSYTjhoA2cIqK/DB05UNWWra6c6NU6gNKO3evaXTjEP8jIezlCEyrMoA/yzlJBKuTgRzl06NcZ8knS9tasMuizvKXl4UC5sftFjlQVA19P3FUNdDuEWJdy7Mqf2laUBvgGu5a3e+d0oQzS86ro8T3jrCARGJv0SmoMPIPcAMd34KJDWuHDN+jCgY4yXKb+sZC8bp6P6sKdW4ZGWXphFhQxGmEJlpIiBFRIRtKqpzWJFbt8wEmnDgQlCp/zm4qW1n4ta/W6U2U2vTDUlDXfGMk+7xoRYEgkWXpY3lFX9nSHvUwI36AGa1hzVWxyRvSb6A9Njcqi0W+ij0hSF44D7YrqBa0OQB2JWY/oJfkHN7HeEzfmHSGwDhLYKrflHiS10uWb7W4IwAy4eMfbTuI9v2zzs6Xeb4faaL/Os4swJDwrhw48L4LdfzPvYzggmuYEeqasN3irJLjo1scCV9/rHS/F2NOfqNjQr2nsoTabLNpnHwUxS6iNQNLK9qTd5jU57plofwGIogiCRAcAAA==</internal-file>
|
||||
<internal-file crc="f38aaa3e2ebfcee22c5187ca5b77bc00" form="base64">H4sIAAAAAAAAAIVWS28jKRC+8yu4jJQcRopn9qkVKznJ2vHKeci2Ntoj7i53o7TBApys59dvVdEP7Ew8F7rq4wOKetHLHUCpljQKHldgl1A4W4Zr2DgPaU6OroJcMyBuTYjaFrDy+hUaXN0BskPEg96CokHMoVoddqDwK0kQS22a2a2ij3zYb9fgxb+gvaKB2Aljfjv9oKNxVjcmHlQmi3HhnT1sVfsVC6h0jFq1X3Hj9j7A2INWSZQki2un402jQ1AkSRbFpAGIikex0AUoGnCH7Q6iic6rQeQNeK1Ygd4qGjLmEu9R1CtdZUtkAiWieEVdgl877UvygbHVrdtqYxcQvYFX8Dc1aiqjBbboHJnmAznv/I5VENOn5cT8d46GjM9Iwf3utX95Qucg89wCosmWl0xdQNg38UcGy0RLSx43mQd/dFPpNnKgk6EW9kg5b2Xi5P6ferff5Z6WjOSUfJYcTF7MHXN0eyLkF+EkRluLIXemu4DO7ZzcWz6Y92xsuYwebBXrmb0Gvceai4pg2eHSWNnNiOtNvFI3utmSNFJzU9VRauNJ/dKqaw/wDQj5qqZgYwMZ9JO6d3hFHXPwZzXxEOoM+UXh8c5WGfSrusPt5RvaRupvaqobnvi941YtMLpCxPlk40j9Y1yDZsjQY1/U3d57U6AbsI4brPJXWBbUfjpNsiovrrANhfiHHMk3jH28PKbP7BP4Avc+XYcu+3RKpWQ6t4CzlBeO18E1+wgLbV9Up0jSUsCoRb6LFvdNCtUm9j1zHJdRI6NvmdFJRiS2IhZSF36usQ2TSjmWdjomnLbptO3QqxPariBDx3Fi0F+Ur4p02o8RSZBIvfZx0yViUAmh/O2xnrXSxUvOYL2f/dtgiLJZ1vvZJ8D+HQ83xhfNEa2dkO0MWz3F2g2Pfu5CQC7bzZDEpprA4TlydNnUWE35oadToRNDXnyiY+dcU5eDfa40++3EWBPq3DqGZcKz62Cs80uQ+t7ya4hvALaPwNiW7QHfu5K8GLVhkZ//bE+8FLOAz2vxgu/tLMhW7K0Ymg737syg7BVKbX2ItH85JfOZXfdPQefXu1PSE07RVjSkVDz6T2jzru9njI43EXtcIrA8zN8aDwW96dimbQWq12UCqIBuocKeM5hEXhpMIk0868POGaziThDdy4WBVq3MUWfru+Qg+cPCYktP6yqZP5TVqjY+Ht6v4Lh+PVlAfeEN029I2XH5qm3UFbh9+MuWj5u5saA6nsyTN6dK5HLuGuqXVN10yp1uNlibNXCe0WuVCp0tiDXIGgm0jOQN136Dz9n3bfjwuJXZAvrDxlnnKEWQZIzC1aLiHkrd8M8US9xOxf+VN8i0cAoAAA==</internal-file>
|
||||
</skl>
|
||||
<phase-group>
|
||||
<phase company-name="SAP AG" date="2016-05-11T12:28:06Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
<phase company-name="SAP AG" date="2016-11-04T21:01:36Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
</phase-group>
|
||||
<tool tool-company="SAP AG" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter" tool-name="TEW: Javascript .properties Flexible File Converter" tool-version="1.1.0"/>
|
||||
</header>
|
||||
@@ -83,6 +83,10 @@
|
||||
<source>Team</source>
|
||||
<target state="signed-off">Команда</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="CompetitorSearchTag" resname="CompetitorSearchTag">
|
||||
<source>Competitor Search Tag</source>
|
||||
<target state="signed-off">Тег поиска участника</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LeaderboardSailingDomainRetrieverChain" resname="LeaderboardSailingDomainRetrieverChain">
|
||||
<source>Leaderboards</source>
|
||||
<target state="signed-off">Таблицы лидеров</target>
|
||||
@@ -111,6 +115,10 @@
|
||||
<source>Races of Competitors</source>
|
||||
<target state="signed-off">Гонки участников</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverSailingDomainRetrieverChain" resname="ManeuverSailingDomainRetrieverChain">
|
||||
<source>Maneuver</source>
|
||||
<target state="signed-off">Маневр</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LeaderboardGroup" resname="LeaderboardGroup">
|
||||
<source>Leaderboard Group</source>
|
||||
<target state="signed-off">Группа таблиц лидеров</target>
|
||||
@@ -135,6 +143,10 @@
|
||||
<source>GPS-Fix</source>
|
||||
<target state="signed-off">Замер GPS</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Maneuver" resname="Maneuver">
|
||||
<source>Maneuver</source>
|
||||
<target state="signed-off">Маневр</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindStrengthInBeaufort" resname="WindStrengthInBeaufort">
|
||||
<source>Wind Strength in Beaufort</source>
|
||||
<target state="signed-off">Сила ветра по шкале Бофорта</target>
|
||||
@@ -191,24 +203,36 @@
|
||||
<source>Hurricane</source>
|
||||
<target state="signed-off">Ураган</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInRace" resname="RelativeScoreInRace">
|
||||
<source>Relative score in race (0 best; 1 worst)</source>
|
||||
<target state="signed-off">Относительная оценка в гонке (0 лучшая; 1 худшая)</target>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScore" resname="RelativeScore">
|
||||
<source>Relative Score (0 best; 1 worst)</source>
|
||||
<target state="signed-off">Относительная оценка (0 лучшая; 1 худшая)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInPercent" resname="RelativeScoreInPercent">
|
||||
<source>Relative Score in %</source>
|
||||
<target state="signed-off">Относительная оценка (%)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInRaceInPercent" resname="RelativeScoreInRaceInPercent">
|
||||
<source>Relative Score in Race in %</source>
|
||||
<target state="signed-off">Относительная оценка в гонке (%)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="AbsoluteRank" resname="AbsoluteRank">
|
||||
<source>Absolute Rank</source>
|
||||
<target state="signed-off">Абсолютный ранг</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindSpeedInBeaufort" resname="WindSpeedInBeaufort">
|
||||
<source>Wind speed in Bft</source>
|
||||
<source>Wind Speed in Bft</source>
|
||||
<target state="signed-off">Скорость ветра по шкале Бофорта</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="DistanceAtStart" resname="DistanceAtStart">
|
||||
<source>Distance to start at start</source>
|
||||
<source>Distance to Start at Start</source>
|
||||
<target state="signed-off">Дистанция до старта при старте</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedWhenStarting" resname="SpeedWhenStarting">
|
||||
<source>Speed when starting</source>
|
||||
<source>Speed at Start</source>
|
||||
<target state="signed-off">Скорость при старте</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedTenSecondsBeforeStart" resname="SpeedTenSecondsBeforeStart">
|
||||
<source>Speed 10s before start</source>
|
||||
<source>Speed 10s Before Start</source>
|
||||
<target state="signed-off">Скорость за 10 с до старта</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankAtFirstMark" resname="RankAtFirstMark">
|
||||
@@ -229,7 +253,7 @@
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="NumberOfPenaltyCircles" resname="NumberOfPenaltyCircles">
|
||||
<source>Number of Penalty Circles</source>
|
||||
<target state="translated">Число штрафных кругов</target>
|
||||
<target state="signed-off">Число штрафных кругов</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankGainsOrLosses" resname="RankGainsOrLosses">
|
||||
<source>Rank Gains or Losses</source>
|
||||
@@ -263,6 +287,70 @@
|
||||
<source>Number of Mark Fixes</source>
|
||||
<target state="signed-off">Число замеров отметки</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverType" resname="ManeuverType">
|
||||
<source>Maneuver Type</source>
|
||||
<target state="signed-off">Тип маневра</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Tack" resname="Tack">
|
||||
<source>Tack</source>
|
||||
<target state="signed-off">Оверштаг</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedBefore" resname="SpeedBefore">
|
||||
<source>Speed Before Maneuver</source>
|
||||
<target state="signed-off">Скорость до маневра</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedAfter" resname="SpeedAfter">
|
||||
<source>Speed After Maneuver</source>
|
||||
<target state="signed-off">Скорость после маневра</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="DirectionChange" resname="DirectionChange">
|
||||
<source>Direction Change in Degrees</source>
|
||||
<target state="signed-off">Изменение направления в градусах</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverLoss" resname="ManeuverLoss">
|
||||
<source>Maneuver Loss</source>
|
||||
<target state="signed-off">Потеря маневра</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Waypoint" resname="Waypoint">
|
||||
<source>Waypoint</source>
|
||||
<target state="signed-off">Путевая точка</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="PassingSide" resname="PassingSide">
|
||||
<source>Passing Side</source>
|
||||
<target state="signed-off">Сторона прохождения</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="TackAtStart" resname="TackAtStart">
|
||||
<source>Tack at Start</source>
|
||||
<target state="signed-off">Оверштаг при старте</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedTenSecondsAfterStart" resname="SpeedTenSecondsAfterStart">
|
||||
<source>Speed 10s After Start</source>
|
||||
<target state="signed-off">Скорость через 10 с после старта</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankThirtySecondsAfterStart" resname="RankThirtySecondsAfterStart">
|
||||
<source>Rank 30s After Start</source>
|
||||
<target state="signed-off">Ранг через 30 с после старта</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindwardDistanceToAdvantageousEndOfLine" resname="WindwardDistanceToAdvantageousEndOfLine">
|
||||
<source>Windward Distance to Advantageous End of Line</source>
|
||||
<target state="signed-off">Дистанция по ветру до выгодного конца линии</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankAfterHalfOfTheFirstLeg" resname="RankAfterHalfOfTheFirstLeg">
|
||||
<source>Rank after the half of the first leg</source>
|
||||
<target state="signed-off">Ранг после половины первого этапа</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="AdvantageousEndOfLine" resname="AdvantageousEndOfLine">
|
||||
<source>Advantageous End of Line</source>
|
||||
<target state="signed-off">Выгодный конец линии</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="TimeSpentInSeconds" resname="TimeSpentInSeconds">
|
||||
<source>Time Spent in Seconds</source>
|
||||
<target state="signed-off">Затраченное время в секундах</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="MedalRace" resname="MedalRace">
|
||||
<source>Medal Race</source>
|
||||
<target state="signed-off">Гонка на медали</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
+160
-72
@@ -1,267 +1,355 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-09-29T12:16:25Z" original="/usr/sap/ljs/app/Converter_5483050776164983/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties" source-language="en" target-language="zh-CN">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-11-09T11:22:54Z" original="/usr/sap/ljs/app/Converter_2566045106627533633/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties" source-language="en" target-language="zh-CN">
|
||||
<header>
|
||||
<skl>
|
||||
<internal-file crc="2476e2fa472ba5cb7a43d465af58c5c7" form="base64">H4sIAAAAAAAAAIVVTW8aMRC9+1fMpVJyiATptypXAiIIFfkQoEY9mt0BLBYb2SaU/vrO2Muuk0b04p1582zPjO23sx1iKWc8ijjO0cywsKb0fVxahykG3Y6HRQTEjfZBmQLnTj1jRbNPAJwQca+2KHkQE1zNjzuU9AU2xEzpanwj+QP3++0CnfiFykkemJ2wyK/D9ypoa1Slw1FmtugVzprjVtZfMcWVCkHJ+isGdu889hwqmUxgW/StCoNKeS/ZgmiKYYUYZBzFVBUoeaAVtjsMOlgnWzMuEOeKOaqt5IESVyW6hVWu5Mq0Wd3YrdJmisFpfEY3WJMnM5qP+5wjc9xzS86vuPJi9Dgb6t/naMS4Igqtd6fc5pFKJua5CUyDmpdSnaLfV+F/CUOipSkPy7Zt/60U7BJaus9bOnJ2v8ubBxHJKXmUe8aNyWt9URAT8tzibaPti/aQRztP/Tr1TTxpU86CQ7MK67Hpo9rTUwiSYTjhoA2cIqK/DB05UNWWra6c6NU6gNKO3evaXTjEP8jIezlCEyrMoA/yzlJBKuTgRzl06NcZ8knS9tasMuizvKXl4UC5sftFjlQVA19P3FUNdDuEWJdy7Mqf2laUBvgGu5a3e+d0oQzS86ro8T3jrCARGJv0SmoMPIPcAMd34KJDWuHDN+jCgY4yXKb+sZC8bp6P6sKdW4ZGWXphFhQxGmEJlpIiBFRIRtKqpzWJFbt8wEmnDgQlCp/zm4qW1n4ta/W6U2U2vTDUlDXfGMk+7xoRYEgkWXpY3lFX9nSHvUwI36AGa1hzVWxyRvSb6A9Njcqi0W+ij0hSF44D7YrqBa0OQB2JWY/oJfkHN7HeEzfmHSGwDhLYKrflHiS10uWb7W4IwAy4eMfbTuI9v2zzs6Xeb4faaL/Os4swJDwrhw48L4LdfzPvYzggmuYEeqasN3irJLjo1scCV9/rHS/F2NOfqNjQr2nsoTabLNpnHwUxS6iNQNLK9qTd5jU57plofwGIogiCRAcAAA==</internal-file>
|
||||
<internal-file crc="f38aaa3e2ebfcee22c5187ca5b77bc00" form="base64">H4sIAAAAAAAAAIVWS28jKRC+8yu4jJQcRopn9qkVKznJ2vHKeci2Ntoj7i53o7TBApys59dvVdEP7Ew8F7rq4wOKetHLHUCpljQKHldgl1A4W4Zr2DgPaU6OroJcMyBuTYjaFrDy+hUaXN0BskPEg96CokHMoVoddqDwK0kQS22a2a2ij3zYb9fgxb+gvaKB2Aljfjv9oKNxVjcmHlQmi3HhnT1sVfsVC6h0jFq1X3Hj9j7A2INWSZQki2un402jQ1AkSRbFpAGIikex0AUoGnCH7Q6iic6rQeQNeK1Ygd4qGjLmEu9R1CtdZUtkAiWieEVdgl877UvygbHVrdtqYxcQvYFX8Dc1aiqjBbboHJnmAznv/I5VENOn5cT8d46GjM9Iwf3utX95Qucg89wCosmWl0xdQNg38UcGy0RLSx43mQd/dFPpNnKgk6EW9kg5b2Xi5P6ferff5Z6WjOSUfJYcTF7MHXN0eyLkF+EkRluLIXemu4DO7ZzcWz6Y92xsuYwebBXrmb0Gvceai4pg2eHSWNnNiOtNvFI3utmSNFJzU9VRauNJ/dKqaw/wDQj5qqZgYwMZ9JO6d3hFHXPwZzXxEOoM+UXh8c5WGfSrusPt5RvaRupvaqobnvi941YtMLpCxPlk40j9Y1yDZsjQY1/U3d57U6AbsI4brPJXWBbUfjpNsiovrrANhfiHHMk3jH28PKbP7BP4Avc+XYcu+3RKpWQ6t4CzlBeO18E1+wgLbV9Up0jSUsCoRb6LFvdNCtUm9j1zHJdRI6NvmdFJRiS2IhZSF36usQ2TSjmWdjomnLbptO3QqxPariBDx3Fi0F+Ur4p02o8RSZBIvfZx0yViUAmh/O2xnrXSxUvOYL2f/dtgiLJZ1vvZJ8D+HQ83xhfNEa2dkO0MWz3F2g2Pfu5CQC7bzZDEpprA4TlydNnUWE35oadToRNDXnyiY+dcU5eDfa40++3EWBPq3DqGZcKz62Cs80uQ+t7ya4hvALaPwNiW7QHfu5K8GLVhkZ//bE+8FLOAz2vxgu/tLMhW7K0Ymg737syg7BVKbX2ItH85JfOZXfdPQefXu1PSE07RVjSkVDz6T2jzru9njI43EXtcIrA8zN8aDwW96dimbQWq12UCqIBuocKeM5hEXhpMIk0868POGaziThDdy4WBVq3MUWfru+Qg+cPCYktP6yqZP5TVqjY+Ht6v4Lh+PVlAfeEN029I2XH5qm3UFbh9+MuWj5u5saA6nsyTN6dK5HLuGuqXVN10yp1uNlibNXCe0WuVCp0tiDXIGgm0jOQN136Dz9n3bfjwuJXZAvrDxlnnKEWQZIzC1aLiHkrd8M8US9xOxf+VN8i0cAoAAA==</internal-file>
|
||||
</skl>
|
||||
<phase-group>
|
||||
<phase company-name="SAP AG" date="2016-05-11T12:28:06Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
<phase company-name="SAP AG" date="2016-11-04T21:01:36Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
</phase-group>
|
||||
<tool tool-company="SAP AG" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter" tool-name="TEW: Javascript .properties Flexible File Converter" tool-version="1.1.0"/>
|
||||
</header>
|
||||
<body>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Speed" resname="Speed">
|
||||
<source>Speed</source>
|
||||
<target state="translated">速度</target>
|
||||
<target state="signed-off">速度</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedTenSecondsBefore" resname="SpeedTenSecondsBefore">
|
||||
<source>Speed 10s before</source>
|
||||
<target>前 10 秒的速度</target>
|
||||
<target state="signed-off">前 10 秒的速度</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="DistanceTraveled" resname="DistanceTraveled">
|
||||
<source>Distance Traveled</source>
|
||||
<target state="translated">航行距离</target>
|
||||
<target state="signed-off">航行距离</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Name" resname="Name">
|
||||
<source>Name</source>
|
||||
<target state="translated">名称</target>
|
||||
<target state="signed-off">名称</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LegType" resname="LegType">
|
||||
<source>Leg Type</source>
|
||||
<target state="translated">航段形式</target>
|
||||
<target state="signed-off">航段形式</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SailID" resname="SailID">
|
||||
<source>Sail Number</source>
|
||||
<target>帆号</target>
|
||||
<target state="signed-off">帆号</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Year" resname="Year">
|
||||
<source>Year</source>
|
||||
<target>年份</target>
|
||||
<target state="signed-off">年份</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LegNumber" resname="LegNumber">
|
||||
<source>Leg Number</source>
|
||||
<target>航段编号</target>
|
||||
<target state="signed-off">航段编号</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Nationality" resname="Nationality">
|
||||
<source>Nationality</source>
|
||||
<target state="translated">国籍</target>
|
||||
<target state="signed-off">国籍</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Acronym" resname="Acronym">
|
||||
<source>Acronym</source>
|
||||
<target>首字母缩略词</target>
|
||||
<target state="signed-off">首字母缩略词</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Regatta" resname="Regatta">
|
||||
<source>Regatta</source>
|
||||
<target state="translated">比赛</target>
|
||||
<target state="signed-off">比赛</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="CourseArea" resname="CourseArea">
|
||||
<source>Course Area</source>
|
||||
<target>场地区域</target>
|
||||
<target state="signed-off">场地区域</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="BoatClass" resname="BoatClass">
|
||||
<source>Boat Class</source>
|
||||
<target state="translated">船只级别</target>
|
||||
<target state="signed-off">船只级别</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Fleet" resname="Fleet">
|
||||
<source>Fleet</source>
|
||||
<target state="translated">船队</target>
|
||||
<target state="signed-off">船队</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Race" resname="Race">
|
||||
<source>Race</source>
|
||||
<target state="translated">比赛轮次</target>
|
||||
<target state="signed-off">比赛轮次</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Competitor" resname="Competitor">
|
||||
<source>Competitor</source>
|
||||
<target>参赛队</target>
|
||||
<target state="signed-off">参赛队</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Boat" resname="Boat">
|
||||
<source>Boat</source>
|
||||
<target>船只</target>
|
||||
<target state="signed-off">船只</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Team" resname="Team">
|
||||
<source>Team</source>
|
||||
<target state="translated">团队</target>
|
||||
<target state="signed-off">团队</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="CompetitorSearchTag" resname="CompetitorSearchTag">
|
||||
<source>Competitor Search Tag</source>
|
||||
<target>参赛队搜索标记</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LeaderboardSailingDomainRetrieverChain" resname="LeaderboardSailingDomainRetrieverChain">
|
||||
<source>Leaderboards</source>
|
||||
<target state="translated">积分榜</target>
|
||||
<target state="signed-off">积分榜</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RaceSailingDomainRetrieverChain" resname="RaceSailingDomainRetrieverChain">
|
||||
<source>Races</source>
|
||||
<target>比赛轮次</target>
|
||||
<target state="signed-off">比赛轮次</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LegSailingDomainRetrieverChain" resname="LegSailingDomainRetrieverChain">
|
||||
<source>Legs</source>
|
||||
<target state="translated">航段</target>
|
||||
<target state="signed-off">航段</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="GPSFixSailingDomainRetrieverChain" resname="GPSFixSailingDomainRetrieverChain">
|
||||
<source>GPS-Fixes</source>
|
||||
<target>GPS 修复</target>
|
||||
<target state="signed-off">GPS 修复</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="MarkPassingSailingDomainRetrieverChain" resname="MarkPassingSailingDomainRetrieverChain">
|
||||
<source>Mark Passings</source>
|
||||
<target>绕标</target>
|
||||
<target state="signed-off">绕标</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RaceResultSailingDomainRetrieverChain" resname="RaceResultSailingDomainRetrieverChain">
|
||||
<source>Race Results</source>
|
||||
<target>比赛轮次结果</target>
|
||||
<target state="signed-off">比赛轮次结果</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RaceOfCompetitorSailingDomainRetrieverChain" resname="RaceOfCompetitorSailingDomainRetrieverChain">
|
||||
<source>Races of Competitors</source>
|
||||
<target>参赛队的比赛轮次</target>
|
||||
<target state="signed-off">参赛队的比赛轮次</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverSailingDomainRetrieverChain" resname="ManeuverSailingDomainRetrieverChain">
|
||||
<source>Maneuver</source>
|
||||
<target>操作</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LeaderboardGroup" resname="LeaderboardGroup">
|
||||
<source>Leaderboard Group</source>
|
||||
<target state="translated">积分榜分组</target>
|
||||
<target state="signed-off">积分榜分组</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Leaderboard" resname="Leaderboard">
|
||||
<source>Leaderboard</source>
|
||||
<target state="translated">积分榜</target>
|
||||
<target state="signed-off">积分榜</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Leg" resname="Leg">
|
||||
<source>Leg</source>
|
||||
<target state="translated">航段</target>
|
||||
<target state="signed-off">航段</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="MarkPassing" resname="MarkPassing">
|
||||
<source>Mark Passing</source>
|
||||
<target>绕标</target>
|
||||
<target state="signed-off">绕标</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="LegOfCompetitor" resname="LegOfCompetitor">
|
||||
<source>Leg of competitor</source>
|
||||
<target>参赛队的航段</target>
|
||||
<target state="signed-off">参赛队的航段</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="GpsFix" resname="GpsFix">
|
||||
<source>GPS-Fix</source>
|
||||
<target>GPS 修复</target>
|
||||
<target state="signed-off">GPS 修复</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Maneuver" resname="Maneuver">
|
||||
<source>Maneuver</source>
|
||||
<target>操作</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindStrengthInBeaufort" resname="WindStrengthInBeaufort">
|
||||
<source>Wind Strength in Beaufort</source>
|
||||
<target>风力(蒲福风级)</target>
|
||||
<target state="signed-off">风力(蒲福风级)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft0" resname="Bft0">
|
||||
<source>Calm</source>
|
||||
<target>无风</target>
|
||||
<target state="signed-off">无风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft1" resname="Bft1">
|
||||
<source>Light air</source>
|
||||
<target>软风</target>
|
||||
<target state="signed-off">软风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft2" resname="Bft2">
|
||||
<source>Light breeze</source>
|
||||
<target>轻风</target>
|
||||
<target state="signed-off">轻风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft3" resname="Bft3">
|
||||
<source>Gentle breeze</source>
|
||||
<target>微风</target>
|
||||
<target state="signed-off">微风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft4" resname="Bft4">
|
||||
<source>Moderate breeze</source>
|
||||
<target>和风</target>
|
||||
<target state="signed-off">和风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft5" resname="Bft5">
|
||||
<source>Fresh breeze</source>
|
||||
<target>劲风</target>
|
||||
<target state="signed-off">劲风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft6" resname="Bft6">
|
||||
<source>Strong breeze</source>
|
||||
<target>强风</target>
|
||||
<target state="signed-off">强风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft7" resname="Bft7">
|
||||
<source>High wind</source>
|
||||
<target>疾风</target>
|
||||
<target state="signed-off">疾风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft8" resname="Bft8">
|
||||
<source>Gale</source>
|
||||
<target>大风</target>
|
||||
<target state="signed-off">大风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft9" resname="Bft9">
|
||||
<source>Strong gale</source>
|
||||
<target>烈风</target>
|
||||
<target state="signed-off">烈风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft10" resname="Bft10">
|
||||
<source>Storm</source>
|
||||
<target>暴风</target>
|
||||
<target state="signed-off">暴风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft11" resname="Bft11">
|
||||
<source>Violent storm</source>
|
||||
<target>飓风</target>
|
||||
<target state="signed-off">飓风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Bft12" resname="Bft12">
|
||||
<source>Hurricane</source>
|
||||
<target>台风</target>
|
||||
<target state="signed-off">台风</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInRace" resname="RelativeScoreInRace">
|
||||
<source>Relative score in race (0 best; 1 worst)</source>
|
||||
<target>比赛轮次中的相对得分(0 最佳;1 最差)</target>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScore" resname="RelativeScore">
|
||||
<source>Relative Score (0 best; 1 worst)</source>
|
||||
<target>相对得分(0 最佳;1 最差)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInPercent" resname="RelativeScoreInPercent">
|
||||
<source>Relative Score in %</source>
|
||||
<target>相对得分 (%)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RelativeScoreInRaceInPercent" resname="RelativeScoreInRaceInPercent">
|
||||
<source>Relative Score in Race in %</source>
|
||||
<target>比赛轮次中的相对得分 (%)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="AbsoluteRank" resname="AbsoluteRank">
|
||||
<source>Absolute Rank</source>
|
||||
<target>绝对名次</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindSpeedInBeaufort" resname="WindSpeedInBeaufort">
|
||||
<source>Wind speed in Bft</source>
|
||||
<target>风速(单位:Bft)</target>
|
||||
<source>Wind Speed in Bft</source>
|
||||
<target state="translated">风速(单位:Bft)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="DistanceAtStart" resname="DistanceAtStart">
|
||||
<source>Distance to start at start</source>
|
||||
<target>起航前与起航线的距离</target>
|
||||
<source>Distance to Start at Start</source>
|
||||
<target state="translated">起航前与起航线的距离</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedWhenStarting" resname="SpeedWhenStarting">
|
||||
<source>Speed when starting</source>
|
||||
<target>起航时的速度</target>
|
||||
<source>Speed at Start</source>
|
||||
<target state="translated">起航时的速度</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedTenSecondsBeforeStart" resname="SpeedTenSecondsBeforeStart">
|
||||
<source>Speed 10s before start</source>
|
||||
<target>起航前 10 秒的速度</target>
|
||||
<source>Speed 10s Before Start</source>
|
||||
<target state="translated">起航前 10 秒的速度</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankAtFirstMark" resname="RankAtFirstMark">
|
||||
<source>Rank at First Mark</source>
|
||||
<target>在第一个标志的名次</target>
|
||||
<target state="signed-off">在第一个标志的名次</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="NumberOfManeuvers" resname="NumberOfManeuvers">
|
||||
<source>Number of Maneuvers</source>
|
||||
<target>操作数量</target>
|
||||
<target state="signed-off">操作数量</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="NumberOfTacks" resname="NumberOfTacks">
|
||||
<source>Number of Tacks</source>
|
||||
<target>迎风转向次数</target>
|
||||
<target state="signed-off">迎风转向次数</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="NumberOfJibes" resname="NumberOfJibes">
|
||||
<source>Number of Jibes</source>
|
||||
<target>顺风转向次数</target>
|
||||
<target state="signed-off">顺风转向次数</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="NumberOfPenaltyCircles" resname="NumberOfPenaltyCircles">
|
||||
<source>Number of Penalty Circles</source>
|
||||
<target>惩罚圈数</target>
|
||||
<target state="signed-off">惩罚圈数</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankGainsOrLosses" resname="RankGainsOrLosses">
|
||||
<source>Rank Gains or Losses</source>
|
||||
<target>名次进阶或落后</target>
|
||||
<target state="signed-off">名次进阶或落后</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="DistanceToStarboardSideAtStart" resname="DistanceToStarboardSideAtStart">
|
||||
<source>Distance to Starboard Side (% of Length)</source>
|
||||
<target>与右舷的距离(长度百分比)</target>
|
||||
<target state="signed-off">与右舷的距离(长度百分比)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="NumberOfPodiumFinish" resname="NumberOfPodiumFinish">
|
||||
<source>Number of Podium Finishes</source>
|
||||
<target>跻身颁奖台次数</target>
|
||||
<target state="signed-off">跻身颁奖台次数</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="NumberOfWins" resname="NumberOfWins">
|
||||
<source>Number of Wins</source>
|
||||
<target>获胜次数</target>
|
||||
<target state="signed-off">获胜次数</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankGainsOrLossesBetweenFirstMarkAndFinish" resname="RankGainsOrLossesBetweenFirstMarkAndFinish">
|
||||
<source>Rank Gains or Losses (1st Mark -> Finish)</source>
|
||||
<target>名次进阶或落后(第一个标志 -> 结束)</target>
|
||||
<target state="signed-off">名次进阶或落后(第一个标志 -> 结束)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="IsTracked" resname="IsTracked">
|
||||
<source>Is Tracked</source>
|
||||
<target>是否跟踪</target>
|
||||
<target state="signed-off">是否跟踪</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="NumberOfCompetitorFixes" resname="NumberOfCompetitorFixes">
|
||||
<source>Number of Competitor Fixes</source>
|
||||
<target>参赛队修复次数</target>
|
||||
<target state="signed-off">参赛队修复次数</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="NumberOfMarkFixes" resname="NumberOfMarkFixes">
|
||||
<source>Number of Mark Fixes</source>
|
||||
<target>标志修复次数</target>
|
||||
<target state="signed-off">标志修复次数</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverType" resname="ManeuverType">
|
||||
<source>Maneuver Type</source>
|
||||
<target>操作类型</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Tack" resname="Tack">
|
||||
<source>Tack</source>
|
||||
<target>迎风转向</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedBefore" resname="SpeedBefore">
|
||||
<source>Speed Before Maneuver</source>
|
||||
<target>操作前的速度</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedAfter" resname="SpeedAfter">
|
||||
<source>Speed After Maneuver</source>
|
||||
<target>操作后的速度</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="DirectionChange" resname="DirectionChange">
|
||||
<source>Direction Change in Degrees</source>
|
||||
<target>风向变化角度</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="ManeuverLoss" resname="ManeuverLoss">
|
||||
<source>Maneuver Loss</source>
|
||||
<target>操作损失</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="Waypoint" resname="Waypoint">
|
||||
<source>Waypoint</source>
|
||||
<target>航路点</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="PassingSide" resname="PassingSide">
|
||||
<source>Passing Side</source>
|
||||
<target>绕标侧</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="TackAtStart" resname="TackAtStart">
|
||||
<source>Tack at Start</source>
|
||||
<target>起航时迎风转向</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="SpeedTenSecondsAfterStart" resname="SpeedTenSecondsAfterStart">
|
||||
<source>Speed 10s After Start</source>
|
||||
<target>起航后 10 秒的速度</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankThirtySecondsAfterStart" resname="RankThirtySecondsAfterStart">
|
||||
<source>Rank 30s After Start</source>
|
||||
<target>起航后 30 秒的名次</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="WindwardDistanceToAdvantageousEndOfLine" resname="WindwardDistanceToAdvantageousEndOfLine">
|
||||
<source>Windward Distance to Advantageous End of Line</source>
|
||||
<target>与有利航线终点的上风距离</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="RankAfterHalfOfTheFirstLeg" resname="RankAfterHalfOfTheFirstLeg">
|
||||
<source>Rank after the half of the first leg</source>
|
||||
<target>第一航段过半后的名次</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="AdvantageousEndOfLine" resname="AdvantageousEndOfLine">
|
||||
<source>Advantageous End of Line</source>
|
||||
<target>有利航线终点</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="TimeSpentInSeconds" resname="TimeSpentInSeconds">
|
||||
<source>Time Spent in Seconds</source>
|
||||
<target>所用时间(秒)</target>
|
||||
</trans-unit>
|
||||
<trans-unit datatype="x-urn:x-sap:sls-mlt:java:flexible-converter:messageformat" id="MedalRace" resname="MedalRace">
|
||||
<source>Medal Race</source>
|
||||
<target>奖牌轮</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.osgi.framework.BundleContext;
|
||||
import com.sap.sailing.datamining.data.HasGPSFixContext;
|
||||
import com.sap.sailing.datamining.data.HasLeaderboardContext;
|
||||
import com.sap.sailing.datamining.data.HasLeaderboardGroupContext;
|
||||
import com.sap.sailing.datamining.data.HasManeuverContext;
|
||||
import com.sap.sailing.datamining.data.HasMarkPassingContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceResultOfCompetitorContext;
|
||||
@@ -22,11 +23,9 @@ import com.sap.sailing.datamining.impl.components.aggregators.ParallelDistanceMa
|
||||
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDistanceMedianAggregationProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDistanceMinAggregationProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.aggregators.ParallelDistanceSumAggregationProcessor;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sse.datamining.DataSourceProvider;
|
||||
import com.sap.sse.datamining.components.AggregationProcessorDefinition;
|
||||
import com.sap.sse.datamining.components.DataRetrieverChainDefinition;
|
||||
import com.sap.sse.datamining.data.ClusterGroup;
|
||||
import com.sap.sse.datamining.impl.AbstractDataMiningActivatorWithPredefinedQueries;
|
||||
import com.sap.sse.datamining.shared.dto.StatisticQueryDefinitionDTO;
|
||||
import com.sap.sse.datamining.shared.impl.PredefinedQueryIdentifier;
|
||||
@@ -82,6 +81,7 @@ public class Activator extends AbstractDataMiningActivatorWithPredefinedQueries
|
||||
internalClasses.add(HasTrackedLegContext.class);
|
||||
internalClasses.add(HasTrackedLegOfCompetitorContext.class);
|
||||
internalClasses.add(HasGPSFixContext.class);
|
||||
internalClasses.add(HasManeuverContext.class);
|
||||
internalClasses.add(HasMarkPassingContext.class);
|
||||
internalClasses.add(HasRaceOfCompetitorContext.class);
|
||||
internalClasses.add(HasLeaderboardGroupContext.class);
|
||||
@@ -124,9 +124,9 @@ public class Activator extends AbstractDataMiningActivatorWithPredefinedQueries
|
||||
dataSourceProviders = new HashSet<>();
|
||||
dataSourceProviders.add(new RacingEventServiceProvider(context));
|
||||
}
|
||||
|
||||
public static ClusterGroup<Speed> getWindStrengthInBeaufortClusterGroup() {
|
||||
return clusterGroups.getWindStrengthInBeaufortCluster();
|
||||
|
||||
public static SailingClusterGroups getClusterGroups() {
|
||||
return clusterGroups;
|
||||
}
|
||||
|
||||
public static Activator getDefault() {
|
||||
|
||||
+21
-4
@@ -3,6 +3,9 @@ package com.sap.sailing.datamining;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.sap.sailing.datamining.data.ClusterFormatter;
|
||||
import com.sap.sailing.datamining.impl.data.LinearDoubleClusterGroup;
|
||||
import com.sap.sailing.datamining.impl.data.PercentageClusterFormatter;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedImpl;
|
||||
import com.sap.sse.datamining.data.Cluster;
|
||||
@@ -17,7 +20,10 @@ import com.sap.sse.datamining.impl.data.LocalizedCluster;
|
||||
|
||||
public class SailingClusterGroups {
|
||||
|
||||
private final ClusterGroup<Speed> windStrengthInBeaufortCluster;
|
||||
private final ClusterGroup<Speed> windStrengthInBeaufortClusterGroup;
|
||||
|
||||
private final ClusterGroup<Double> percentageClusterGroup;
|
||||
private final ClusterFormatter<Double> percentageClusterFormatter;
|
||||
|
||||
public SailingClusterGroups() {
|
||||
Collection<Cluster<Speed>> clusters = new ArrayList<>();
|
||||
@@ -98,11 +104,22 @@ public class SailingClusterGroups {
|
||||
lowerBound = new ComparableClusterBoundary<Speed>(lowerBoundWindSpeed, ComparisonStrategy.GREATER_EQUALS_THAN);
|
||||
clusters.add(new LocalizedCluster<Speed>("Bft12", new ClusterWithSingleBoundary<Speed>(lowerBound)));
|
||||
|
||||
windStrengthInBeaufortCluster = new FixClusterGroup<Speed>(clusters);
|
||||
windStrengthInBeaufortClusterGroup = new FixClusterGroup<Speed>(clusters);
|
||||
|
||||
percentageClusterGroup = new LinearDoubleClusterGroup(0.0, 1.0, 0.1, true);
|
||||
percentageClusterFormatter = new PercentageClusterFormatter();
|
||||
}
|
||||
|
||||
public ClusterGroup<Speed> getWindStrengthInBeaufortCluster() {
|
||||
return windStrengthInBeaufortCluster;
|
||||
public ClusterGroup<Speed> getWindStrengthInBeaufortClusterGroup() {
|
||||
return windStrengthInBeaufortClusterGroup;
|
||||
}
|
||||
|
||||
public ClusterGroup<Double> getPercentageClusterGroup() {
|
||||
return percentageClusterGroup;
|
||||
}
|
||||
|
||||
public ClusterFormatter<Double> getPercentageClusterFormatter() {
|
||||
return percentageClusterFormatter;
|
||||
}
|
||||
|
||||
}
|
||||
+13
-5
@@ -5,6 +5,7 @@ import java.util.Collection;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasGPSFixContext;
|
||||
import com.sap.sailing.datamining.data.HasLeaderboardContext;
|
||||
import com.sap.sailing.datamining.data.HasManeuverContext;
|
||||
import com.sap.sailing.datamining.data.HasMarkPassingContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasRaceResultOfCompetitorContext;
|
||||
@@ -15,6 +16,7 @@ import com.sap.sailing.datamining.impl.components.CompetitorOfRaceInLeaderboardR
|
||||
import com.sap.sailing.datamining.impl.components.GPSFixRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.LeaderboardGroupRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.LeaderboardRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.ManeuverRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.MarkPassingRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.RaceOfCompetitorRetrievalProcessor;
|
||||
import com.sap.sailing.datamining.impl.components.TrackedLegOfCompetitorRetrievalProcessor;
|
||||
@@ -48,11 +50,6 @@ public class SailingDataRetrievalChainDefinitions {
|
||||
trackedRaceRetrieverChainDefinition.endWith(LeaderboardRetrievalProcessor.class, TrackedRaceRetrievalProcessor.class,
|
||||
HasTrackedRaceContext.class, "Race");
|
||||
dataRetrieverChainDefinitions.add(trackedRaceRetrieverChainDefinition);
|
||||
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasMarkPassingContext> markPassingRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
trackedRaceRetrieverChainDefinition, HasMarkPassingContext.class, "MarkPassingSailingDomainRetrieverChain");
|
||||
markPassingRetrieverChainDefinition.endWith(TrackedRaceRetrievalProcessor.class, MarkPassingRetrievalProcessor.class, HasMarkPassingContext.class, "MarkPassing");
|
||||
dataRetrieverChainDefinitions.add(markPassingRetrieverChainDefinition);
|
||||
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasRaceOfCompetitorContext> raceOfCompetitorRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
trackedRaceRetrieverChainDefinition, HasRaceOfCompetitorContext.class, "RaceOfCompetitorSailingDomainRetrieverChain");
|
||||
@@ -71,6 +68,17 @@ public class SailingDataRetrievalChainDefinitions {
|
||||
gpsFixRetrieverChainDefinition.endWith(TrackedLegOfCompetitorRetrievalProcessor.class, GPSFixRetrievalProcessor.class,
|
||||
HasGPSFixContext.class, "GpsFix");
|
||||
dataRetrieverChainDefinitions.add(gpsFixRetrieverChainDefinition);
|
||||
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasManeuverContext> maneuverRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
legOfCompetitorRetrieverChainDefinition, HasManeuverContext.class, "ManeuverSailingDomainRetrieverChain");
|
||||
maneuverRetrieverChainDefinition.endWith(TrackedLegOfCompetitorRetrievalProcessor.class, ManeuverRetrievalProcessor.class,
|
||||
HasManeuverContext.class, "Maneuver");
|
||||
dataRetrieverChainDefinitions.add(maneuverRetrieverChainDefinition);
|
||||
|
||||
final DataRetrieverChainDefinition<RacingEventService, HasMarkPassingContext> markPassingRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
|
||||
legOfCompetitorRetrieverChainDefinition, HasMarkPassingContext.class, "MarkPassingSailingDomainRetrieverChain");
|
||||
markPassingRetrieverChainDefinition.endWith(TrackedLegOfCompetitorRetrievalProcessor.class, MarkPassingRetrievalProcessor.class, HasMarkPassingContext.class, "MarkPassing");
|
||||
dataRetrieverChainDefinitions.add(markPassingRetrieverChainDefinition);
|
||||
}
|
||||
|
||||
public Iterable<DataRetrieverChainDefinition<?, ?>> get() {
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sse.datamining.data.Cluster;
|
||||
|
||||
// TODO Move to sse bundle, after 49er analysis
|
||||
public interface ClusterFormatter<T extends Serializable> {
|
||||
|
||||
String format(Cluster<T> cluster);
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
|
||||
public interface HasManeuverContext {
|
||||
|
||||
@Connector(scanForStatistics=false)
|
||||
HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext();
|
||||
|
||||
Maneuver getManeuver();
|
||||
|
||||
//TODO Clean-Up:
|
||||
// Move Dimensions and Statistics to Maneuver and connect to it
|
||||
@Dimension(messageKey="ManeuverType", ordinal=12)
|
||||
ManeuverType getManeuverType();
|
||||
|
||||
@Dimension(messageKey="Tack", ordinal=13)
|
||||
Tack getTack();
|
||||
|
||||
@Connector(messageKey="SpeedBefore", ordinal=0)
|
||||
SpeedWithBearing getSpeedBefore();
|
||||
@Connector(messageKey="SpeedAfter", ordinal=1)
|
||||
SpeedWithBearing getSpeedAfter();
|
||||
|
||||
@Statistic(messageKey="DirectionChange", resultDecimals=2, ordinal=2)
|
||||
Double getDirectionChangeInDegrees();
|
||||
|
||||
@Statistic(messageKey="ManeuverLoss", resultDecimals=0, ordinal=3)
|
||||
Distance getManeuverLoss();
|
||||
|
||||
}
|
||||
+32
-16
@@ -1,29 +1,45 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.tracking.MarkPassingManeuver;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
|
||||
public interface HasMarkPassingContext {
|
||||
|
||||
@Connector
|
||||
HasTrackedRaceContext getTrackedRaceContext();
|
||||
@Connector(scanForStatistics=false)
|
||||
HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext();
|
||||
|
||||
MarkPassingManeuver getManeuver();
|
||||
|
||||
//TODO Clean-Up:
|
||||
// Move Dimensions and Statistics to Maneuver/MarkPassingManeuver and connect to it
|
||||
// Find a way to implement HasManeuverContext and HasMarkPassingManeuver with a base class
|
||||
@Dimension(messageKey="Tack", ordinal=12)
|
||||
Tack getTack();
|
||||
|
||||
@Connector(messageKey="Waypoint", ordinal=13)
|
||||
Waypoint getWaypoint();
|
||||
|
||||
@Dimension(messageKey="PassingSide", ordinal=13)
|
||||
NauticalSide getPassingSide();
|
||||
|
||||
@Connector
|
||||
MarkPassing getMarkPassing();
|
||||
@Connector(messageKey="SpeedBefore", ordinal=0)
|
||||
SpeedWithBearing getSpeedBefore();
|
||||
@Connector(messageKey="SpeedAfter", ordinal=1)
|
||||
SpeedWithBearing getSpeedAfter();
|
||||
|
||||
@Connector(messageKey="Competitor")
|
||||
Competitor getCompetitor();
|
||||
@Statistic(messageKey="DirectionChange", resultDecimals=2, ordinal=2)
|
||||
Double getDirectionChangeInDegrees();
|
||||
|
||||
@Connector(messageKey="Speed", ordinal=1)
|
||||
Speed getSpeed();
|
||||
@Statistic(messageKey="RelativeScore", ordinal=3, resultDecimals=2)
|
||||
Double getRelativeRank();
|
||||
|
||||
@Connector(messageKey="SpeedTenSecondsBefore", ordinal=2)
|
||||
Speed getSpeedTenSecondsBefore();
|
||||
@Statistic(messageKey="AbsoluteRank", ordinal=4, resultDecimals=2)
|
||||
Double getAbsoluteRank();
|
||||
|
||||
@Dimension(messageKey="LegType", ordinal=6)
|
||||
String getPreviousLegTypeSignifier() throws NoWindException;
|
||||
}
|
||||
+43
-15
@@ -2,9 +2,13 @@ package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
|
||||
|
||||
public interface HasRaceOfCompetitorContext {
|
||||
|
||||
@@ -14,34 +18,58 @@ public interface HasRaceOfCompetitorContext {
|
||||
@Connector(messageKey="Competitor")
|
||||
public Competitor getCompetitor();
|
||||
|
||||
@Dimension(messageKey="CompetitorSearchTag", ordinal=11) // TODO Clean me: Move Dimension to Competitor when possible
|
||||
public String getCompetitorSearchTag();
|
||||
|
||||
@Dimension(messageKey="TackAtStart", ordinal=12)
|
||||
public Tack getTackAtStart() throws NoWindException;
|
||||
|
||||
@Dimension(messageKey="DistanceToStarboardSideAtStart", ordinal=13)
|
||||
public ClusterDTO getPercentageClusterForDistanceToStarboardSideAtStart();
|
||||
|
||||
@Dimension(messageKey="RelativeScoreInPercent", ordinal=14)
|
||||
public ClusterDTO getPercentageClusterForRelativeScore();
|
||||
|
||||
@Statistic(messageKey="DistanceAtStart", resultDecimals=2, ordinal=0)
|
||||
public Distance getDistanceToStartLineAtStart();
|
||||
|
||||
@Statistic(messageKey="DistanceToStarboardSideAtStart", resultDecimals=2, ordinal=1)
|
||||
public Double getNormalizedDistanceToStarboardSideAtStart();
|
||||
|
||||
@Connector(messageKey="SpeedWhenStarting", ordinal=2)
|
||||
@Statistic(messageKey="WindwardDistanceToAdvantageousEndOfLine", resultDecimals=2, ordinal=2)
|
||||
public Distance getWindwardDistanceToAdvantageousLineEndAtStart();
|
||||
|
||||
@Connector(messageKey="SpeedWhenStarting", ordinal=3)
|
||||
public Speed getSpeedWhenStarting();
|
||||
|
||||
@Connector(messageKey="SpeedTenSecondsBeforeStart", ordinal=3)
|
||||
@Connector(messageKey="SpeedTenSecondsBeforeStart", ordinal=4)
|
||||
public Speed getSpeedTenSecondsBeforeStart();
|
||||
|
||||
@Statistic(messageKey="RankAtFirstMark", resultDecimals=2, ordinal=4)
|
||||
public Double getRankAtFirstMark();
|
||||
@Connector(messageKey="SpeedTenSecondsAfterStart", ordinal=5)
|
||||
public Speed getSpeedTenSecondsAfterStart();
|
||||
|
||||
@Statistic(messageKey="NumberOfManeuvers", resultDecimals=0, ordinal=5)
|
||||
public int getNumberOfManeuvers();
|
||||
|
||||
@Statistic(messageKey="NumberOfTacks", resultDecimals=2, ordinal=6)
|
||||
public int getNumberOfTacks();
|
||||
|
||||
@Statistic(messageKey="NumberOfJibes", resultDecimals=2, ordinal=7)
|
||||
public int getNumberOfJibes();
|
||||
|
||||
@Statistic(messageKey="NumberOfPenaltyCircles", resultDecimals=2, ordinal=8)
|
||||
public int getNumberOfPenaltyCircles();
|
||||
@Statistic(messageKey="RankThirtySecondsAfterStart", resultDecimals=2, ordinal=6)
|
||||
public Double getRankThirtySecondsAfterStart();
|
||||
|
||||
@Statistic(messageKey="RankAfterHalfOfTheFirstLeg", resultDecimals=2, ordinal=7)
|
||||
public Double getRankAfterHalfOfTheFirstLeg();
|
||||
|
||||
@Statistic(messageKey="RankAtFirstMark", resultDecimals=2, ordinal=8)
|
||||
public Double getRankAtFirstMark();
|
||||
|
||||
@Statistic(messageKey="RankGainsOrLossesBetweenFirstMarkAndFinish", resultDecimals=2, ordinal=9)
|
||||
public Double getRankGainsOrLossesBetweenFirstMarkAndFinish();
|
||||
|
||||
@Statistic(messageKey="NumberOfManeuvers", resultDecimals=0, ordinal=10)
|
||||
public int getNumberOfManeuvers();
|
||||
|
||||
@Statistic(messageKey="NumberOfTacks", resultDecimals=2, ordinal=11)
|
||||
public int getNumberOfTacks();
|
||||
|
||||
@Statistic(messageKey="NumberOfJibes", resultDecimals=2, ordinal=12)
|
||||
public int getNumberOfJibes();
|
||||
|
||||
@Statistic(messageKey="NumberOfPenaltyCircles", resultDecimals=2, ordinal=13)
|
||||
public int getNumberOfPenaltyCircles();
|
||||
|
||||
}
|
||||
+17
-11
@@ -12,22 +12,28 @@ public interface HasRaceResultOfCompetitorContext {
|
||||
|
||||
@Connector(messageKey="Competitor")
|
||||
public Competitor getCompetitor();
|
||||
|
||||
/**
|
||||
* 0 means the competitor won the race, 1 means the competitor ranked last
|
||||
*/
|
||||
@Statistic(messageKey="RelativeScoreInRace", ordinal=1, resultDecimals=2)
|
||||
public double getRelativeRank();
|
||||
|
||||
@Dimension(messageKey="WindSpeedInBeaufort")
|
||||
int getAverageWindSpeedInRoundedBeaufort();
|
||||
|
||||
@Dimension(messageKey="Regatta")
|
||||
String getRegattaName();
|
||||
|
||||
@Statistic(messageKey="NumberOfPodiumFinish", ordinal=2)
|
||||
@Dimension(messageKey="CompetitorSearchTag", ordinal=11) // TODO Clean me: Move Dimension to Competitor when possible
|
||||
public String getCompetitorSearchTag();
|
||||
|
||||
@Dimension(messageKey="WindSpeedInBeaufort")
|
||||
int getAverageWindSpeedInRoundedBeaufort();
|
||||
|
||||
/**
|
||||
* 0 means the competitor won the race, 1 means the competitor ranked last
|
||||
*/
|
||||
@Statistic(messageKey="RelativeScore", ordinal=1, resultDecimals=2)
|
||||
public Double getRelativeRank();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRank", ordinal=2, resultDecimals=2)
|
||||
public Double getAbsoluteRank();
|
||||
|
||||
@Statistic(messageKey="NumberOfPodiumFinish", ordinal=3)
|
||||
public Boolean isPodiumFinish();
|
||||
|
||||
@Statistic(messageKey="NumberOfWins", ordinal=3)
|
||||
@Statistic(messageKey="NumberOfWins", ordinal=4)
|
||||
public Boolean isWin();
|
||||
}
|
||||
+17
@@ -4,7 +4,9 @@ import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
import com.sap.sse.datamining.annotations.Statistic;
|
||||
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
|
||||
|
||||
public interface HasTrackedLegOfCompetitorContext {
|
||||
|
||||
@@ -12,6 +14,12 @@ public interface HasTrackedLegOfCompetitorContext {
|
||||
public HasTrackedLegContext getTrackedLegContext();
|
||||
|
||||
public TrackedLegOfCompetitor getTrackedLegOfCompetitor();
|
||||
|
||||
@Dimension(messageKey="CompetitorSearchTag", ordinal=11) // TODO Clean me: Move Dimension to Competitor when possible
|
||||
public String getCompetitorSearchTag();
|
||||
|
||||
@Dimension(messageKey="RelativeScoreInRaceInPercent", ordinal=12)
|
||||
public ClusterDTO getPercentageClusterForRelativeScoreInRace();
|
||||
|
||||
@Connector(messageKey="Competitor")
|
||||
public Competitor getCompetitor();
|
||||
@@ -21,5 +29,14 @@ public interface HasTrackedLegOfCompetitorContext {
|
||||
|
||||
@Statistic(messageKey="RankGainsOrLosses", resultDecimals=2, ordinal=1)
|
||||
public Double getRankGainsOrLosses();
|
||||
|
||||
@Statistic(messageKey="RelativeScore", resultDecimals=2, ordinal=2)
|
||||
public Double getRelativeRank();
|
||||
|
||||
@Statistic(messageKey="AbsoluteRank", resultDecimals=2, ordinal=3)
|
||||
public Double getAbsoluteRank();
|
||||
|
||||
@Statistic(messageKey="TimeSpentInSeconds", resultDecimals=0, ordinal=4)
|
||||
public Long getTimeTakenInSeconds();
|
||||
|
||||
}
|
||||
+14
-1
@@ -1,10 +1,12 @@
|
||||
package com.sap.sailing.datamining.data;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.CourseArea;
|
||||
import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.datamining.annotations.Connector;
|
||||
import com.sap.sse.datamining.annotations.Dimension;
|
||||
@@ -35,7 +37,13 @@ public interface HasTrackedRaceContext {
|
||||
@Dimension(messageKey="Year", ordinal=2)
|
||||
public Integer getYear();
|
||||
|
||||
@Dimension(messageKey="IsTracked", ordinal=6)
|
||||
@Dimension(messageKey="AdvantageousEndOfLine", ordinal=6)
|
||||
public NauticalSide getAdvantageousEndOfLine();
|
||||
|
||||
@Dimension(messageKey="MedalRace", ordinal=7)
|
||||
public Boolean isMedalRace();
|
||||
|
||||
@Dimension(messageKey="IsTracked", ordinal=7)
|
||||
public Boolean isTracked();
|
||||
|
||||
@Statistic(messageKey="NumberOfCompetitorFixes", resultDecimals=0, ordinal=0)
|
||||
@@ -44,4 +52,9 @@ public interface HasTrackedRaceContext {
|
||||
@Statistic(messageKey="NumberOfMarkFixes", resultDecimals=0, ordinal=1)
|
||||
public int getNumberOfMarkFixes();
|
||||
|
||||
// Convenience methods for race dependent calculation to avoid code duplication
|
||||
public Double getRelativeScoreForCompetitor(Competitor competitor);
|
||||
|
||||
public Double getRankAtFinishForCompetitor(Competitor competitor);
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.sap.sailing.datamining.impl.components;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasManeuverContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.impl.data.ManeuverWithContext;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.datamining.components.Processor;
|
||||
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
||||
|
||||
public class ManeuverRetrievalProcessor extends AbstractRetrievalProcessor<HasTrackedLegOfCompetitorContext, HasManeuverContext> {
|
||||
|
||||
public ManeuverRetrievalProcessor(ExecutorService executor, Collection<Processor<HasManeuverContext, ?>> resultReceivers, int retrievalLevel) {
|
||||
super(HasTrackedLegOfCompetitorContext.class, HasManeuverContext.class, executor, resultReceivers, retrievalLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<HasManeuverContext> retrieveData(HasTrackedLegOfCompetitorContext element) {
|
||||
Collection<HasManeuverContext> maneuversWithContext = new ArrayList<>();
|
||||
TimePoint finishTime = element.getTrackedLegOfCompetitor().getFinishTime();
|
||||
if (finishTime != null) {
|
||||
try {
|
||||
List<Maneuver> maneuvers = element.getTrackedLegOfCompetitor().getManeuvers(finishTime, false);
|
||||
for (Maneuver maneuver : maneuvers) {
|
||||
maneuversWithContext.add(new ManeuverWithContext(element, maneuver));
|
||||
}
|
||||
} catch (NoWindException e) {
|
||||
throw new IllegalStateException("No wind retrieving the maneuvers", e);
|
||||
}
|
||||
}
|
||||
return maneuversWithContext;
|
||||
}
|
||||
|
||||
}
|
||||
+23
-24
@@ -1,46 +1,45 @@
|
||||
package com.sap.sailing.datamining.impl.components;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.NavigableSet;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasMarkPassingContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.impl.data.MarkPassingWithContext;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.MarkPassingManeuver;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.datamining.components.Processor;
|
||||
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
|
||||
|
||||
public class MarkPassingRetrievalProcessor extends AbstractRetrievalProcessor<HasTrackedRaceContext, HasMarkPassingContext> {
|
||||
public class MarkPassingRetrievalProcessor extends AbstractRetrievalProcessor<HasTrackedLegOfCompetitorContext, HasMarkPassingContext> {
|
||||
|
||||
public MarkPassingRetrievalProcessor(ExecutorService executor,
|
||||
Collection<Processor<HasMarkPassingContext, ?>> resultReceivers, int retrievalLevel) {
|
||||
super(HasTrackedRaceContext.class, HasMarkPassingContext.class, executor, resultReceivers, retrievalLevel);
|
||||
super(HasTrackedLegOfCompetitorContext.class, HasMarkPassingContext.class, executor, resultReceivers, retrievalLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<HasMarkPassingContext> retrieveData(HasTrackedRaceContext element) {
|
||||
TrackedRace trackedRace = element.getTrackedRace();
|
||||
Set<HasMarkPassingContext> result = new HashSet<>();
|
||||
trackedRace.getRace().getCourse().lockForRead();
|
||||
try {
|
||||
for (Competitor competitor : trackedRace.getRace().getCompetitors()) {
|
||||
NavigableSet<MarkPassing> markPassingsForCompetitor = trackedRace.getMarkPassings(competitor);
|
||||
trackedRace.lockForRead(markPassingsForCompetitor);
|
||||
try {
|
||||
markPassingsForCompetitor.stream().forEach(mp->result.add(new MarkPassingWithContext(element, mp)));
|
||||
} finally {
|
||||
trackedRace.unlockAfterRead(markPassingsForCompetitor);
|
||||
protected Iterable<HasMarkPassingContext> retrieveData(HasTrackedLegOfCompetitorContext element) {
|
||||
Collection<HasMarkPassingContext> maneuversWithContext = new ArrayList<>();
|
||||
TimePoint finishTime = element.getTrackedLegOfCompetitor().getFinishTime();
|
||||
if (finishTime != null) {
|
||||
try {
|
||||
List<Maneuver> maneuvers = element.getTrackedLegOfCompetitor().getManeuvers(finishTime, false);
|
||||
for (Maneuver maneuver : maneuvers) {
|
||||
if (maneuver.getType() == ManeuverType.MARK_PASSING) {
|
||||
maneuversWithContext.add(new MarkPassingWithContext(element, (MarkPassingManeuver) maneuver));
|
||||
}
|
||||
}
|
||||
} catch (NoWindException e) {
|
||||
throw new IllegalStateException("No wind retrieving the mark passings", e);
|
||||
}
|
||||
} finally {
|
||||
trackedRace.getRace().getCourse().unlockAfterRead();
|
||||
}
|
||||
return result;
|
||||
return maneuversWithContext;
|
||||
}
|
||||
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.datamining.data.ClusterFormatter;
|
||||
import com.sap.sse.datamining.data.Cluster;
|
||||
import com.sap.sse.datamining.data.ClusterBoundary;
|
||||
import com.sap.sse.datamining.impl.data.AbstractCluster;
|
||||
import com.sap.sse.datamining.impl.data.AbstractClusterBoundary;
|
||||
import com.sap.sse.datamining.impl.data.ClusterWithLowerAndUpperBoundaries;
|
||||
import com.sap.sse.datamining.impl.data.ClusterWithSingleBoundary;
|
||||
import com.sap.sse.datamining.impl.data.ComparisonStrategy;
|
||||
import com.sap.sse.datamining.impl.data.LocalizedCluster;
|
||||
|
||||
//TODO Clean and move to sse bundle after 49er analysis
|
||||
public abstract class AbstractClusterFormatter<T extends Serializable> implements ClusterFormatter<T> {
|
||||
|
||||
private static final char INFINITE = '\u221e';
|
||||
|
||||
private final ClusterBoundariesAccessor boundariesAccessor = new ClusterBoundariesAccessor();
|
||||
private final BoundaryValueAccessor valueAccessor = new BoundaryValueAccessor();
|
||||
|
||||
@Override
|
||||
public String format(Cluster<T> cluster) {
|
||||
if (cluster instanceof LocalizedCluster) {
|
||||
// TODO recursive call format(localizedCluster.getInnerCluster()) after 49er analysis
|
||||
}
|
||||
if (cluster instanceof ClusterWithSingleBoundary) {
|
||||
return formatClusterWithSingleBoundary((ClusterWithSingleBoundary<T>) cluster);
|
||||
}
|
||||
if (cluster instanceof ClusterWithLowerAndUpperBoundaries) {
|
||||
return formatClusterWithLowerAndUpperBoundaries((ClusterWithLowerAndUpperBoundaries<T>) cluster);
|
||||
}
|
||||
throw new IllegalArgumentException("Can't format clusters of type " + cluster.getClass().getName());
|
||||
}
|
||||
|
||||
protected String formatClusterWithSingleBoundary(ClusterWithSingleBoundary<T> cluster) {
|
||||
List<ClusterBoundary<T>> boundaries = boundariesAccessor.getBoundaries(cluster);
|
||||
if (boundaries == null) {
|
||||
return "<Unformattable>";
|
||||
}
|
||||
|
||||
ClusterBoundary<T> boundary = boundaries.get(0);
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (boundary.getStrategy() == ComparisonStrategy.LOWER_EQUALS_THAN ||
|
||||
boundary.getStrategy() == ComparisonStrategy.LOWER_THAN) {
|
||||
builder.append("-" + INFINITE + " - ");
|
||||
}
|
||||
builder.append(formatBoundary(boundary));
|
||||
if (boundary.getStrategy() == ComparisonStrategy.GREATER_EQUALS_THAN ||
|
||||
boundary.getStrategy() == ComparisonStrategy.GREATER_THAN) {
|
||||
builder.append(" - " + INFINITE);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
protected String formatClusterWithLowerAndUpperBoundaries(ClusterWithLowerAndUpperBoundaries<T> cluster) {
|
||||
List<ClusterBoundary<T>> boundaries = boundariesAccessor.getBoundaries(cluster);
|
||||
if (boundaries == null) {
|
||||
return "<Unformattable>";
|
||||
}
|
||||
|
||||
return String.format("%s - %s", formatBoundary(boundaries.get(0)), formatBoundary(boundaries.get(1)));
|
||||
}
|
||||
|
||||
protected String formatBoundary(ClusterBoundary<T> boundary) {
|
||||
String value = formatValue(valueAccessor.getValue((AbstractClusterBoundary<T>) boundary));
|
||||
if (value == null) {
|
||||
return "<Unformattable>";
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
ComparisonStrategy strategy = boundary.getStrategy();
|
||||
if (strategy == ComparisonStrategy.GREATER_EQUALS_THAN || strategy == ComparisonStrategy.GREATER_THAN) {
|
||||
builder.append(strategy.getSignifier());
|
||||
}
|
||||
builder.append(value);
|
||||
if (strategy == ComparisonStrategy.LOWER_EQUALS_THAN || strategy == ComparisonStrategy.LOWER_THAN) {
|
||||
builder.append(strategy.getSignifier());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
protected abstract String formatValue(T value);
|
||||
|
||||
//FIXME Please delete me
|
||||
private class ClusterBoundariesAccessor {
|
||||
|
||||
private static final String boundariesFieldName = "boundaries";
|
||||
|
||||
public List<ClusterBoundary<T>> getBoundaries(AbstractCluster<T> cluster) {
|
||||
List<ClusterBoundary<T>> boundaries = null;
|
||||
Field boundariesField = null;
|
||||
try {
|
||||
boundariesField = AbstractCluster.class.getDeclaredField(boundariesFieldName);
|
||||
boundariesField.setAccessible(true);
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<ClusterBoundary<T>> reflectedBoundaries = (Collection<ClusterBoundary<T>>) boundariesField.get(cluster);
|
||||
boundaries = new ArrayList<>();
|
||||
for (ClusterBoundary<T> boundary : reflectedBoundaries) {
|
||||
boundaries.add(boundary);
|
||||
}
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
} finally {
|
||||
if (boundariesField != null) {
|
||||
boundariesField.setAccessible(false);
|
||||
}
|
||||
}
|
||||
return boundaries;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//FIXME Please delete me
|
||||
private class BoundaryValueAccessor {
|
||||
|
||||
private static final String valueFieldName = "boundaryValue";
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T getValue(AbstractClusterBoundary<T> boundary) {
|
||||
T value = null;
|
||||
Field valueField = null;
|
||||
try {
|
||||
valueField = AbstractClusterBoundary.class.getDeclaredField(valueFieldName);
|
||||
valueField.setAccessible(true);
|
||||
value = (T) valueField.get(boundary);
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
|
||||
} finally {
|
||||
if (valueField != null) {
|
||||
valueField.setAccessible(false);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -36,7 +36,7 @@ public class GPSFixWithContext implements HasGPSFixContext {
|
||||
@Override
|
||||
public ClusterDTO getWindStrengthAsBeaufortCluster(Locale locale, ResourceBundleStringMessages stringMessages) {
|
||||
Wind wind = getWind();
|
||||
Cluster<?> cluster = Activator.getWindStrengthInBeaufortClusterGroup().getClusterFor(wind);
|
||||
Cluster<?> cluster = Activator.getClusterGroups().getWindStrengthInBeaufortClusterGroup().getClusterFor(wind);
|
||||
return new ClusterDTO(cluster.asLocalizedString(locale, stringMessages));
|
||||
}
|
||||
|
||||
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sse.datamining.data.Cluster;
|
||||
import com.sap.sse.datamining.data.ClusterGroup;
|
||||
import com.sap.sse.datamining.impl.data.ClusterWithLowerAndUpperBoundaries;
|
||||
import com.sap.sse.datamining.impl.data.ClusterWithSingleBoundary;
|
||||
import com.sap.sse.datamining.impl.data.ComparableClusterBoundary;
|
||||
import com.sap.sse.datamining.impl.data.ComparisonStrategy;
|
||||
|
||||
// TODO: Improve and move to com.sap.sse.datamining
|
||||
public class LinearDoubleClusterGroup implements ClusterGroup<Double> {
|
||||
private static final long serialVersionUID = 1559316450183865115L;
|
||||
|
||||
private final double lowerBound;
|
||||
private final double upperBound;
|
||||
private final double stepSize;
|
||||
private final boolean hardBounds;
|
||||
|
||||
private final transient Map<Integer, Cluster<Double>> clusterCache;
|
||||
private final int lastClusterIndex;
|
||||
|
||||
public LinearDoubleClusterGroup(double lowerBound, double upperBound, double stepSize, boolean hardBounds) {
|
||||
this.lowerBound = lowerBound;
|
||||
this.upperBound = upperBound;
|
||||
this.stepSize = stepSize;
|
||||
this.hardBounds = hardBounds;
|
||||
|
||||
clusterCache = new HashMap<>();
|
||||
lastClusterIndex = calculateLastClusterIndex(this.upperBound, this.stepSize);
|
||||
}
|
||||
|
||||
private static int calculateLastClusterIndex(double upperBound, double stepSize) {
|
||||
double doubleIndex = upperBound / stepSize;
|
||||
int index = (int) doubleIndex;
|
||||
double fractionalPart = doubleIndex - index;
|
||||
if (fractionalPart <= 0.0001) {
|
||||
index--;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cluster<Double> getClusterFor(Double valueObject) {
|
||||
double value = valueObject.doubleValue();
|
||||
if (value < lowerBound) {
|
||||
return hardBounds ? null : getCluster(0);
|
||||
}
|
||||
if (value > upperBound) {
|
||||
return hardBounds ? null : getCluster(lastClusterIndex);
|
||||
}
|
||||
|
||||
if (Math.abs(upperBound - value) < 0.0001) {
|
||||
return getCluster(lastClusterIndex);
|
||||
}
|
||||
return getCluster((int) (value / stepSize));
|
||||
}
|
||||
|
||||
private Cluster<Double> getCluster(int index) {
|
||||
if (!clusterCache.containsKey(index)) {
|
||||
clusterCache.put(index, createCluster(index));
|
||||
}
|
||||
return clusterCache.get(index);
|
||||
}
|
||||
|
||||
private Cluster<Double> createCluster(int index) {
|
||||
if (index == 0 && !hardBounds) {
|
||||
return new ClusterWithSingleBoundary<>(createUpperBound(index, ComparisonStrategy.LOWER_THAN));
|
||||
}
|
||||
if (index == lastClusterIndex && !hardBounds) {
|
||||
return new ClusterWithSingleBoundary<>(createLowerBound(index, ComparisonStrategy.GREATER_EQUALS_THAN));
|
||||
}
|
||||
|
||||
ComparisonStrategy upperComparisonStrategy = index == lastClusterIndex ? ComparisonStrategy.LOWER_EQUALS_THAN : ComparisonStrategy.LOWER_THAN;
|
||||
return new ClusterWithLowerAndUpperBoundaries<>(createLowerBound(index, ComparisonStrategy.GREATER_EQUALS_THAN),
|
||||
createUpperBound(index, upperComparisonStrategy));
|
||||
}
|
||||
|
||||
private ComparableClusterBoundary<Double> createLowerBound(int index, ComparisonStrategy comparisonStrategy) {
|
||||
return new ComparableClusterBoundary<Double>(this.lowerBound + stepSize * index, comparisonStrategy);
|
||||
}
|
||||
|
||||
private ComparableClusterBoundary<Double> createUpperBound(int index, ComparisonStrategy comparisonStrategy) {
|
||||
return new ComparableClusterBoundary<Double>(this.lowerBound + stepSize * (index + 1.0), comparisonStrategy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Double> getClusterElementsType() {
|
||||
return Double.class;
|
||||
}
|
||||
|
||||
public double getLowerGroupBound() {
|
||||
return lowerBound;
|
||||
}
|
||||
|
||||
public double getUpperGroupBound() {
|
||||
return upperBound;
|
||||
}
|
||||
|
||||
public double getStepSize() {
|
||||
return stepSize;
|
||||
}
|
||||
|
||||
public boolean isHardBounds() {
|
||||
return hardBounds;
|
||||
}
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasManeuverContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
|
||||
public class ManeuverWithContext implements HasManeuverContext {
|
||||
|
||||
private final HasTrackedLegOfCompetitorContext trackedLegOfCompetitor;
|
||||
private final Maneuver maneuver;
|
||||
|
||||
public ManeuverWithContext(HasTrackedLegOfCompetitorContext trackedLegOfCompetitor, Maneuver maneuver) {
|
||||
this.trackedLegOfCompetitor = trackedLegOfCompetitor;
|
||||
this.maneuver = maneuver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext() {
|
||||
return trackedLegOfCompetitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Maneuver getManeuver() {
|
||||
return maneuver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManeuverType getManeuverType() {
|
||||
return getManeuver().getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tack getTack() {
|
||||
return getManeuver().getNewTack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpeedWithBearing getSpeedBefore() {
|
||||
return getManeuver().getSpeedWithBearingBefore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpeedWithBearing getSpeedAfter() {
|
||||
return getManeuver().getSpeedWithBearingAfter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getDirectionChangeInDegrees() {
|
||||
return getManeuver().getDirectionChangeInDegrees();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getManeuverLoss() {
|
||||
return getManeuver().getManeuverLoss();
|
||||
}
|
||||
|
||||
}
|
||||
+62
-49
@@ -1,74 +1,87 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import com.sap.sailing.datamining.data.HasMarkPassingContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.tracking.MarkPassing;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.tracking.MarkPassingManeuver;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class MarkPassingWithContext implements HasMarkPassingContext {
|
||||
private final HasTrackedRaceContext trackedRaceContext;
|
||||
private final MarkPassing markPassing;
|
||||
|
||||
public MarkPassingWithContext(HasTrackedRaceContext trackedRaceContext, MarkPassing markPassing) {
|
||||
super();
|
||||
this.trackedRaceContext = trackedRaceContext;
|
||||
this.markPassing = markPassing;
|
||||
private final HasTrackedLegOfCompetitorContext trackedLegOfCompetitor;
|
||||
private final MarkPassingManeuver maneuver;
|
||||
|
||||
private Double absoluteRank;
|
||||
private boolean rankHasBeenInitialized;
|
||||
|
||||
public MarkPassingWithContext(HasTrackedLegOfCompetitorContext trackedLegOfCompetitor, MarkPassingManeuver maneuver) {
|
||||
this.trackedLegOfCompetitor = trackedLegOfCompetitor;
|
||||
this.maneuver = maneuver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HasTrackedRaceContext getTrackedRaceContext() {
|
||||
return trackedRaceContext;
|
||||
public HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext() {
|
||||
return trackedLegOfCompetitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MarkPassing getMarkPassing() {
|
||||
return markPassing;
|
||||
public MarkPassingManeuver getManeuver() {
|
||||
return maneuver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Competitor getCompetitor() {
|
||||
return markPassing.getCompetitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getSpeed() {
|
||||
return getTrackedRace().getTrack(getCompetitor()).getEstimatedSpeed(getMarkPassing().getTimePoint());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getSpeedTenSecondsBefore() {
|
||||
return getTrackedRace().getTrack(getCompetitor()).getEstimatedSpeed(getMarkPassing().getTimePoint().minus(10000 /* ms */));
|
||||
}
|
||||
|
||||
private TrackedRace getTrackedRace() {
|
||||
return trackedRaceContext.getTrackedRace();
|
||||
public Tack getTack() {
|
||||
return getManeuver().getNewTack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreviousLegTypeSignifier() throws NoWindException {
|
||||
final String result;
|
||||
TrackedLeg previousLeg = getPreviousLeg();
|
||||
if (previousLeg == null) {
|
||||
result = "Start";
|
||||
} else {
|
||||
result = previousLeg.getLegType(getMarkPassing().getTimePoint()).toString();
|
||||
}
|
||||
return result;
|
||||
public Waypoint getWaypoint() {
|
||||
return getManeuver().getWaypointPassed();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NauticalSide getPassingSide() {
|
||||
return getManeuver().getSide();
|
||||
}
|
||||
|
||||
private TrackedLeg getPreviousLeg() {
|
||||
final TrackedLeg result;
|
||||
Waypoint waypoint = markPassing.getWaypoint();
|
||||
if (waypoint == getTrackedRace().getRace().getCourse().getFirstWaypoint()) {
|
||||
result = null;
|
||||
} else {
|
||||
result = getTrackedRace().getTrackedLegFinishingAt(waypoint);
|
||||
}
|
||||
return result;
|
||||
@Override
|
||||
public SpeedWithBearing getSpeedBefore() {
|
||||
return getManeuver().getSpeedWithBearingBefore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpeedWithBearing getSpeedAfter() {
|
||||
return getManeuver().getSpeedWithBearingAfter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getDirectionChangeInDegrees() {
|
||||
return getManeuver().getDirectionChangeInDegrees();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRelativeRank() {
|
||||
Leaderboard leaderboard = getTrackedLegOfCompetitorContext().getTrackedLegContext().getTrackedRaceContext().getLeaderboardContext().getLeaderboard();
|
||||
double competitorCount = Util.size(leaderboard.getCompetitors());
|
||||
return getAbsoluteRank() == null ? null : getAbsoluteRank() / competitorCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getAbsoluteRank() {
|
||||
if (!rankHasBeenInitialized) {
|
||||
TrackedRace trackedRace = getTrackedLegOfCompetitorContext().getTrackedLegContext().getTrackedRaceContext().getTrackedRace();
|
||||
Competitor competitor = getTrackedLegOfCompetitorContext().getCompetitor();
|
||||
int rank = trackedRace.getRank(competitor, getManeuver().getTimePoint());
|
||||
absoluteRank = rank == 0 ? null : Double.valueOf(rank);
|
||||
rankHasBeenInitialized = true;
|
||||
}
|
||||
return absoluteRank;
|
||||
}
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
public class PercentageClusterFormatter extends AbstractClusterFormatter<Double> {
|
||||
|
||||
@Override
|
||||
protected String formatValue(Double value) {
|
||||
return (int) (value * 100) + "%";
|
||||
}
|
||||
|
||||
}
|
||||
+135
-22
@@ -2,18 +2,32 @@ package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.sap.sailing.datamining.Activator;
|
||||
import com.sap.sailing.datamining.SailingClusterGroups;
|
||||
import com.sap.sailing.datamining.data.HasRaceOfCompetitorContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.base.Course;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.Waypoint;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Speed;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.LineDetails;
|
||||
import com.sap.sailing.domain.tracking.Maneuver;
|
||||
import com.sap.sailing.domain.tracking.TrackedLeg;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.WindPositionMode;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.datamining.data.Cluster;
|
||||
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
|
||||
|
||||
public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext {
|
||||
|
||||
@@ -38,12 +52,89 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext {
|
||||
public Competitor getCompetitor() {
|
||||
return competitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCompetitorSearchTag() {
|
||||
return getCompetitor().getSearchTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tack getTackAtStart() throws NoWindException {
|
||||
TimePoint startOfRace = getTrackedRace().getStartOfRace();
|
||||
return startOfRace == null ? null : getTrackedRace().getTack(getCompetitor(), startOfRace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClusterDTO getPercentageClusterForDistanceToStarboardSideAtStart() {
|
||||
Double normalizedDistance = getNormalizedDistanceToStarboardSideAtStart();
|
||||
if (normalizedDistance == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SailingClusterGroups clusterGroups = Activator.getClusterGroups();
|
||||
Cluster<Double> cluster = clusterGroups.getPercentageClusterGroup().getClusterFor(normalizedDistance);
|
||||
return new ClusterDTO(clusterGroups.getPercentageClusterFormatter().format(cluster));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getDistanceToStartLineAtStart() {
|
||||
return getTrackedRace().getDistanceToStartLine(getCompetitor(), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getNormalizedDistanceToStarboardSideAtStart() {
|
||||
TrackedRace trackedRace = getTrackedRace();
|
||||
TrackedLegOfCompetitor firstTrackedLegOfCompetitor = trackedRace.getTrackedLeg(competitor, trackedRace.getRace().getCourse().getFirstLeg());
|
||||
TimePoint competitorStartTime = firstTrackedLegOfCompetitor.getStartTime();
|
||||
if (competitorStartTime == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Double distance = trackedRace.getDistanceFromStarboardSideOfStartLine(getCompetitor(), competitorStartTime).getMeters();
|
||||
Double length = trackedRace.getStartLine(competitorStartTime).getLength().getMeters();
|
||||
return distance / length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getWindwardDistanceToAdvantageousLineEndAtStart() {
|
||||
TrackedRace trackedRace = getTrackedRace();
|
||||
TimePoint startOfRace = trackedRace.getStartOfRace();
|
||||
LineDetails startLine = trackedRace.getStartLine(startOfRace);
|
||||
Mark advantageousMark = null;
|
||||
switch (startLine.getAdvantageousSideWhileApproachingLine()) {
|
||||
case PORT:
|
||||
advantageousMark = startLine.getPortMarkWhileApproachingLine();
|
||||
break;
|
||||
case STARBOARD:
|
||||
advantageousMark = startLine.getStarboardMarkWhileApproachingLine();
|
||||
break;
|
||||
}
|
||||
if (advantageousMark == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
GPSFixTrack<Mark, GPSFix> advantageousMarkTrack = trackedRace.getOrCreateTrack(advantageousMark);
|
||||
Position advantageousMarkPosition = advantageousMarkTrack.getEstimatedPosition(startOfRace, false);
|
||||
GPSFixTrack<Competitor, GPSFixMoving> competitorTrack = trackedRace.getTrack(getCompetitor());
|
||||
Position competitorPosition = competitorTrack.getEstimatedPosition(startOfRace, false);
|
||||
|
||||
TrackedLeg trackedLeg = trackedRace.getTrackedLeg(trackedRace.getRace().getCourse().getFirstLeg());
|
||||
Distance distance = trackedLeg.getWindwardDistance(competitorPosition, advantageousMarkPosition, startOfRace, WindPositionMode.LEG_MIDDLE);
|
||||
return distance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClusterDTO getPercentageClusterForRelativeScore() {
|
||||
Double relativeScore = getTrackedRaceContext().getRelativeScoreForCompetitor(getCompetitor());
|
||||
if (relativeScore == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SailingClusterGroups clusterGroups = Activator.getClusterGroups();
|
||||
Cluster<Double> cluster = clusterGroups.getPercentageClusterGroup().getClusterFor(relativeScore);
|
||||
return new ClusterDTO(clusterGroups.getPercentageClusterFormatter().format(cluster));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getSpeedWhenStarting() {
|
||||
return getTrackedRace().getSpeedWhenCrossingStartLine(getCompetitor());
|
||||
@@ -54,14 +145,57 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext {
|
||||
return getTrackedRace().getSpeed(getCompetitor(), TimeUnit.SECONDS.toMillis(10));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Speed getSpeedTenSecondsAfterStart() {
|
||||
TimePoint startOfRace = getTrackedRace().getStartOfRace();
|
||||
if (startOfRace == null) {
|
||||
return null;
|
||||
}
|
||||
return getTrackedRace().getTrack(getCompetitor()).getEstimatedSpeed(startOfRace.plus(TimeUnit.SECONDS.toMillis(10)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRankThirtySecondsAfterStart() {
|
||||
TimePoint startOfRace = getTrackedRace().getStartOfRace();
|
||||
if (startOfRace == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int rank = getTrackedRace().getRank(getCompetitor(), startOfRace.plus(TimeUnit.SECONDS.toMillis(30)));
|
||||
return rank == 0 ? null : Double.valueOf(rank);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRankAfterHalfOfTheFirstLeg() {
|
||||
Course course = getTrackedRace().getRace().getCourse();
|
||||
TrackedLegOfCompetitor trackedLeg = getTrackedRace().getTrackedLeg(getCompetitor(), course.getFirstLeg());
|
||||
TimePoint startTime = trackedLeg.getStartTime();
|
||||
TimePoint finishTime = trackedLeg.getFinishTime();
|
||||
if (startTime == null || finishTime == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
long halfOffset = (finishTime.asMillis() - startTime.asMillis()) / 2;
|
||||
int rank = getTrackedRace().getRank(getCompetitor(), startTime.plus(halfOffset));
|
||||
return rank == 0 ? null : Double.valueOf(rank);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRankAtFirstMark() {
|
||||
Course course = getTrackedRace().getRace().getCourse();
|
||||
Waypoint firstMark = course.getFirstLeg().getTo();
|
||||
Competitor competitor = getCompetitor();
|
||||
return Double.valueOf(getTrackedRace().getRank(competitor, getTrackedRace().getMarkPassing(competitor, firstMark).getTimePoint()));
|
||||
int rank = getTrackedRace().getRank(competitor, getTrackedRace().getMarkPassing(competitor, firstMark).getTimePoint());
|
||||
return rank == 0 ? null : Double.valueOf(rank);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRankGainsOrLossesBetweenFirstMarkAndFinish() {
|
||||
Double rankAtFirstMark = getRankAtFirstMark();
|
||||
Double rankAtFinish = getTrackedRaceContext().getRankAtFinishForCompetitor(getCompetitor());
|
||||
return rankAtFirstMark != null && rankAtFinish != null ? rankAtFirstMark - rankAtFinish : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumberOfManeuvers() {
|
||||
return getNumberOfTacks() + getNumberOfJibes();
|
||||
@@ -92,26 +226,5 @@ public class RaceOfCompetitorWithContext implements HasRaceOfCompetitorContext {
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRankGainsOrLossesBetweenFirstMarkAndFinish() {
|
||||
Double rankAtFirstMark = getRankAtFirstMark();
|
||||
Double rankAtFinish = getRankAtFinish();
|
||||
return rankAtFirstMark - rankAtFinish;
|
||||
}
|
||||
|
||||
private Double getRankAtFinish() {
|
||||
return Double.valueOf(getTrackedRace().getRank(getCompetitor(), getTrackedRace().getEndOfTracking()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getNormalizedDistanceToStarboardSideAtStart() {
|
||||
TrackedRace trackedRace = getTrackedRace();
|
||||
TrackedLegOfCompetitor firstTrackedLegOfCompetitor = trackedRace.getTrackedLeg(competitor, trackedRace.getRace().getCourse().getFirstLeg());
|
||||
TimePoint competitorStartTime = firstTrackedLegOfCompetitor.getStartTime();
|
||||
Double distance = trackedRace.getDistanceFromStarboardSideOfStartLine(getCompetitor(), competitorStartTime).getMeters();
|
||||
Double length = trackedRace.getStartLine(competitorStartTime).getLength().getMeters();
|
||||
return distance / length;
|
||||
}
|
||||
|
||||
}
|
||||
+25
-12
@@ -62,17 +62,17 @@ public class RaceResultOfCompetitorWithContext implements HasRaceResultOfCompeti
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRelativeRank() {
|
||||
Leaderboard leaderboard = getLeaderboard();
|
||||
final TimePoint now = MillisecondsTimePoint.now();
|
||||
double competitorCount = Util.size(leaderboard.getCompetitors());
|
||||
double points = leaderboard.getTotalPoints(competitor, raceColumn, now);
|
||||
double relativeLowPoints = leaderboard.getScoringScheme().isHigherBetter() ?
|
||||
competitorCount - points : points;
|
||||
final double result = relativeLowPoints / competitorCount;
|
||||
public String getRegattaName() {
|
||||
Leaderboard leaderboard = getLeaderboard();;
|
||||
final String result = leaderboard.getName();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCompetitorSearchTag() {
|
||||
return getCompetitor().getSearchTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAverageWindSpeedInRoundedBeaufort() {
|
||||
Speed exactResult = getAverageWindSpeed();
|
||||
@@ -157,10 +157,23 @@ public class RaceResultOfCompetitorWithContext implements HasRaceResultOfCompeti
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRegattaName() {
|
||||
Leaderboard leaderboard = getLeaderboard();;
|
||||
final String result = leaderboard.getName();
|
||||
return result;
|
||||
public Double getRelativeRank() {
|
||||
Leaderboard leaderboard = getLeaderboard();
|
||||
final TimePoint now = MillisecondsTimePoint.now();
|
||||
double competitorCount = Util.size(leaderboard.getCompetitors());
|
||||
Double points = leaderboard.getTotalPoints(competitor, raceColumn, now);
|
||||
if (points != null) {
|
||||
double relativeLowPoints = leaderboard.getScoringScheme().isHigherBetter() ? competitorCount - points
|
||||
: points;
|
||||
final double result = relativeLowPoints / competitorCount;
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getAbsoluteRank() {
|
||||
return getLeaderboard().getTotalPoints(competitor, raceColumn, MillisecondsTimePoint.now());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+75
-4
@@ -1,12 +1,18 @@
|
||||
package com.sap.sailing.datamining.impl.data;
|
||||
|
||||
import com.sap.sailing.datamining.Activator;
|
||||
import com.sap.sailing.datamining.SailingClusterGroups;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegContext;
|
||||
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
|
||||
import com.sap.sailing.domain.base.Competitor;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.leaderboard.Leaderboard;
|
||||
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.datamining.data.Cluster;
|
||||
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
|
||||
|
||||
public class TrackedLegOfCompetitorWithContext implements HasTrackedLegOfCompetitorContext {
|
||||
|
||||
@@ -15,6 +21,11 @@ public class TrackedLegOfCompetitorWithContext implements HasTrackedLegOfCompeti
|
||||
private final TrackedLegOfCompetitor trackedLegOfCompetitor;
|
||||
private final Competitor competitor;
|
||||
|
||||
private Double rankAtStart;
|
||||
private boolean isRankAtStartInitialized;
|
||||
private Double rankAtFinish;
|
||||
private boolean isRankAtFinishInitialized;
|
||||
|
||||
public TrackedLegOfCompetitorWithContext(HasTrackedLegContext trackedLegContext, TrackedLegOfCompetitor trackedLegOfCompetitor) {
|
||||
this.trackedLegContext = trackedLegContext;
|
||||
this.trackedLegOfCompetitor = trackedLegOfCompetitor;
|
||||
@@ -35,6 +46,23 @@ public class TrackedLegOfCompetitorWithContext implements HasTrackedLegOfCompeti
|
||||
public Competitor getCompetitor() {
|
||||
return competitor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCompetitorSearchTag() {
|
||||
return getCompetitor().getSearchTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClusterDTO getPercentageClusterForRelativeScoreInRace() {
|
||||
Double relativeScore = getTrackedLegContext().getTrackedRaceContext().getRelativeScoreForCompetitor(getCompetitor());
|
||||
if (relativeScore == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SailingClusterGroups clusterGroups = Activator.getClusterGroups();
|
||||
Cluster<Double> cluster = clusterGroups.getPercentageClusterGroup().getClusterFor(relativeScore);
|
||||
return new ClusterDTO(clusterGroups.getPercentageClusterFormatter().format(cluster));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getDistanceTraveled() {
|
||||
@@ -44,10 +72,53 @@ public class TrackedLegOfCompetitorWithContext implements HasTrackedLegOfCompeti
|
||||
|
||||
@Override
|
||||
public Double getRankGainsOrLosses() {
|
||||
TrackedRace trackedRace = getTrackedLegContext().getTrackedRaceContext().getTrackedRace();
|
||||
Double rankAtStart = Double.valueOf(trackedRace.getRank(getCompetitor(), getTrackedLegOfCompetitor().getStartTime()));
|
||||
Double rankAtFinish = Double.valueOf(trackedRace.getRank(getCompetitor(), getTrackedLegOfCompetitor().getFinishTime()));
|
||||
return rankAtStart - rankAtFinish;
|
||||
Double rankAtStart = getRankAtStart();
|
||||
Double rankAtFinish = getRankAtFinish();
|
||||
return rankAtStart != null && rankAtFinish != null ? rankAtStart - rankAtFinish : null;
|
||||
}
|
||||
|
||||
private Double getRankAtStart() {
|
||||
if (!isRankAtStartInitialized) {
|
||||
TrackedRace trackedRace = getTrackedLegContext().getTrackedRaceContext().getTrackedRace();
|
||||
int rank = trackedRace.getRank(getCompetitor(), getTrackedLegOfCompetitor().getStartTime());
|
||||
rankAtStart = rank == 0 ? null : Double.valueOf(rank);
|
||||
isRankAtStartInitialized = true;
|
||||
}
|
||||
return rankAtStart;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRelativeRank() {
|
||||
Leaderboard leaderboard = getTrackedLegContext().getTrackedRaceContext().getLeaderboardContext().getLeaderboard();
|
||||
double competitorCount = Util.size(leaderboard.getCompetitors());
|
||||
Double rankAtFinish = getRankAtFinish();
|
||||
return rankAtFinish == null ? null : rankAtFinish / competitorCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getAbsoluteRank() {
|
||||
return getRankAtFinish();
|
||||
}
|
||||
|
||||
private Double getRankAtFinish() {
|
||||
if (!isRankAtFinishInitialized) {
|
||||
TrackedRace trackedRace = getTrackedLegContext().getTrackedRaceContext().getTrackedRace();
|
||||
int rank = trackedRace.getRank(getCompetitor(), getTrackedLegOfCompetitor().getFinishTime());
|
||||
rankAtFinish = rank == 0 ? null : Double.valueOf(rank);
|
||||
isRankAtFinishInitialized = true;
|
||||
}
|
||||
return rankAtFinish;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getTimeTakenInSeconds() {
|
||||
TimePoint startTime = getTrackedLegOfCompetitor().getStartTime();
|
||||
TimePoint finishTime = getTrackedLegOfCompetitor().getFinishTime();
|
||||
if (startTime == null || finishTime == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (finishTime.asMillis() - startTime.asMillis()) / 1000;
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -11,9 +11,11 @@ import com.sap.sailing.domain.base.Fleet;
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.base.RaceDefinition;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.LineDetails;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
@@ -90,6 +92,17 @@ public class TrackedRaceWithContext implements HasTrackedRaceContext {
|
||||
calendar.setTime(time.asDate());
|
||||
return calendar.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NauticalSide getAdvantageousEndOfLine() {
|
||||
LineDetails startLine = getTrackedRace().getStartLine(getTrackedRace().getStartOfRace());
|
||||
return startLine.getAdvantageousSideWhileApproachingLine();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isMedalRace() {
|
||||
return getLeaderboardContext().getLeaderboard().getRaceColumnAndFleet(getTrackedRace()).getA().isMedalRace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isTracked() {
|
||||
@@ -125,5 +138,20 @@ public class TrackedRaceWithContext implements HasTrackedRaceContext {
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
// Convenience methods for race dependent calculation to avoid code duplication
|
||||
public Double getRelativeScoreForCompetitor(Competitor competitor) {
|
||||
Double rankAtFinish = getRankAtFinishForCompetitor(competitor);
|
||||
if (rankAtFinish == null) {
|
||||
return null;
|
||||
}
|
||||
return rankAtFinish / Util.size(getTrackedRace().getRace().getCompetitors());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRankAtFinishForCompetitor(Competitor competitor) {
|
||||
int rank = getTrackedRace().getRank(competitor, getTrackedRace().getEndOfTracking());
|
||||
return rank == 0 ? null : Double.valueOf(rank);
|
||||
}
|
||||
|
||||
}
|
||||
+10
-10
@@ -113,20 +113,20 @@ public enum BoatClassMasterdata {
|
||||
|
||||
private final String displayName;
|
||||
private final String[] alternativeNames;
|
||||
private final double hullLengthInMeter;
|
||||
private final double hullBeamInMeter;
|
||||
private final double hullLengthInMeters;
|
||||
private final double hullBeamInMeters;
|
||||
private final BoatHullType hullType;
|
||||
private final boolean typicallyStartsUpwind;
|
||||
private final boolean hasAdditionalDownwindSail;
|
||||
|
||||
private static Map<String, BoatClassMasterdata> fromUnifiedDisplayAndAlternativeNamesToBoatClassMasterdata;
|
||||
|
||||
private BoatClassMasterdata(String displayName, boolean typicallyStartsUpwind, double hullLengthInMeter,
|
||||
double hullBeamInMeter, BoatHullType hullType, boolean hasAdditionalDownwindSail, String... alternativeNames) {
|
||||
private BoatClassMasterdata(String displayName, boolean typicallyStartsUpwind, double hullLengthInMeters,
|
||||
double hullBeamInMeters, BoatHullType hullType, boolean hasAdditionalDownwindSail, String... alternativeNames) {
|
||||
this.displayName = displayName;
|
||||
this.typicallyStartsUpwind = typicallyStartsUpwind;
|
||||
this.hullLengthInMeter = hullLengthInMeter;
|
||||
this.hullBeamInMeter = hullBeamInMeter;
|
||||
this.hullLengthInMeters = hullLengthInMeters;
|
||||
this.hullBeamInMeters = hullBeamInMeters;
|
||||
this.hullType = hullType;
|
||||
this.hasAdditionalDownwindSail = hasAdditionalDownwindSail;
|
||||
this.alternativeNames = alternativeNames;
|
||||
@@ -147,8 +147,8 @@ public enum BoatClassMasterdata {
|
||||
double hullBeamInMeter, BoatHullType hullType, boolean hasAdditionalDownwindSail) {
|
||||
this.displayName = displayName;
|
||||
this.typicallyStartsUpwind = typicallyStartsUpwind;
|
||||
this.hullLengthInMeter = hullLengthInMeter;
|
||||
this.hullBeamInMeter = hullBeamInMeter;
|
||||
this.hullLengthInMeters = hullLengthInMeter;
|
||||
this.hullBeamInMeters = hullBeamInMeter;
|
||||
this.hullType = hullType;
|
||||
this.hasAdditionalDownwindSail = hasAdditionalDownwindSail;
|
||||
this.alternativeNames = null;
|
||||
@@ -192,7 +192,7 @@ public enum BoatClassMasterdata {
|
||||
}
|
||||
|
||||
public Distance getHullLength() {
|
||||
return new MeterDistance(hullLengthInMeter);
|
||||
return new MeterDistance(hullLengthInMeters);
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
@@ -204,7 +204,7 @@ public enum BoatClassMasterdata {
|
||||
}
|
||||
|
||||
public Distance getHullBeam() {
|
||||
return new MeterDistance(hullBeamInMeter);
|
||||
return new MeterDistance(hullBeamInMeters);
|
||||
}
|
||||
|
||||
public BoatHullType getHullType() {
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.sap.sse.common.Duration;
|
||||
*
|
||||
*/
|
||||
public interface Distance extends Comparable<Distance>, Serializable {
|
||||
static final Distance NULL = new Distance() {
|
||||
static class NullDistance implements Distance {
|
||||
private static final long serialVersionUID = -3167560884686340893L;
|
||||
|
||||
@Override
|
||||
@@ -96,7 +96,9 @@ public interface Distance extends Comparable<Distance>, Serializable {
|
||||
public Distance abs() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static final NullDistance NULL = new NullDistance();
|
||||
|
||||
double getGeographicalMiles();
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@ public class RegattaName implements RegattaIdentifier {
|
||||
return regattaName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getRegattaName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRegatta(RegattaFetcher regattaFetcher) {
|
||||
return regattaFetcher.getRegatta(this);
|
||||
|
||||
+9
-7
@@ -2,6 +2,8 @@ package com.sap.sailing.domain.common.dto;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
|
||||
public class BoatClassDTO extends NamedDTO implements Serializable, Comparable<BoatClassDTO> {
|
||||
private static final long serialVersionUID = 1981789833769906676L;
|
||||
|
||||
@@ -11,24 +13,24 @@ public class BoatClassDTO extends NamedDTO implements Serializable, Comparable<B
|
||||
*/
|
||||
public static final String DEFAULT_NAME = "Default";
|
||||
|
||||
private double hullLengthInMeters;
|
||||
private Distance hullLength;
|
||||
private String displayName;
|
||||
|
||||
BoatClassDTO() {}
|
||||
|
||||
public BoatClassDTO(String name, String displayName, double hullLengthInMeters) {
|
||||
public BoatClassDTO(String name, String displayName, Distance hullLength) {
|
||||
super(name);
|
||||
this.hullLengthInMeters = hullLengthInMeters;
|
||||
this.hullLength = hullLength;
|
||||
}
|
||||
|
||||
public BoatClassDTO(String name, double hullLengthInMeters) {
|
||||
public BoatClassDTO(String name, Distance hullLength) {
|
||||
super(name);
|
||||
this.hullLengthInMeters = hullLengthInMeters;
|
||||
this.hullLength = hullLength;
|
||||
this.displayName = null;
|
||||
}
|
||||
|
||||
public double getHullLengthInMeters() {
|
||||
return hullLengthInMeters;
|
||||
public Distance getHullLength() {
|
||||
return hullLength;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
|
||||
+49
@@ -3,10 +3,13 @@ package com.sap.sailing.domain.common.dto;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sse.common.Duration;
|
||||
import com.sap.sse.common.impl.MillisecondsDurationImpl;
|
||||
|
||||
/**
|
||||
* Holds a single competitor's scoring details for a single race. It may optionally contain
|
||||
@@ -78,6 +81,8 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
*/
|
||||
public Duration averageSamplingInterval;
|
||||
|
||||
public Double averageRideHeightInMeters;
|
||||
|
||||
/**
|
||||
* The time gap to the competitor leading the race; for one-design races this is the time the competitor is expected
|
||||
* to need to reach the leader's (windward) position (if in the same leg) or the difference between the time at
|
||||
@@ -132,6 +137,44 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
public boolean hasScoreCorrection() {
|
||||
return totalPointsCorrected || (reasonForMaxPoints != null && reasonForMaxPoints != MaxPointsReason.NONE);
|
||||
}
|
||||
|
||||
public Duration getTimeSailedInMillis() {
|
||||
final Duration result;
|
||||
if (legDetails != null) {
|
||||
long timeInMilliseconds = 0;
|
||||
for (LegEntryDTO legDetail : legDetails) {
|
||||
if (legDetail != null) {
|
||||
if (legDetail.distanceTraveledInMeters != null && legDetail.timeInMilliseconds != null) {
|
||||
timeInMilliseconds += legDetail.timeInMilliseconds;
|
||||
} else {
|
||||
timeInMilliseconds = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = new MillisecondsDurationImpl(timeInMilliseconds);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Distance getDistanceTraveledInMeters() {
|
||||
Distance result = null;
|
||||
if (legDetails != null) {
|
||||
for (LegEntryDTO legDetail : legDetails) {
|
||||
if (legDetail != null) {
|
||||
if (legDetail.distanceTraveledInMeters != null) {
|
||||
if (result == null) {
|
||||
result = Distance.NULL;
|
||||
}
|
||||
result = result.add(new MeterDistance(legDetail.distanceTraveledInMeters));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
@@ -174,6 +217,7 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
result = prime * result
|
||||
+ ((speedOverGroundAtStartOfRaceInKnots == null) ? 0 : speedOverGroundAtStartOfRaceInKnots.hashCode());
|
||||
result = prime * result + ((startTack == null) ? 0 : startTack.hashCode());
|
||||
result = prime * result + ((averageRideHeightInMeters == null) ? 0 : averageRideHeightInMeters.hashCode());
|
||||
result = prime * result + ((averageSamplingInterval == null) ? 0 : averageSamplingInterval.hashCode());
|
||||
result = prime * result + ((timeSinceLastPositionFixInSeconds == null) ? 0 : timeSinceLastPositionFixInSeconds.hashCode());
|
||||
result = prime * result + ((netPoints == null) ? 0 : netPoints.hashCode());
|
||||
@@ -282,6 +326,11 @@ public class LeaderboardEntryDTO implements Serializable {
|
||||
return false;
|
||||
if (startTack != other.startTack)
|
||||
return false;
|
||||
if (averageRideHeightInMeters == null) {
|
||||
if (other.averageRideHeightInMeters != null)
|
||||
return false;
|
||||
} else if (!averageRideHeightInMeters.equals(other.averageRideHeightInMeters))
|
||||
return false;
|
||||
if (averageSamplingInterval == null) {
|
||||
if (other.averageSamplingInterval != null)
|
||||
return false;
|
||||
|
||||
+25
@@ -4,6 +4,9 @@ import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sse.common.Duration;
|
||||
|
||||
/**
|
||||
* Holds data about one competitor and all races represented by the owning {@link LeaderboardDTO leaderboard}.
|
||||
*
|
||||
@@ -117,6 +120,28 @@ public class LeaderboardRowDTO implements Serializable {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Distance getDistanceTraveledInMeters(String raceColumnName) {
|
||||
final Distance result;
|
||||
LeaderboardEntryDTO fieldsForRace = fieldsByRaceColumnName.get(raceColumnName);
|
||||
if (fieldsForRace != null) {
|
||||
result = fieldsForRace.getDistanceTraveledInMeters();
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Duration getTimeSailed(String raceColumnName) {
|
||||
final Duration result;
|
||||
LeaderboardEntryDTO fieldsForRace = fieldsByRaceColumnName.get(raceColumnName);
|
||||
if (fieldsForRace != null) {
|
||||
result = fieldsForRace.getTimeSailedInMillis();
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LeaderboardRowDTO for competitor "+competitor;
|
||||
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
package com.sap.sailing.domain.common.tracking;
|
||||
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
|
||||
/**
|
||||
* Specific {@link SensorFix} for bravo devices (http://www.bravosystems.es/).
|
||||
*
|
||||
@@ -12,5 +14,5 @@ public interface BravoFix extends SensorFix {
|
||||
*
|
||||
* @return the ride height
|
||||
*/
|
||||
double getRideHeight();
|
||||
Distance getRideHeight();
|
||||
}
|
||||
+4
-2
@@ -1,5 +1,7 @@
|
||||
package com.sap.sailing.domain.common.tracking.impl;
|
||||
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.sensordata.BravoSensorDataMetadata;
|
||||
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||
import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
|
||||
@@ -32,8 +34,8 @@ public class BravoFixImpl implements BravoFix {
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getRideHeight() {
|
||||
return fix.get(BravoSensorDataMetadata.INSTANCE.rideHeightColumn);
|
||||
public Distance getRideHeight() {
|
||||
return new MeterDistance(fix.get(BravoSensorDataMetadata.INSTANCE.rideHeightColumn));
|
||||
}
|
||||
|
||||
}
|
||||
+2
-1
@@ -1144,11 +1144,12 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
logger.log(Level.WARNING, "Error loading racing procedure configration for regatta.", e);
|
||||
}
|
||||
}
|
||||
final Double buoyZoneRadiusInHullLengths = (Double) dbRegatta.get(FieldNames.REGATTA_BUOY_ZONE_RADIUS_IN_HULL_LENGTHS.name());
|
||||
final Boolean useStartTimeInference = (Boolean) dbRegatta.get(FieldNames.REGATTA_USE_START_TIME_INFERENCE.name());
|
||||
final Boolean controlTrackingFromStartAndFinishTimes = (Boolean) dbRegatta.get(FieldNames.REGATTA_CONTROL_TRACKING_FROM_START_AND_FINISH_TIMES.name());
|
||||
final RankingMetricConstructor rankingMetricConstructor = loadRankingMetricConstructor(dbRegatta);
|
||||
result = new RegattaImpl(getRaceLogStore(), getRegattaLogStore(), name, boatClass, startDate, endDate, series, /* persistent */true,
|
||||
loadScoringScheme(dbRegatta), id, courseArea, useStartTimeInference == null ? true
|
||||
loadScoringScheme(dbRegatta), id, courseArea, buoyZoneRadiusInHullLengths == null ? Regatta.DEFAULT_BUOY_ZONE_RADIUS_IN_HULL_LENGTHS : buoyZoneRadiusInHullLengths, useStartTimeInference == null ? true
|
||||
: useStartTimeInference, controlTrackingFromStartAndFinishTimes == null ? false : controlTrackingFromStartAndFinishTimes,
|
||||
rankingMetricConstructor);
|
||||
result.setRegattaConfiguration(configuration);
|
||||
|
||||
+1
@@ -34,6 +34,7 @@ public enum FieldNames {
|
||||
REGATTA_END_DATE,
|
||||
REGATTA_SERIES,
|
||||
REGATTA_REGATTA_CONFIGURATION,
|
||||
REGATTA_BUOY_ZONE_RADIUS_IN_HULL_LENGTHS,
|
||||
REGATTA_USE_START_TIME_INFERENCE,
|
||||
REGATTA_CONTROL_TRACKING_FROM_START_AND_FINISH_TIMES,
|
||||
SERIES_NAME,
|
||||
|
||||
+1
@@ -646,6 +646,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
DBObject configurationObject = (DBObject) JSON.parse(json.toString());
|
||||
dbRegatta.put(FieldNames.REGATTA_REGATTA_CONFIGURATION.name(), configurationObject);
|
||||
}
|
||||
dbRegatta.put(FieldNames.REGATTA_BUOY_ZONE_RADIUS_IN_HULL_LENGTHS.name(), regatta.getBuoyZoneRadiusInHullLengths());
|
||||
dbRegatta.put(FieldNames.REGATTA_USE_START_TIME_INFERENCE.name(), regatta.useStartTimeInference());
|
||||
dbRegatta.put(FieldNames.REGATTA_CONTROL_TRACKING_FROM_START_AND_FINISH_TIMES.name(), regatta.isControlTrackingFromStartAndFinishTimes());
|
||||
dbRegatta.put(FieldNames.REGATTA_RANKING_METRIC.name(), storeRankingMetric(regatta));
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public class CreateAndTrackWithRaceLogTest {
|
||||
service);
|
||||
regatta = service.createRegatta(RegattaImpl.getDefaultName("regatta", "Laser"), "Laser",
|
||||
/* startDate */null, /* endDate */null, UUID.randomUUID(), Collections.<Series> singletonList(series), false,
|
||||
new HighPoint(), UUID.randomUUID(), /* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
|
||||
new HighPoint(), UUID.randomUUID(), /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false, OneDesignRankingMetric::new);
|
||||
series.addRaceColumn(columnName, /* trackedRegattaRegistry */null);
|
||||
leaderboard = service.addRegattaLeaderboard(regatta.getRegattaIdentifier(), "RegattaLeaderboard", new int[] {});
|
||||
adapter = RaceLogTrackingAdapterFactory.INSTANCE.getAdapter(DomainFactory.INSTANCE);
|
||||
|
||||
+8
-12
@@ -49,9 +49,11 @@ import com.sap.sailing.domain.base.impl.CourseImpl;
|
||||
import com.sap.sailing.domain.base.impl.RaceDefinitionImpl;
|
||||
import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.base.impl.WaypointImpl;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.sensordata.BravoSensorDataMetadata;
|
||||
import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
@@ -95,9 +97,9 @@ public class SensorFixStoreAndLoadTest {
|
||||
private static final long FIX_TIMESTAMP2 = 120;
|
||||
private static final long FIX_TIMESTAMP3 = 210;
|
||||
private static final long AFTER_LAST_FIX = FIX_TIMESTAMP3 + 1;
|
||||
private static final double FIX_RIDE_HEIGHT = 1337.0;
|
||||
private static final double FIX_RIDE_HEIGHT2 = 1338.0;
|
||||
private static final double FIX_RIDE_HEIGHT3 = 1336.0;
|
||||
private static final Distance FIX_RIDE_HEIGHT = new MeterDistance(1337.0);
|
||||
private static final Distance FIX_RIDE_HEIGHT2 = new MeterDistance(1338.0);
|
||||
private static final Distance FIX_RIDE_HEIGHT3 = new MeterDistance(1336.0);
|
||||
private static final double FIX_TEST_VALUE = 12.0;
|
||||
protected final MockSmartphoneImeiServiceFinderFactory serviceFinderFactory = new MockSmartphoneImeiServiceFinderFactory();
|
||||
protected final DeviceIdentifier device = new SmartphoneImeiIdentifier("a");
|
||||
@@ -384,20 +386,14 @@ public class SensorFixStoreAndLoadTest {
|
||||
public void testBravoFixIsCorrectlyWrapped() throws InterruptedException {
|
||||
regattaLog.add(new RegattaLogDeviceCompetitorBravoMappingEventImpl(new MillisecondsTimePoint(3), author, comp,
|
||||
device, new MillisecondsTimePoint(START_OF_TRACKING), new MillisecondsTimePoint(MID_OF_TRACKING)));
|
||||
|
||||
addBravoFixes();
|
||||
|
||||
FixLoaderAndTracker fixLoaderAndTracker = createFixLoaderAndTracker();
|
||||
|
||||
trackedRace.attachRaceLog(raceLog);
|
||||
trackedRace.attachRegattaLog(regattaLog);
|
||||
|
||||
trackedRace.waitForLoadingToFinish();
|
||||
|
||||
BravoFixTrack<Competitor> bravoFixTrack = trackedRace.getSensorTrack(comp, BravoFixTrack.TRACK_NAME);
|
||||
assertEquals(FIX_RIDE_HEIGHT,
|
||||
bravoFixTrack.getFirstFixAtOrAfter(new MillisecondsTimePoint(FIX_TIMESTAMP)).getRideHeight());
|
||||
|
||||
fixLoaderAndTracker.stop(true);
|
||||
}
|
||||
|
||||
@@ -482,9 +478,9 @@ public class SensorFixStoreAndLoadTest {
|
||||
}
|
||||
|
||||
private void addBravoFixes() {
|
||||
store.storeFix(device, createBravoDoubleVectorFixWithRideHeight(FIX_TIMESTAMP, FIX_RIDE_HEIGHT));
|
||||
store.storeFix(device, createBravoDoubleVectorFixWithRideHeight(FIX_TIMESTAMP2, FIX_RIDE_HEIGHT2));
|
||||
store.storeFix(device, createBravoDoubleVectorFixWithRideHeight(FIX_TIMESTAMP3, FIX_RIDE_HEIGHT3));
|
||||
store.storeFix(device, createBravoDoubleVectorFixWithRideHeight(FIX_TIMESTAMP, FIX_RIDE_HEIGHT.getMeters()));
|
||||
store.storeFix(device, createBravoDoubleVectorFixWithRideHeight(FIX_TIMESTAMP2, FIX_RIDE_HEIGHT2.getMeters()));
|
||||
store.storeFix(device, createBravoDoubleVectorFixWithRideHeight(FIX_TIMESTAMP3, FIX_RIDE_HEIGHT3.getMeters()));
|
||||
}
|
||||
|
||||
private FixLoaderAndTracker createFixLoaderAndTracker() {
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file datatype="javapropertyresourcebundle" original="/usr/sap/ljs/app/Converter_5483050776164983/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties" source-language="en">
|
||||
<file datatype="javapropertyresourcebundle" original="/usr/sap/ljs/app/Converter_2566045106627533633/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties" source-language="en">
|
||||
<header>
|
||||
<skl>
|
||||
<internal-file crc="cdbdcb19e10086d34f715e2a7da26eef" form="base64">H4sIAAAAAAAAAF2RTU/DMAyG7/0VvnGZEGekHgYSUiVgY+3gnLXeajWNo9jbqBD/naQtbOLm+PXH+zgaTN2ROxTuRGqU2D1xyKs5C5c07DlkUhv3tnnkBlfhnYR0G2zFGzyQKIal5C+mQ5BjQBj4CK05IWiL8HX3DUvvgZyosRabW6hadJDmjQV7tpbPaeM0HjhAbanuRtWS6+AoSY5jA0hvgvqWXZzOEOb1YCQ7o625x4rzjymKBRmtyq1gkLzU2AfxmcxkxjWBqbmWllNqkm2c6SL7Ce0wwlYtyXO0khf7Ec9EzICmSb40atAbssATUYMnqhHOpO34TvjGpvLhcoYFCPXeDjPrDuMREpIkN/fZ7shDha7BkKcQdIwz432pHLCYxlT4qclSw+5GLzdPCwfUBXiLRvB36X1qL1jyuftyDu9n/D/p+hzJwDqSxm/2/tX0mJfLNZSROOE/JHuTnEnMFa6kQ6v/S2HOZz95rIJYdwIAAA==</internal-file>
|
||||
</skl>
|
||||
<phase-group>
|
||||
<phase company-name="SAP AG" date="2016-05-11T12:28:05Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
<phase company-name="SAP AG" date="2016-11-04T21:01:36Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
</phase-group>
|
||||
<tool tool-company="SAP AG" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter" tool-name="TEW: Javascript .properties Flexible File Converter" tool-version="1.1.0"/>
|
||||
</header>
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-09-29T12:18:02Z" original="/usr/sap/ljs/app/Converter_5483050776164983/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties" source-language="en" target-language="ja">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-11-09T11:20:30Z" original="/usr/sap/ljs/app/Converter_2566045106627533633/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties" source-language="en" target-language="ja">
|
||||
<header>
|
||||
<skl>
|
||||
<internal-file crc="cdbdcb19e10086d34f715e2a7da26eef" form="base64">H4sIAAAAAAAAAF2RTU/DMAyG7/0VvnGZEGekHgYSUiVgY+3gnLXeajWNo9jbqBD/naQtbOLm+PXH+zgaTN2ROxTuRGqU2D1xyKs5C5c07DlkUhv3tnnkBlfhnYR0G2zFGzyQKIal5C+mQ5BjQBj4CK05IWiL8HX3DUvvgZyosRabW6hadJDmjQV7tpbPaeM0HjhAbanuRtWS6+AoSY5jA0hvgvqWXZzOEOb1YCQ7o625x4rzjymKBRmtyq1gkLzU2AfxmcxkxjWBqbmWllNqkm2c6SL7Ce0wwlYtyXO0khf7Ec9EzICmSb40atAbssATUYMnqhHOpO34TvjGpvLhcoYFCPXeDjPrDuMREpIkN/fZ7shDha7BkKcQdIwz432pHLCYxlT4qclSw+5GLzdPCwfUBXiLRvB36X1qL1jyuftyDu9n/D/p+hzJwDqSxm/2/tX0mJfLNZSROOE/JHuTnEnMFa6kQ6v/S2HOZz95rIJYdwIAAA==</internal-file>
|
||||
</skl>
|
||||
<phase-group>
|
||||
<phase company-name="SAP AG" date="2016-05-11T12:28:05Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
<phase company-name="SAP AG" date="2016-11-04T21:01:36Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
</phase-group>
|
||||
<tool tool-company="SAP AG" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter" tool-name="TEW: Javascript .properties Flexible File Converter" tool-version="1.1.0"/>
|
||||
</header>
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-09-29T12:18:02Z" original="/usr/sap/ljs/app/Converter_5483050776164983/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties" source-language="en" target-language="ru">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-11-09T11:22:32Z" original="/usr/sap/ljs/app/Converter_2566045106627533633/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties" source-language="en" target-language="ru">
|
||||
<header>
|
||||
<skl>
|
||||
<internal-file crc="cdbdcb19e10086d34f715e2a7da26eef" form="base64">H4sIAAAAAAAAAF2RTU/DMAyG7/0VvnGZEGekHgYSUiVgY+3gnLXeajWNo9jbqBD/naQtbOLm+PXH+zgaTN2ROxTuRGqU2D1xyKs5C5c07DlkUhv3tnnkBlfhnYR0G2zFGzyQKIal5C+mQ5BjQBj4CK05IWiL8HX3DUvvgZyosRabW6hadJDmjQV7tpbPaeM0HjhAbanuRtWS6+AoSY5jA0hvgvqWXZzOEOb1YCQ7o625x4rzjymKBRmtyq1gkLzU2AfxmcxkxjWBqbmWllNqkm2c6SL7Ce0wwlYtyXO0khf7Ec9EzICmSb40atAbssATUYMnqhHOpO34TvjGpvLhcoYFCPXeDjPrDuMREpIkN/fZ7shDha7BkKcQdIwz432pHLCYxlT4qclSw+5GLzdPCwfUBXiLRvB36X1qL1jyuftyDu9n/D/p+hzJwDqSxm/2/tX0mJfLNZSROOE/JHuTnEnMFa6kQ6v/S2HOZz95rIJYdwIAAA==</internal-file>
|
||||
</skl>
|
||||
<phase-group>
|
||||
<phase company-name="SAP AG" date="2016-05-11T12:28:05Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
<phase company-name="SAP AG" date="2016-11-04T21:01:36Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
</phase-group>
|
||||
<tool tool-company="SAP AG" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter" tool-name="TEW: Javascript .properties Flexible File Converter" tool-version="1.1.0"/>
|
||||
</header>
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-09-29T12:18:02Z" original="/usr/sap/ljs/app/Converter_5483050776164983/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties" source-language="en" target-language="zh-CN">
|
||||
<file datatype="javapropertyresourcebundle" date="2016-11-09T11:24:24Z" original="/usr/sap/ljs/app/Converter_2566045106627533633/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties" source-language="en" target-language="zh-CN">
|
||||
<header>
|
||||
<skl>
|
||||
<internal-file crc="cdbdcb19e10086d34f715e2a7da26eef" form="base64">H4sIAAAAAAAAAF2RTU/DMAyG7/0VvnGZEGekHgYSUiVgY+3gnLXeajWNo9jbqBD/naQtbOLm+PXH+zgaTN2ROxTuRGqU2D1xyKs5C5c07DlkUhv3tnnkBlfhnYR0G2zFGzyQKIal5C+mQ5BjQBj4CK05IWiL8HX3DUvvgZyosRabW6hadJDmjQV7tpbPaeM0HjhAbanuRtWS6+AoSY5jA0hvgvqWXZzOEOb1YCQ7o625x4rzjymKBRmtyq1gkLzU2AfxmcxkxjWBqbmWllNqkm2c6SL7Ce0wwlYtyXO0khf7Ec9EzICmSb40atAbssATUYMnqhHOpO34TvjGpvLhcoYFCPXeDjPrDuMREpIkN/fZ7shDha7BkKcQdIwz432pHLCYxlT4qclSw+5GLzdPCwfUBXiLRvB36X1qL1jyuftyDu9n/D/p+hzJwDqSxm/2/tX0mJfLNZSROOE/JHuTnEnMFa6kQ6v/S2HOZz95rIJYdwIAAA==</internal-file>
|
||||
</skl>
|
||||
<phase-group>
|
||||
<phase company-name="SAP AG" date="2016-05-11T12:28:05Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
<phase company-name="SAP AG" date="2016-11-04T21:01:36Z" phase-name="file-creation" process-name="file-creation" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter"/>
|
||||
</phase-group>
|
||||
<tool tool-company="SAP AG" tool-id="urn:x-sap:sls-mlt:java:properties-flexible-converter" tool-name="TEW: Javascript .properties Flexible File Converter" tool-version="1.1.0"/>
|
||||
</header>
|
||||
|
||||
+1
-1
@@ -250,7 +250,7 @@ public class TransientCompetitorStoreImpl implements CompetitorStore, Serializab
|
||||
c.getFlagImage() == null ? null : c.getFlagImage().toString(),
|
||||
new BoatDTO(c.getBoat().getName(), c.getBoat().getSailID(), c.getBoat().getColor()),
|
||||
new BoatClassDTO(c.getBoat().getBoatClass()
|
||||
.getName(), c.getBoat().getBoatClass().getDisplayName(), c.getBoat().getBoatClass().getHullLength().getMeters()),
|
||||
.getName(), c.getBoat().getBoatClass().getDisplayName(), c.getBoat().getBoatClass().getHullLength()),
|
||||
c.getTimeOnTimeFactor(), c.getTimeOnDistanceAllowancePerNauticalMile(), c.getSearchTag());
|
||||
weakCompetitorDTOCache.put(c, competitorDTO);
|
||||
}
|
||||
|
||||
+5
-4
@@ -35,6 +35,7 @@ import com.sap.sailing.domain.common.dto.LeaderboardRowDTO;
|
||||
import com.sap.sailing.domain.common.dto.LegEntryDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceDTO;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.test.StoredTrackBasedTest;
|
||||
import com.sap.sse.common.Cloner;
|
||||
import com.sap.sse.common.Color;
|
||||
@@ -234,7 +235,7 @@ public class LeaderboardDTODiffingTest {
|
||||
public void testCompetitorListChange() {
|
||||
newVersion.competitors = new ArrayList<CompetitorDTO>(newVersion.competitors); // clone competitor list so it's not identical to that of previous version
|
||||
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "someone@nobody.de", "DE", "GER", "Germany", "912p09871203987",
|
||||
/* imageURL */ null, /* flagImageURL */ null, new BoatDTO("LSC", "GER 1234"), new BoatClassDTO("505", 5.05), /* timeOnTimeFactor */ null,
|
||||
/* imageURL */ null, /* flagImageURL */ null, new BoatDTO("LSC", "GER 1234"), new BoatClassDTO("505", new MeterDistance(5.05)), /* timeOnTimeFactor */ null,
|
||||
/* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
newVersion.competitors.add(13, somebodyNew); // insert a competitor; this should mess up all others' indexes; check if this works
|
||||
CompetitorDTO wolfgang = getPreviousCompetitorByName("HUNGER +JESS");
|
||||
@@ -255,7 +256,7 @@ public class LeaderboardDTODiffingTest {
|
||||
newVersion.setSuppressedCompetitors(newSuppressedCompetitors);
|
||||
newVersion.competitors = new ArrayList<CompetitorDTO>(newVersion.competitors); // clone competitor list so it's not identical to that of previous version
|
||||
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "someone@nobody.de", "DE", "GER", "Germany", "912p09871203987",
|
||||
/* imageURL */ null, /* flagImageURL */ null, new BoatDTO("LSC", "GER 1234"), new BoatClassDTO("505", 5.05), /* timeOnTimeFactor */ null,
|
||||
/* imageURL */ null, /* flagImageURL */ null, new BoatDTO("LSC", "GER 1234"), new BoatClassDTO("505", new MeterDistance(5.05)), /* timeOnTimeFactor */ null,
|
||||
/* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
newVersion.setSuppressed(newVersion.competitors.get(13), true); // suppress an existing competitor; compaction should reduce this to a single number only
|
||||
newVersion.setSuppressed(somebodyNew, true); // check that mixed mode with existing and new competitors works as well
|
||||
@@ -278,7 +279,7 @@ public class LeaderboardDTODiffingTest {
|
||||
public void testDisplayNameChange() {
|
||||
newVersion.competitors = new ArrayList<CompetitorDTO>(newVersion.competitors); // clone competitor list so it's not identical to that of previous version
|
||||
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "someone@nobody.de", "DE", "GER", "Germany", "912p09871203987",
|
||||
/* imageURL */ null, /* flagImageURL */ null, new BoatDTO("LSC", "GER 1234"), new BoatClassDTO("505", 5.05), /* timeOnTimeFactor */ null,
|
||||
/* imageURL */ null, /* flagImageURL */ null, new BoatDTO("LSC", "GER 1234"), new BoatClassDTO("505", new MeterDistance(5.05)), /* timeOnTimeFactor */ null,
|
||||
/* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
newVersion.competitors.add(somebodyNew);
|
||||
newVersion.competitorDisplayNames = new HashMap<CompetitorDTO, String>(newVersion.competitorDisplayNames);
|
||||
@@ -308,7 +309,7 @@ public class LeaderboardDTODiffingTest {
|
||||
newVersion.setCompetitorsFromBestToWorst(r9, newOrdering);
|
||||
newVersion.competitors = new ArrayList<CompetitorDTO>(newVersion.competitors); // clone competitor list so it's not identical to that of previous version
|
||||
CompetitorDTO somebodyNew = new CompetitorDTOImpl("Someone New", Color.RED, "someone@nobody.de", "DE", "GER", "Germany", "912p09871203987",
|
||||
/* imageURL */ null, /* flagImageURL */ null, new BoatDTO("LSC", "GER 1234"), new BoatClassDTO("505", 5.05), /* timeOnTimeFactor */ null,
|
||||
/* imageURL */ null, /* flagImageURL */ null, new BoatDTO("LSC", "GER 1234"), new BoatClassDTO("505", new MeterDistance(5.05)), /* timeOnTimeFactor */ null,
|
||||
/* timeOnDistanceAllowancePerNauticalMile */ null, null);
|
||||
newVersion.competitors.add(somebodyNew);
|
||||
newOrdering.add(somebodyNew);
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
import com.sap.sailing.domain.common.impl.NauticalMileDistance;
|
||||
import com.sap.sailing.domain.common.tracking.impl.CompactGPSFixImpl;
|
||||
import com.sap.sailing.domain.common.tracking.impl.CompactGPSFixMovingImpl;
|
||||
@@ -67,6 +68,12 @@ public class PositionTest {
|
||||
assertEquals(20004, Math.abs(southPole.getDistance(northPole).getKilometers()), 0.0001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void radTest() {
|
||||
assertEquals(180, new MeterDistance(20005000).getCentralAngleDeg(), 0.01);
|
||||
assertEquals(Math.PI, new MeterDistance(20005000).getCentralAngleRad(), 0.01);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bearingTest() {
|
||||
// Note that the bearing is a bearing on a great circle!
|
||||
|
||||
@@ -374,6 +374,27 @@ public class TrackTest {
|
||||
getB().getKnots(), 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxSpeedForFixOverwrittenWithLowerSpeed() {
|
||||
DynamicGPSFixMovingTrackImpl<Object> track = new DynamicGPSFixMovingTrackImpl<Object>(new Object(), /* millisecondsOverWhichToAverage */ 30000l);
|
||||
GPSFixMoving slow = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(3600000), new KnotSpeedWithBearingImpl(
|
||||
1, new DegreeBearingImpl(123)));
|
||||
GPSFixMoving fast = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(3600000), new KnotSpeedWithBearingImpl(
|
||||
2, new DegreeBearingImpl(123)));
|
||||
track.addGPSFix(fast);
|
||||
assertEquals(2., track.getMaximumSpeedOverGround(new MillisecondsTimePoint(0), new MillisecondsTimePoint(10800000)).
|
||||
getB().getKnots(), 0.001);
|
||||
track.addGPSFix(slow);
|
||||
track.lockForRead();
|
||||
try {
|
||||
assertEquals(1, track.getFixes().size());
|
||||
} finally {
|
||||
track.unlockAfterRead();
|
||||
}
|
||||
assertEquals(1., track.getMaximumSpeedOverGround(new MillisecondsTimePoint(0), new MillisecondsTimePoint(10800000)).
|
||||
getB().getKnots(), 0.001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaxSpeedForMovingTrackWithFixAtIntervalBoundaryAfterQuery() {
|
||||
DynamicGPSFixMovingTrackImpl<Object> track = new DynamicGPSFixMovingTrackImpl<Object>(new Object(), /* millisecondsOverWhichToAverage */ 30000l);
|
||||
|
||||
+19
-3
@@ -447,6 +447,15 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getBuoyZoneRadiusInHullLengths(){
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBuoyZoneRadiusInHullLengths(Double buoyZoneRadiusInHullLengths){
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegattaLikeIdentifier getRegattaLikeIdentifier() {
|
||||
return null;
|
||||
@@ -532,15 +541,12 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
|
||||
@Override
|
||||
public boolean isControlTrackingFromStartAndFinishTimes() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setControlTrackingFromStartAndFinishTimes(
|
||||
boolean controlTrackingFromStartAndFinishTimes) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1121,4 +1127,14 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
public Iterable<RaceLog> getAttachedRaceLogs() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableSet<MarkPassing> getMarkPassings(Competitor competitor, boolean waitForLatestUpdates) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getAverageRideHeight(Competitor competitor, TimePoint timePoint) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+10
@@ -681,4 +681,14 @@ public class MockedTrackedRaceWithStartTimeAndRanks implements TrackedRace {
|
||||
public Iterable<RaceLog> getAttachedRaceLogs() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableSet<MarkPassing> getMarkPassings(Competitor competitor, boolean waitForLatestUpdates) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getAverageRideHeight(Competitor competitor, TimePoint timePoint) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -82,8 +82,8 @@ public class BravoFixTrackSerializationTest {
|
||||
assertRideHeight(track, testFixData.timePoint, testFixData.rideHeight);
|
||||
}
|
||||
|
||||
private void assertRideHeight(BravoFixTrack<Competitor> track, TimePoint timePoint, double expected) {
|
||||
assertEquals(expected, track.getRideHeight(timePoint), 0.0);
|
||||
private void assertRideHeight(BravoFixTrack<Competitor> track, TimePoint timePoint, double expectedRideHeightInMeters) {
|
||||
assertEquals(expectedRideHeightInMeters, track.getRideHeight(timePoint).getMeters(), 0.0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -24,6 +24,9 @@ import com.sap.sse.common.TimePoint;
|
||||
*
|
||||
*/
|
||||
public interface Regatta extends NamedWithID, IsRegattaLike, HasRaceColumnsAndRegattaLike {
|
||||
|
||||
public static final double DEFAULT_BUOY_ZONE_RADIUS_IN_HULL_LENGTHS = 2;
|
||||
|
||||
ScoringScheme getScoringScheme();
|
||||
|
||||
/**
|
||||
@@ -155,6 +158,14 @@ public interface Regatta extends NamedWithID, IsRegattaLike, HasRaceColumnsAndRe
|
||||
|
||||
RegattaAndRaceIdentifier getRaceIdentifier(RaceDefinition race);
|
||||
|
||||
/**
|
||||
* Define the value which would be multipled by hull length from {@link BoatClass}.
|
||||
* Next the calculated value {@link RegattaUtil} would be used to fill out radius of buoy on race map setting.
|
||||
*/
|
||||
public Double getBuoyZoneRadiusInHullLengths();
|
||||
|
||||
public void setBuoyZoneRadiusInHullLengths(Double buoyZoneRadiusInHullLengths);
|
||||
|
||||
/**
|
||||
* When there is no race committee app in place and no operator is managing the race start times for this regatta,
|
||||
* start times can optionally be inferred from the start mark passings by the {@link TrackedRace}s in this regatta.
|
||||
|
||||
@@ -115,6 +115,7 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
private transient RaceLogStore raceLogStore;
|
||||
private final IsRegattaLike regattaLikeHelper;
|
||||
private final RankingMetricConstructor rankingMetricConstructor;
|
||||
private Double buoyZoneRadiusInHullLengths;
|
||||
|
||||
private CourseArea defaultCourseArea;
|
||||
private RegattaConfiguration configuration;
|
||||
@@ -162,7 +163,7 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
Iterable<? extends Series> series, boolean persistent, ScoringScheme scoringScheme, Serializable id,
|
||||
CourseArea courseArea, RankingMetricConstructor rankingMetricConstructor) {
|
||||
this(EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, name, boatClass, startDate, endDate, series,
|
||||
persistent, scoringScheme, id, courseArea, /* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false,
|
||||
persistent, scoringScheme, id, courseArea, 0.0, /* useStartTimeInference */true, /* controlTrackingFromStartAndFinishTimes */ false,
|
||||
rankingMetricConstructor);
|
||||
}
|
||||
|
||||
@@ -204,7 +205,7 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
/* isMedal */false, /* isFleetsCanRunInParallel */ true, Collections
|
||||
.singletonList(new FleetImpl(LeaderboardNameConstants.DEFAULT_FLEET_NAME)),
|
||||
/* race column names */new ArrayList<String>(), trackedRegattaRegistry)), /* persistent */false,
|
||||
scoringScheme, id, courseArea, /* useStartTimeInference */true, controlTrackingFromStartAndFinishTimes,
|
||||
scoringScheme, id, courseArea, /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */true, controlTrackingFromStartAndFinishTimes,
|
||||
rankingMetricConstructor);
|
||||
}
|
||||
|
||||
@@ -215,7 +216,7 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
*/
|
||||
public <S extends Series> RegattaImpl(RaceLogStore raceLogStore, RegattaLogStore regattaLogStore, String name,
|
||||
BoatClass boatClass, TimePoint startDate, TimePoint endDate, Iterable<S> series, boolean persistent,
|
||||
ScoringScheme scoringScheme, Serializable id, CourseArea courseArea, boolean useStartTimeInference,
|
||||
ScoringScheme scoringScheme, Serializable id, CourseArea courseArea, Double buoyZoneRadiusInHullLengths, boolean useStartTimeInference,
|
||||
boolean controlTrackingFromStartAndFinishTimes, RankingMetricConstructor rankingMetricConstructor) {
|
||||
super(name);
|
||||
this.rankingMetricConstructor = rankingMetricConstructor;
|
||||
@@ -241,6 +242,7 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
this.scoringScheme = scoringScheme;
|
||||
this.defaultCourseArea = courseArea;
|
||||
this.configuration = null;
|
||||
this.buoyZoneRadiusInHullLengths = buoyZoneRadiusInHullLengths;
|
||||
this.regattaLikeHelper = new BaseRegattaLikeImpl(new RegattaAsRegattaLikeIdentifier(this), regattaLogStore) {
|
||||
private static final long serialVersionUID = 8546222568682770206L;
|
||||
|
||||
@@ -572,6 +574,16 @@ public class RegattaImpl extends NamedImpl implements Regatta, RaceColumnListene
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getBuoyZoneRadiusInHullLengths() {
|
||||
return buoyZoneRadiusInHullLengths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBuoyZoneRadiusInHullLengths(Double buoyZoneRadiusInHullLengths) {
|
||||
this.buoyZoneRadiusInHullLengths = buoyZoneRadiusInHullLengths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CourseArea getDefaultCourseArea() {
|
||||
return defaultCourseArea;
|
||||
|
||||
+6
-2
@@ -1437,6 +1437,8 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
} else {
|
||||
entryDTO.timeSinceLastPositionFixInSeconds = null;
|
||||
}
|
||||
final Distance averageRideHeight = trackedRace.getAverageRideHeight(competitor, timePoint);
|
||||
entryDTO.averageRideHeightInMeters = averageRideHeight == null ? null : averageRideHeight.getMeters();
|
||||
}
|
||||
if (addLegDetails && trackedRace != null) {
|
||||
try {
|
||||
@@ -1721,11 +1723,13 @@ public abstract class AbstractSimpleLeaderboardImpl implements Leaderboard, Race
|
||||
Double speedOverGroundInKnots;
|
||||
if (trackedLeg.hasFinishedLeg(timePoint)) {
|
||||
speedOverGroundInKnots = averageSpeedOverGround == null ? null : averageSpeedOverGround.getKnots();
|
||||
result.currentRideHeightInMeters = trackedLeg.getAverageRideHeight(timePoint);
|
||||
final Distance averageRideHeight = trackedLeg.getAverageRideHeight(timePoint);
|
||||
result.currentRideHeightInMeters = averageRideHeight == null ? null : averageRideHeight.getMeters();
|
||||
} else {
|
||||
final SpeedWithBearing speedOverGround = trackedLeg.getSpeedOverGround(timePoint);
|
||||
speedOverGroundInKnots = speedOverGround == null ? null : speedOverGround.getKnots();
|
||||
result.currentRideHeightInMeters = trackedLeg.getRideHeight(timePoint);
|
||||
final Distance rideHeight = trackedLeg.getRideHeight(timePoint);
|
||||
result.currentRideHeightInMeters = rideHeight == null ? null : rideHeight.getMeters();
|
||||
}
|
||||
result.currentSpeedOverGroundInKnots = speedOverGroundInKnots == null ? null : speedOverGroundInKnots;
|
||||
Distance distanceTraveled = trackedLeg.getDistanceTraveled(timePoint);
|
||||
|
||||
+53
-5
@@ -26,6 +26,8 @@ import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.Util.Triple;
|
||||
import com.sap.sse.common.util.IntHolder;
|
||||
import com.sap.sse.concurrent.LockUtil;
|
||||
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
||||
import com.sap.sse.util.ThreadPoolUtil;
|
||||
|
||||
/**
|
||||
@@ -60,14 +62,16 @@ public class MarkPassingCalculator {
|
||||
* started and then terminated again.
|
||||
*/
|
||||
private final Thread listenerThread;
|
||||
|
||||
private final Listen listen;
|
||||
|
||||
/**
|
||||
* Synchronized using the {@link #listenerThread} as monitor object.
|
||||
*/
|
||||
private boolean listenerThreadStarted;
|
||||
|
||||
public MarkPassingCalculator(DynamicTrackedRace race, boolean listen, boolean waitForInitialMarkPassingCalculation) {
|
||||
if (listen) {
|
||||
public MarkPassingCalculator(DynamicTrackedRace race, boolean doListen, boolean waitForInitialMarkPassingCalculation) {
|
||||
if (doListen) {
|
||||
listener = new MarkPassingUpdateListener(race);
|
||||
} else {
|
||||
listener = null;
|
||||
@@ -75,10 +79,12 @@ public class MarkPassingCalculator {
|
||||
this.race = race;
|
||||
finder = new CandidateFinderImpl(race, executor);
|
||||
chooser = new CandidateChooserImpl(race);
|
||||
if (listen) {
|
||||
listenerThread = new Thread(new Listen(race.getRace().getName()), "MarkPassingCalculator for race " + race.getRace().getName());
|
||||
if (doListen) {
|
||||
listen = new Listen(race.getRace().getName());
|
||||
listenerThread = new Thread(listen, "MarkPassingCalculator for race " + race.getRace().getName());
|
||||
} else {
|
||||
listenerThread = null;
|
||||
listen = null;
|
||||
}
|
||||
Thread t = new Thread(() -> {
|
||||
final Set<Callable<Void>> tasks = new HashSet<>();
|
||||
@@ -94,7 +100,7 @@ public class MarkPassingCalculator {
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error trying to compute initial set of mark passings for race "+race.getRace().getName(), e);
|
||||
}
|
||||
if (listen) {
|
||||
if (doListen) {
|
||||
listenerThread.setDaemon(true);
|
||||
listenerThread.start();
|
||||
synchronized (listenerThread) {
|
||||
@@ -131,6 +137,28 @@ public class MarkPassingCalculator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It's used for locking the calculation thread for read. You will be blocked if the calculation is in progress.
|
||||
* Make sure that you unlock the thread with the method {@link MarkPassingCalculator#unlockForRead()} once you don't
|
||||
* need it any more, using a {@code finally} clause to ensure unlocking even with abnormal termination.
|
||||
*/
|
||||
public void lockForRead() {
|
||||
if (listen != null) {
|
||||
listen.lockForRead();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks the calculation thread for read.
|
||||
*
|
||||
* @see #lockForRead
|
||||
*/
|
||||
public void unlockForRead() {
|
||||
if (listen != null) {
|
||||
listen.unlockAfterRead();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits until an object is in the queue, then drains it entirely. After that the information is sorted depending on
|
||||
* whether it is a fix, an updated waypoint or an updated fixed markpassing. Finally, if <code>suspended</code> is
|
||||
@@ -143,8 +171,25 @@ public class MarkPassingCalculator {
|
||||
private class Listen implements Runnable {
|
||||
private final String raceName;
|
||||
|
||||
/**
|
||||
* The write lock is being held by the thread running this {@link Runnable} after successfully having
|
||||
* waited for the next update to be pushed to the {@link MarkPassingUpdateListener#getQueue() queue},
|
||||
* before draining the queue starts and until the processing of all events from the queue has completed.
|
||||
* This way, trying to obtain the read lock will block until all pending updates have been processed.
|
||||
*/
|
||||
private final NamedReentrantReadWriteLock lock;
|
||||
|
||||
public Listen(String raceName) {
|
||||
this.raceName = raceName;
|
||||
lock = new NamedReentrantReadWriteLock("lock for calculation thread (" + Listen.class.getSimpleName() + ")", /* fair */ false);
|
||||
}
|
||||
|
||||
public void lockForRead() {
|
||||
LockUtil.lockForRead(lock);
|
||||
}
|
||||
|
||||
public void unlockAfterRead() {
|
||||
LockUtil.unlockAfterRead(lock);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -171,6 +216,7 @@ public class MarkPassingCalculator {
|
||||
logger.log(Level.SEVERE, "MarkPassingCalculator for "+raceName+" threw exception " + e.getMessage()
|
||||
+ " while waiting for new GPSFixes");
|
||||
}
|
||||
LockUtil.lockForWrite(lock);
|
||||
listener.getQueue().drainTo(allNewFixInsertions);
|
||||
logger.fine("MPC for "+raceName+" received "+ allNewFixInsertions.size()+" new updates.");
|
||||
for (StorePositionUpdateStrategy fixInsertion : allNewFixInsertions) {
|
||||
@@ -225,6 +271,8 @@ public class MarkPassingCalculator {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error while calculating markpassings for race "+raceName+": " + e.getMessage(), e);
|
||||
} finally {
|
||||
LockUtil.unlockAfterWrite(lock);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.sap.sailing.domain.tracking;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.WithID;
|
||||
@@ -22,7 +23,7 @@ public interface BravoFixTrack<ItemType extends WithID & Serializable> extends S
|
||||
* @return the ride height for the given {@link TimePoint} or <code>null</code> if the {@link TimePoint} is not in the range
|
||||
* where we have fixes for.
|
||||
*/
|
||||
Double getRideHeight(TimePoint timePoint);
|
||||
Distance getRideHeight(TimePoint timePoint);
|
||||
|
||||
/**
|
||||
* Calculates the average ride height for the given time range.
|
||||
@@ -34,5 +35,5 @@ public interface BravoFixTrack<ItemType extends WithID & Serializable> extends S
|
||||
* @return the average ride height for the given time range or <code>null</code> if there are no fixes in the given
|
||||
* time range.
|
||||
*/
|
||||
Double getAverageRideHeight(TimePoint from, TimePoint to);
|
||||
Distance getAverageRideHeight(TimePoint from, TimePoint to);
|
||||
}
|
||||
+2
-2
@@ -97,7 +97,7 @@ public interface TrackedLegOfCompetitor extends Serializable {
|
||||
* <code>timePoint</code>. If the competitor already completed the leg at <code>timePoint</code> and the respective
|
||||
* mark passing event was already received, the average ride height for the entire leg (and no further) is computed.
|
||||
*/
|
||||
Double getAverageRideHeight(TimePoint timePoint);
|
||||
Distance getAverageRideHeight(TimePoint timePoint);
|
||||
|
||||
/**
|
||||
* @return <code>null</code> if the competitor hasn't started this leg yet, otherwise the fix where the maximum speed was
|
||||
@@ -237,7 +237,7 @@ public interface TrackedLegOfCompetitor extends Serializable {
|
||||
* <code>timePoint</code>, returns the current ride height for this time point. If the competitor has already
|
||||
* finished the leg, the ride height at the time the competitor finished the leg is returned.
|
||||
*/
|
||||
Double getRideHeight(TimePoint at);
|
||||
Distance getRideHeight(TimePoint at);
|
||||
|
||||
/**
|
||||
* Computes the distance along the wind track to the wind-projected position of the race's overall leader. If leader
|
||||
|
||||
@@ -45,8 +45,10 @@ import com.sap.sailing.domain.common.racelog.RacingProcedureType;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.SensorFix;
|
||||
import com.sap.sailing.domain.markpassingcalculation.MarkPassingCalculator;
|
||||
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.domain.racelog.tracking.GPSFixStore;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric;
|
||||
import com.sap.sailing.domain.ranking.RankingMetric.RankingInfo;
|
||||
import com.sap.sailing.domain.tracking.impl.NonCachingMarkPositionAtTimePointCache;
|
||||
@@ -434,6 +436,17 @@ public interface TrackedRace extends Serializable, IsManagedByCache<SharedDomain
|
||||
* lock.
|
||||
*/
|
||||
NavigableSet<MarkPassing> getMarkPassings(Competitor competitor);
|
||||
|
||||
/**
|
||||
* Returns competitor's mark passings.
|
||||
*
|
||||
* @param waitForLatestUpdates
|
||||
* if any mark passing updates are pending because some calculations are currently going on and updates
|
||||
* haven't all been processed yet then the call will block until these updates have been processed in
|
||||
* case this parameter is set to {@code true}. For this the method uses a lock on the
|
||||
* {@link MarkPassingCalculator }to block the thread until all calculations will be finished.
|
||||
*/
|
||||
NavigableSet<MarkPassing> getMarkPassings(Competitor competitor, boolean waitForLatestUpdates);
|
||||
|
||||
/**
|
||||
* This obtains the course's read lock before asking for the read lock for the <code>markPassings</code> structure.
|
||||
@@ -685,6 +698,8 @@ public interface TrackedRace extends Serializable, IsManagedByCache<SharedDomain
|
||||
Distance getAverageSignedCrossTrackError(Competitor competitor, TimePoint from, TimePoint to, boolean upwindOnly,
|
||||
boolean waitForLatestAnalysis) throws NoWindException;
|
||||
|
||||
public Distance getAverageRideHeight(Competitor competitor, TimePoint timePoint);
|
||||
|
||||
WindStore getWindStore();
|
||||
|
||||
Competitor getOverallLeader(TimePoint timePoint);
|
||||
|
||||
+15
-10
@@ -1,10 +1,8 @@
|
||||
package com.sap.sailing.domain.tracking.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.Spliterator;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.sensordata.BravoSensorDataMetadata;
|
||||
import com.sap.sailing.domain.common.tracking.BravoFix;
|
||||
import com.sap.sailing.domain.tracking.BravoFixTrack;
|
||||
@@ -34,7 +32,7 @@ public class BravoFixTrackImpl<ItemType extends WithID & Serializable> extends S
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRideHeight(TimePoint timePoint) {
|
||||
public Distance getRideHeight(TimePoint timePoint) {
|
||||
BravoFix fixAfter = getFirstFixAtOrAfter(timePoint);
|
||||
if (fixAfter != null && fixAfter.getTimePoint().compareTo(timePoint) == 0) {
|
||||
// exact match of timepoint -> no interpolation necessary
|
||||
@@ -54,17 +52,24 @@ public class BravoFixTrackImpl<ItemType extends WithID & Serializable> extends S
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getAverageRideHeight(TimePoint from, TimePoint to) {
|
||||
public Distance getAverageRideHeight(TimePoint from, TimePoint to) {
|
||||
final Distance result;
|
||||
lockForRead();
|
||||
try {
|
||||
Spliterator<BravoFix> fixes = getFixes(from, true, to, true).spliterator();
|
||||
OptionalDouble average = StreamSupport.stream(fixes, false).mapToDouble(BravoFix::getRideHeight).average();
|
||||
if (average.isPresent()) {
|
||||
return average.getAsDouble();
|
||||
Distance sum = Distance.NULL;
|
||||
int count = 0;
|
||||
for (final BravoFix fix : getFixes(from, true, to, true)) {
|
||||
sum = sum.add(fix.getRideHeight());
|
||||
count++;
|
||||
}
|
||||
if (count > 0) {
|
||||
result = sum.scale(1./count);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
} finally {
|
||||
unlockAfterRead();
|
||||
}
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -723,7 +723,7 @@ public class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends MappedTra
|
||||
* then the next fix is added to the result interval. This is because for that next fix, <code>fix</code> in that case will be relevant
|
||||
* for speed estimation because it's the closest fix.
|
||||
*/
|
||||
protected Util.Pair<TimePoint, TimePoint> getTimeIntervalWhoseEstimatedSpeedMayHaveChangedAfterAddingFix(FixType fix) {
|
||||
protected TimeRange getTimeIntervalWhoseEstimatedSpeedMayHaveChangedAfterAddingFix(FixType fix) {
|
||||
TimePoint intervalStart = null;
|
||||
TimePoint intervalEnd = null;
|
||||
lockForRead();
|
||||
@@ -783,7 +783,7 @@ public class GPSFixTrackImpl<ItemType, FixType extends GPSFix> extends MappedTra
|
||||
} finally {
|
||||
unlockAfterRead();
|
||||
}
|
||||
return new Util.Pair<TimePoint, TimePoint>(intervalStart, intervalEnd);
|
||||
return new TimeRangeImpl(intervalStart, intervalEnd);
|
||||
}
|
||||
|
||||
protected FixType createDummyGPSFix(TimePoint at) {
|
||||
|
||||
+22
-18
@@ -13,8 +13,10 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.tracking.GPSFixTrack;
|
||||
import com.sap.sailing.domain.tracking.GPSTrackListener;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.TimeRange;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
import com.sap.sse.concurrent.LockUtil;
|
||||
import com.sap.sse.concurrent.NamedReentrantReadWriteLock;
|
||||
import com.sap.sse.util.impl.ArrayListNavigableSet;
|
||||
@@ -58,9 +60,9 @@ public class MaxSpeedCache<ItemType, FixType extends GPSFix> implements GPSTrack
|
||||
* Keys are the "from" time points as passed to {@link #getMaxSpeed(TimePoint, TimePoint)}. Values are navigable
|
||||
* sets of pairs whose {@link Pair#getA() a} component is the "to" parameter as passed to
|
||||
* {@link #getMaxSpeed(TimePoint, TimePoint)}, and whose {@link Pair#getB() b} component is the track's fix where
|
||||
* the averaged maximum speed for that interval was achieved together with the averaged speed at that point. The
|
||||
* navigable set is ordered according to ascending <code>to</code> time points, yielding shorter cache intervals
|
||||
* before longer intervals.
|
||||
* the maximum speed for that interval was achieved together with the speed at that point. The navigable set is
|
||||
* ordered according to ascending <code>to</code> time points, yielding shorter cache intervals before longer
|
||||
* intervals.
|
||||
*/
|
||||
private final Map<TimePoint, NavigableSet<Util.Pair<TimePoint, Util.Pair<FixType, Speed>>>> cache;
|
||||
|
||||
@@ -88,7 +90,7 @@ public class MaxSpeedCache<ItemType, FixType extends GPSFix> implements GPSTrack
|
||||
@Override
|
||||
public void gpsFixReceived(FixType fix, ItemType item, boolean firstFixInTrack) {
|
||||
// find the invalidation interval such that getFixesRelevantForSpeedEstimation, when passed any time point from that interval, produces "fix"
|
||||
Util.Pair<TimePoint, TimePoint> invalidationInterval = track.getTimeIntervalWhoseEstimatedSpeedMayHaveChangedAfterAddingFix(fix);
|
||||
TimeRange invalidationInterval = track.getTimeIntervalWhoseEstimatedSpeedMayHaveChangedAfterAddingFix(fix);
|
||||
LockUtil.lockForWrite(lock);
|
||||
HashMap<TimePoint, NavigableSet<Util.Pair<TimePoint, Util.Pair<FixType, Speed>>>> additionalCacheEntries =
|
||||
new HashMap<TimePoint, NavigableSet<Util.Pair<TimePoint, Util.Pair<FixType, Speed>>>>();
|
||||
@@ -131,33 +133,35 @@ public class MaxSpeedCache<ItemType, FixType extends GPSFix> implements GPSTrack
|
||||
|
||||
private Map<TimePoint, NavigableSet<Util.Pair<TimePoint, Util.Pair<FixType, Speed>>>> invalidateEntriesAndReturnAdditionalCacheEntries(
|
||||
Entry<TimePoint, NavigableSet<Util.Pair<TimePoint, Util.Pair<FixType, Speed>>>> cacheEntry,
|
||||
Util.Pair<TimePoint, TimePoint> invalidationInterval) {
|
||||
TimeRange invalidationInterval) {
|
||||
assert lock.writeLock().isHeldByCurrentThread();
|
||||
// cannot modify cache here because caller is in an iteration over cache's entry set; request additions by returning them
|
||||
Map<TimePoint, NavigableSet<Util.Pair<TimePoint, Util.Pair<FixType, Speed>>>> result = new HashMap<>();
|
||||
if (!cacheEntry.getKey().after(invalidationInterval.getB())) {
|
||||
final TimePoint cacheEntryFrom = cacheEntry.getKey();
|
||||
if (!cacheEntryFrom.after(invalidationInterval.to())) {
|
||||
// invalidation can only become necessary if the cache entry doesn't start after the end of the invalidation interval
|
||||
TimePoint croppedFrom; // start of the remaining valid part of the cache entries
|
||||
if (cacheEntry.getKey().before(invalidationInterval.getA())) {
|
||||
croppedFrom = cacheEntry.getKey();
|
||||
} else {
|
||||
croppedFrom = invalidationInterval.getB(); // cache entry starts in the invalidationInterval; earliest valid point is end of invalidation interval
|
||||
}
|
||||
// now scan all entries whose "to" is at or after the invalidationInterval's start:
|
||||
for (Iterator<Util.Pair<TimePoint, Util.Pair<FixType, Speed>>> toAndResultIter = cacheEntry.getValue().tailSet(
|
||||
new Util.Pair<TimePoint, Util.Pair<FixType, Speed>>(invalidationInterval.getA(), null), /* inclusive */ true).iterator();
|
||||
new Util.Pair<TimePoint, Util.Pair<FixType, Speed>>(invalidationInterval.from(), null), /* inclusive */ true).iterator();
|
||||
toAndResultIter.hasNext(); ) {
|
||||
Util.Pair<TimePoint, Util.Pair<FixType, Speed>> toAndResult = toAndResultIter.next();
|
||||
// cacheEntry's from is before or in the invalidation interval; the current "to" in this loop iteration is in or after the interval
|
||||
// and at or after "from"; in any case the record needs to be deleted:
|
||||
toAndResultIter.remove();
|
||||
// if the current "to" is at or after croppedFrom, check if the old max fix is in the cropped interval; if so, request
|
||||
// creation of a new cache entry:
|
||||
// check if the old max fix is outside the invalidation interval; if so, request creation of a new cropped cache entry
|
||||
if (toAndResult.getB() != null) {
|
||||
final TimePoint maxFixTimePoint = toAndResult.getB().getA().getTimePoint();
|
||||
if (!toAndResult.getA().before(croppedFrom) && !maxFixTimePoint.before(croppedFrom)
|
||||
&& !maxFixTimePoint.after(toAndResult.getA())) {
|
||||
addEntryToMap(croppedFrom, toAndResult.getA(), toAndResult.getB(), result);
|
||||
if (!invalidationInterval.includes(maxFixTimePoint)) {
|
||||
final TimePoint cacheEntryTo = toAndResult.getA();
|
||||
final TimeRange croppedCacheEntryTimeRangeContainingMaxFix;
|
||||
if (invalidationInterval.startsAfter(maxFixTimePoint)) {
|
||||
croppedCacheEntryTimeRangeContainingMaxFix = new TimeRangeImpl(cacheEntryFrom, invalidationInterval.from());
|
||||
} else { // invalidation interval must end before the maxFixTimePoint
|
||||
assert invalidationInterval.endsBefore(maxFixTimePoint);
|
||||
croppedCacheEntryTimeRangeContainingMaxFix = new TimeRangeImpl(invalidationInterval.to(), cacheEntryTo);
|
||||
}
|
||||
addEntryToMap(croppedCacheEntryTimeRangeContainingMaxFix.from(),
|
||||
croppedCacheEntryTimeRangeContainingMaxFix.to(), toAndResult.getB(), result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-6
@@ -174,8 +174,7 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
|
||||
}
|
||||
if (timePointToUse != null) {
|
||||
Distance d = getDistanceTraveled(timePointToUse);
|
||||
long millis = timePointToUse.asMillis() - legStart.getTimePoint().asMillis();
|
||||
result = d.inTime(millis);
|
||||
result = d.inTime(legStart.getTimePoint().until(timePointToUse));
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
@@ -184,7 +183,7 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getAverageRideHeight(TimePoint timePoint) {
|
||||
public Distance getAverageRideHeight(TimePoint timePoint) {
|
||||
MarkPassing legStart = getMarkPassingForLegStart();
|
||||
if (legStart != null) {
|
||||
BravoFixTrack<Competitor> track = getTrackedRace()
|
||||
@@ -677,15 +676,17 @@ public class TrackedLegOfCompetitorImpl implements TrackedLegOfCompetitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRideHeight(TimePoint at) {
|
||||
public Distance getRideHeight(TimePoint at) {
|
||||
final Distance result;
|
||||
if (hasStartedLeg(at)) {
|
||||
TimePoint timePoint =hasFinishedLeg(at) ? getMarkPassingForLegEnd().getTimePoint() : at;
|
||||
BravoFixTrack<Competitor> track = getTrackedRace()
|
||||
.<BravoFix, BravoFixTrack<Competitor>> getSensorTrack(competitor, BravoFixTrack.TRACK_NAME);
|
||||
return track == null ? null : track.getRideHeight(timePoint);
|
||||
result = track == null ? null : track.getRideHeight(timePoint);
|
||||
} else {
|
||||
return null;
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+31
-1
@@ -707,7 +707,21 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
|
||||
@Override
|
||||
public NavigableSet<MarkPassing> getMarkPassings(Competitor competitor) {
|
||||
return markPassingsForCompetitor.get(competitor);
|
||||
return getMarkPassings(competitor, /* waitForLatestUpdates */ false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableSet<MarkPassing> getMarkPassings(Competitor competitor, boolean waitForLatestUpdates) {
|
||||
if (waitForLatestUpdates && markPassingCalculator != null) {
|
||||
markPassingCalculator.lockForRead();
|
||||
}
|
||||
try {
|
||||
return markPassingsForCompetitor.get(competitor);
|
||||
} finally {
|
||||
if (waitForLatestUpdates && markPassingCalculator != null) {
|
||||
markPassingCalculator.unlockForRead();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected NavigableSet<MarkPassing> getMarkPassingsInOrderAsNavigableSet(Waypoint waypoint) {
|
||||
@@ -1538,6 +1552,22 @@ public abstract class TrackedRaceImpl extends TrackedRaceWithWindEssentials impl
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getAverageRideHeight(Competitor competitor, TimePoint timePoint) {
|
||||
final Distance result;
|
||||
BravoFixTrack<Competitor> track = getSensorTrack(competitor, BravoFixTrack.TRACK_NAME);
|
||||
final Leg firstLeg;
|
||||
final TrackedLegOfCompetitor firstTrackedLeg;
|
||||
if (track != null && (firstLeg = getRace().getCourse().getFirstLeg()) != null && (firstTrackedLeg = getTrackedLeg(competitor, firstLeg)).hasStartedLeg(timePoint)) {
|
||||
final TrackedLegOfCompetitor lastTrackedLeg = getTrackedLegFinishingAt(getRace().getCourse().getLastWaypoint()).getTrackedLeg(competitor);
|
||||
TimePoint endTimePoint = lastTrackedLeg.hasFinishedLeg(timePoint) ? lastTrackedLeg.getFinishTime() : timePoint;
|
||||
result = track.getAverageRideHeight(firstTrackedLeg.getStartTime(), endTimePoint);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrackedLegOfCompetitor getCurrentLeg(Competitor competitor, TimePoint timePoint) {
|
||||
// If the mark passing that starts a leg happened exactly at timePoint, the MarkPassingByTimeComparator won't consider
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.sap.sailing.util;
|
||||
|
||||
import com.sap.sailing.domain.base.BoatClass;
|
||||
import com.sap.sailing.domain.base.Regatta;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.impl.MeterDistance;
|
||||
|
||||
public class RegattaUtil {
|
||||
|
||||
public static final Distance DEFAULT_BUOY_ZONE_RADIUS = new MeterDistance(15);
|
||||
|
||||
public static Distance getCalculatedRegattaBuoyZoneRadius(Regatta regatta, BoatClass boatClass) {
|
||||
final double buoyZoneRadiusInHullLengths;
|
||||
if (regatta != null && regatta.getBuoyZoneRadiusInHullLengths() != null) {
|
||||
buoyZoneRadiusInHullLengths = regatta.getBuoyZoneRadiusInHullLengths();
|
||||
} else {
|
||||
buoyZoneRadiusInHullLengths = Regatta.DEFAULT_BUOY_ZONE_RADIUS_IN_HULL_LENGTHS;
|
||||
}
|
||||
final Distance boatHullLength = boatClass == null ? null : boatClass.getHullLength();
|
||||
final Distance buyZoneRadius = boatHullLength == null ? DEFAULT_BUOY_ZONE_RADIUS
|
||||
: boatHullLength.scale(buoyZoneRadiusInHullLengths);
|
||||
return buyZoneRadius;
|
||||
}
|
||||
}
|
||||
+10
@@ -860,4 +860,14 @@ public class MockedTrackedRace implements DynamicTrackedRace {
|
||||
public Iterable<RaceLog> getAttachedRaceLogs() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableSet<MarkPassing> getMarkPassings(Competitor competitor, boolean waitForLatestUpdates) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getAverageRideHeight(Competitor competitor, TimePoint timePoint) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -41,7 +41,7 @@ public class PingMarkViaRegattaLogTest {
|
||||
Collections.singletonList(columnName), service);
|
||||
Regatta regatta = service.createRegatta(RegattaImpl.getDefaultName("regatta", "Laser"), "Laser", /*startDate*/ null, /*endDate*/ null,
|
||||
UUID.randomUUID(), Collections.<Series>singletonList(series),
|
||||
false, new HighPoint(), UUID.randomUUID(), /* useStartTimeInference */ true,
|
||||
false, new HighPoint(), UUID.randomUUID(), /*buoyZoneRadiusInHullLengths*/2.0, /* useStartTimeInference */ true,
|
||||
/* controlTrackingFromStartAndFinishTimes */ false, RankingMetricsFactory.getRankingMetricConstructor(RankingMetrics.ONE_DESIGN));
|
||||
RegattaLeaderboard leaderboard = service.addRegattaLeaderboard(regatta.getRegattaIdentifier(), "RegattaLeaderboard", new int[] {});
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
<!-- Any title is fine -->
|
||||
<!-- -->
|
||||
<title>SAP Sailing Analytics AutoPlay</title>
|
||||
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/sailing-reset-2.0.cache.css">
|
||||
<link rel="stylesheet" type="text/css" href="/sailing-normalize-3.0.2.cache.css">
|
||||
<link rel="stylesheet" type="text/css" href="/sailing-fontface-1.0.cache.css">
|
||||
<link rel="stylesheet" type="text/css" href="LeaderboardNewHome.css">
|
||||
|
||||
@@ -1,256 +1,260 @@
|
||||
/** Add css rules here for your application. */
|
||||
/*
|
||||
body #calendar:after
|
||||
content: " ";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
*/
|
||||
.clearafter {
|
||||
clear: both;
|
||||
font-size: 1px;
|
||||
height: 0px;
|
||||
line-height: 0px;
|
||||
margin: -1px 0 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cover {
|
||||
left: -1000px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: -1000px;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
background: url(images/spectatorview-bg.png) no-repeat left top #ebebeb;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
padding: 85px 0 0 0;
|
||||
margin: 0;
|
||||
color: #3b3b3b;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2968c0;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
table td,select,button {
|
||||
line-height: 1;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.gwt-DialogBox {
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.gwt-ToggleButton {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.gwt-PopupPanelGlass {
|
||||
z-index: 19;
|
||||
}
|
||||
|
||||
.contentOuterPanel {
|
||||
background: #dddcdc;
|
||||
margin: 0 12px 0 12px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
/** Example rules used by the template application (remove for your app) */
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
color: #777777;
|
||||
margin: 40px 0px 70px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
.LogoAndTitlePanel {
|
||||
height: 68px;
|
||||
font-family: Arial, Verdana, sans-serif;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
background-image: url(images/white_gradient_header.png), url(images/header_bg_modern.png);
|
||||
background-position: center top, 0 0;
|
||||
background-repeat: no-repeat, repeat-x;
|
||||
box-shadow: 0 0 20px #858585;
|
||||
-moz-box-shadow: 0 0 20px #858585;
|
||||
-webkit-box-shadow: 0 0 20px #858585;
|
||||
-o-box-shadow: 0 0 20px #858585;
|
||||
-ms-box-shadow: 0 0 20px #858585;
|
||||
}
|
||||
|
||||
.LogoAndTitlePanel:after {
|
||||
content: " ";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.RaceBoardHeaderPanel {
|
||||
margin: 0 12px 18px 12px;
|
||||
}
|
||||
|
||||
.sapLogo {
|
||||
float: left;
|
||||
margin: 13px 0 0 12px;
|
||||
}
|
||||
|
||||
.sailingAnalyticsLabelPanel {
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
|
||||
.sailingAnalyticsLabel {
|
||||
float: left;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin: 15px 0 0 0;
|
||||
}
|
||||
|
||||
.leaderboardLabel {
|
||||
border-bottom: 2px solid #007dc0;
|
||||
font-weight: bold;
|
||||
padding: 0 0 6px 0;
|
||||
}
|
||||
|
||||
.refreshAndSettings {
|
||||
background: #f2f2f2;
|
||||
border-bottom: 2px solid #fff;
|
||||
border-top: 2px solid #fff;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.refreshAndSettings table td {
|
||||
padding: 0 10px 0 0;
|
||||
}
|
||||
|
||||
.refreshAndSettings table table td {
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
|
||||
.race-name {
|
||||
margin: 2px 10px 0 0;
|
||||
line-height: 1.0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
input.magnifier {
|
||||
display: block;
|
||||
margin: 3px auto 0 auto !important;
|
||||
}
|
||||
|
||||
.footerShadowPanel {
|
||||
position: fixed;
|
||||
height: 50px;
|
||||
bottom: 0;
|
||||
background: url(images/footer_shadow.png) left bottom repeat-x;
|
||||
width: 100%;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.mainPanel {
|
||||
width: 100%;
|
||||
margin-left: 13px;
|
||||
}
|
||||
|
||||
.errorLabel {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
.chart-importantMessage {
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
padding: 49px 0 0 80px;
|
||||
width: 400px;
|
||||
color: #7c7c7c;
|
||||
background: url(images/important-message.png) left center no-repeat;
|
||||
}
|
||||
|
||||
.chart-busyMessage {
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
padding: 49px 0 0 40px;
|
||||
width: 400px;
|
||||
color: #7c7c7c;
|
||||
background: url(images/busy_indicator_circle.gif) left center no-repeat;
|
||||
}
|
||||
|
||||
.dataMiningPanel {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.dataMiningPanel-filledElement {
|
||||
background: url("images/btn-cta-orangeleft.png") repeat-x scroll center 0 transparent;
|
||||
border-bottom-left-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
font-family: 'Open Sans',Verdana,Arial,sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
margin: 0 0 0 0;
|
||||
padding: 2px 7px 2px 3px;
|
||||
height: 18px;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
-moz-border-radius: 5px 0 0 5px;
|
||||
-webkit-border-radius: 5px 0 0 5px;
|
||||
-o-border-radius: 5px 0 0 5px;
|
||||
-ms-border-radius: 5px 0 0 5px;
|
||||
border-radius: 5px 0 0 5px;
|
||||
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
-o-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
-ms-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.settingsAnchor {
|
||||
position: relative;
|
||||
top: 9px;
|
||||
}
|
||||
|
||||
.groupingProviderElement {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.statisticProviderElement {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.definitionProviderControls {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.definitionProviderControlsElements {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.queryDefinitionViewerContent {
|
||||
background-color: white;
|
||||
padding: 5px;
|
||||
/** Add css rules here for your application. */
|
||||
/*
|
||||
body #calendar:after
|
||||
content: " ";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
*/
|
||||
html {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.clearafter {
|
||||
clear: both;
|
||||
font-size: 1px;
|
||||
height: 0px;
|
||||
line-height: 0px;
|
||||
margin: -1px 0 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cover {
|
||||
left: -1000px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: -1000px;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
background: url(images/spectatorview-bg.png) no-repeat left top #ebebeb;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
line-height: 1;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
padding: 85px 0 0 0;
|
||||
margin: 0;
|
||||
color: #3b3b3b;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2968c0;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
table td,select,button {
|
||||
line-height: 1;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.gwt-DialogBox {
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
.gwt-ToggleButton {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.gwt-PopupPanelGlass {
|
||||
z-index: 19;
|
||||
}
|
||||
|
||||
.contentOuterPanel {
|
||||
background: #dddcdc;
|
||||
margin: 0 12px 0 12px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
/** Example rules used by the template application (remove for your app) */
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
color: #777777;
|
||||
margin: 40px 0px 70px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
.LogoAndTitlePanel {
|
||||
height: 68px;
|
||||
font-family: Arial, Verdana, sans-serif;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
background-image: url(images/white_gradient_header.png), url(images/header_bg_modern.png);
|
||||
background-position: center top, 0 0;
|
||||
background-repeat: no-repeat, repeat-x;
|
||||
box-shadow: 0 0 20px #858585;
|
||||
-moz-box-shadow: 0 0 20px #858585;
|
||||
-webkit-box-shadow: 0 0 20px #858585;
|
||||
-o-box-shadow: 0 0 20px #858585;
|
||||
-ms-box-shadow: 0 0 20px #858585;
|
||||
}
|
||||
|
||||
.LogoAndTitlePanel:after {
|
||||
content: " ";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.RaceBoardHeaderPanel {
|
||||
margin: 0 12px 18px 12px;
|
||||
}
|
||||
|
||||
.sapLogo {
|
||||
float: left;
|
||||
margin: 13px 0 0 12px;
|
||||
}
|
||||
|
||||
.sailingAnalyticsLabelPanel {
|
||||
margin: 10px 0 0 0;
|
||||
}
|
||||
|
||||
.sailingAnalyticsLabel {
|
||||
float: left;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
margin: 15px 0 0 0;
|
||||
}
|
||||
|
||||
.leaderboardLabel {
|
||||
border-bottom: 2px solid #007dc0;
|
||||
font-weight: bold;
|
||||
padding: 0 0 6px 0;
|
||||
}
|
||||
|
||||
.refreshAndSettings {
|
||||
background: #f2f2f2;
|
||||
border-bottom: 2px solid #fff;
|
||||
border-top: 2px solid #fff;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.refreshAndSettings table td {
|
||||
padding: 0 10px 0 0;
|
||||
}
|
||||
|
||||
.refreshAndSettings table table td {
|
||||
padding: 0 0 0 0;
|
||||
}
|
||||
|
||||
.race-name {
|
||||
margin: 2px 10px 0 0;
|
||||
line-height: 1.0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
input.magnifier {
|
||||
display: block;
|
||||
margin: 3px auto 0 auto !important;
|
||||
}
|
||||
|
||||
.footerShadowPanel {
|
||||
position: fixed;
|
||||
height: 50px;
|
||||
bottom: 0;
|
||||
background: url(images/footer_shadow.png) left bottom repeat-x;
|
||||
width: 100%;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.mainPanel {
|
||||
width: 100%;
|
||||
margin-left: 13px;
|
||||
}
|
||||
|
||||
.errorLabel {
|
||||
color: #FF0000;
|
||||
}
|
||||
|
||||
.chart-importantMessage {
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
padding: 49px 0 0 80px;
|
||||
width: 400px;
|
||||
color: #7c7c7c;
|
||||
background: url(images/important-message.png) left center no-repeat;
|
||||
}
|
||||
|
||||
.chart-busyMessage {
|
||||
font-family: 'Open Sans',Arial,Verdana,sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
height: 70px;
|
||||
margin: 0 auto;
|
||||
padding: 49px 0 0 40px;
|
||||
width: 400px;
|
||||
color: #7c7c7c;
|
||||
background: url(images/busy_indicator_circle.gif) left center no-repeat;
|
||||
}
|
||||
|
||||
.dataMiningPanel {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.dataMiningPanel-filledElement {
|
||||
background: url("images/btn-cta-orangeleft.png") repeat-x scroll center 0 transparent;
|
||||
border-bottom-left-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
font-family: 'Open Sans',Verdana,Arial,sans-serif;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
margin: 0 0 0 0;
|
||||
padding: 2px 7px 2px 3px;
|
||||
height: 18px;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
-moz-border-radius: 5px 0 0 5px;
|
||||
-webkit-border-radius: 5px 0 0 5px;
|
||||
-o-border-radius: 5px 0 0 5px;
|
||||
-ms-border-radius: 5px 0 0 5px;
|
||||
border-radius: 5px 0 0 5px;
|
||||
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
-o-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
-ms-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.settingsAnchor {
|
||||
position: relative;
|
||||
top: 9px;
|
||||
}
|
||||
|
||||
.groupingProviderElement {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.statisticProviderElement {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.definitionProviderControls {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.definitionProviderControlsElements {
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.queryDefinitionViewerContent {
|
||||
background-color: white;
|
||||
padding: 5px;
|
||||
}
|
||||
@@ -5,9 +5,7 @@ table {
|
||||
}
|
||||
|
||||
.leaderboardContent td, .leaderboardContent th {
|
||||
vertical-align: bottom;
|
||||
line-height: 1.3;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.leaderboardContent-toolbar {
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
top: -1000px;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
body {
|
||||
background: url(images/spectatorview-bg.png) no-repeat left top #ebebeb;
|
||||
@@ -48,7 +51,7 @@ table td,select,button {
|
||||
|
||||
.contentOuterPanel {
|
||||
background: #dddcdc;
|
||||
margin: 0 12px 0 12px;
|
||||
margin: 0 12px 120px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
@@ -159,6 +162,7 @@ input.magnifier {
|
||||
.mainPanel {
|
||||
width: 100%;
|
||||
margin-left: 13px;
|
||||
margin-bottom: 120px;
|
||||
}
|
||||
|
||||
.leaderboardGroupPanel-GroupName {
|
||||
@@ -187,7 +191,8 @@ input.magnifier {
|
||||
margin: 5px 5px 5px 0;
|
||||
text-decoration: none;
|
||||
font-family: 'Open Sans', Arial, Verdana, sans-serif;
|
||||
font-weight: 600
|
||||
font-weight: 600;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.leaderboardGroupPanel-BoatClass {
|
||||
@@ -206,8 +211,8 @@ input.magnifier {
|
||||
padding: 5px;
|
||||
display: block;
|
||||
float: left;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path fill=
|
||||
"#FFF" d="M10,2a8,8,0,1,1-8,8,8,8,0,0,1,8-8m0-2A10,10,0,1,0,20,10,10,10,0,0,0,
|
||||
10,0h0ZM9.71,10l0.08,0L9.71,10V10m-2-3.43v7l3.07-1.74L13.86,10,10.78,8.26,7.71,
|
||||
6.52h0Z"/></svg>
|
||||
|
After Width: | Height: | Size: 252 B |
+31
-2
@@ -7,8 +7,16 @@ import com.google.gwt.event.shared.EventBus;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.AcceptsOneWidget;
|
||||
import com.sap.sailing.gwt.autoplay.client.shared.leaderboard.LeaderboardWithHeaderPerspectiveLifecycle;
|
||||
import com.sap.sailing.gwt.autoplay.client.shared.leaderboard.LeaderboardWithHeaderPerspectiveSettings;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.raceboard.RaceBoardPerspectiveLifecycle;
|
||||
import com.sap.sailing.gwt.ui.raceboard.RaceBoardPerspectiveSettings;
|
||||
import com.sap.sailing.gwt.ui.shared.EventDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardGroupDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
|
||||
import com.sap.sse.gwt.client.mvp.ErrorView;
|
||||
import com.sap.sse.gwt.client.shared.perspective.PerspectiveLifecycleWithAllSettings;
|
||||
import com.sap.sse.gwt.client.useragent.UserAgentDetails;
|
||||
import com.sap.sse.gwt.shared.GwtHttpRequestUtils;
|
||||
|
||||
@@ -26,6 +34,17 @@ public class PlayerActivity extends AbstractActivity {
|
||||
this.autoPlayController = null;
|
||||
}
|
||||
|
||||
private StrippedLeaderboardDTO getSelectedLeaderboard(EventDTO event,String leaderBoardName) {
|
||||
for (LeaderboardGroupDTO leaderboardGroup : event.getLeaderboardGroups()) {
|
||||
for (StrippedLeaderboardDTO leaderboard : leaderboardGroup.getLeaderboards()) {
|
||||
if (leaderboard.name.equals(leaderBoardName)) {
|
||||
return leaderboard;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(final AcceptsOneWidget panel, EventBus eventBus) {
|
||||
final boolean showRaceDetails = GwtHttpRequestUtils.getBooleanParameter(PARAM_SHOW_RACE_DETAILS, false);
|
||||
@@ -36,6 +55,16 @@ public class PlayerActivity extends AbstractActivity {
|
||||
clientFactory.getSailingService().getEventById(eventUUID, true, new AsyncCallback<EventDTO>() {
|
||||
@Override
|
||||
public void onSuccess(final EventDTO event) {
|
||||
|
||||
//This place fixes a specific null pointer bug3950, once the settings are redone, this should be removed, and instead be done via playerplace (see comment there)
|
||||
StrippedLeaderboardDTO leaderBoardDTO = getSelectedLeaderboard(event,playerPlace.getConfiguration().getLeaderboardName());
|
||||
LeaderboardWithHeaderPerspectiveLifecycle leaderboardPerspectiveLifecycle = new LeaderboardWithHeaderPerspectiveLifecycle(leaderBoardDTO, StringMessages.INSTANCE);
|
||||
PerspectiveLifecycleWithAllSettings<LeaderboardWithHeaderPerspectiveLifecycle, LeaderboardWithHeaderPerspectiveSettings> leaderboardPerspectiveLifecyclesAndSettings = new PerspectiveLifecycleWithAllSettings<>(leaderboardPerspectiveLifecycle, leaderboardPerspectiveLifecycle.createDefaultSettings());
|
||||
RaceBoardPerspectiveLifecycle raceboardPerspectiveLifecycle = new RaceBoardPerspectiveLifecycle(leaderBoardDTO, StringMessages.INSTANCE);
|
||||
PerspectiveLifecycleWithAllSettings<RaceBoardPerspectiveLifecycle, RaceBoardPerspectiveSettings> raceboardPerspectiveLifecyclesAndSettings = new PerspectiveLifecycleWithAllSettings<>(raceboardPerspectiveLifecycle, raceboardPerspectiveLifecycle.createDefaultSettings());
|
||||
|
||||
|
||||
|
||||
UserAgentDetails userAgent = new UserAgentDetails(Window.Navigator.getUserAgent());
|
||||
|
||||
PlayerView view = clientFactory.createPlayerView();
|
||||
@@ -44,8 +73,8 @@ public class PlayerActivity extends AbstractActivity {
|
||||
autoPlayController = new AutoPlayController(clientFactory.getSailingService(), clientFactory
|
||||
.getMediaService(), clientFactory.getUserService(), clientFactory.getErrorReporter(),
|
||||
playerPlace.getConfiguration(), userAgent, delayToLiveMillis, showRaceDetails, view,
|
||||
playerPlace.getLeaderboardPerspectiveLifecycleWithAllSettings(),
|
||||
playerPlace.getRaceboardPerspectiveLifecycleWithAllSettings());
|
||||
leaderboardPerspectiveLifecyclesAndSettings,
|
||||
raceboardPerspectiveLifecyclesAndSettings);
|
||||
autoPlayController.updatePlayMode(AutoPlayModes.Leaderboard);
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -23,6 +23,8 @@ public class PlayerPlace extends AbstractBasePlace {
|
||||
Integer timeToSwitchBeforeRaceStartInSeconds = Integer.valueOf(getParameter(AutoPlayerConfiguration.PARAM_TIME_TO_SWITCH_BEFORE_RACE_START));
|
||||
|
||||
this.playerConfiguration = new AutoPlayerConfiguration(eventUuidAsString, leaderboardName, fullscreen, timeToSwitchBeforeRaceStartInSeconds);
|
||||
|
||||
//these are currently regenerated in the PlayerActivity, based on the historydata. Once the settings are properly stored, this should be replaced.
|
||||
this.leaderboardPerspectiveLifecycleWithAllSettings = null;
|
||||
this.raceboardPerspectiveLifecycleWithAllSettings = null;
|
||||
}
|
||||
|
||||
+11
-1
@@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sse.gwt.dispatch.shared.commands.DTO;
|
||||
|
||||
public class RegattaMetadataDTO extends RegattaReferenceDTO implements HasRegattaMetadata {
|
||||
@@ -18,6 +19,7 @@ public class RegattaMetadataDTO extends RegattaReferenceDTO implements HasRegatt
|
||||
private RegattaState state;
|
||||
private boolean flexibleLeaderboard;
|
||||
private RaceDataInfo raceDataInfo;
|
||||
private Distance buoyZoneRadius;
|
||||
|
||||
public RegattaMetadataDTO() {
|
||||
}
|
||||
@@ -122,7 +124,15 @@ public class RegattaMetadataDTO extends RegattaReferenceDTO implements HasRegatt
|
||||
public void setRaceDataInfo(RaceDataInfo raceDataInfo) {
|
||||
this.raceDataInfo = raceDataInfo;
|
||||
}
|
||||
|
||||
|
||||
public Distance getBuoyZoneRadius() {
|
||||
return buoyZoneRadius;
|
||||
}
|
||||
|
||||
public void setBuoyZoneRadius(Distance buoyZoneRadius) {
|
||||
this.buoyZoneRadius = buoyZoneRadius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holder class for flags, which inform about GPS, wind, video or audio data availability.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ public class GetFavoritesAction implements SailingAction<FavoritesResult> {
|
||||
if (preferences != null) {
|
||||
for (BoatClassNotificationPreference pref : preferences.getBoatClasses()) {
|
||||
String name = pref.getBoatClass().getName(), displayName = pref.getBoatClass().getDisplayName();
|
||||
selected.add(new BoatClassDTO(name, displayName, pref.getBoatClass().getHullLength().getMeters()));
|
||||
selected.add(new BoatClassDTO(name, displayName, pref.getBoatClass().getHullLength()));
|
||||
notifyAboutUpcomingRaces |= pref.isNotifyAboutUpcomingRaces();
|
||||
notifyAboutResults |= pref.isNotifyAboutResults();
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ public class DropdownItem extends Widget {
|
||||
setElement(uiBinder.createAndBindUi(this));
|
||||
|
||||
if(active) {
|
||||
getElement().addClassName(local_res.css().dropdownregattas_content_linkactive());
|
||||
getElement().addClassName(local_res.css().dropdown_content_linkactive());
|
||||
}
|
||||
|
||||
this.link.setHref(link);
|
||||
|
||||
+2
-2
@@ -8,8 +8,8 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
</ui:style>
|
||||
<a ui:field="link" class="{local_res.css.dropdown_content_link} {local_res.css.dropdownregattas_content_link}">
|
||||
<div ui:field="title" class="{local_res.css.dropdown_content_link_title} {local_res.css.dropdownregattas_content_link_title}">
|
||||
<a ui:field="link" class="{local_res.css.dropdown_content_link}">
|
||||
<div ui:field="title" class="{local_res.css.dropdown_content_link_title}">
|
||||
<!-- regatta.name -->
|
||||
</div>
|
||||
</a>
|
||||
|
||||
+54
-78
@@ -10,92 +10,40 @@
|
||||
}
|
||||
.dropdown {
|
||||
font-size: 1rem;
|
||||
width: 20em;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
text-align: left;
|
||||
}
|
||||
.dropdown_head {
|
||||
display: block;
|
||||
}
|
||||
.dropdown_head_title {
|
||||
font-size: 1.866666666666667em;
|
||||
cursor: pointer;
|
||||
background: #f8f8f8;
|
||||
color: #cfcfcf;
|
||||
height: 1.464285714285714em;
|
||||
line-height: 1.428571428571429em;
|
||||
padding-left: 0.535714285714286em;
|
||||
font-weight: 700;
|
||||
}
|
||||
.dropdown_head_title_button {
|
||||
float: right;
|
||||
}
|
||||
.dropdown_content {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
background: #f6f9fc;
|
||||
display: none;
|
||||
width: 20em;
|
||||
height: auto;
|
||||
max-height: 23.333333333333332em;
|
||||
overflow: auto;
|
||||
box-shadow: 0 0.066666666666667em 0.266666666666667em #eee;
|
||||
border-bottom: solid 1px #eee;
|
||||
}
|
||||
.jsdropdownactive .dropdown_content {
|
||||
display: block;
|
||||
}
|
||||
.dropdown_content_link {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
padding: 1.333333333333333em 3.333333333333333em 1em 1em;
|
||||
border-bottom: 1px solid #f4f4f4;
|
||||
}
|
||||
.dropdown_content_link:hover,
|
||||
.dropdown_content_link:focus {
|
||||
background: #f8f8f8;
|
||||
text-decoration: none;
|
||||
}
|
||||
.dropdown_content_link:hover .dropdown_content_link_title,
|
||||
.dropdown_content_link:focus .dropdown_content_link_title {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.dropdown_content_link_title {
|
||||
color: #008fcc;
|
||||
display: block;
|
||||
font-weight: 600;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.dropdown_content_link_subtitle {
|
||||
color: #cfcfcf;
|
||||
font-size: 1.066666666666667em;
|
||||
}
|
||||
.dropdownregattas {
|
||||
width: 100%;
|
||||
min-width: 21.333333333333332em;
|
||||
margin-left: -0.666666666666667em;
|
||||
}
|
||||
.dropdownregattas_head {
|
||||
display: inherit;
|
||||
}
|
||||
.dropdownregattas_head_title {
|
||||
padding-left: 0.357142857142857em;
|
||||
background: #f2f2f2;
|
||||
color: #333;
|
||||
.dropdown_head {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
padding-left: 0.75em;
|
||||
padding-right: 1.75em;
|
||||
border-radius: 0.107142857142857em;
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
.dropdownregattas_head_title:hover {
|
||||
.dropdown_head:hover {
|
||||
border: 1px solid #cfcfcf;
|
||||
background-color: #eee;
|
||||
text-decoration: none;
|
||||
}
|
||||
.dropdownregattas_head_title_button {
|
||||
position: relative;
|
||||
.dropdown_head_title {
|
||||
font-size: 1.866666666666667em;
|
||||
color: #333;
|
||||
height: 1.464285714285714em;
|
||||
line-height: 1.428571428571429em;
|
||||
font-weight: 700;
|
||||
}
|
||||
.dropdown_head_title_button {
|
||||
position: absolute;
|
||||
top: 0.75em;
|
||||
right: 0;
|
||||
display: inline-block;
|
||||
margin-left: 0.714285714285714em;
|
||||
top: 50%;
|
||||
height: 0.285714285714286em;
|
||||
width: 0.428571428571429em;
|
||||
background-image: url("images/home/dropdown__button--arrow@2x.png");
|
||||
@@ -108,20 +56,51 @@
|
||||
transform: translate(-50%, -50%);
|
||||
float: none;
|
||||
}
|
||||
.dropdownregattas_content {
|
||||
.dropdown_content {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
display: none;
|
||||
height: auto;
|
||||
max-height: 23.333333333333332em;
|
||||
overflow: auto;
|
||||
width: auto;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 0.133333333333333em 0.133333333333333em 0.333333333333333em #ccc;
|
||||
}
|
||||
.dropdownregattas_content_link {
|
||||
.dropdownregattas_content {
|
||||
}
|
||||
.jsdropdownactive .dropdown_content {
|
||||
display: block;
|
||||
}
|
||||
.dropdown_content_link {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
padding: 1.333333333333333em 3.333333333333333em 1em 1em;
|
||||
border-bottom: 1px solid #f4f4f4;
|
||||
position: relative;
|
||||
border: none;
|
||||
}
|
||||
.dropdownregattas_content_link:hover {
|
||||
.dropdown_content_link:hover,
|
||||
.dropdown_content_link:focus {
|
||||
background: #f8f8f8;
|
||||
text-decoration: none;
|
||||
}
|
||||
.dropdownregattas_content_linkactive:after {
|
||||
.dropdown_content_link:hover .dropdown_content_link_title,
|
||||
.dropdown_content_link:focus .dropdown_content_link_title {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.dropdown_content_link_title {
|
||||
display: block;
|
||||
font-weight: 600;
|
||||
font-size: 1.2em;
|
||||
color: #666;
|
||||
}
|
||||
.dropdown_content_link_subtitle {
|
||||
color: #cfcfcf;
|
||||
font-size: 1.066666666666667em;
|
||||
}
|
||||
.dropdown_content_linkactive:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 1.333333333333333em;
|
||||
@@ -137,9 +116,6 @@
|
||||
-ms-transform: translate(0, -50%);
|
||||
transform: translate(0, -50%);
|
||||
}
|
||||
.dropdownregattas_content_link_title {
|
||||
color: #666;
|
||||
}
|
||||
.leaderboardquickaccess {
|
||||
font-size: 1rem;
|
||||
text-align: right;
|
||||
|
||||
+7
-7
@@ -11,19 +11,19 @@
|
||||
<a ui:field="eventLogoAnchorUi"><div ui:field="eventLogo" class="{local_res.css.eventheader_intro_logo_image}" /></a>
|
||||
</div>
|
||||
<!-- IF header.dropdown === 'regattas' -->
|
||||
<div ui:field="dropdownTitle" class="{local_res.css.dropdown} {local_res.css.dropdownregattas} {local_res.css.jsdropdown}">
|
||||
<div class="{local_res.css.dropdown_head} {local_res.css.dropdownregattas_head} {local_res.css.jsdropdown_head}">
|
||||
<a ui:field="dropdownTrigger" class="{local_res.css.dropdown_head_title} {local_res.css.dropdownregattas_head_title}">
|
||||
<div ui:field="dropdownTitle" class="{local_res.css.dropdown} {local_res.css.jsdropdown}">
|
||||
<a ui:field="dropdownTrigger" class="{local_res.css.dropdown_head} {local_res.css.jsdropdown_head}">
|
||||
<span class="{local_res.css.dropdown_head_title}">
|
||||
<span ui:field="dropdownEventName"></span>
|
||||
<!-- IF event.state === 'live' -->
|
||||
<div ui:field="dropdownEventState" data-labeltype="live" class="{res.mainCss.label} {res.mainCss.labellarge}">
|
||||
<!-- <ui:text from='{i18n.live}' /> -->
|
||||
</div>
|
||||
<!-- IFEND event.state === 'live' -->
|
||||
<div class="{local_res.css.dropdown_head_title_button} {local_res.css.dropdownregattas_head_title_button}"></div>
|
||||
</a>
|
||||
</div>
|
||||
<g:FlowPanel ui:field="dropdownContent" addStyleNames="{local_res.css.dropdown_content} {local_res.css.dropdownregattas_content} {local_res.css.jsdropdown_content}">
|
||||
<div class="{local_res.css.dropdown_head_title_button}"></div>
|
||||
</span>
|
||||
</a>
|
||||
<g:FlowPanel ui:field="dropdownContent" addStyleNames="{local_res.css.dropdown_content} {local_res.css.jsdropdown_content}">
|
||||
<!-- EACH regattaItem in event.regattas -->
|
||||
<!-- TODO <s:eventHeader.RegattasDropdownItem ui:field='regattaItem'></s> -->
|
||||
<!-- EACHEND -->
|
||||
|
||||
+1
-8
@@ -23,14 +23,7 @@ public interface EventHeaderResources extends ClientBundle {
|
||||
String dropdown_content_link();
|
||||
String dropdown_content_link_title();
|
||||
String dropdown_content_link_subtitle();
|
||||
String dropdownregattas();
|
||||
String dropdownregattas_head();
|
||||
String dropdownregattas_head_title();
|
||||
String dropdownregattas_head_title_button();
|
||||
String dropdownregattas_content();
|
||||
String dropdownregattas_content_link();
|
||||
String dropdownregattas_content_linkactive();
|
||||
String dropdownregattas_content_link_title();
|
||||
String dropdown_content_linkactive();
|
||||
String leaderboardquickaccess();
|
||||
String eventheader();
|
||||
String eventheader_breadcrumb();
|
||||
|
||||
+43
-1
@@ -10,6 +10,8 @@ import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.dom.client.Style.Visibility;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.event.logical.shared.AttachEvent;
|
||||
import com.google.gwt.event.logical.shared.AttachEvent.Handler;
|
||||
import com.google.gwt.event.logical.shared.CloseEvent;
|
||||
import com.google.gwt.event.logical.shared.CloseHandler;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
@@ -21,10 +23,13 @@ import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.HTMLPanel;
|
||||
import com.google.gwt.user.client.ui.PopupPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.dto.LeaderboardDTO;
|
||||
import com.sap.sailing.domain.common.dto.RaceColumnDTO;
|
||||
import com.sap.sailing.gwt.home.desktop.partials.old.EventRegattaLeaderboardResources;
|
||||
import com.sap.sailing.gwt.home.desktop.partials.old.LeaderboardDelegate;
|
||||
import com.sap.sailing.gwt.ui.client.DebugIdHelper;
|
||||
import com.sap.sailing.gwt.ui.client.LeaderboardUpdateListener;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.common.client.DateAndTimeFormatterUtil;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel;
|
||||
@@ -64,7 +69,7 @@ public class OldLeaderboard extends Composite implements BusyStateChangeListener
|
||||
this(null);
|
||||
}
|
||||
|
||||
public OldLeaderboard(OldLeaderboardDelegate delegate) {
|
||||
public OldLeaderboard(final OldLeaderboardDelegate delegate) {
|
||||
this.leaderboardPanel = null;
|
||||
EventRegattaLeaderboardResources.INSTANCE.css().ensureInjected();
|
||||
initWidget(uiBinder.createAndBindUi(this));
|
||||
@@ -73,6 +78,28 @@ public class OldLeaderboard extends Composite implements BusyStateChangeListener
|
||||
fullscreenAnchor.setTitle(StringMessages.INSTANCE.openFullscreenView());
|
||||
this.delegate = delegate;
|
||||
this.setupFullscreenDelegate();
|
||||
|
||||
// adding handler on page loading
|
||||
this.addAttachHandler(new Handler() {
|
||||
@Override
|
||||
public void onAttachOrDetach(AttachEvent event) {
|
||||
if (event.isAttached() && leaderboardPanel != null) {
|
||||
// waiting while leaderboard is loaded
|
||||
leaderboardPanel.addLeaderboardUpdateListener(new LeaderboardUpdateListener() {
|
||||
@Override
|
||||
public void updatedLeaderboard(LeaderboardDTO leaderboard) {
|
||||
// If race or regatta is live then check button by default
|
||||
if (leaderboard.hasLiveRace(autoRefreshTimer.getLiveTimePointInMillis())) {
|
||||
turnOnAutoPlay();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void currentRaceSelected(RaceIdentifier raceIdentifier, RaceColumnDTO raceColumn) { }
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setupFullscreenDelegate() {
|
||||
@@ -105,6 +132,21 @@ public class OldLeaderboard extends Composite implements BusyStateChangeListener
|
||||
}, ClickEvent.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method turns on auto playing mode on leaderboard
|
||||
*/
|
||||
private void turnOnAutoPlay() {
|
||||
if (autoRefreshTimer.getPlayState() != PlayStates.Playing) {
|
||||
autoRefreshTimer.setPlayMode(PlayModes.Live);
|
||||
}
|
||||
|
||||
// Styles applied each time because of tabs switching. In this case play mode stays as Playing but styling is lost
|
||||
autoRefreshAnchor.addStyleName(local_res.css().regattaleaderboard_meta_reload_live());
|
||||
if (delegate != null) {
|
||||
delegate.getAutoRefreshControl().addStyleName(local_res.css().regattaleaderboard_meta_reload_live());
|
||||
}
|
||||
}
|
||||
|
||||
@UiHandler("autoRefreshAnchor")
|
||||
void toogleAutoRefreshClicked(ClickEvent event) {
|
||||
autoRefreshAnchor.removeStyleName(local_res.css().regattaleaderboard_meta_reload_live());
|
||||
|
||||
+19
-2
@@ -107,6 +107,21 @@ public class OldMultiLeaderboard extends Composite implements SelectedLeaderboar
|
||||
}, ClickEvent.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method turns on auto playing mode on leaderboard
|
||||
*/
|
||||
public void turnOnAutoPlay() {
|
||||
if (autoRefreshTimer.getPlayState() != PlayStates.Playing) {
|
||||
autoRefreshTimer.setPlayMode(PlayModes.Live);
|
||||
}
|
||||
|
||||
// Styles applied each time because of tabs switching. In this case play mode stays as Playing but styling is lost
|
||||
autoRefreshAnchor.addStyleName(local_res.css().regattaleaderboard_meta_reload_live());
|
||||
if (delegate != null) {
|
||||
delegate.getAutoRefreshControl().addStyleName(local_res.css().regattaleaderboard_meta_reload_live());
|
||||
}
|
||||
}
|
||||
|
||||
@UiHandler("autoRefreshAnchor")
|
||||
void toogleAutoRefreshClicked(ClickEvent event) {
|
||||
if (autoRefreshTimer != null) {
|
||||
@@ -114,7 +129,8 @@ public class OldMultiLeaderboard extends Composite implements SelectedLeaderboar
|
||||
autoRefreshAnchor.removeStyleName(local_res.css().regattaleaderboard_meta_reload_playing());
|
||||
if (delegate != null) {
|
||||
delegate.getAutoRefreshControl().removeStyleName(local_res.css().regattaleaderboard_meta_reload_live());
|
||||
delegate.getAutoRefreshControl().removeStyleName(local_res.css().regattaleaderboard_meta_reload_playing());
|
||||
delegate.getAutoRefreshControl()
|
||||
.removeStyleName(local_res.css().regattaleaderboard_meta_reload_playing());
|
||||
}
|
||||
if (autoRefreshTimer.getPlayState() == PlayStates.Playing) {
|
||||
autoRefreshTimer.pause();
|
||||
@@ -131,7 +147,8 @@ public class OldMultiLeaderboard extends Composite implements SelectedLeaderboar
|
||||
autoRefreshAnchor.addStyleName(local_res.css().regattaleaderboard_meta_reload_live());
|
||||
if (delegate != null) {
|
||||
// delegate.getAutoRefreshControl().getElement().getStyle().setBackgroundColor("red");
|
||||
delegate.getAutoRefreshControl().addStyleName(local_res.css().regattaleaderboard_meta_reload_live());
|
||||
delegate.getAutoRefreshControl()
|
||||
.addStyleName(local_res.css().regattaleaderboard_meta_reload_live());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-13
@@ -1,14 +1,14 @@
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
|
||||
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"
|
||||
xmlns:dp="urn:import:com.sap.sailing.gwt.home.desktop.partials">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.desktop.partials.racelist.RaceListResources" />
|
||||
<g:HTMLPanel addStyleNames="{local_res.css.raceslistlive}">
|
||||
<h3 ui:field="titleUi"></h3>
|
||||
<div style="display: none;" ui:field="infoUi"></div>
|
||||
<div style="display: none; font-weight: bold; font-style: italic;" ui:field="noContentPlaceholderUi"></div>
|
||||
<dp:racelist.AbstractRaceList ui:field="raceListUi"/>
|
||||
</g:HTMLPanel>
|
||||
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
|
||||
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"
|
||||
xmlns:s="urn:import:com.sap.sailing.gwt.home.client.shared"
|
||||
xmlns:dp="urn:import:com.sap.sailing.gwt.home.desktop.partials">
|
||||
<ui:with field="i18n" type="com.sap.sailing.gwt.ui.client.StringMessages" />
|
||||
<ui:with field="res" type="com.sap.sailing.gwt.common.client.SharedResources" />
|
||||
<ui:with field="local_res" type="com.sap.sailing.gwt.home.desktop.partials.racelist.RaceListResources" />
|
||||
<g:HTMLPanel addStyleNames="{local_res.css.raceslistlive}">
|
||||
<h3 ui:field="titleUi"></h3>
|
||||
<div style="display: none;" ui:field="infoUi"></div>
|
||||
<div style="display: none; font-weight: bold; font-style: italic;" ui:field="noContentPlaceholderUi"></div>
|
||||
<dp:racelist.AbstractRaceList ui:field="raceListUi"/>
|
||||
</g:HTMLPanel>
|
||||
</ui:UiBinder>
|
||||
+19
@@ -63,6 +63,7 @@
|
||||
.raceviewerlaunchpad:hover {
|
||||
cursor: pointer;
|
||||
background: #0081b8;
|
||||
text-decoration: none;
|
||||
}
|
||||
.raceviewerlaunchpadlive {
|
||||
background: #e94a1b;
|
||||
@@ -79,11 +80,29 @@
|
||||
.raceviewerlaunchpadlive .raceviewerlaunchpad_content_item_icon svg {
|
||||
fill: #e94a1b;
|
||||
}
|
||||
.raceviewerlaunchpadplanned {
|
||||
background: #999999;
|
||||
}
|
||||
.raceviewerlaunchpadplanned:hover {
|
||||
background: #8a8a8a;
|
||||
}
|
||||
.raceviewerlaunchpadplanned .raceviewerlaunchpad_content_item {
|
||||
color: #999999;
|
||||
}
|
||||
.raceviewerlaunchpadplanned .raceviewerlaunchpad_content_item:hover {
|
||||
background: #999999;
|
||||
}
|
||||
.raceviewerlaunchpadplanned .raceviewerlaunchpad_content_item_icon svg {
|
||||
fill: #999999;
|
||||
}
|
||||
.raceviewerlaunchpad_icon {
|
||||
margin-left: 0.666666666666667em;
|
||||
width: 1.666666666666667em;
|
||||
height: 1.333333333333333em;
|
||||
}
|
||||
.raceviewerlaunchpad_icon img {
|
||||
height: 100%;
|
||||
}
|
||||
.raceviewerlaunchpad_icon svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
+109
-84
@@ -1,85 +1,110 @@
|
||||
package com.sap.sailing.gwt.home.desktop.partials.raceviewerlaunchpad;
|
||||
|
||||
import com.google.gwt.cell.client.AbstractCell;
|
||||
import com.google.gwt.cell.client.ValueUpdater;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.BrowserEvents;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.NativeEvent;
|
||||
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
|
||||
import com.google.gwt.safehtml.shared.SafeHtml;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.PopupPanel;
|
||||
import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
|
||||
import com.sap.sailing.gwt.home.communication.race.RaceMetadataDTO;
|
||||
import com.sap.sailing.gwt.home.communication.race.SimpleRaceMetadataDTO;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.EventView;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.EventView.Presenter;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class RaceviewerLaunchPadCell<T extends RaceMetadataDTO<?>> extends AbstractCell<T> {
|
||||
|
||||
interface CellTemplates extends SafeHtmlTemplates {
|
||||
@Template("<div class=\"{0}\">{1}</div>")
|
||||
SafeHtml raceNotTracked(String styleNames, String text);
|
||||
|
||||
@Template("<div class=\"{0}\"><div>{2}</div><div class=\"{1}\"><img src=\"images/home/launch-loupe.svg\"/></div>")
|
||||
SafeHtml raceviewerLaunchPad(String styleNames, String iconStyleNames, String text);
|
||||
}
|
||||
|
||||
private static final CellTemplates TEMPLATE = GWT.create(CellTemplates.class);
|
||||
private static final StringMessages I18N = StringMessages.INSTANCE;
|
||||
|
||||
private final RaceviewerLaunchPadResources local_res = RaceviewerLaunchPadResources.INSTANCE;
|
||||
private final String notTrackedStyleNames = local_res.css().raceviewerlaunchpad_not_tracked();
|
||||
private final String analyzeStyleNames = local_res.css().raceviewerlaunchpad();
|
||||
private final String liveStyleNames = Util.join(" ", analyzeStyleNames, local_res.css().raceviewerlaunchpadlive());
|
||||
private final String iconStyleNames = local_res.css().raceviewerlaunchpad_icon();
|
||||
|
||||
private final EventView.Presenter presenter;
|
||||
private final PopupPanel panel = new PopupPanel(true, false);
|
||||
|
||||
public RaceviewerLaunchPadCell(Presenter presenter) {
|
||||
super(BrowserEvents.CLICK);
|
||||
local_res.css().ensureInjected();
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBrowserEvent(Context context, final Element parent, T data, NativeEvent event,
|
||||
ValueUpdater<T> valueUpdater) {
|
||||
if (data.hasValidTrackingData() && BrowserEvents.CLICK.equals(event.getType())
|
||||
&& parent.getFirstChildElement().isOrHasChild(Element.as(event.getEventTarget()))) {
|
||||
panel.setWidget(new RaceviewerLaunchPad(data, panel) {
|
||||
@Override
|
||||
protected String getRaceViewerURL(SimpleRaceMetadataDTO data, String mode) {
|
||||
return presenter.getRaceViewerURL(data, mode);
|
||||
}
|
||||
});
|
||||
panel.setPopupPositionAndShow(new PositionCallback() {
|
||||
@Override
|
||||
public void setPosition(int offsetWidth, int offsetHeight) {
|
||||
int alignBottom = parent.getAbsoluteTop() + parent.getOffsetHeight() - offsetHeight;
|
||||
int top = (alignBottom - Window.getScrollTop() < 0 ? parent.getAbsoluteTop() - 1 : alignBottom + 1);
|
||||
panel.setPopupPosition(parent.getAbsoluteRight() + 1 - offsetWidth, top);
|
||||
panel.getElement().scrollIntoView();
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
super.onBrowserEvent(context, parent, data, event, valueUpdater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Context context, T data, SafeHtmlBuilder sb) {
|
||||
if (data.hasValidTrackingData()) {
|
||||
String styleNames = data.isFinished() ? analyzeStyleNames : liveStyleNames;
|
||||
sb.append(TEMPLATE.raceviewerLaunchPad(styleNames, iconStyleNames, I18N.raceDetailsToShow()));
|
||||
} else {
|
||||
package com.sap.sailing.gwt.home.desktop.partials.raceviewerlaunchpad;
|
||||
|
||||
import com.google.gwt.cell.client.AbstractCell;
|
||||
import com.google.gwt.cell.client.ValueUpdater;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.BrowserEvents;
|
||||
import com.google.gwt.dom.client.Element;
|
||||
import com.google.gwt.dom.client.NativeEvent;
|
||||
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
|
||||
import com.google.gwt.safehtml.shared.SafeHtml;
|
||||
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.PopupPanel;
|
||||
import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
|
||||
import com.sap.sailing.gwt.home.communication.race.RaceMetadataDTO;
|
||||
import com.sap.sailing.gwt.home.communication.race.SimpleRaceMetadataDTO;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.EventView;
|
||||
import com.sap.sailing.gwt.home.desktop.places.event.EventView.Presenter;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.raceboard.RaceBoardModes;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
public class RaceviewerLaunchPadCell<T extends RaceMetadataDTO<?>> extends AbstractCell<T> {
|
||||
|
||||
interface CellTemplates extends SafeHtmlTemplates {
|
||||
@Template("<div class=\"{0}\">{1}</div>")
|
||||
SafeHtml raceNotTracked(String styleNames, String text);
|
||||
|
||||
@Template("<div class=\"{0}\"><div>{2}</div><div class=\"{1}\"><img src=\"images/home/launch-loupe.svg\"/></div>")
|
||||
SafeHtml raceviewerLaunchPad(String styleNames, String iconStyleNames, String text);
|
||||
|
||||
@Template("<a href=\"{4}\" target=\"_blank\" class=\"{0}\"><div>{2}</div><div class=\"{1}\"><img src=\"images/home/{3}.svg\"/></div></a> ")
|
||||
SafeHtml standaloneButton(String styleNames, String iconStyleNames, String text, String icon, String link);
|
||||
}
|
||||
|
||||
private static final CellTemplates TEMPLATE = GWT.create(CellTemplates.class);
|
||||
private static final StringMessages I18N = StringMessages.INSTANCE;
|
||||
|
||||
private final RaceviewerLaunchPadResources local_res = RaceviewerLaunchPadResources.INSTANCE;
|
||||
private final String notTrackedStyleNames = local_res.css().raceviewerlaunchpad_not_tracked();
|
||||
private final String analyzeStyleNames = local_res.css().raceviewerlaunchpad();
|
||||
private final String plannedStyleNames = Util.join(" ", analyzeStyleNames, local_res.css().raceviewerlaunchpadplanned());
|
||||
private final String liveStyleNames = Util.join(" ", analyzeStyleNames, local_res.css().raceviewerlaunchpadlive());
|
||||
private final String iconStyleNames = local_res.css().raceviewerlaunchpad_icon();
|
||||
|
||||
private final EventView.Presenter presenter;
|
||||
private final PopupPanel panel = new PopupPanel(true, false);
|
||||
|
||||
public RaceviewerLaunchPadCell(Presenter presenter) {
|
||||
super(BrowserEvents.CLICK);
|
||||
local_res.css().ensureInjected();
|
||||
this.presenter = presenter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBrowserEvent(Context context, final Element parent, T data, NativeEvent event,
|
||||
ValueUpdater<T> valueUpdater) {
|
||||
if (!renderAsDirectLinkButton(data)) {
|
||||
if (data.hasValidTrackingData() && BrowserEvents.CLICK.equals(event.getType())
|
||||
&& parent.getFirstChildElement().isOrHasChild(Element.as(event.getEventTarget()))) {
|
||||
panel.setWidget(createLaunchPad(parent.getFirstChildElement(), data));
|
||||
panel.setPopupPositionAndShow(new PositionCallback() {
|
||||
@Override
|
||||
public void setPosition(int offsetWidth, int offsetHeight) {
|
||||
int alignBottom = parent.getAbsoluteTop() + parent.getOffsetHeight() - offsetHeight;
|
||||
int top = (alignBottom - Window.getScrollTop() < 0 ? parent.getAbsoluteTop() - 1 : alignBottom + 1);
|
||||
panel.setPopupPosition(parent.getAbsoluteRight() + 1 - offsetWidth, top);
|
||||
panel.getElement().scrollIntoView();
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
super.onBrowserEvent(context, parent, data, event, valueUpdater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Context context, T data, SafeHtmlBuilder sb) {
|
||||
if (data.hasValidTrackingData()) {
|
||||
if (renderAsDirectLinkButton(data)) {
|
||||
sb.append(TEMPLATE.standaloneButton(plannedStyleNames, iconStyleNames, I18N.watchLive(),
|
||||
"launch-play", presenter.getRaceViewerURL(data, RaceBoardModes.PLAYER.name())));
|
||||
} else {
|
||||
String styleNames = data.isFinished() ? analyzeStyleNames : liveStyleNames;
|
||||
sb.append(TEMPLATE.raceviewerLaunchPad(styleNames, iconStyleNames, I18N.raceDetailsToShow()));
|
||||
}
|
||||
} else {
|
||||
sb.append(TEMPLATE.raceNotTracked(notTrackedStyleNames, I18N.eventRegattaRaceNotTracked()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link RaceviewerLaunchPad} for the given data object.
|
||||
*/
|
||||
private RaceviewerLaunchPad createLaunchPad(Element button, T data) {
|
||||
RaceviewerLaunchPad launchPad = new RaceviewerLaunchPad(data, panel) {
|
||||
@Override
|
||||
protected String getRaceViewerURL(SimpleRaceMetadataDTO data, String raceBoardMode) {
|
||||
return presenter.getRaceViewerURL(data, raceBoardMode);
|
||||
}
|
||||
};
|
||||
return launchPad;
|
||||
}
|
||||
|
||||
/** Determine whether a direct link button should be/is rendered instead of a menu popup. */
|
||||
private boolean renderAsDirectLinkButton(T data) {
|
||||
return !data.isFinished() && !data.isRunning();
|
||||
}
|
||||
|
||||
}
|
||||
+1
@@ -18,6 +18,7 @@ public interface RaceviewerLaunchPadResources extends ClientBundle {
|
||||
String raceviewerlaunchpad_date();
|
||||
String raceviewerlaunchpad_cta();
|
||||
String raceviewerlaunchpadlive();
|
||||
String raceviewerlaunchpadplanned();
|
||||
String raceviewerlaunchpad_content_item();
|
||||
String raceviewerlaunchpad_content_item_icon();
|
||||
String raceviewerlaunchpad_icon();
|
||||
|
||||
+3
@@ -174,6 +174,9 @@
|
||||
.fleet_races_raceplanned:hover {
|
||||
background-color: #8a8a8a;
|
||||
}
|
||||
.fleet_races_raceplanned .fleet_races_race_name:after {
|
||||
background: url("images/home/launch-play.svg") no-repeat center center;
|
||||
}
|
||||
.fleet_races_raceuntracked .fleet_races_race_name:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
-14
@@ -34,7 +34,6 @@ public class Solutions extends Composite {
|
||||
@UiField Anchor inSightAnchor;
|
||||
@UiField Anchor buoyPingerAnchor;
|
||||
@UiField Anchor postRaceAnchor;
|
||||
@UiField Anchor trainingDiaryAnchor;
|
||||
@UiField Anchor simulatorAnchor;
|
||||
|
||||
@UiField DivElement sapInSailingDiv;
|
||||
@@ -43,7 +42,6 @@ public class Solutions extends Composite {
|
||||
@UiField DivElement inSightDiv;
|
||||
@UiField DivElement buoyPingerDiv;
|
||||
@UiField DivElement postRaceDiv;
|
||||
@UiField DivElement trainingDiaryDiv;
|
||||
@UiField DivElement simulatorDiv;
|
||||
|
||||
@UiField
|
||||
@@ -60,7 +58,6 @@ public class Solutions extends Composite {
|
||||
private final PlaceNavigation<SolutionsPlace> inSightAppNavigation;
|
||||
private final PlaceNavigation<SolutionsPlace> buoyPingerAppNavigation;
|
||||
private final PlaceNavigation<SolutionsPlace> postRaceAnalyticsNavigation;
|
||||
private final PlaceNavigation<SolutionsPlace> trainingDiaryNavigation;
|
||||
private final PlaceNavigation<SolutionsPlace> sailingSimulatorNavigation;
|
||||
|
||||
private final SolutionsNavigationTabs navigationTab;
|
||||
@@ -98,7 +95,6 @@ public class Solutions extends Composite {
|
||||
inSightAppNavigation = placesNavigator.getSolutionsNavigation(SolutionsNavigationTabs.InSightApp);
|
||||
buoyPingerAppNavigation = placesNavigator.getSolutionsNavigation(SolutionsNavigationTabs.BuoyPingerApp);
|
||||
postRaceAnalyticsNavigation = placesNavigator.getSolutionsNavigation(SolutionsNavigationTabs.PostRaceAnalytics);
|
||||
trainingDiaryNavigation = placesNavigator.getSolutionsNavigation(SolutionsNavigationTabs.TrainingDiary);
|
||||
sailingSimulatorNavigation = placesNavigator.getSolutionsNavigation(SolutionsNavigationTabs.SailingSimulator);
|
||||
|
||||
sapInSailingAnchor.setHref(sapInSailingNavigation.getTargetUrl());
|
||||
@@ -107,7 +103,6 @@ public class Solutions extends Composite {
|
||||
inSightAnchor.setHref(inSightAppNavigation.getTargetUrl());
|
||||
buoyPingerAnchor.setHref(buoyPingerAppNavigation.getTargetUrl());
|
||||
postRaceAnchor.setHref(postRaceAnalyticsNavigation.getTargetUrl());
|
||||
trainingDiaryAnchor.setHref(trainingDiaryNavigation.getTargetUrl());
|
||||
simulatorAnchor.setHref(sailingSimulatorNavigation.getTargetUrl());
|
||||
}
|
||||
|
||||
@@ -155,12 +150,6 @@ public class Solutions extends Composite {
|
||||
handleClickEventWithLocalNavigation(e, postRaceAnalyticsNavigation);
|
||||
}
|
||||
|
||||
@UiHandler("trainingDiaryAnchor")
|
||||
public void scrollToTrainingDiary(ClickEvent e) {
|
||||
scrollToView(SolutionsNavigationTabs.TrainingDiary);
|
||||
handleClickEventWithLocalNavigation(e, trainingDiaryNavigation);
|
||||
}
|
||||
|
||||
@UiHandler("simulatorAnchor")
|
||||
public void scrollToSimulator(ClickEvent e) {
|
||||
scrollToView(SolutionsNavigationTabs.SailingSimulator);
|
||||
@@ -200,9 +189,6 @@ public class Solutions extends Composite {
|
||||
case PostRaceAnalytics:
|
||||
postRaceDiv.scrollIntoView();
|
||||
break;
|
||||
case TrainingDiary:
|
||||
trainingDiaryDiv.scrollIntoView();
|
||||
break;
|
||||
case SailingSimulator:
|
||||
simulatorDiv.scrollIntoView();
|
||||
break;
|
||||
|
||||
-28
@@ -40,9 +40,6 @@
|
||||
<g:Anchor ui:field="postRaceAnchor" styleName="{local_res.css.solutions_nav_link}">
|
||||
<ui:text from='{i18n.solutionsPostHeadline}' />
|
||||
</g:Anchor>
|
||||
<g:Anchor ui:field="trainingDiaryAnchor" styleName="{local_res.css.solutions_nav_link}">
|
||||
<ui:text from='{i18n.solutionsTrainingHeadline}' />
|
||||
</g:Anchor>
|
||||
<g:Anchor ui:field="simulatorAnchor" styleName="{local_res.css.solutions_nav_link}">
|
||||
<ui:text from='{i18n.solutionsSimulatorHeadline}' />
|
||||
</g:Anchor>
|
||||
@@ -244,31 +241,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ui:field="trainingDiaryDiv"
|
||||
class="{local_res.css.solutions_content} {local_res.css.solutions_contenttraining}">
|
||||
<div class="{res.mediaCss.grid} {local_res.css.gridalternator}">
|
||||
<div class="{res.mediaCss.small12} {res.mediaCss.column}">
|
||||
<div class="{local_res.css.solutions_contenttraining_body}">
|
||||
<h2>
|
||||
<ui:text from='{i18n.i18nDeSolutionsTrainingHeadline}' />
|
||||
</h2>
|
||||
<p>
|
||||
<ui:text from='{i18n.i18nDeSolutionsTrainingText}' />
|
||||
</p>
|
||||
<div
|
||||
class="{style.storeBadgesContainer}"
|
||||
>
|
||||
<a
|
||||
alt="Get it on Appstore"
|
||||
href="{i18n.appstoreStgTrainingstagebuch}"
|
||||
target="_blank" class="{local_res.css.solutions_content_linkappstore}">
|
||||
<img src="images/home/appstore{i18n.appstoreBadgeSuffix}.svg"></img>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ui:field="simulatorDiv"
|
||||
class="{local_res.css.solutions_content} {local_res.css.solutions_contentsimulator}">
|
||||
<div class="{res.mediaCss.grid} {local_res.css.gridalternator}">
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@
|
||||
width: 100%;
|
||||
padding: 5.2em;
|
||||
line-height: 0.9;
|
||||
text-shadow: 0 0 18px rgba(0,0,0,0.13), 0 2px 6px rgba(0,0,0,0.25);
|
||||
text-shadow: 0 0 18px rgba(0,0,0,0.50), 0 2px 6px rgba(0,0,0,0.50);
|
||||
text-align: center;
|
||||
opacity: 1;
|
||||
-ms-filter: none;
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ public class TabletAndDesktopRegattaEventView extends Composite implements Event
|
||||
|
||||
if(currentPresenter.getEventDTO().getType() == EventType.SERIES_EVENT) {
|
||||
final PlaceNavigation<SeriesDefaultPlace> currentEventSeriesNavigation = currentPresenter.getCurrentEventSeriesNavigation();
|
||||
Anchor seriesAnchor = new Anchor(currentPresenter.getEventDTO().getSeriesName());
|
||||
Anchor seriesAnchor = new Anchor(i18n.overallLeaderboardSelection());
|
||||
seriesAnchor.setHref(currentEventSeriesNavigation.getTargetUrl());
|
||||
seriesAnchor.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
|
||||
Loaded 100 of 309 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user