diff --git a/configuration/releaseAndroidApps.sh b/configuration/releaseAndroidApps.sh
index c97824ede70..68430deff26 100755
--- a/configuration/releaseAndroidApps.sh
+++ b/configuration/releaseAndroidApps.sh
@@ -85,7 +85,9 @@ git checkout $ANDROID_RELEASE_BRANCH
git merge -m "Merging $GIT_REMOTE/$ANDROID_RELEASE_BRANCH" $GIT_REMOTE/$ANDROID_RELEASE_BRANCH
git fetch $GIT_REMOTE $RELEASE_BRANCH:$RELEASE_BRANCH
git merge -m "Merging $RELEASE_BRANCH into $ANDROID_RELEASE_BRANCH, probably incorporating version setting to -SNAPSHOT" $GIT_REMOTE/$RELEASE_BRANCH
-git push $GIT_REMOTE $ANDROID_RELEASE_BRANCH:$ANDROID_RELEASE_BRANCH
+if [ "$PERFORM_GIT_OPERATIONS" = "1" ]; then
+ git push $GIT_REMOTE $ANDROID_RELEASE_BRANCH:$ANDROID_RELEASE_BRANCH
+fi
# Patch the AndroidManifest.xml files to upgrade the android:versionCode sequential counter relevant for the PlayStore
# and the android:versionName which is what the user sees and which we expect to follow a major.minor version scheme,
diff --git a/doc/SAPSailingAnalytics_Administrator_Training.pptx b/doc/SAPSailingAnalytics_Administrator_Training.pptx
index 7dd67d8a5f3..ddae3ea0b3d 100644
Binary files a/doc/SAPSailingAnalytics_Administrator_Training.pptx and b/doc/SAPSailingAnalytics_Administrator_Training.pptx differ
diff --git a/home.md b/home.md
index 2ff9a805a82..572b28c7185 100644
--- a/home.md
+++ b/home.md
@@ -1,148 +1,149 @@
-# Welcome to the SAP Sailing Wiki
-
-This is the Wiki where useful information regarding this project can be found.
-
-### The Pitch
-
-Like businesses, sailors need the latest information to make strategic decisions - but they need it even faster. One wrong tack, a false estimation of the current, or the slightest wind shift can cost the skipper the entire race. As premium sponsor of the Kieler Woche 2011, and co-sponsor of Sailing Team Germany (STG), SAP is showing how innovative IT solutions providing real time data analysis can give teams the competitive edge.
-
-SAP is at the center of today’s technology revolution, developing innovations that not only help businesses run like never before, but also improve the lives of people everywhere. As market leader in enterprise application software, SAP SE (NYSE: SAP) helps companies of all sizes and industries run better. From back office to boardroom, warehouse to storefront, desktop to mobile device – SAP empowers people and organizations to work together more efficiently and use business insight more effectively to stay ahead of the competition. SAP applications and services enable more than 258,000 customers to operate profitably, adapt continuously, and grow sustainably.
-
-# Table of Contents
-
-## Information
-
-### General
-
-* [[Information about this Wiki and HowTo|wiki/info/general/wiki]]
-* [[General Project Information|wiki/info/general/general-information]]
-* [[Inventory|wiki/info/general/inventar-liste]]
-
-### Landscape and Development
-
-* [[Architecture and Infrastructure|wiki/info/landscape/architecture-and-infrastructure]]
- * [[Runtime Environment|wiki/info/landscape/runtime-environment]]
- * [[Basic architectual principles|wiki/info/landscape/basic-architectural-principles]]
- * [[User Management|wiki/info/landscape/usermanagement]]
- * [[Development Environment|wiki/info/landscape/development-environment]]
- * [[Production Environment|wiki/info/landscape/production-environment]]
- * [[Typical Development Scenarios|wiki/info/landscape/typical-development-scenarios]]
-* [[RaceLog Tracking Server Architecture|wiki/info/landscape/server]]
- * Environment Overview [[PDF|wiki/info/mobile/event-tracking/architecture.pdf]] | [[SVG|wiki/info/mobile/event-tracking/architecture.svg]]
-* Amazon
- * [[Amazon EC2|wiki/info/landscape/amazon-ec2]]
- * [[EC2 Backup Strategy|wiki/info/landscape/amazon-ec2-backup-strategy]]
- * [[Creating an EC2 image from scratch|wiki/info/landscape/creating-ec2-image-from-scratch]]
- * [[EC2 mail relaying|wiki/info/landscape/mail-relaying]]
-* [[Building and Deploying|wiki/info/landscape/building-and-deploying]]
-* [[Data Mining Architecture|wiki/info/landscape/data-mining-architecture]]
-* [[Typical Data Mining Scenarios|wiki/info/landscape/typical-data-mining-scenarios]]
-* [[Create clickable UI prototypes with Axure|wiki/info/landscape/ui-clickable-prototypes]]
-* [[Webdesign|wiki/info/landscape/webdesign]]
-
-### Mobile
-
-* [[Mobile Development|wiki/info/mobile/mobile-development]]
-* Tracking App
- * [[Tracking App Specification|wiki/info/mobile/app-spec/app-spec]]
- * [[Event Tracking|wiki/info/mobile/event-tracking/event-tracking]]
- * [[Steps for setting up Smartphone Tracking|wiki/info/mobile/smartphone-tracking-steps]]
- * [[Tracking App Prototype Architecture|wiki/info/mobile/app]]
-* Racecommittee App
- * [[Racecommittee App|wiki/info/mobile/racecommittee-app]]
- * [[Environment|wiki/info/mobile/racecommittee-app-environment]]
- * [[Administrator|wiki/info/mobile/racecommittee-app-administrator]]
- * [[User|wiki/info/mobile/racecommittee-app-user]]
-* [[Android and Release Build|wiki/info/mobile/android-and-release-build]]
-* [[Energy consumption of mobile apps|wiki/info/mobile/energy-consumption]]
-* [[Data consumption of mobile apps|wiki/info/mobile/data-consumption]]
-* [[Mobile Sailing Analytics|wiki/info/mobile/mobilesailinganalytics]]
-* [[Push Notifications|wiki/info/mobile/push-notifications]]
-
-### API
-
-* [[Web Services API|wiki/info/api/sailing-webservices]]
-* [[API v1|wiki/info/api/api-v1]]
-* [[Tracking App API|wiki/info/api/tracking-app-api]]
-* [[Training API v1 draft|wiki/info/api/training-api-v1-draft]]
-
-### Security
- * [[Fortify Tests|wiki/info/security/fortify]]
- * [[SSL / HTTPS Support|wiki/info/security/ssl-support]]
-
-### Miscellaneous
-
-* [[Big Data - Numbers|wiki/info/misc/big-data-numbers]]
-* [[Data Quality|wiki/info/misc/data-quality]]
-* [[Sailing Domain Algorithms|wiki/info/misc/sailing-domain-algorithms]]
-* [[Google Analytics (Web Page Tracking)|wiki/info/misc/ganalytics]]
-* [[S3 Development Sample|wiki/info/misc/s3-sample]]
-
-* [[FAQ for League Operators|wiki/info/misc/league-operators-faq]]
-* [[Prionet related information|wiki/info/misc/prionet-related-information]]
-* [[TracTrac Workshop 2013|wiki/info/misc/tractracworkshop2013]]
-
-## HowTo
-
-* [[Onboarding|wiki/howto/onboarding]]
-
-
-### Development
-
-* [[Create boat graphics for the 2D race viewer|wiki/howto/development/boatgraphicssvg]]
-* [[Continuous Integration with Hudson/Jenkins|wiki/howto/development/ci]]
-* [[Dispatch|wiki/howto/development/dispatch]]
-* [[Working with GWT UI Binder|wiki/howto/development/gwt-ui-binder]]
-* [[Java De(Serialization) and Circular Dependencies|wiki/howto/development/java-de-serialization-and-circular-dependencies]]
-* [[JMX Support|wiki/howto/development/jmx]]
-* [[Working with GWT Locally|wiki/howto/development/local-gwt]]
-* [[Log File Analysis|wiki/howto/development/log-file-analysis]]
-* [[UI Tests with Selenium|wiki/howto/development/selenium-ui-tests]]
-* [[Profiling|wiki/howto/development/profiling]]
-* [[Working with GWT Super Dev Mode|wiki/howto/development/super-dev-mode]]
-
-### For Event Managers
-
-* [[Set up local network with replication server|wiki/howto/eventmanagers/event-network-with-replica]]
-* [[Operating Igtimi WindBots|wiki/howto/eventmanagers/windbot-operations]]
-* [[Linking Race Videos|wiki/howto/eventmanagers/linking-race-videos]]
-* [[Import official results|wiki/howto/eventmanagers/results-import]]
-
-### Setup
-
-* [[Configure Races on Server|wiki/howto/setup/configure-races-on-server]]
-* [[Setting up internal Jenkins on SAP Monsoon|wiki/howto/setup/setting-up-jenkins-on-sap-monsoon]]
-
-### Miscellaneous
-
-* [[Cook Book|wiki/howto/misc/cook-book]]
-* [[Polars|wiki/howto/misc/polars]]
-* [[Server Replication|wiki/howto/misc/server-replication]]
-* [[TracTrac|wiki/howto/misc/tractrac-lifecycle]]
-* [[UI Tests|wiki/howto/misc/ui-tests-tutorial]]
-* [[Uploading Media Content|wiki/howto/misc/uploading-media-content]]
-* [[Monitoring Apache and RabbitMQ|wiki/misc/monitoring-apache-and-rabbitmq]]
-
-## Projects
-* [[Analytics on a stick|wiki/projects/analytics-on-a-stick]]
-
-## Events and Planning
-* [[Project Planning (bigger development)|wiki/events/planning]]
-* [[General Event Planning|wiki/events/general-event-planning]]
-* [[Information about Extreme Sailing Series|wiki/events/extreme-sailing-series]]
-* [[Travemünder Woche 2014 event page|wiki/events/tw2014]]
-* [[505 worlds Kiel 2014 event page|wiki/events/505-worlds-kiel-2014]]
-* [[Kieler Woche event page|wiki/events/kieler-woche-2015]]
-* [[Charleston Race Week 2016|wiki/events/Charleston-Race-Week-2016]]
-* [[Sailing Leagues 2016|wiki/events/sailing-Leagues-2016]]
-
-## Planning
-* [[Overview|https://wiki.sapsailing.com/pages/wiki/planning/]]
-
-## Internal services (not related to wiki but useful)
-
-* [Bugzilla Issue Tracking System](http://bugzilla.sapsailing.com/bugzilla/)
-* [GIT Repository (SAP)](ssh://git.wdf.sap.corp:29418/SAPSail/sapsailingcapture.git)
-* [Maven Repository Browser](http://maven.sapsailing.com/maven/) (see [[how to setup repository for Android builds|wiki/info/mobile/racecommittee-app-environment]])
-* [Main Sailing Website](http://www.sapsailing.com)
-* [Visitor Statistics](http://analysis.sapsailing.com/)
+# Welcome to the SAP Sailing Wiki
+
+This is the Wiki where useful information regarding this project can be found.
+
+### The Pitch
+
+Like businesses, sailors need the latest information to make strategic decisions - but they need it even faster. One wrong tack, a false estimation of the current, or the slightest wind shift can cost the skipper the entire race. As premium sponsor of the Kieler Woche 2011, and co-sponsor of Sailing Team Germany (STG), SAP is showing how innovative IT solutions providing real time data analysis can give teams the competitive edge.
+
+SAP is at the center of today’s technology revolution, developing innovations that not only help businesses run like never before, but also improve the lives of people everywhere. As market leader in enterprise application software, SAP SE (NYSE: SAP) helps companies of all sizes and industries run better. From back office to boardroom, warehouse to storefront, desktop to mobile device – SAP empowers people and organizations to work together more efficiently and use business insight more effectively to stay ahead of the competition. SAP applications and services enable more than 258,000 customers to operate profitably, adapt continuously, and grow sustainably.
+
+# Table of Contents
+
+## Information
+
+### General
+
+* [[Information about this Wiki and HowTo|wiki/info/general/wiki]]
+* [[General Project Information|wiki/info/general/general-information]]
+* [[Inventory|wiki/info/general/inventar-liste]]
+
+### Landscape and Development
+
+* [[Architecture and Infrastructure|wiki/info/landscape/architecture-and-infrastructure]]
+ * [[Runtime Environment|wiki/info/landscape/runtime-environment]]
+ * [[Basic architectual principles|wiki/info/landscape/basic-architectural-principles]]
+ * [[User Management|wiki/info/landscape/usermanagement]]
+ * [[Development Environment|wiki/info/landscape/development-environment]]
+ * [[Production Environment|wiki/info/landscape/production-environment]]
+ * [[Typical Development Scenarios|wiki/info/landscape/typical-development-scenarios]]
+* [[RaceLog Tracking Server Architecture|wiki/info/landscape/server]]
+ * Environment Overview [[PDF|wiki/info/mobile/event-tracking/architecture.pdf]] | [[SVG|wiki/info/mobile/event-tracking/architecture.svg]]
+* Amazon
+ * [[Amazon EC2|wiki/info/landscape/amazon-ec2]]
+ * [[EC2 Backup Strategy|wiki/info/landscape/amazon-ec2-backup-strategy]]
+ * [[Creating an EC2 image from scratch|wiki/info/landscape/creating-ec2-image-from-scratch]]
+ * [[EC2 mail relaying|wiki/info/landscape/mail-relaying]]
+* [[Building and Deploying|wiki/info/landscape/building-and-deploying]]
+* [[Data Mining Architecture|wiki/info/landscape/data-mining-architecture]]
+* [[Typical Data Mining Scenarios|wiki/info/landscape/typical-data-mining-scenarios]]
+* [[Create clickable UI prototypes with Axure|wiki/info/landscape/ui-clickable-prototypes]]
+* [[Webdesign|wiki/info/landscape/webdesign]]
+
+### Mobile
+
+* [[Mobile Development|wiki/info/mobile/mobile-development]]
+* Tracking App
+ * [[Tracking App Specification|wiki/info/mobile/app-spec/app-spec]]
+ * [[Event Tracking|wiki/info/mobile/event-tracking/event-tracking]]
+ * [[Steps for setting up Smartphone Tracking|wiki/info/mobile/smartphone-tracking-steps]]
+ * [[Tracking App Prototype Architecture|wiki/info/mobile/app]]
+* Racecommittee App
+ * [[Racecommittee App|wiki/info/mobile/racecommittee-app]]
+ * [[Environment|wiki/info/mobile/racecommittee-app-environment]]
+ * [[Administrator|wiki/info/mobile/racecommittee-app-administrator]]
+ * [[User|wiki/info/mobile/racecommittee-app-user]]
+* [[Android and Release Build|wiki/info/mobile/android-and-release-build]]
+* [[Energy consumption of mobile apps|wiki/info/mobile/energy-consumption]]
+* [[Data consumption of mobile apps|wiki/info/mobile/data-consumption]]
+* [[Mobile Sailing Analytics|wiki/info/mobile/mobilesailinganalytics]]
+* [[Push Notifications|wiki/info/mobile/push-notifications]]
+* [[NMEA|wiki/info/mobile/nmea]]
+
+### API
+
+* [[Web Services API|wiki/info/api/sailing-webservices]]
+* [[API v1|wiki/info/api/api-v1]]
+* [[Tracking App API|wiki/info/api/tracking-app-api]]
+* [[Training API v1 draft|wiki/info/api/training-api-v1-draft]]
+
+### Security
+ * [[Fortify Tests|wiki/info/security/fortify]]
+ * [[SSL / HTTPS Support|wiki/info/security/ssl-support]]
+
+### Miscellaneous
+
+* [[Big Data - Numbers|wiki/info/misc/big-data-numbers]]
+* [[Data Quality|wiki/info/misc/data-quality]]
+* [[Sailing Domain Algorithms|wiki/info/misc/sailing-domain-algorithms]]
+* [[Google Analytics (Web Page Tracking)|wiki/info/misc/ganalytics]]
+* [[S3 Development Sample|wiki/info/misc/s3-sample]]
+
+* [[FAQ for League Operators|wiki/info/misc/league-operators-faq]]
+* [[Prionet related information|wiki/info/misc/prionet-related-information]]
+* [[TracTrac Workshop 2013|wiki/info/misc/tractracworkshop2013]]
+
+## HowTo
+
+* [[Onboarding|wiki/howto/onboarding]]
+
+
+### Development
+
+* [[Create boat graphics for the 2D race viewer|wiki/howto/development/boatgraphicssvg]]
+* [[Continuous Integration with Hudson/Jenkins|wiki/howto/development/ci]]
+* [[Dispatch|wiki/howto/development/dispatch]]
+* [[Working with GWT UI Binder|wiki/howto/development/gwt-ui-binder]]
+* [[Java De(Serialization) and Circular Dependencies|wiki/howto/development/java-de-serialization-and-circular-dependencies]]
+* [[JMX Support|wiki/howto/development/jmx]]
+* [[Working with GWT Locally|wiki/howto/development/local-gwt]]
+* [[Log File Analysis|wiki/howto/development/log-file-analysis]]
+* [[UI Tests with Selenium|wiki/howto/development/selenium-ui-tests]]
+* [[Profiling|wiki/howto/development/profiling]]
+* [[Working with GWT Super Dev Mode|wiki/howto/development/super-dev-mode]]
+
+### For Event Managers
+
+* [[Set up local network with replication server|wiki/howto/eventmanagers/event-network-with-replica]]
+* [[Operating Igtimi WindBots|wiki/howto/eventmanagers/windbot-operations]]
+* [[Linking Race Videos|wiki/howto/eventmanagers/linking-race-videos]]
+* [[Import official results|wiki/howto/eventmanagers/results-import]]
+
+### Setup
+
+* [[Configure Races on Server|wiki/howto/setup/configure-races-on-server]]
+* [[Setting up internal Jenkins on SAP Monsoon|wiki/howto/setup/setting-up-jenkins-on-sap-monsoon]]
+
+### Miscellaneous
+
+* [[Cook Book|wiki/howto/misc/cook-book]]
+* [[Polars|wiki/howto/misc/polars]]
+* [[Server Replication|wiki/howto/misc/server-replication]]
+* [[TracTrac|wiki/howto/misc/tractrac-lifecycle]]
+* [[UI Tests|wiki/howto/misc/ui-tests-tutorial]]
+* [[Uploading Media Content|wiki/howto/misc/uploading-media-content]]
+* [[Monitoring Apache and RabbitMQ|wiki/misc/monitoring-apache-and-rabbitmq]]
+
+## Projects
+* [[Analytics on a stick|wiki/projects/analytics-on-a-stick]]
+
+## Events and Planning
+* [[Project Planning (bigger development)|wiki/events/planning]]
+* [[General Event Planning|wiki/events/general-event-planning]]
+* [[Information about Extreme Sailing Series|wiki/events/extreme-sailing-series]]
+* [[Travemünder Woche 2014 event page|wiki/events/tw2014]]
+* [[505 worlds Kiel 2014 event page|wiki/events/505-worlds-kiel-2014]]
+* [[Kieler Woche event page|wiki/events/kieler-woche-2015]]
+* [[Charleston Race Week 2016|wiki/events/Charleston-Race-Week-2016]]
+* [[Sailing Leagues 2016|wiki/events/sailing-Leagues-2016]]
+
+## Planning
+* [[Overview|https://wiki.sapsailing.com/pages/wiki/planning/]]
+
+## Internal services (not related to wiki but useful)
+
+* [Bugzilla Issue Tracking System](http://bugzilla.sapsailing.com/bugzilla/)
+* [GIT Repository (SAP)](ssh://git.wdf.sap.corp:29418/SAPSail/sapsailingcapture.git)
+* [Maven Repository Browser](http://maven.sapsailing.com/maven/) (see [[how to setup repository for Android builds|wiki/info/mobile/racecommittee-app-environment]])
+* [Main Sailing Website](http://www.sapsailing.com)
+* [Visitor Statistics](http://analysis.sapsailing.com/)
diff --git a/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT.launch b/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT.launch
index e6b9e6eed4d..324e2b3954d 100644
--- a/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT.launch
+++ b/java/com.sap.sailing.dashboards.gwt/SailingDashboardsGWT.launch
@@ -3,7 +3,7 @@
-
+
@@ -38,7 +38,7 @@
-
+
diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties
index 270fcb64c37..2cf4ae6cf36 100644
--- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties
+++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages.properties
@@ -97,7 +97,7 @@ WindSourceName=Wind Source Name
windFrom=True Wind Direction (TWD)
windSpeedKnots=True Wind Speed (kts)
speedInKnots=Speed (kts)
-bearing=Direction (T)
+bearing=Direction (°T)
WindTrack=Wind Track
timeSpentFoiling=Time spent foiling
yaw=Yaw
diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties
index bc7c0e6f9f1..38878b0106c 100644
--- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties
+++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_de.properties
@@ -1,11 +1,11 @@
Competitor=Teilnehmer
-DistanceTraveled=zurckgelegte Distanz
+DistanceTraveled=zurückgelegte Distanz
Boat=Boot
Team=Team
Name=Name
SearchTag=Such-Tag
-Nationality=Nationalitts
-Acronym=Abkrzung
+Nationality=Nationalitäts
+Acronym=Abkürzung
SailID=Segelnummer
LegNumber=Nummer des Schenkels
LegType=Art des Schenkels
@@ -26,7 +26,7 @@ WindFixSailingDomainRetrieverChain=Windmessungen
MarkPassingSailingDomainRetrieverChain=Tonnenrundungen
RaceResultSailingDomainRetrieverChain=Rennergebnisse
RaceOfCompetitorSailingDomainRetrieverChain=Rennen eines Teilnehmers
-ManeuverSailingDomainRetrieverChain=Manver
+ManeuverSailingDomainRetrieverChain=Manöver
LeaderboardGroup=Ranglisten Gruppe
Leaderboard=Rangliste
Leg=Schenkel
@@ -36,19 +36,19 @@ GpsFix=GPS-Fix
BravoFix=Bravo-Fix
BravoFixTrack=Bravo-Messreihe
WindFix=Windmessung
-Maneuver=Manver
+Maneuver=Manöver
Speed=Geschwindigkeit
SpeedTenSecondsBefore=Geschwindigkeit 10s vorher
-WindStrengthInBeaufort=Windstrke in Beaufort
+WindStrengthInBeaufort=Windstärke in Beaufort
Bft0=Windstille
Bft1=leiser Zug
Bft2=leichte Brise
Bft3=schwacher Wind
-Bft4=miger Wind
+Bft4=mäßiger Wind
Bft5=frischer Wind
Bft6=starker Wind
Bft7=steifer Wind
-Bft8=strmischer Wind
+Bft8=stürmischer Wind
Bft9=Sturm
Bft10=schwerer Sturm
Bft11=orkanartiger Sturm
@@ -59,53 +59,53 @@ 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
+SpeedWhenStarting=Geschwindigkeit beim Überqueren der Startlinie
SpeedTenSecondsBeforeStart=Geschwindigkeit 10s vor dem Startzeitpunkt
RankAtFirstMark=Position beim ersten Wegpunkt
-NumberOfManeuvers=Anzahl der Manver
+NumberOfManeuvers=Anzahl der Manöver
NumberOfTacks=Anzahl der Wenden
NumberOfJibes=Anzahl der Halsen
NumberOfPenaltyCircles=Anzahl der Straf-Kreise
RankGainsOrLosses=Positions-Verluste oder -Gewinne
-DistanceToStarboardSideAtStart=Distanz zur Steuerbordseite (% der Lnge)
+DistanceToStarboardSideAtStart=Distanz zur Steuerbordseite (% der Länge)
NumberOfPodiumFinish=Azahl der Podium-Siege
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
-ManeuverType=Art des Manvers
+ManeuverType=Art des Manövers
Tack=Bug
-SpeedBefore=Geschwindigkeit bevor dem Manver
-SpeedAfter=Geschwindigkeit nach dem Manver
-DirectionChange=Richtungsnderung in Grad
-AbsoluteDirectionChange=Absolute Richtungsnderung in Grad (positiv)
+SpeedBefore=Geschwindigkeit bevor dem Manöver
+SpeedAfter=Geschwindigkeit nach dem Manöver
+DirectionChange=Richtungsänderung in Grad
+AbsoluteDirectionChange=Absolute Richtungsänderung in Grad (positiv)
ToSide=In Richtung (Backbord / Steuerbord)
-ManeuverLoss=Manververlust
+ManeuverLoss=Manöververlust
Waypoint=Wegpunkt
PassingSide=Passierende Seite
TackAtStart=Startbug
SpeedTenSecondsAfterStart=Geschwindigkeit 10s nach dem Startzeitpunkt
RankThirtySecondsAfterStart=Absolute Platzierung 30s nach dem Startzeitpunkt
-WindwardDistanceToAdvantageousEndOfLine=Windwrtige Distanz zum Bevorteilten Ende der Startlinie
-RankAfterHalfOfTheFirstLeg=Platzierung nach der Hlfte des ersten Schenkels
+WindwardDistanceToAdvantageousEndOfLine=Windwärtige Distanz zum Bevorteilten Ende der Startlinie
+RankAfterHalfOfTheFirstLeg=Platzierung nach der Hälfte des ersten Schenkels
AdvantageousEndOfLine=Bevorteiltes Ende der Startlinie
-TimeSpentInSeconds=Bentigte Zeit in Sekunden
+TimeSpentInSeconds=Benötigte Zeit in Sekunden
MedalRace=Medaillenrennen
WindSourceType=Art der Windmessung
WindSourceName=Name der Windmessreihe
windFrom=Wind aus Richtung (TWD)
windSpeedKnots=Wahre Windgeschwindigkeit (kn)
speedInKnots=Fahrt (kn)
-bearing=Richtung ()
+bearing=Richtung (°)
WindTrack=Windmessreihe
timeSpentFoiling=Zeit auf Foils
yaw=Gierung
pitch=Neigung
-heel=Krngung
-rideHeight=Foiling-Hhe
-rideHeightPort=Foiling-Hhe Backbord-Rumpf
-rideHeightStarboard=Foiling-Hhe Steuerbord-Rumpf
+heel=Krängung
+rideHeight=Foiling-Höhe
+rideHeightPort=Foiling-Höhe Backbord-Rumpf
+rideHeightStarboard=Foiling-Höhe Steuerbord-Rumpf
IsFoiling=Foilt
FoilingDuration=Foilingdauer
FoilingDistance=Gefoilte Distanz
@@ -113,8 +113,8 @@ TakeoffSpeedInKnotsInKnots=Abhebegeschwindigkeit in Knoten
LandingSpeedInKnots=Landegeschwindigkeit in Knoten
AbsoluteTrueWindAngleAtTakeoff=Absoluter Winkel zum wahren Wind (TWA) beim Abheben
AbsoluteTrueWindAngleAtLanding=Absoluter Winkel zum wahren Wind (TWA) beim Landen
-WindStrengthInBeaufortAtTakeoff=Windstrke beim Abheben in Beaufort
-WindStrengthInBeaufortAtLanding=Windstrke beim Landen in Beaufort
+WindStrengthInBeaufortAtTakeoff=Windstärke beim Abheben in Beaufort
+WindStrengthInBeaufortAtLanding=Windstärke beim Landen in Beaufort
WindAtTakeoff=Wind beim Abheben
WindAtLanding=Wind beim Landen
StartsOnLegType=Bahnschnenkeltyp beim Abheben
diff --git a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_fr.properties b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_fr.properties
index 88bc7ee0d9a..6f159b878f5 100755
--- a/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_fr.properties
+++ b/java/com.sap.sailing.datamining/resources/stringmessages/Sailing_StringMessages_fr.properties
@@ -97,7 +97,7 @@ WindSourceName=Nom de la source du vent
windFrom=Direction réelle du vent (TWD)
windSpeedKnots=Vitesse réelle du vent (en nds)
speedInKnots=Vitesse (nds)
-bearing=Direction (�T)
+bearing=Direction (°T)
WindTrack=Enregistrement vent
timeSpentFoiling=Temps passé en planing
yaw=Dévier
diff --git a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/Activator.java b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/Activator.java
index 277a985a470..a4b07bf9900 100644
--- a/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/Activator.java
+++ b/java/com.sap.sailing.datamining/src/com/sap/sailing/datamining/Activator.java
@@ -1,5 +1,6 @@
package com.sap.sailing.datamining;
+import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
@@ -61,7 +62,8 @@ public class Activator extends AbstractDataMiningActivatorWithPredefinedQueries
private boolean dataSourceProvidersHaveBeenInitialized;
public Activator() {
- sailingServerStringMessages = new ResourceBundleStringMessagesImpl(STRING_MESSAGES_BASE_NAME, getClassLoader());
+ sailingServerStringMessages = new ResourceBundleStringMessagesImpl(STRING_MESSAGES_BASE_NAME, getClassLoader(),
+ StandardCharsets.UTF_8.name());
dataRetrieverChainDefinitions = new SailingDataRetrievalChainDefinitions();
predefinedQueries = new SailingPredefinedQueries();
}
diff --git a/java/com.sap.sailing.domain.common/.settings/org.eclipse.core.resources.prefs b/java/com.sap.sailing.domain.common/.settings/org.eclipse.core.resources.prefs
index c111da40d73..10a03d63ab8 100755
--- a/java/com.sap.sailing.domain.common/.settings/org.eclipse.core.resources.prefs
+++ b/java/com.sap.sailing.domain.common/.settings/org.eclipse.core.resources.prefs
@@ -2,4 +2,5 @@ eclipse.preferences.version=1
encoding//src/com/sap/sailing/domain/common/AbstractBearing.java=UTF-8
encoding//src/com/sap/sailing/domain/common/confidence/impl/ConfidenceBasedAveragerImpl.java=utf-8
encoding//src/com/sap/sailing/domain/common/impl/AbstractSpeedWithAbstractBearingImpl.java=UTF-8
-encoding//src/com/sap/sailing/domain/common/tracking/impl/CompactGPSFixMovingImpl.java=UTF-8
+encoding//src/com/sap/sailing/domain/common/tracking/impl/AbstractCompactGPSFixMovingImpl.java=UTF-8
+encoding//src/com/sap/sailing/domain/common/tracking/impl/VeryCompactGPSFixMovingImpl.java=UTF-8
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MasterDataImportObjectCreationCount.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MasterDataImportObjectCreationCount.java
index d44d06e960a..0b63d3fc7fd 100644
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MasterDataImportObjectCreationCount.java
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/MasterDataImportObjectCreationCount.java
@@ -3,16 +3,18 @@ package com.sap.sailing.domain.common;
import java.io.Serializable;
import java.util.Set;
-public interface MasterDataImportObjectCreationCount extends Serializable{
+public interface MasterDataImportObjectCreationCount extends Serializable {
+ int getLeaderboardCount();
- public abstract int getLeaderboardCount();
+ int getLeaderboardGroupCount();
- public abstract int getLeaderboardGroupCount();
+ int getEventCount();
- public abstract int getEventCount();
+ int getRegattaCount();
- public abstract int getRegattaCount();
+ int getMediaTrackCount();
- public abstract Set getOverwrittenRegattaNames();
+ Set getOverwrittenRegattaNames();
+ void addOneMediaTrack();
}
\ No newline at end of file
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoringSchemeType.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoringSchemeType.java
index fd57cced22b..d9cc8610b5b 100755
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoringSchemeType.java
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/ScoringSchemeType.java
@@ -4,6 +4,6 @@ public enum ScoringSchemeType {
// make sure to also add new ones to ScoringSchemeTypeFormatter
LOW_POINT, HIGH_POINT, HIGH_POINT_ESS_OVERALL,HIGH_POINT_ESS_OVERALL_12, HIGH_POINT_LAST_BREAKS_TIE, HIGH_POINT_FIRST_GETS_TEN,
HIGH_POINT_FIRST_GETS_ONE, LOW_POINT_WINNER_GETS_ZERO, HIGH_POINT_WINNER_GETS_SIX, HIGH_POINT_WINNER_GETS_FIVE, HIGH_POINT_WINNER_GETS_EIGHT,
- HIGH_POINT_WINNER_GETS_EIGHT_AND_INTERPOLATION, HIGH_POINT_FIRST_GETS_TEN_OR_EIGHT, HIGH_POINT_FIRST_GETS_TWELVE_OR_EIGHT, LOW_POINT_WITH_ELIMINATIONS_AND_ROUNDS_WINNER_GETS_07,
+ HIGH_POINT_WINNER_GETS_EIGHT_AND_INTERPOLATION, HIGH_POINT_FIRST_GETS_TEN_OR_EIGHT, HIGH_POINT_FIRST_GETS_TWELVE_OR_EIGHT, HIGH_POINT_FIRST_GETS_TWELVE_OR_EIGHT_2017, LOW_POINT_WITH_ELIMINATIONS_AND_ROUNDS_WINNER_GETS_07,
LOW_POINT_LEAGUE_OVERALL, HIGH_POINT_MATCH_RACING, LOW_POINT_TIE_BREAK_BASED_ON_LAST_SERIES_ONLY
}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/MasterDataImportObjectCreationCountImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/MasterDataImportObjectCreationCountImpl.java
index 766c00c4751..792c4b42279 100644
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/MasterDataImportObjectCreationCountImpl.java
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/MasterDataImportObjectCreationCountImpl.java
@@ -17,12 +17,12 @@ import com.sap.sailing.domain.common.MasterDataImportObjectCreationCount;
*
*/
public class MasterDataImportObjectCreationCountImpl implements MasterDataImportObjectCreationCount {
-
private static final long serialVersionUID = -3677005970701170818L;
private int leaderboardCount = 0;
private int leaderboardGroupCount = 0;
private int eventCount = 0;
private int regattaCount = 0;
+ private int mediaTrackCount = 0;
private Set createdLeaderboards = new HashSet();
private Set createdLeaderboardGroups = new HashSet();
@@ -52,7 +52,11 @@ public class MasterDataImportObjectCreationCountImpl implements MasterDataImport
public void addOneRegatta(String id) {
createdRegattas.add(id);
regattaCount++;
-
+ }
+
+ @Override
+ public void addOneMediaTrack() {
+ mediaTrackCount++;
}
public void add(MasterDataImportObjectCreationCountImpl toAdd) {
@@ -101,6 +105,11 @@ public class MasterDataImportObjectCreationCountImpl implements MasterDataImport
public int getRegattaCount() {
return regattaCount;
}
+
+ @Override
+ public int getMediaTrackCount() {
+ return mediaTrackCount;
+ }
@Override
public Set getOverwrittenRegattaNames() {
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/WindImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/WindImpl.java
index 1ae650de809..516686bd0d7 100755
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/WindImpl.java
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/impl/WindImpl.java
@@ -33,7 +33,7 @@ public class WindImpl extends KnotSpeedWithBearingImpl implements Wind {
}
public static int hashCode(double latDeg, double lngDeg, long timePointAsMillis) {
- return (31 * (int) (timePointAsMillis & Integer.MAX_VALUE)) ^ (int) (latDeg*lngDeg);
+ return (31 * (int) (timePointAsMillis & Integer.MAX_VALUE)) ^ (int) (Math.round(latDeg)*Math.round(lngDeg));
}
/**
* Wind hash is determined based on time point and position only to speed this up a little.
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/media/MediaTrack.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/media/MediaTrack.java
index d1d2fe16eda..f2fa748442c 100644
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/media/MediaTrack.java
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/media/MediaTrack.java
@@ -69,7 +69,6 @@ public class MediaTrack implements Serializable {
Set assignedRaces) {
this(title, url, startTime, duration, mimeType, assignedRaces);
this.dbId = dbId;
-
}
public String toString() {
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoSensorDataMetadata.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoSensorDataMetadata.java
index b7b1b9dd201..5f8d177bf6e 100644
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoSensorDataMetadata.java
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/sensordata/BravoSensorDataMetadata.java
@@ -14,10 +14,11 @@ public enum BravoSensorDataMetadata {
INSTANCE;
- private static final String RIDE_HEIGHT_PORT_HULL = "RideHeightPortHull";
- private static final String RIDE_HEIGHT_STBD_HULL = "RideHeightStbdHull";
- private static final String HEEL = "Heel";
- private static final String PITCH = "ImuSensor_Pitch";
+ public static final String RIDE_HEIGHT = "RideHeight";
+ public static final String RIDE_HEIGHT_PORT_HULL = "RideHeightPortHull";
+ public static final String RIDE_HEIGHT_STBD_HULL = "RideHeightStbdHull";
+ public static final String HEEL = "Heel";
+ public static final String PITCH = "ImuSensor_Pitch";
private final int HEADER_COLUMN_OFFSET = 3;
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactGPSFixImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/AbstractCompactGPSFixImpl.java
similarity index 54%
rename from java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactGPSFixImpl.java
rename to java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/AbstractCompactGPSFixImpl.java
index 16a009c6e86..bfd89ce129e 100755
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactGPSFixImpl.java
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/AbstractCompactGPSFixImpl.java
@@ -1,11 +1,6 @@
package com.sap.sailing.domain.common.tracking.impl;
-import com.sap.sailing.domain.common.AbstractBearing;
-import com.sap.sailing.domain.common.AbstractPosition;
-import com.sap.sailing.domain.common.Bearing;
-import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.SpeedWithBearing;
-import com.sap.sailing.domain.common.impl.AbstractSpeedWithAbstractBearingImpl;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.AbstractTimePoint;
@@ -21,9 +16,9 @@ import com.sap.sse.common.impl.AbstractTimePoint;
* @author Axel Uhl (d043530)
*
*/
-public class CompactGPSFixImpl extends AbstractGPSFixImpl {
- private static final long serialVersionUID = 8167588584536992501L;
-
+public abstract class AbstractCompactGPSFixImpl extends AbstractGPSFixImpl {
+ private static final long serialVersionUID = 3943572107870245437L;
+
/**
* Bit mask for {@link #whatIsCached}, telling whether validity is currently cached
*/
@@ -39,9 +34,7 @@ public class CompactGPSFixImpl extends AbstractGPSFixImpl {
* {@link #whatIsCached}&{@link #IS_VALIDITY_CACHED} != 0
*/
private static final byte VALIDITY = 1<<2;
-
- private final double latDeg;
- private final double lngDeg;
+
private final long timePointAsMillis;
/**
@@ -52,32 +45,6 @@ public class CompactGPSFixImpl extends AbstractGPSFixImpl {
*/
private byte whatIsCached = 0;
- /**
- * When {@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0, this field tells the estimated speed's
- * true "bearing" (true course over ground) in degrees.
- */
- private double cachedEstimatedSpeedBearingInDegrees;
-
- /**
- * When {@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0, this field tells the estimated speed
- * in knots.
- */
- private double cachedEstimatedSpeedInKnots;
-
- public class CompactPosition extends AbstractPosition {
- private static final long serialVersionUID = 5621506820766614178L;
-
- @Override
- public double getLatDeg() {
- return latDeg;
- }
-
- @Override
- public double getLngDeg() {
- return lngDeg;
- }
- }
-
private class CompactTimePoint extends AbstractTimePoint implements TimePoint {
private static final long serialVersionUID = -2470922642359937437L;
@@ -87,37 +54,12 @@ public class CompactGPSFixImpl extends AbstractGPSFixImpl {
}
}
- private class CompactEstimatedSpeedBearing extends AbstractBearing {
- private static final long serialVersionUID = 8549231429037883121L;
-
- @Override
- public double getDegrees() {
- return cachedEstimatedSpeedBearingInDegrees;
- }
- }
-
- private class CompactEstimatedSpeed extends AbstractSpeedWithAbstractBearingImpl {
- private static final long serialVersionUID = -5871855443391817248L;
-
- @Override
- public Bearing getBearing() {
- return new CompactEstimatedSpeedBearing();
- }
-
- @Override
- public double getKnots() {
- return cachedEstimatedSpeedInKnots;
- }
- }
-
- public CompactGPSFixImpl(Position position, TimePoint timePoint) {
- latDeg = position.getLatDeg();
- lngDeg = position.getLngDeg();
+ public AbstractCompactGPSFixImpl(TimePoint timePoint) {
timePointAsMillis = timePoint==null?-1:timePoint.asMillis();
}
-
- public CompactGPSFixImpl(GPSFix gpsFix) {
- this(gpsFix.getPosition(), gpsFix.getTimePoint());
+
+ public AbstractCompactGPSFixImpl(GPSFix gpsFix) {
+ this(gpsFix.getTimePoint());
}
@Override
@@ -125,11 +67,6 @@ public class CompactGPSFixImpl extends AbstractGPSFixImpl {
return getTimePoint() + ": " + getPosition();
}
- @Override
- public Position getPosition() {
- return new CompactPosition();
- }
-
@Override
public TimePoint getTimePoint() {
return new CompactTimePoint();
@@ -166,12 +103,6 @@ public class CompactGPSFixImpl extends AbstractGPSFixImpl {
return (whatIsCached & IS_ESTIMATED_SPEED_CACHED) != 0;
}
- @Override
- public SpeedWithBearing getCachedEstimatedSpeed() {
- assert isEstimatedSpeedCached();
- return new CompactEstimatedSpeed();
- }
-
@Override
public void invalidateEstimatedSpeedCache() {
whatIsCached &= ~IS_ESTIMATED_SPEED_CACHED;
@@ -179,10 +110,6 @@ public class CompactGPSFixImpl extends AbstractGPSFixImpl {
@Override
public void cacheEstimatedSpeed(SpeedWithBearing estimatedSpeed) {
- cachedEstimatedSpeedBearingInDegrees = estimatedSpeed.getBearing().getDegrees();
- cachedEstimatedSpeedInKnots = estimatedSpeed.getKnots();
whatIsCached |= IS_ESTIMATED_SPEED_CACHED;
}
-
-
}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactGPSFixMovingImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/AbstractCompactGPSFixMovingImpl.java
similarity index 66%
rename from java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactGPSFixMovingImpl.java
rename to java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/AbstractCompactGPSFixMovingImpl.java
index b48f26dcd05..a23e80dd0a3 100755
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactGPSFixMovingImpl.java
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/AbstractCompactGPSFixMovingImpl.java
@@ -1,6 +1,5 @@
package com.sap.sailing.domain.common.tracking.impl;
-import com.sap.sailing.domain.common.AbstractBearing;
import com.sap.sailing.domain.common.AbstractSpeedImpl;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.CourseChange;
@@ -21,23 +20,14 @@ import com.sap.sse.common.TimePoint;
* @author Axel Uhl (d043530)
*
*/
-public class CompactGPSFixMovingImpl extends CompactGPSFixImpl implements GPSFixMoving {
- private static final long serialVersionUID = 761582024504236533L;
- private final double knotSpeed;
- private final double degBearing;
-
- private class CompactSpeedWithBearing extends AbstractSpeedImpl implements SpeedWithBearing {
+public abstract class AbstractCompactGPSFixMovingImpl extends AbstractCompactGPSFixImpl implements GPSFixMoving {
+ private static final long serialVersionUID = 3977983319207618335L;
+
+ protected abstract class AbstractCompactSpeedWithBearing extends AbstractSpeedImpl implements SpeedWithBearing {
private static final long serialVersionUID = 1802065090733146728L;
@Override
- public double getKnots() {
- return knotSpeed;
- }
-
- @Override
- public Bearing getBearing() {
- return new CompactBearing();
- }
+ public abstract double getKnots();
@Override
public Position travelTo(Position pos, TimePoint from, TimePoint to) {
@@ -81,33 +71,12 @@ public class CompactGPSFixMovingImpl extends CompactGPSFixImpl implements GPSFix
}
}
- private class CompactBearing extends AbstractBearing {
- private static final long serialVersionUID = -6474909210513108635L;
-
- @Override
- public double getDegrees() {
- return degBearing;
- }
-
- @Override
- public double getRadians() {
- return degBearing / 180. * Math.PI;
- }
+ public AbstractCompactGPSFixMovingImpl(TimePoint timePoint) {
+ super(timePoint);
}
- public CompactGPSFixMovingImpl(Position position, TimePoint timePoint, SpeedWithBearing speed) {
- super(position, timePoint);
- knotSpeed = speed.getKnots();
- degBearing = speed.getBearing().getDegrees();
- }
-
- public CompactGPSFixMovingImpl(GPSFixMoving gpsFixMoving) {
- this(gpsFixMoving.getPosition(), gpsFixMoving.getTimePoint(), gpsFixMoving.getSpeed());
- }
-
- @Override
- public SpeedWithBearing getSpeed() {
- return new CompactSpeedWithBearing();
+ public AbstractCompactGPSFixMovingImpl(GPSFixMoving gpsFixMoving) throws CompactionNotPossibleException {
+ this(gpsFixMoving.getTimePoint());
}
@Override
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/AbstractCompactWindImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/AbstractCompactWindImpl.java
new file mode 100755
index 00000000000..81c83d7008e
--- /dev/null
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/AbstractCompactWindImpl.java
@@ -0,0 +1,129 @@
+package com.sap.sailing.domain.common.tracking.impl;
+
+import com.sap.sailing.domain.common.Bearing;
+import com.sap.sailing.domain.common.Position;
+import com.sap.sailing.domain.common.Wind;
+import com.sap.sailing.domain.common.impl.AbstractSpeedWithAbstractBearingImpl;
+import com.sap.sailing.domain.common.impl.WindImpl;
+import com.sap.sse.common.TimePoint;
+import com.sap.sse.common.Util;
+import com.sap.sse.common.impl.AbstractTimePoint;
+
+public abstract class AbstractCompactWindImpl extends AbstractSpeedWithAbstractBearingImpl implements Wind {
+ private static final long serialVersionUID = -5059956032663387929L;
+
+ /**
+ * bit mask for {@link #flags}, telling the bit encoding whether the position is {@code null}.
+ */
+ private static final byte POSITION_IS_NULL = 1<<0;
+
+ /**
+ * bit mask for {@link #flags}, telling the bit encoding whether the bearing is {@code null}.
+ */
+ private static final byte BEARING_IS_NULL = 1<<1;
+
+ /**
+ * bit mask for {@link #flags}, telling the bit encoding whether the time point is {@code null}.
+ */
+ private static final byte TIME_POINT_IS_NULL = 1<<2;
+
+ /**
+ * See the bit mask values such as {@link #POSITION_IS_NULL}, {@link #BEARING_IS_NULL} and {@link #TIME_POINT_IS_NULL}.
+ */
+ private final byte flags;
+
+ private final long timePointAsMillis;
+
+ private class CompactTimePoint extends AbstractTimePoint implements TimePoint {
+ private static final long serialVersionUID = -2470922642359937437L;
+
+ @Override
+ public long asMillis() {
+ return timePointAsMillis;
+ }
+ }
+
+ public AbstractCompactWindImpl(Wind wind) {
+ final boolean bearingIsNull;
+ final boolean positionIsNull;
+ final boolean timePointIsNull;
+ bearingIsNull = wind.getBearing() == null;
+ positionIsNull = wind.getPosition() == null;
+ if (wind.getTimePoint() == null) {
+ timePointIsNull = true;
+ this.timePointAsMillis = 0;
+ } else {
+ timePointIsNull = false;
+ this.timePointAsMillis = wind.getTimePoint().asMillis();
+ }
+ flags = (byte) ((byte) (bearingIsNull ? BEARING_IS_NULL : (byte) 0) | (positionIsNull ? POSITION_IS_NULL : (byte) 0) | (timePointIsNull ? TIME_POINT_IS_NULL : (byte) 0));
+ }
+
+ @Override
+ public Position getPosition() {
+ if ((flags & POSITION_IS_NULL) != 0) {
+ return null;
+ } else {
+ return getCompactPosition();
+ }
+ }
+
+ protected abstract Position getCompactPosition();
+
+ @Override
+ public TimePoint getTimePoint() {
+ if ((flags & TIME_POINT_IS_NULL) != 0) {
+ return null;
+ } else {
+ return new CompactTimePoint();
+ }
+ }
+
+ @Override
+ public Bearing getBearing() {
+ if ((flags & BEARING_IS_NULL) != 0) {
+ return null;
+ } else {
+ return getCompactBearing();
+ }
+ }
+
+ protected abstract Bearing getCompactBearing();
+
+ /**
+ * Make abstract to force implementing subclasses to implement this method.
+ */
+ @Override
+ public abstract double getKnots();
+
+ @Override
+ public Bearing getFrom() {
+ if (getBearing() == null) {
+ return null;
+ } else {
+ return getBearing().reverse();
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return WindImpl.hashCode(getPosition().getLatDeg(), getPosition().getLngDeg(), (flags&TIME_POINT_IS_NULL) != 0?0:timePointAsMillis);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (!(obj instanceof Wind))
+ return false;
+ Wind other = (Wind) obj;
+ return Util.equalsWithNull(getPosition(), other.getPosition()) && Util.equalsWithNull(getTimePoint(), other.getTimePoint());
+ }
+
+ @Override
+ public String toString() {
+ return ""+getTimePoint()+"@"+getPosition()+": "+getKnots()+"kn from "+getFrom();
+ }
+}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactPositionHelper.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactPositionHelper.java
new file mode 100755
index 00000000000..b391ca92522
--- /dev/null
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactPositionHelper.java
@@ -0,0 +1,75 @@
+package com.sap.sailing.domain.common.tracking.impl;
+
+import com.sap.sailing.domain.common.Bearing;
+import com.sap.sailing.domain.common.Position;
+import com.sap.sailing.domain.common.Speed;
+
+/**
+ * A utility class that "compact" fix implementations such as {@link VeryCompactGPSFixImpl} etc. can use
+ * to obtain representations of latitudes, longitudes, knot speeds and degree bearings marshalled in
+ * types that sacrifice very little accuracy from a real-world perspective, yet use a data type for
+ * encoding that requires fewer bytes than a {@code double} value.
+ *
+ * Latitude and longitude values are represented using a signed {@code int} value, scaling their range (-90..+90 and
+ * -180..+180, respectively over the full {@code int} range. This gives a resolution of 4.6mm for latitudes,
+ * and at the equator of 9.3mm for longitudes.
+ *
+ * Bearings / courses over ground are represented as a signed {@code short} value, mapping the range of -360..+360 to the
+ * value range of the {@code short} datatype. This results in a resolution of 0.01.
+ *
+ * Speed values are represented in knots in their compact form; lossy compaction uses a signed {@code short} value for
+ * the knot speeds, assuming a range of -500kts..+500kts, spreading this range over the value range of the {@code short}
+ * datatype. This results in a resolution of 0.015kts.
+ *
+ * If an attempt is made to obtain a compact form of a knot speed or bearing where the value if out of the range described above,
+ * a {@link CompactionNotPossibleException} will be thrown. Callers should then transparently resort to the precise
+ * compaction counterparts for the respective type.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class CompactPositionHelper {
+ private static final double LAT_SCALE = 90. / (double) (1 << 31); // int
+ private static final double LNG_SCALE = 180. / (double) (1 << 31); // int
+
+ private static final double KNOT_SPEED_SCALE = 500. /* knots; what that we track would ever be faster? */ / (double) (1<<15); // short
+ private static final double DEGREE_BEARING_SCALE = 360. / (double) (1<<15); // short
+
+ // Positions
+ public static double getLatDeg(int latDegScaled) {
+ return LAT_SCALE * latDegScaled;
+ }
+
+ public static double getLngDeg(int lngDegScaled) {
+ return LNG_SCALE * lngDegScaled;
+ }
+
+ public static int getLngDegScaled(Position position) {
+ return (int) (position.getLngDeg() / LNG_SCALE);
+ }
+
+ public static int getLatDegScaled(Position position) {
+ return (int) (position.getLatDeg() / LAT_SCALE);
+ }
+
+ // Speeds / Bearings
+ public static double getKnotSpeed(short knotSpeedScaled) {
+ return KNOT_SPEED_SCALE * knotSpeedScaled;
+ }
+
+ public static double getDegreeBearing(short degreeBearingScaled) {
+ return DEGREE_BEARING_SCALE * degreeBearingScaled;
+ }
+
+ public static short getKnotSpeedScaled(Speed speed) throws CompactionNotPossibleException {
+ final double knotSpeedScaled = speed.getKnots() / KNOT_SPEED_SCALE;
+ if (knotSpeedScaled > Short.MAX_VALUE || knotSpeedScaled < Short.MIN_VALUE) {
+ throw new CompactionNotPossibleException("Speed "+speed+" cannot be compacted; "+speed.getKnots()+" does not fit into a signed short value");
+ }
+ return (short) knotSpeedScaled;
+ }
+
+ public static short getDegreeBearingScaled(Bearing bearing) {
+ return (short) (bearing.getDegrees() / DEGREE_BEARING_SCALE);
+ }
+}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactWindImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactWindImpl.java
deleted file mode 100755
index 0c0035c54e7..00000000000
--- a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactWindImpl.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package com.sap.sailing.domain.common.tracking.impl;
-
-import com.sap.sailing.domain.common.AbstractBearing;
-import com.sap.sailing.domain.common.AbstractPosition;
-import com.sap.sailing.domain.common.Bearing;
-import com.sap.sailing.domain.common.Position;
-import com.sap.sailing.domain.common.Wind;
-import com.sap.sailing.domain.common.impl.AbstractSpeedWithAbstractBearingImpl;
-import com.sap.sailing.domain.common.impl.WindImpl;
-import com.sap.sse.common.TimePoint;
-import com.sap.sse.common.Util;
-import com.sap.sse.common.impl.AbstractTimePoint;
-
-public class CompactWindImpl extends AbstractSpeedWithAbstractBearingImpl implements Wind {
- private static final long serialVersionUID = -5059956032663387929L;
- private final double latDeg;
- private final double lngDeg;
- private final boolean positionIsNull;
- private final boolean bearingIsNull;
- private final boolean timePointIsNull;
- private final double speedInKnots;
- private final double degBearing;
- private final long timePointAsMillis;
-
- public class CompactPosition extends AbstractPosition {
- private static final long serialVersionUID = 5621506820766614178L;
-
- @Override
- public double getLatDeg() {
- return latDeg;
- }
-
- @Override
- public double getLngDeg() {
- return lngDeg;
- }
-
- @Override
- public boolean equals(Object o) {
- return this==o || o instanceof Position && getLatDeg() == ((Position) o).getLatDeg() && getLngDeg() == ((Position) o).getLngDeg();
- }
- }
-
- private class CompactBearing extends AbstractBearing {
- private static final long serialVersionUID = -6474909210513108635L;
-
- @Override
- public double getDegrees() {
- return degBearing;
- }
-
- @Override
- public double getRadians() {
- return degBearing / 180. * Math.PI;
- }
-
- @Override
- public boolean equals(Object object) {
- return this==object || object instanceof Bearing && getDegrees() == ((Bearing) object).getDegrees();
- }
- }
-
- private class CompactTimePoint extends AbstractTimePoint implements TimePoint {
- private static final long serialVersionUID = -2470922642359937437L;
-
- @Override
- public long asMillis() {
- return timePointAsMillis;
- }
- }
-
- public CompactWindImpl(Wind wind) {
- if (wind.getBearing() == null) {
- bearingIsNull = true;
- degBearing = 0;
- } else {
- this.degBearing = wind.getBearing().getDegrees();
- bearingIsNull = false;
- }
- if (wind.getPosition() == null) {
- positionIsNull = true;
- this.latDeg = 0;
- this.lngDeg = 0;
- } else {
- this.latDeg = wind.getPosition().getLatDeg();
- this.lngDeg = wind.getPosition().getLngDeg();
- positionIsNull = false;
- }
- this.speedInKnots = wind.getKnots();
- if (wind.getTimePoint() == null) {
- timePointIsNull = true;
- this.timePointAsMillis = 0;
- } else {
- timePointIsNull = false;
- this.timePointAsMillis = wind.getTimePoint().asMillis();
- }
- }
-
- @Override
- public Position getPosition() {
- if (positionIsNull) {
- return null;
- } else {
- return new CompactPosition();
- }
- }
-
- @Override
- public TimePoint getTimePoint() {
- if (timePointIsNull) {
- return null;
- } else {
- return new CompactTimePoint();
- }
- }
-
- @Override
- public Bearing getBearing() {
- if (bearingIsNull) {
- return null;
- } else {
- return new CompactBearing();
- }
- }
-
- @Override
- public double getKnots() {
- return speedInKnots;
- }
-
- @Override
- public Bearing getFrom() {
- if (getBearing() == null) {
- return null;
- } else {
- return getBearing().reverse();
- }
- }
-
- @Override
- public int hashCode() {
- return WindImpl.hashCode(latDeg, lngDeg, timePointIsNull?0:timePointAsMillis);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!super.equals(obj))
- return false;
- if (!(obj instanceof Wind))
- return false;
- Wind other = (Wind) obj;
- return Util.equalsWithNull(getPosition(), other.getPosition()) && Util.equalsWithNull(getTimePoint(), other.getTimePoint());
- }
-
- @Override
- public String toString() {
- return ""+getTimePoint()+"@"+getPosition()+": "+getKnots()+"kn from "+getFrom();
- }
-}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactionNotPossibleException.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactionNotPossibleException.java
new file mode 100755
index 00000000000..43be75fd2d0
--- /dev/null
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/CompactionNotPossibleException.java
@@ -0,0 +1,37 @@
+package com.sap.sailing.domain.common.tracking.impl;
+
+/**
+ * Throws when an attempt is made to turn a fix of some sort into a more compact form, probably
+ * slightly reducing accuracy and/or reducing value ranges, such as for the speeds possible, where
+ * the fix presented cannot be turned into its compact form without exceeding a range. This would
+ * lead to an overflow or wrap-around and cannot be tolerated. Clients need to handle this exception
+ * by skipping compaction and using the original fix instead.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class CompactionNotPossibleException extends Exception {
+ private static final long serialVersionUID = -723044264487667717L;
+
+ public CompactionNotPossibleException() {
+ super();
+ }
+
+ public CompactionNotPossibleException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+ public CompactionNotPossibleException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public CompactionNotPossibleException(String message) {
+ super(message);
+ }
+
+ public CompactionNotPossibleException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/PreciseCompactGPSFixImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/PreciseCompactGPSFixImpl.java
new file mode 100755
index 00000000000..1cf8940a462
--- /dev/null
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/PreciseCompactGPSFixImpl.java
@@ -0,0 +1,105 @@
+package com.sap.sailing.domain.common.tracking.impl;
+
+import com.sap.sailing.domain.common.AbstractBearing;
+import com.sap.sailing.domain.common.AbstractPosition;
+import com.sap.sailing.domain.common.Bearing;
+import com.sap.sailing.domain.common.Position;
+import com.sap.sailing.domain.common.SpeedWithBearing;
+import com.sap.sailing.domain.common.impl.AbstractSpeedWithAbstractBearingImpl;
+import com.sap.sailing.domain.common.tracking.GPSFix;
+import com.sap.sse.common.TimePoint;
+
+/**
+ * A compact representation of a GPS fix which collects all primitive-typed attributes in one object to avoid
+ * memory overhead otherwise created by using too many individual fine-grained objects.
+ *
+ * Objects of this type are assumed to be contained in at most one {@link DynamicGPSFixTrackImpl}. It is
+ * therefore permissible to cache information about validity to speed up the otherwise expensive
+ * {@link DynamicGPSFixTrackImpl#isValid(PartialNavigableSetView, GPSFix)} computation.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class PreciseCompactGPSFixImpl extends AbstractCompactGPSFixImpl {
+ private static final long serialVersionUID = 8167588584536992501L;
+
+ private final double latDeg;
+ private final double lngDeg;
+
+ /**
+ * When {@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0, this field tells the estimated speed's
+ * true "bearing" (true course over ground) in degrees.
+ */
+ private double cachedEstimatedSpeedBearingInDegrees;
+
+ /**
+ * When {@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0, this field tells the estimated speed
+ * in knots.
+ */
+ private double cachedEstimatedSpeedInKnots;
+
+ public class PreciseCompactPosition extends AbstractPosition {
+ private static final long serialVersionUID = 5621506820766614178L;
+
+ @Override
+ public double getLatDeg() {
+ return latDeg;
+ }
+
+ @Override
+ public double getLngDeg() {
+ return lngDeg;
+ }
+ }
+
+ private class PreciseCompactEstimatedSpeedBearing extends AbstractBearing {
+ private static final long serialVersionUID = 8549231429037883121L;
+
+ @Override
+ public double getDegrees() {
+ return cachedEstimatedSpeedBearingInDegrees;
+ }
+ }
+
+ private class PreciseCompactEstimatedSpeed extends AbstractSpeedWithAbstractBearingImpl {
+ private static final long serialVersionUID = -5871855443391817248L;
+
+ @Override
+ public Bearing getBearing() {
+ return new PreciseCompactEstimatedSpeedBearing();
+ }
+
+ @Override
+ public double getKnots() {
+ return cachedEstimatedSpeedInKnots;
+ }
+ }
+
+ public PreciseCompactGPSFixImpl(Position position, TimePoint timePoint) {
+ super(timePoint);
+ latDeg = position.getLatDeg();
+ lngDeg = position.getLngDeg();
+ }
+
+ public PreciseCompactGPSFixImpl(GPSFix gpsFix) {
+ this(gpsFix.getPosition(), gpsFix.getTimePoint());
+ }
+
+ @Override
+ public Position getPosition() {
+ return new PreciseCompactPosition();
+ }
+
+ @Override
+ public SpeedWithBearing getCachedEstimatedSpeed() {
+ assert isEstimatedSpeedCached();
+ return new PreciseCompactEstimatedSpeed();
+ }
+
+ @Override
+ public void cacheEstimatedSpeed(SpeedWithBearing estimatedSpeed) {
+ cachedEstimatedSpeedBearingInDegrees = estimatedSpeed.getBearing().getDegrees();
+ cachedEstimatedSpeedInKnots = estimatedSpeed.getKnots();
+ super.cacheEstimatedSpeed(estimatedSpeed);
+ }
+}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/PreciseCompactGPSFixMovingImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/PreciseCompactGPSFixMovingImpl.java
new file mode 100755
index 00000000000..cc6944a24b9
--- /dev/null
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/PreciseCompactGPSFixMovingImpl.java
@@ -0,0 +1,135 @@
+package com.sap.sailing.domain.common.tracking.impl;
+
+import com.sap.sailing.domain.common.AbstractBearing;
+import com.sap.sailing.domain.common.AbstractPosition;
+import com.sap.sailing.domain.common.Bearing;
+import com.sap.sailing.domain.common.Position;
+import com.sap.sailing.domain.common.SpeedWithBearing;
+import com.sap.sailing.domain.common.impl.AbstractSpeedWithAbstractBearingImpl;
+import com.sap.sailing.domain.common.tracking.GPSFixMoving;
+import com.sap.sse.common.TimePoint;
+
+/**
+ * A memory-conserving representation of a {@link GPSFixMoving} object that produces the fine-grained
+ * objects for {@link Position}, {@link SpeedWithBearing}, {@link Bearing} and {@link TimePoint} dynamically
+ * as thin wrappers around this object which holds all elementary attributes required. This saves several
+ * object references and object headers.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class PreciseCompactGPSFixMovingImpl extends AbstractCompactGPSFixMovingImpl {
+ private static final long serialVersionUID = 761582024504236533L;
+ private final double latDeg;
+ private final double lngDeg;
+ private final double knotSpeed;
+ private final double degBearing;
+
+ /**
+ * When {@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0, this field tells the estimated speed's
+ * true "bearing" (true course over ground) in degrees.
+ */
+ private double cachedEstimatedSpeedBearingInDegrees;
+
+ /**
+ * When {@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0, this field tells the estimated speed
+ * in knots.
+ */
+ private double cachedEstimatedSpeedInKnots;
+
+
+ private class PreciseCompactSpeedWithBearing extends AbstractCompactSpeedWithBearing implements SpeedWithBearing {
+ private static final long serialVersionUID = 1802065090733146728L;
+
+ @Override
+ public double getKnots() {
+ return knotSpeed;
+ }
+
+ @Override
+ public Bearing getBearing() {
+ return new PreciseCompactBearing();
+ }
+ }
+
+ private class PreciseCompactBearing extends AbstractBearing {
+ private static final long serialVersionUID = -6474909210513108635L;
+
+ @Override
+ public double getDegrees() {
+ return degBearing;
+ }
+ }
+
+ public class PreciseCompactPosition extends AbstractPosition {
+ private static final long serialVersionUID = 5621506820766614178L;
+
+ @Override
+ public double getLatDeg() {
+ return latDeg;
+ }
+
+ @Override
+ public double getLngDeg() {
+ return lngDeg;
+ }
+ }
+
+ private class PreciseCompactEstimatedSpeedBearing extends AbstractBearing {
+ private static final long serialVersionUID = 8549231429037883121L;
+
+ @Override
+ public double getDegrees() {
+ return cachedEstimatedSpeedBearingInDegrees;
+ }
+ }
+
+ private class PreciseCompactEstimatedSpeed extends AbstractSpeedWithAbstractBearingImpl {
+ private static final long serialVersionUID = -5871855443391817248L;
+
+ @Override
+ public Bearing getBearing() {
+ return new PreciseCompactEstimatedSpeedBearing();
+ }
+
+ @Override
+ public double getKnots() {
+ return cachedEstimatedSpeedInKnots;
+ }
+ }
+
+ public PreciseCompactGPSFixMovingImpl(Position position, TimePoint timePoint, SpeedWithBearing speed) {
+ super(timePoint);
+ latDeg = position.getLatDeg();
+ lngDeg = position.getLngDeg();
+ knotSpeed = speed==null?0:speed.getKnots();
+ degBearing = speed==null?0:speed.getBearing().getDegrees();
+ }
+
+ public PreciseCompactGPSFixMovingImpl(GPSFixMoving gpsFixMoving) {
+ this(gpsFixMoving.getPosition(), gpsFixMoving.getTimePoint(), gpsFixMoving.getSpeed());
+ }
+
+ @Override
+ public SpeedWithBearing getSpeed() {
+ return new PreciseCompactSpeedWithBearing();
+ }
+
+ @Override
+ public Position getPosition() {
+ return new PreciseCompactPosition();
+ }
+
+ @Override
+ public SpeedWithBearing getCachedEstimatedSpeed() {
+ assert isEstimatedSpeedCached();
+ return new PreciseCompactEstimatedSpeed();
+ }
+
+ @Override
+ public void cacheEstimatedSpeed(SpeedWithBearing estimatedSpeed) {
+ cachedEstimatedSpeedBearingInDegrees = estimatedSpeed.getBearing().getDegrees();
+ cachedEstimatedSpeedInKnots = estimatedSpeed.getKnots();
+ super.cacheEstimatedSpeed(estimatedSpeed);
+ }
+}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/PreciseCompactWindImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/PreciseCompactWindImpl.java
new file mode 100755
index 00000000000..12a444c2cb2
--- /dev/null
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/PreciseCompactWindImpl.java
@@ -0,0 +1,81 @@
+package com.sap.sailing.domain.common.tracking.impl;
+
+import com.sap.sailing.domain.common.AbstractBearing;
+import com.sap.sailing.domain.common.AbstractPosition;
+import com.sap.sailing.domain.common.Bearing;
+import com.sap.sailing.domain.common.Position;
+import com.sap.sailing.domain.common.Wind;
+
+/**
+ * Keeps the precise values of lat/lng and speed/course.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class PreciseCompactWindImpl extends AbstractCompactWindImpl {
+ private static final long serialVersionUID = -5059956032663387929L;
+ private final double latDeg;
+ private final double lngDeg;
+ private final double speedInKnots;
+ private final double degBearing;
+
+ public class CompactPosition extends AbstractPosition {
+ private static final long serialVersionUID = 5621506820766614178L;
+
+ @Override
+ public double getLatDeg() {
+ return latDeg;
+ }
+
+ @Override
+ public double getLngDeg() {
+ return lngDeg;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return this==o || o instanceof Position && getLatDeg() == ((Position) o).getLatDeg() && getLngDeg() == ((Position) o).getLngDeg();
+ }
+ }
+
+ private class CompactBearing extends AbstractBearing {
+ private static final long serialVersionUID = -6474909210513108635L;
+
+ @Override
+ public double getDegrees() {
+ return degBearing;
+ }
+ }
+
+ public PreciseCompactWindImpl(Wind wind) {
+ super(wind);
+ if (wind.getBearing() == null) {
+ degBearing = 0;
+ } else {
+ this.degBearing = wind.getBearing().getDegrees();
+ }
+ if (wind.getPosition() == null) {
+ this.latDeg = 0;
+ this.lngDeg = 0;
+ } else {
+ this.latDeg = wind.getPosition().getLatDeg();
+ this.lngDeg = wind.getPosition().getLngDeg();
+ }
+ this.speedInKnots = wind.getKnots();
+ }
+
+ @Override
+ public double getKnots() {
+ return speedInKnots;
+ }
+
+ @Override
+ protected Position getCompactPosition() {
+ return new CompactPosition();
+ }
+
+ @Override
+ protected Bearing getCompactBearing() {
+ return new CompactBearing();
+ }
+}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/VeryCompactGPSFixImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/VeryCompactGPSFixImpl.java
new file mode 100755
index 00000000000..ff6b0931d43
--- /dev/null
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/VeryCompactGPSFixImpl.java
@@ -0,0 +1,128 @@
+package com.sap.sailing.domain.common.tracking.impl;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.sap.sailing.domain.common.AbstractBearing;
+import com.sap.sailing.domain.common.AbstractPosition;
+import com.sap.sailing.domain.common.Bearing;
+import com.sap.sailing.domain.common.Position;
+import com.sap.sailing.domain.common.SpeedWithBearing;
+import com.sap.sailing.domain.common.impl.AbstractSpeedWithAbstractBearingImpl;
+import com.sap.sailing.domain.common.tracking.GPSFix;
+import com.sap.sse.common.TimePoint;
+
+/**
+ * A compact representation of a GPS fix which collects all primitive-typed attributes in one object to avoid
+ * memory overhead otherwise created by using too many individual fine-grained objects.
+ *
+ * Objects of this type are assumed to be contained in at most one {@link DynamicGPSFixTrackImpl}. It is
+ * therefore permissible to cache information about validity to speed up the otherwise expensive
+ * {@link DynamicGPSFixTrackImpl#isValid(PartialNavigableSetView, GPSFix)} computation.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class VeryCompactGPSFixImpl extends AbstractCompactGPSFixImpl {
+ private static final long serialVersionUID = 3943572107870245437L;
+
+ private static final Logger logger = Logger.getLogger(VeryCompactGPSFixImpl.class.getName());
+
+ /**
+ * See {@link CompactPositionHelper}
+ */
+ private final int latDegScaled;
+
+ /**
+ * See {@link CompactPositionHelper}
+ */
+ private final int lngDegScaled;
+
+ /**
+ * When {@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0, this field tells the estimated speed's
+ * true "bearing" (true course over ground) in degrees, scaled into a short value using {@link CompactPositionHelper}.
+ */
+ private short cachedEstimatedSpeedBearingInDegreesScaled;
+
+ /**
+ * When {@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0, this field tells the estimated speed
+ * in knots, scaled into a short value using {@link CompactPositionHelper}.
+ */
+ private short cachedEstimatedSpeedInKnotsScaled;
+
+ public class CompactPosition extends AbstractPosition {
+ private static final long serialVersionUID = 5621506820766614178L;
+
+ @Override
+ public double getLatDeg() {
+ return CompactPositionHelper.getLatDeg(latDegScaled);
+ }
+
+ @Override
+ public double getLngDeg() {
+ return CompactPositionHelper.getLngDeg(lngDegScaled);
+ }
+ }
+
+ private class VeryCompactEstimatedSpeedBearing extends AbstractBearing {
+ private static final long serialVersionUID = 8549231429037883121L;
+
+ @Override
+ public double getDegrees() {
+ return CompactPositionHelper.getDegreeBearing(cachedEstimatedSpeedBearingInDegreesScaled);
+ }
+ }
+
+ private class VeryCompactEstimatedSpeed extends AbstractSpeedWithAbstractBearingImpl {
+ private static final long serialVersionUID = -5871855443391817248L;
+
+ @Override
+ public Bearing getBearing() {
+ return new VeryCompactEstimatedSpeedBearing();
+ }
+
+ @Override
+ public double getKnots() {
+ return CompactPositionHelper.getKnotSpeed(cachedEstimatedSpeedInKnotsScaled);
+ }
+ }
+
+ public VeryCompactGPSFixImpl(Position position, TimePoint timePoint) {
+ super(timePoint);
+ latDegScaled = CompactPositionHelper.getLatDegScaled(position);
+ lngDegScaled = CompactPositionHelper.getLngDegScaled(position);
+ }
+
+ public VeryCompactGPSFixImpl(GPSFix gpsFix) {
+ this(gpsFix.getPosition(), gpsFix.getTimePoint());
+ }
+
+ @Override
+ public Position getPosition() {
+ return new CompactPosition();
+ }
+
+ @Override
+ public SpeedWithBearing getCachedEstimatedSpeed() {
+ assert isEstimatedSpeedCached();
+ return new VeryCompactEstimatedSpeed();
+ }
+
+ /**
+ * Under rare circumstances, caching the speed may fail for the compact representation of a GPS fix.
+ * This can happen if the speed estimated exceeds the range that can be represented in this compact
+ * form which is less than in the original form where the speed amount is represented as a {@code double}
+ * value. In this case, a warning message is logged with level {@link Level#FINER}, and the speed remains
+ * uncached.
+ */
+ @Override
+ public void cacheEstimatedSpeed(SpeedWithBearing estimatedSpeed) {
+ try {
+ cachedEstimatedSpeedInKnotsScaled = CompactPositionHelper.getKnotSpeedScaled(estimatedSpeed);
+ cachedEstimatedSpeedBearingInDegreesScaled = CompactPositionHelper.getDegreeBearingScaled(estimatedSpeed.getBearing());
+ super.cacheEstimatedSpeed(estimatedSpeed);
+ } catch (CompactionNotPossibleException e) {
+ logger.log(Level.FINER, "Cannot cache estimated speed "+estimatedSpeed+" in compact fix:", e);
+ }
+ }
+}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/VeryCompactGPSFixMovingImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/VeryCompactGPSFixMovingImpl.java
new file mode 100755
index 00000000000..625379af503
--- /dev/null
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/VeryCompactGPSFixMovingImpl.java
@@ -0,0 +1,171 @@
+package com.sap.sailing.domain.common.tracking.impl;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.sap.sailing.domain.common.AbstractBearing;
+import com.sap.sailing.domain.common.AbstractPosition;
+import com.sap.sailing.domain.common.Bearing;
+import com.sap.sailing.domain.common.Position;
+import com.sap.sailing.domain.common.SpeedWithBearing;
+import com.sap.sailing.domain.common.impl.AbstractSpeedWithAbstractBearingImpl;
+import com.sap.sailing.domain.common.tracking.GPSFixMoving;
+import com.sap.sse.common.TimePoint;
+
+/**
+ * A memory-conserving representation of a {@link GPSFixMoving} object that produces the fine-grained
+ * objects for {@link Position}, {@link SpeedWithBearing}, {@link Bearing} and {@link TimePoint} dynamically
+ * as thin wrappers around this object which holds all elementary attributes required. This saves several
+ * object references and object headers.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class VeryCompactGPSFixMovingImpl extends AbstractCompactGPSFixMovingImpl {
+ private static final long serialVersionUID = 3977983319207618335L;
+
+ private static final Logger logger = Logger.getLogger(VeryCompactGPSFixMovingImpl.class.getName());
+
+ /**
+ * See {@link CompactPositionHelper}
+ */
+ private final int latDegScaled;
+
+ /**
+ * See {@link CompactPositionHelper}
+ */
+ private final int lngDegScaled;
+
+ /**
+ * See {@link CompactPositionHelper}
+ */
+ private final short speedInKnotsScaled;
+
+ /**
+ * See {@link CompactPositionHelper}
+ */
+ private final short degreeBearingScaled;
+
+ /**
+ * When {@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0, this field tells the estimated speed's
+ * true "bearing" (true course over ground) in degrees, scaled into a short value using {@link CompactPositionHelper}.
+ */
+ private short cachedEstimatedSpeedBearingInDegreesScaled;
+
+ /**
+ * When {@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0, this field tells the estimated speed
+ * in knots, scaled into a short value using {@link CompactPositionHelper}.
+ */
+ private short cachedEstimatedSpeedInKnotsScaled;
+
+ public class VeryCompactPosition extends AbstractPosition {
+ private static final long serialVersionUID = 5621506820766614178L;
+
+ @Override
+ public double getLatDeg() {
+ return CompactPositionHelper.getLatDeg(latDegScaled);
+ }
+
+ @Override
+ public double getLngDeg() {
+ return CompactPositionHelper.getLngDeg(lngDegScaled);
+ }
+ }
+
+ private class VeryCompactSpeedWithBearing extends AbstractCompactSpeedWithBearing {
+ private static final long serialVersionUID = 1802065090733146728L;
+
+ @Override
+ public double getKnots() {
+ return CompactPositionHelper.getKnotSpeed(speedInKnotsScaled);
+ }
+
+ @Override
+ public Bearing getBearing() {
+ return new VeryCompactBearing();
+ }
+ }
+
+ private class VeryCompactBearing extends AbstractBearing {
+ private static final long serialVersionUID = 8167886382067060570L;
+
+ @Override
+ public double getDegrees() {
+ return CompactPositionHelper.getDegreeBearing(degreeBearingScaled);
+ }
+ }
+
+ private class VeryCompactEstimatedSpeedBearing extends AbstractBearing {
+ private static final long serialVersionUID = 8549231429037883121L;
+
+ @Override
+ public double getDegrees() {
+ return CompactPositionHelper.getDegreeBearing(cachedEstimatedSpeedBearingInDegreesScaled);
+ }
+ }
+
+ private class VeryCompactEstimatedSpeed extends AbstractSpeedWithAbstractBearingImpl {
+ private static final long serialVersionUID = -5871855443391817248L;
+
+ @Override
+ public Bearing getBearing() {
+ return new VeryCompactEstimatedSpeedBearing();
+ }
+
+ @Override
+ public double getKnots() {
+ return CompactPositionHelper.getKnotSpeed(cachedEstimatedSpeedInKnotsScaled);
+ }
+ }
+
+ public VeryCompactGPSFixMovingImpl(Position position, TimePoint timePoint, SpeedWithBearing speed) throws CompactionNotPossibleException {
+ super(timePoint);
+ latDegScaled = CompactPositionHelper.getLatDegScaled(position);
+ lngDegScaled = CompactPositionHelper.getLngDegScaled(position);
+ if (speed == null) {
+ speedInKnotsScaled = 0;
+ degreeBearingScaled = 0;
+ } else {
+ speedInKnotsScaled = CompactPositionHelper.getKnotSpeedScaled(speed);
+ degreeBearingScaled = CompactPositionHelper.getDegreeBearingScaled(speed.getBearing());
+ }
+ }
+
+ public VeryCompactGPSFixMovingImpl(GPSFixMoving gpsFixMoving) throws CompactionNotPossibleException {
+ this(gpsFixMoving.getPosition(), gpsFixMoving.getTimePoint(), gpsFixMoving.getSpeed());
+ }
+
+ @Override
+ public SpeedWithBearing getSpeed() {
+ return new VeryCompactSpeedWithBearing();
+ }
+
+ @Override
+ public Position getPosition() {
+ return new VeryCompactPosition();
+ }
+
+ @Override
+ public SpeedWithBearing getCachedEstimatedSpeed() {
+ assert isEstimatedSpeedCached();
+ return new VeryCompactEstimatedSpeed();
+ }
+
+ /**
+ * Under rare circumstances, caching the speed may fail for the compact representation of a GPS fix.
+ * This can happen if the speed estimated exceeds the range that can be represented in this compact
+ * form which is less than in the original form where the speed amount is represented as a {@code double}
+ * value. In this case, a warning message is logged with level {@link Level#FINER}, and the speed remains
+ * uncached.
+ */
+ @Override
+ public void cacheEstimatedSpeed(SpeedWithBearing estimatedSpeed) {
+ try {
+ cachedEstimatedSpeedInKnotsScaled = CompactPositionHelper.getKnotSpeedScaled(estimatedSpeed);
+ cachedEstimatedSpeedBearingInDegreesScaled = CompactPositionHelper.getDegreeBearingScaled(estimatedSpeed.getBearing());
+ super.cacheEstimatedSpeed(estimatedSpeed);
+ } catch (CompactionNotPossibleException e) {
+ logger.log(Level.FINER, "Cannot cache estimated speed "+estimatedSpeed+" in compact fix:", e);
+ }
+ }
+}
diff --git a/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/VeryCompactWindImpl.java b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/VeryCompactWindImpl.java
new file mode 100755
index 00000000000..1d3b60b3988
--- /dev/null
+++ b/java/com.sap.sailing.domain.common/src/com/sap/sailing/domain/common/tracking/impl/VeryCompactWindImpl.java
@@ -0,0 +1,92 @@
+package com.sap.sailing.domain.common.tracking.impl;
+
+import com.sap.sailing.domain.common.AbstractBearing;
+import com.sap.sailing.domain.common.AbstractPosition;
+import com.sap.sailing.domain.common.Bearing;
+import com.sap.sailing.domain.common.Position;
+import com.sap.sailing.domain.common.Wind;
+
+/**
+ * Uses scaled, rounded internal representations of the values for lat/lng and speed/course. See
+ * {@link CompactPositionHelper} for the details of how value ranges and accuracies are affected.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class VeryCompactWindImpl extends AbstractCompactWindImpl {
+ private static final long serialVersionUID = -5059956032663387929L;
+ /**
+ * See {@link CompactPositionHelper}
+ */
+ private final int latDegScaled;
+
+ /**
+ * See {@link CompactPositionHelper}
+ */
+ private final int lngDegScaled;
+
+ /**
+ * See {@link CompactPositionHelper}
+ */
+ private final short speedInKnotsScaled;
+
+ /**
+ * See {@link CompactPositionHelper}
+ */
+ private final short degreeBearingScaled;
+
+ public class VeryCompactPosition extends AbstractPosition {
+ private static final long serialVersionUID = 5621506820766614178L;
+
+ @Override
+ public double getLatDeg() {
+ return CompactPositionHelper.getLatDeg(latDegScaled);
+ }
+
+ @Override
+ public double getLngDeg() {
+ return CompactPositionHelper.getLngDeg(lngDegScaled);
+ }
+ }
+
+ private class VeryCompactBearing extends AbstractBearing {
+ private static final long serialVersionUID = -6474909210513108635L;
+
+ @Override
+ public double getDegrees() {
+ return CompactPositionHelper.getDegreeBearing(degreeBearingScaled);
+ }
+ }
+
+ public VeryCompactWindImpl(Wind wind) throws CompactionNotPossibleException {
+ super(wind);
+ if (wind.getBearing() == null) {
+ degreeBearingScaled = 0;
+ } else {
+ this.degreeBearingScaled = CompactPositionHelper.getDegreeBearingScaled(wind.getBearing());
+ }
+ if (wind.getPosition() == null) {
+ this.latDegScaled = 0;
+ this.lngDegScaled = 0;
+ } else {
+ this.latDegScaled = CompactPositionHelper.getLatDegScaled(wind.getPosition());
+ this.lngDegScaled = CompactPositionHelper.getLngDegScaled(wind.getPosition());
+ }
+ this.speedInKnotsScaled = CompactPositionHelper.getKnotSpeedScaled(wind);
+ }
+
+ @Override
+ public double getKnots() {
+ return CompactPositionHelper.getKnotSpeed(speedInKnotsScaled);
+ }
+
+ @Override
+ protected Position getCompactPosition() {
+ return new VeryCompactPosition();
+ }
+
+ @Override
+ protected Bearing getCompactBearing() {
+ return new VeryCompactBearing();
+ }
+}
diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java
index 84b317d9e5c..fad4cdaf86a 100644
--- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java
+++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/DomainObjectFactoryImpl.java
@@ -1962,7 +1962,7 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
if (controlPointClass.equals(Mark.class.getSimpleName())) {
Mark mark = loadMark((DBObject) dbObject.get(FieldNames.CONTROLPOINT_VALUE.name()));
controlPoint = mark;
- } else if(controlPointClass.equals("Gate")) {
+ } else if (controlPointClass.equals("Gate")) {
ControlPointWithTwoMarks cpwtm = loadControlPointWithTwoMarks((DBObject) dbObject.get(FieldNames.CONTROLPOINT_VALUE.name()));
dbObject.put(FieldNames.CONTROLPOINT_CLASS.name(), ControlPointWithTwoMarks.class.getSimpleName());
controlPoint = cpwtm;
@@ -2318,8 +2318,14 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
}
}
try {
- callback.accept(connectivityParamsPersistenceService.mapTo(map));
- logger.info("Done restoring race #"+ finalI +"/"+count+" of type "+type);
+ final RaceTrackingConnectivityParameters params = connectivityParamsPersistenceService.mapTo(map);
+ if (params != null) {
+ callback.accept(params);
+ logger.info("Done restoring race #"+ finalI +"/"+count+" of type "+type);
+ } else {
+ logger.warning("Couldn't restore race #"+ finalI +"/"+count+" of type "+type+
+ " because the parameters loaded from the DB couldn't be mapped. Maybe the owning leaderboard was removed?");
+ }
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception trying to load race #"+ finalI +"/"+count+" of type "+type+
" from restore connectivity parameters "
diff --git a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java
index 575635388ba..891e6dc15cc 100644
--- a/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java
+++ b/java/com.sap.sailing.domain.persistence/src/com/sap/sailing/domain/persistence/impl/MongoObjectFactoryImpl.java
@@ -221,7 +221,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
public DBCollection getWindTrackCollection() {
DBCollection result = database.getCollection(CollectionNames.WIND_TRACKS.name());
- result.createIndex(new BasicDBObject(FieldNames.REGATTA_NAME.name(), null));
+ result.createIndex(new BasicDBObject(FieldNames.REGATTA_NAME.name(), 1));
return result;
}
@@ -237,7 +237,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
public DBCollection getGPSFixMetadataCollection() {
DBCollection collection = database.getCollection(CollectionNames.GPS_FIXES_METADATA.name());
DBObject index = new BasicDBObject();
- index.put(FieldNames.DEVICE_ID.name(), null);
+ index.put(FieldNames.DEVICE_ID.name(), 1);
collection.createIndex(index);
return collection;
}
@@ -741,7 +741,7 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
public DBCollection getRaceLogCollection() {
DBCollection result = database.getCollection(CollectionNames.RACE_LOGS.name());
- result.createIndex(new BasicDBObject(FieldNames.RACE_LOG_IDENTIFIER.name(), null));
+ result.createIndex(new BasicDBObject(FieldNames.RACE_LOG_IDENTIFIER.name(), 1));
return result;
}
@@ -1372,8 +1372,8 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
public DBCollection getRegattaLogCollection() {
DBCollection result = database.getCollection(CollectionNames.REGATTA_LOGS.name());
- DBObject index = new BasicDBObject(FieldNames.REGATTA_LOG_IDENTIFIER_TYPE.name(), null);
- index.put(FieldNames.REGATTA_LOG_IDENTIFIER_NAME.name(), null);
+ DBObject index = new BasicDBObject(FieldNames.REGATTA_LOG_IDENTIFIER_TYPE.name(), 1);
+ index.put(FieldNames.REGATTA_LOG_IDENTIFIER_NAME.name(), 1);
result.createIndex(index);
return result;
}
diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter.test/src/com/sap/sailing/domain/racelogtracking/test/impl/SensorFixStoreAndLoadTest.java b/java/com.sap.sailing.domain.racelogtrackingadapter.test/src/com/sap/sailing/domain/racelogtracking/test/impl/SensorFixStoreAndLoadTest.java
index 2e7f4e17d99..aaafe78372d 100644
--- a/java/com.sap.sailing.domain.racelogtrackingadapter.test/src/com/sap/sailing/domain/racelogtracking/test/impl/SensorFixStoreAndLoadTest.java
+++ b/java/com.sap.sailing.domain.racelogtrackingadapter.test/src/com/sap/sailing/domain/racelogtracking/test/impl/SensorFixStoreAndLoadTest.java
@@ -566,8 +566,7 @@ public class SensorFixStoreAndLoadTest {
public static final String TRACK_NAME = "TestFixTrack";
public TestFixTrackImpl(ItemType trackedItem, String trackName) {
- super(trackedItem, trackName, TestFixImpl.COLUMNS,
- TRACK_NAME + " for " + trackedItem);
+ super(trackedItem, trackName, TRACK_NAME + " for " + trackedItem);
}
public Double getTextValue(TimePoint timePoint) {
diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter.testsupport/src/com/sap/sailing/domain/racelog/tracking/test/mock/MockGPSFixMongoServiceFinder.java b/java/com.sap.sailing.domain.racelogtrackingadapter.testsupport/src/com/sap/sailing/domain/racelog/tracking/test/mock/MockGPSFixMongoServiceFinder.java
index 241b5fff5f3..b29d32db4b8 100644
--- a/java/com.sap.sailing.domain.racelogtrackingadapter.testsupport/src/com/sap/sailing/domain/racelog/tracking/test/mock/MockGPSFixMongoServiceFinder.java
+++ b/java/com.sap.sailing.domain.racelogtrackingadapter.testsupport/src/com/sap/sailing/domain/racelog/tracking/test/mock/MockGPSFixMongoServiceFinder.java
@@ -4,8 +4,8 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
-import com.sap.sailing.domain.common.tracking.impl.CompactGPSFixImpl;
-import com.sap.sailing.domain.common.tracking.impl.CompactGPSFixMovingImpl;
+import com.sap.sailing.domain.common.tracking.impl.VeryCompactGPSFixImpl;
+import com.sap.sailing.domain.common.tracking.impl.VeryCompactGPSFixMovingImpl;
import com.sap.sailing.domain.common.tracking.impl.DoubleVectorFixImpl;
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
@@ -26,9 +26,9 @@ public class MockGPSFixMongoServiceFinder extends AbstractTypeBasedServiceFinder
@Override
public FixMongoHandler> findService(String fixType) {
if (fixType.equals(GPSFixMovingImpl.class.getName()) ||
- fixType.equals(CompactGPSFixMovingImpl.class.getName())) return movingHandler;
+ fixType.equals(VeryCompactGPSFixMovingImpl.class.getName())) return movingHandler;
if (fixType.equals(GPSFixImpl.class.getName()) ||
- fixType.equals(CompactGPSFixImpl.class.getName())) return handler;
+ fixType.equals(VeryCompactGPSFixImpl.class.getName())) return handler;
if (fixType.equals(DoubleVectorFixImpl.class.getName())) return doubleVectorFixHandler;
return null;
}
diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties b/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties
index b0171dd4f67..46bc5fd7db1 100644
--- a/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties
+++ b/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages.properties
@@ -5,7 +5,7 @@ iOSUsers=Start iOS App
androidUsers=Start Android App
alternativelyVisitThisLink=If you are reading this mail on the device with the App already installed, simply click below to start:
buoyTender=buoy tender
-appStoreInstallText=If you don't have the App yet, please install:
+appStoreInstallText=If you don''t have the App yet, please install:
appIos=Install iOS App
appAndroid=Install Android App
buoyPingerAppName=SAP Sailing Buoy Pinger
diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages_de.properties b/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages_de.properties
index dd6e394c6fc..59d987ee6be 100644
--- a/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages_de.properties
+++ b/java/com.sap.sailing.domain.racelogtrackingadapter/resources/stringmessages/TrackingStringMessages_de.properties
@@ -1,11 +1,11 @@
-trackingInvitationFor=Einladung zum Tracken fr
+trackingInvitationFor=Einladung zum Tracken für
scanQRCodeOrVisitUrlToRegisterAs=Installiere die {0} App. Dann scanne den QRCode oder klicke den Link mit deinem Smartphone an, um dich zu registrieren als
welcomeTo=Willkommen zu
iOSUsers=iOS App starten
androidUsers=Android App starten
-alternativelyVisitThisLink=Wenn die App bereits installiert ist, und du diese Mail auch auf dem Gerte offen hast, dann einfach hier clicken:
+alternativelyVisitThisLink=Wenn die App bereits installiert ist, und du diese Mail auch auf dem Geräte offen hast, dann einfach hier clicken:
buoyTender=Bojenleger
-appStoreInstallText=Falls die App noch nicht installiert ist, kannst du sie hier finden:
+appStoreInstallText=Falls die App noch nicht installiert ist, kannst du sie hier finden:Ÿ
appIos=iOS App installieren
appAndroid=Android App installieren
buoyPingerAppName=SAP Sailing Buoy Pinger
diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogConnectivityParamsHandler.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogConnectivityParamsHandler.java
index e3ef23fa681..b18a8638196 100644
--- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogConnectivityParamsHandler.java
+++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogConnectivityParamsHandler.java
@@ -49,12 +49,22 @@ public class RaceLogConnectivityParamsHandler extends AbstractRaceTrackingConnec
@Override
public RaceTrackingConnectivityParameters mapTo(Map map) throws MalformedURLException, URISyntaxException {
+ final RaceTrackingConnectivityParameters result;
final RegattaLeaderboard leaderboard = (RegattaLeaderboard) racingEventService.getLeaderboardByName((String) map.get(LEADERBOARD_NAME));
- final RaceColumn raceColumn = leaderboard.getRaceColumnByName((String) map.get(RACE_COLUMN_NAME));
- return new RaceLogConnectivityParams(racingEventService, leaderboard.getRegatta(), raceColumn,
- raceColumn.getFleetByName((String) map.get(FLEET_NAME)), leaderboard,
- ((Number) map.get(DELAY_TO_LIVE_IN_MILLIS)).longValue(), domainFactory, isTrackWind(map),
- isCorrectWindDirectionByMagneticDeclination(map));
+ if (leaderboard == null) {
+ result = null;
+ } else {
+ final RaceColumn raceColumn = leaderboard.getRaceColumnByName((String) map.get(RACE_COLUMN_NAME));
+ if (raceColumn == null) {
+ result = null;
+ } else {
+ result = new RaceLogConnectivityParams(racingEventService, leaderboard.getRegatta(), raceColumn,
+ raceColumn.getFleetByName((String) map.get(FLEET_NAME)), leaderboard,
+ ((Number) map.get(DELAY_TO_LIVE_IN_MILLIS)).longValue(), domainFactory, isTrackWind(map),
+ isCorrectWindDirectionByMagneticDeclination(map));
+ }
+ }
+ return result;
}
@Override
diff --git a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingI18n.java b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingI18n.java
index 0a3fa3a6876..5fc6497003b 100644
--- a/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingI18n.java
+++ b/java/com.sap.sailing.domain.racelogtrackingadapter/src/com/sap/sailing/domain/racelogtracking/impl/RaceLogTrackingI18n.java
@@ -1,5 +1,7 @@
package com.sap.sailing.domain.racelogtracking.impl;
+import java.nio.charset.StandardCharsets;
+
import com.sap.sse.i18n.ResourceBundleStringMessages;
import com.sap.sse.i18n.impl.ResourceBundleStringMessagesImpl;
@@ -7,5 +9,5 @@ public class RaceLogTrackingI18n {
private static final String RESOURCE_BASE_NAME = "stringmessages/TrackingStringMessages";
public static final ResourceBundleStringMessages STRING_MESSAGES = new ResourceBundleStringMessagesImpl(
- RESOURCE_BASE_NAME, RaceLogTrackingI18n.class.getClassLoader());
+ RESOURCE_BASE_NAME, RaceLogTrackingI18n.class.getClassLoader(), StandardCharsets.UTF_8.name());
}
diff --git a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/impl/AllEventsOfTypeFinder.java b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/impl/AllEventsOfTypeFinder.java
index 0608dbba198..27250399856 100644
--- a/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/impl/AllEventsOfTypeFinder.java
+++ b/java/com.sap.sailing.domain.shared.android/src/com/sap/sailing/domain/abstractlog/impl/AllEventsOfTypeFinder.java
@@ -17,8 +17,8 @@ VisitorT> extends BaseLogAnalyzer> {
private final Class> ofType;
private final boolean onlyUnrevoked;
- public AllEventsOfTypeFinder(LogT raceLog, boolean onlyUnrevoked, Class> ofType) {
- super(raceLog);
+ public AllEventsOfTypeFinder(LogT log, boolean onlyUnrevoked, Class> ofType) {
+ super(log);
this.ofType = ofType;
this.onlyUnrevoked = onlyUnrevoked;
}
diff --git a/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/SwissTimingReplayService.java b/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/SwissTimingReplayService.java
index 2553cc2d0d0..40347ac6d11 100755
--- a/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/SwissTimingReplayService.java
+++ b/java/com.sap.sailing.domain.swisstimingreplayadapter/src/com/sap/sailing/domain/swisstimingreplayadapter/SwissTimingReplayService.java
@@ -35,14 +35,10 @@ public interface SwissTimingReplayService {
* @param link
* the URL without the implicit "http://" prefix, as obtained, e.g., from
* {@link SwissTimingReplayRace#getLink()}.
- * @param raceName TODO
* @param raceID
* the SwissTiming ID for the race
- * @param trackerManager TODO
* @param useInternalMarkPassingAlgorithm
* use our own instead of the SwissTiming-provided mark rounding / split times
- * @param raceLogStore TODO
- * @param regattaLogStore TODO
* @param boatClassNameName
* only required if {@code regattaToAddTo} is {@code null}; used for the retrieval/creation of a default
* regatta
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractTracTracLiveTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractTracTracLiveTest.java
index e5acc80daf5..4a6fced0e2b 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractTracTracLiveTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/AbstractTracTracLiveTest.java
@@ -25,6 +25,7 @@ import com.sap.sailing.domain.tractracadapter.Receiver;
import com.sap.sailing.domain.tractracadapter.TracTracConnectionConstants;
import com.sap.sailing.domain.tractracadapter.TracTracControlPoint;
import com.sap.sailing.domain.tractracadapter.impl.ControlPointAdapter;
+import com.sap.sse.common.Duration;
import com.sap.sse.common.Util.Pair;
import com.tractrac.model.lib.api.ModelLocator;
import com.tractrac.model.lib.api.event.CreateModelException;
@@ -36,6 +37,7 @@ import com.tractrac.subscription.lib.api.IRaceSubscriber;
import com.tractrac.subscription.lib.api.ISubscriberFactory;
import com.tractrac.subscription.lib.api.SubscriberInitializationException;
import com.tractrac.subscription.lib.api.SubscriptionLocator;
+import com.tractrac.util.lib.api.exceptions.TimeOutException;
/**
* Subclassing tests have to call {@link #addListenersForStoredDataAndStartController(Iterable)} to kick off
@@ -65,6 +67,7 @@ public abstract class AbstractTracTracLiveTest extends StoredTrackBasedTest {
* Default set-up for an STG training session in Weymouth, 2011
* @throws SubscriberInitializationException
* @throws CreateModelException
+ * @throws TimeOutException
*/
@Before
public void setUp() throws MalformedURLException, IOException, InterruptedException, URISyntaxException, SubscriberInitializationException, ParseException, CreateModelException {
@@ -95,26 +98,30 @@ public abstract class AbstractTracTracLiveTest extends StoredTrackBasedTest {
protected void setUp(URL paramUrl, URI liveUri, URI storedUri) throws FileNotFoundException, MalformedURLException, URISyntaxException, SubscriberInitializationException, CreateModelException {
// Read event data from configuration file
- final IRace race = ModelLocator.getEventFactory().createRace(new URI(paramUrl.toString()));
- this.race = race;
- ISubscriberFactory subscriberFactory = SubscriptionLocator.getSusbcriberFactory();
- if (storedUri == null) {
- eventSubscriber = subscriberFactory.createEventSubscriber(race.getEvent());
- raceSubscriber = subscriberFactory.createRaceSubscriber(race);
- } else {
- eventSubscriber = subscriberFactory.createEventSubscriber(race.getEvent(), liveUri, storedUri);
- raceSubscriber = subscriberFactory.createRaceSubscriber(race, liveUri, storedUri);
- }
- assertNotNull(race);
- // Initialize data controller using live and stored data sources
- if (storedUri != null && storedUri.toString().startsWith("file:")) {
- try {
- URI oldStoredUri = storedUri;
- storedUri = new URI(storedUri.toString().replaceFirst("file:/([^/])", "file:////$1"));
- logger.info("Replaced storedUri "+oldStoredUri+" by "+storedUri);
- } catch (URISyntaxException e) {
- e.printStackTrace();
+ try {
+ final IRace race = ModelLocator.getEventFactory().createRace(new URI(paramUrl.toString()), (int) /* timeout in milliseconds */ Duration.ONE_MINUTE.asMillis());
+ this.race = race;
+ ISubscriberFactory subscriberFactory = SubscriptionLocator.getSusbcriberFactory();
+ if (storedUri == null) {
+ eventSubscriber = subscriberFactory.createEventSubscriber(race.getEvent());
+ raceSubscriber = subscriberFactory.createRaceSubscriber(race);
+ } else {
+ eventSubscriber = subscriberFactory.createEventSubscriber(race.getEvent(), liveUri, storedUri);
+ raceSubscriber = subscriberFactory.createRaceSubscriber(race, liveUri, storedUri);
}
+ assertNotNull(race);
+ // Initialize data controller using live and stored data sources
+ if (storedUri != null && storedUri.toString().startsWith("file:")) {
+ try {
+ URI oldStoredUri = storedUri;
+ storedUri = new URI(storedUri.toString().replaceFirst("file:/([^/])", "file:////$1"));
+ logger.info("Replaced storedUri "+oldStoredUri+" by "+storedUri);
+ } catch (URISyntaxException e) {
+ e.printStackTrace();
+ }
+ }
+ } catch (TimeOutException te) {
+ throw new RuntimeException(te);
}
// test cases need to start the thread calling addListenersForStoredDataAndStartController
// after adding their listeners
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/DistanceCacheInvalidationAfterLoadingFinishedTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/DistanceCacheInvalidationAfterLoadingFinishedTest.java
index 290a02d13cc..a9f0cdd75a0 100644
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/DistanceCacheInvalidationAfterLoadingFinishedTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/DistanceCacheInvalidationAfterLoadingFinishedTest.java
@@ -57,6 +57,6 @@ public class DistanceCacheInvalidationAfterLoadingFinishedTest extends TrackBase
final Distance distance = speed.travel(Duration.ONE_SECOND);
trackedRace.recordFix(competitor, new GPSFixMovingImpl(startPos.translateGreatCircle(bearing, distance), now.plus(Duration.ONE_SECOND), speed));
trackedRace.onStatusChanged(tdl, new TrackedRaceStatusImpl(TrackedRaceStatusEnum.TRACKING, /* progress */ 1.0));
- assertEquals(distance.getMeters(), trackedRace.getDistanceTraveled(competitor, now.plus(Duration.ONE_SECOND.times(2))).getMeters(), 0.000001); // ask 1s after the second fix
+ assertEquals(distance.getMeters(), trackedRace.getDistanceTraveled(competitor, now.plus(Duration.ONE_SECOND.times(2))).getMeters(), 0.01); // ask 1s after the second fix
}
}
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java
index 5bcdb5ecfd1..e774019e597 100644
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LeaderboardScoringAndRankingTest.java
@@ -61,6 +61,7 @@ import com.sap.sailing.domain.leaderboard.impl.HighPoint;
import com.sap.sailing.domain.leaderboard.impl.HighPointExtremeSailingSeriesOverall;
import com.sap.sailing.domain.leaderboard.impl.HighPointFirstGets10LastBreaksTie;
import com.sap.sailing.domain.leaderboard.impl.HighPointFirstGets10Or8AndLastBreaksTie;
+import com.sap.sailing.domain.leaderboard.impl.HighPointFirstGets12Or8AndLastBreaksTie2017;
import com.sap.sailing.domain.leaderboard.impl.LeaderboardGroupImpl;
import com.sap.sailing.domain.leaderboard.impl.LowPoint;
import com.sap.sailing.domain.leaderboard.impl.RegattaLeaderboardImpl;
@@ -1454,6 +1455,44 @@ public class LeaderboardScoringAndRankingTest extends LeaderboardScoringAndRanki
assertEquals(new Double(1), leaderboardHighPointESSOverall.getNetPoints(competitors[14], later));
assertEquals(new Double(1), leaderboardHighPointESSOverall.getNetPoints(competitors[15], later));
}
+
+ @Test
+ public void testESS2017WithCompetitorsBeingDSQScoringTwoLessThanLastCompetingCompetitor() throws NoWindException {
+ Competitor[] competitors = createCompetitors(8).toArray(new Competitor[0]);
+ TimePoint now = MillisecondsTimePoint.now();
+ TimePoint later = new MillisecondsTimePoint(now.asMillis()+1000);
+ FlexibleLeaderboard leaderboardHighPoint12LastBreaksTie2017 = new FlexibleLeaderboardImpl("Test ESS Highpoint",
+ new ThresholdBasedResultDiscardingRuleImpl(/* discarding thresholds */ new int[0]),
+ new HighPointFirstGets12Or8AndLastBreaksTie2017(), null);
+ RaceColumn raceColumn = leaderboardHighPoint12LastBreaksTie2017
+ .addRace(new MockedTrackedRaceWithStartTimeAndRanks(now, Arrays.asList(competitors)), "R1", /* medalRace */
+ false);
+ // test basic scores with best getting 12 and worst getting 5 in a 12 point scheme
+ assertTrue(leaderboardHighPoint12LastBreaksTie2017.getScoringScheme().getScoreComparator(/* nullScoresAreBetter */ false).compare(
+ leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[0], later),
+ leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[3], later)) < 0); // c0 better than c3
+ assertEquals(8, leaderboardHighPoint12LastBreaksTie2017.getCompetitorsFromBestToWorst(later).size());
+ assertEquals(new Double(12), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[0], later));
+ assertEquals(new Double(5), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[7], later));
+ // now let's assume that the first competitor is DSQ so it gets 4 points
+ leaderboardHighPoint12LastBreaksTie2017.getScoreCorrection().setMaxPointsReason(competitors[0], raceColumn, MaxPointsReason.DSQ);
+ assertEquals(8, leaderboardHighPoint12LastBreaksTie2017.getCompetitorsFromBestToWorst(later).size());
+ assertEquals(new Double(12), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[1], later));
+ assertEquals(new Double(4), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[0], later));
+ assertEquals(new Double(6), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[7], later));
+ leaderboardHighPoint12LastBreaksTie2017.getScoreCorrection().setMaxPointsReason(competitors[0], raceColumn, MaxPointsReason.NONE);
+ assertEquals(new Double(12), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[0], later));
+ assertEquals(new Double(5), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[7], later));
+ leaderboardHighPoint12LastBreaksTie2017.getScoreCorrection().setMaxPointsReason(competitors[0], raceColumn, MaxPointsReason.DNS);
+ assertEquals(new Double(12), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[1], later));
+ assertEquals(new Double(5), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[0], later));
+ assertEquals(new Double(6), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[7], later));
+ // two competitors not started leading to tie
+ leaderboardHighPoint12LastBreaksTie2017.getScoreCorrection().setMaxPointsReason(competitors[1], raceColumn, MaxPointsReason.DNS);
+ assertEquals(new Double(12), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[2], later));
+ assertEquals(new Double(6), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[1], later));
+ assertEquals(new Double(6), leaderboardHighPoint12LastBreaksTie2017.getNetPoints(competitors[0], later));
+ }
@Test
public void testOverallLeaderboardWithESSHighPointScoring() throws NoWindException {
@@ -1538,6 +1577,7 @@ public class LeaderboardScoringAndRankingTest extends LeaderboardScoringAndRanki
assertEquals(c[0], rankedCompetitors.get(0));
assertEquals(c[2], rankedCompetitors.get(1));
}
+
@Test
public void testHighPointScoringEightWithInterpolationWhenFleetNotComplete() throws NoWindException {
int competitorsCount = 21;
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LineAnalysisTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LineAnalysisTest.java
index ce9baf13dfb..5dc92520644 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LineAnalysisTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/LineAnalysisTest.java
@@ -74,7 +74,7 @@ public class LineAnalysisTest extends TrackBasedTest {
final Distance distanceBehindLine = new MeterDistance(10);
final Position behindMiddleOfLine = lineMiddle.translateGreatCircle(awayFromCourseSideOrthogonalToLine, distanceBehindLine);
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(behindMiddleOfLine, now, new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(45))));
- assertEquals(distanceBehindLine.getMeters(), trackedRace.getDistanceToStartLine(competitor, now).getMeters(), 0.000001);
+ assertEquals(distanceBehindLine.getMeters(), trackedRace.getDistanceToStartLine(competitor, now).getMeters(), 0.01);
}
@Test
@@ -90,7 +90,7 @@ public class LineAnalysisTest extends TrackBasedTest {
final Position behindOutsideOfLine = outsideOfLine.translateGreatCircle(awayFromCourseSideOrthogonalToLine, distanceBehindLine);
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(behindOutsideOfLine, now, new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(45))));
// the distance is that of the hypotenuse formed by the two cathesuses of 10m and 30m length, respectively:
- assertEquals(Math.sqrt(10.*10.+30.*30.), trackedRace.getDistanceToStartLine(competitor, now).getMeters(), 0.001);
+ assertEquals(Math.sqrt(10.*10.+30.*30.), trackedRace.getDistanceToStartLine(competitor, now).getMeters(), 0.01);
}
private Mark getMark(String name) {
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/MultipleClassesInRegattaTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/MultipleClassesInRegattaTest.java
index 6d0ced1c310..2386c1ebf30 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/MultipleClassesInRegattaTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/MultipleClassesInRegattaTest.java
@@ -96,7 +96,7 @@ public class MultipleClassesInRegattaTest {
/* offsetToStartTimeOfSimulatedRace */ null, /* ignoreTracTracMarkPassings*/
false, EmptyRaceLogStore.INSTANCE, EmptyRegattaLogStore.INSTANCE, domainFactory,
tracTracUsername, tracTracPassword, TracTracConnectionConstants.ONLINE_STATUS, TracTracConnectionConstants.ONLINE_VISIBILITY,
- /* trackWind */ false, /* correctWindDirectionByMagneticDeclination */ true, /* preferReplayIfAvailable */ false);
+ /* trackWind */ false, /* correctWindDirectionByMagneticDeclination */ true, /* preferReplayIfAvailable */ false, /* timeoutInMillis */ -1);
}
@After
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/NonCompetingCompetitorTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/NonCompetingCompetitorTest.java
new file mode 100755
index 00000000000..8a7759ea7d2
--- /dev/null
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/NonCompetingCompetitorTest.java
@@ -0,0 +1,51 @@
+package com.sap.sailing.domain.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.text.ParseException;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.sap.sailing.domain.base.Competitor;
+import com.sap.sailing.domain.common.NoWindException;
+import com.sap.sailing.domain.tractracadapter.ReceiverType;
+import com.tractrac.model.lib.api.event.CreateModelException;
+import com.tractrac.subscription.lib.api.SubscriberInitializationException;
+
+public class NonCompetingCompetitorTest extends AbstractManeuverDetectionTestCase {
+ public NonCompetingCompetitorTest() throws MalformedURLException, URISyntaxException {
+ super();
+ }
+
+ @Override
+ protected String getExpectedEventName() {
+ return "ESS ST. Petersburg 2016";
+ }
+
+
+ @Before
+ public void setUp() throws URISyntaxException, IOException, InterruptedException, ParseException, SubscriberInitializationException, CreateModelException {
+ super.setUp();
+ super.setUp(
+ new URL("http://dev.tractrac.com/events/event_20160222_ESSSTPeter_1473057208/clientparams.php?event=event_20160222_ESSSTPeter_1473057208&race=5a265e70-519a-0134-dd23-10b11c4ed8fd&random=296858907"),
+ /* liveUri */null, /* storedUri */null, new ReceiverType[] { ReceiverType.MARKPASSINGS,
+ ReceiverType.MARKPOSITIONS, ReceiverType.RACECOURSE, ReceiverType.RAWPOSITIONS });
+ }
+
+ /**
+ * Asserts that the "Ump..." competitors are considered non-competing and therefore don't show up
+ */
+ @Test
+ public void testNoNonCompetingCompetitors() throws ParseException, NoWindException {
+ for (final Competitor competitor : getTrackedRace().getRace().getCompetitors()) {
+ assertFalse(competitor.getName().startsWith("Ump"));
+ assertSame(getDomainFactory().getOrCreateBoatClass("GC32"), competitor.getBoat().getBoatClass());
+ }
+ }
+}
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PositionAssert.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PositionAssert.java
new file mode 100755
index 00000000000..b88c1a4742a
--- /dev/null
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PositionAssert.java
@@ -0,0 +1,77 @@
+package com.sap.sailing.domain.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.util.Set;
+
+import com.sap.sailing.domain.common.Bearing;
+import com.sap.sailing.domain.common.Position;
+import com.sap.sailing.domain.common.Speed;
+import com.sap.sailing.domain.common.SpeedWithBearing;
+import com.sap.sailing.domain.common.Wind;
+import com.sap.sailing.domain.common.tracking.GPSFix;
+import com.sap.sailing.domain.common.tracking.GPSFixMoving;
+
+/**
+ * Contains equality assertions for "compact" fixes, allowing for deltas to be specified, assuming
+ * that the "compact" version of a fix may vary slightly from its original.
+ *
+ * @author Axel Uhl (d043530)
+ *
+ */
+public class PositionAssert {
+ public static void assertPositionEquals(Position p1, Position p2, double degreeDelta) {
+ assertEquals(p1.getLatDeg(), p2.getLatDeg(), degreeDelta);
+ assertEquals(p1.getLngDeg(), p2.getLngDeg(), degreeDelta);
+ }
+
+ public static void assertGPSFixEquals(GPSFixMoving f1, GPSFixMoving f2, double positionDegreeDelta, double bearingDegreeDelta, double knotDelta) {
+ assertGPSFixEquals((GPSFix) f1, (GPSFix) f2, positionDegreeDelta);
+ assertSpeedEquals(f1.getSpeed(), f2.getSpeed(), bearingDegreeDelta, knotDelta);
+ }
+
+ public static void assertBearingEquals(Bearing b1, Bearing b2, double bearingDegreeDelta) {
+ assertEquals(b1.getDegrees(), b2.getDegrees(), bearingDegreeDelta);
+ }
+
+ public static void assertGPSFixEquals(GPSFix f1, GPSFix f2, double positionDegreeDelta) {
+ assertPositionEquals(f1.getPosition(), f2.getPosition(), positionDegreeDelta);
+ assertEquals(f1.getTimePoint(), f2.getTimePoint());
+ }
+
+ public static void assertWindEquals(Wind w1, Wind w2, double posDegDelta, double bearingDegreeDelta, double knotSpeedDelta) {
+ assertEquals(w1.getTimePoint(), w2.getTimePoint());
+ assertPositionEquals(w1.getPosition(), w2.getPosition(), posDegDelta);
+ assertBearingEquals(w1.getBearing(), w2.getBearing(), bearingDegreeDelta);
+ assertSpeedEquals(w1, w2, bearingDegreeDelta, knotSpeedDelta);
+ }
+
+ public static void assertSpeedEquals(Speed s1, Speed s2, double knotSpeedDelta) {
+ assertEquals(s1.getKnots(), s2.getKnots(), knotSpeedDelta);
+ }
+
+ public static void assertSpeedEquals(SpeedWithBearing s1, SpeedWithBearing s2, double bearingDegreeDelta, double knotSpeedDelta) {
+ assertBearingEquals(s1.getBearing(), s2.getBearing(), bearingDegreeDelta);
+ assertSpeedEquals((Speed) s1, (Speed) s2, knotSpeedDelta);
+ }
+
+ public static void assertWindEquals(Set expectedWinds, Set actualWinds, double posDegDelta,
+ double bearingDegreeDelta, double knotSpeedDelta) {
+ for (final Wind expectedWind : expectedWinds) {
+ boolean found = false;
+ for (final Wind actualWind : actualWinds) {
+ try {
+ assertWindEquals(expectedWind, actualWind, posDegDelta, bearingDegreeDelta, knotSpeedDelta);
+ found = true;
+ break;
+ } catch (AssertionError e) {
+ // not equals
+ }
+ }
+ if (!found) {
+ fail("Expected to find "+expectedWind+" in "+actualWinds+" but didn't");
+ }
+ }
+ }
+}
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PositionTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PositionTest.java
index 1d76669219e..5c7b653a13e 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PositionTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/PositionTest.java
@@ -16,8 +16,11 @@ 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;
+import com.sap.sailing.domain.common.tracking.GPSFix;
+import com.sap.sailing.domain.common.tracking.impl.VeryCompactGPSFixImpl;
+import com.sap.sailing.domain.common.tracking.impl.VeryCompactGPSFixMovingImpl;
+import com.sap.sailing.domain.common.tracking.impl.CompactionNotPossibleException;
+import com.sap.sse.common.TimePoint;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class PositionTest {
@@ -32,20 +35,40 @@ public class PositionTest {
@Test
public void testEqualityBetweenCompactAndVerbosePosition() {
Position p1 = new DegreePosition(49.2, 008.3);
- CompactGPSFixImpl compactFix = new CompactGPSFixImpl(p1, MillisecondsTimePoint.now());
+ VeryCompactGPSFixImpl compactFix = new VeryCompactGPSFixImpl(p1, MillisecondsTimePoint.now());
assertNotSame(p1, compactFix.getPosition());
- assertEquals(p1, compactFix.getPosition());
+ PositionAssert.assertPositionEquals(p1, compactFix.getPosition(), 0.000001);
}
@Test
- public void testEqualityBetweenCompactAndVerboseSpeedWithBearing() {
+ public void testCompactFixRange() {
+ final TimePoint now = MillisecondsTimePoint.now();
+ assertCompactFixHasEqualLatLng(now, 0., 0.);
+ assertCompactFixHasEqualLatLng(now, 90., 0.);
+ assertCompactFixHasEqualLatLng(now, -90., 0.);
+ assertCompactFixHasEqualLatLng(now, 0., 180.);
+ assertCompactFixHasEqualLatLng(now, 0., -180.);
+ assertCompactFixHasEqualLatLng(now, 45., 45.);
+ assertCompactFixHasEqualLatLng(now, 0., -45.);
+ assertCompactFixHasEqualLatLng(now, -45., 45.);
+ assertCompactFixHasEqualLatLng(now, 0., 45.);
+ }
+
+ private void assertCompactFixHasEqualLatLng(final TimePoint now, final double latDeg, final double lngDeg) {
+ GPSFix fix = new VeryCompactGPSFixImpl(new DegreePosition(latDeg, lngDeg), now);
+ assertEquals(latDeg, fix.getPosition().getLatDeg(), 0.0000001);
+ assertEquals(lngDeg, fix.getPosition().getLngDeg(), 0.0000001);
+ }
+
+ @Test
+ public void testEqualityBetweenCompactAndVerboseSpeedWithBearing() throws CompactionNotPossibleException {
Position p1 = new DegreePosition(49.2, 008.3);
SpeedWithBearing swb = new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123));
- CompactGPSFixMovingImpl compactFix = new CompactGPSFixMovingImpl(p1, MillisecondsTimePoint.now(), swb);
+ VeryCompactGPSFixMovingImpl compactFix = new VeryCompactGPSFixMovingImpl(p1, MillisecondsTimePoint.now(), swb);
assertNotSame(p1, compactFix.getPosition());
- assertEquals(p1, compactFix.getPosition());
+ PositionAssert.assertPositionEquals(p1, compactFix.getPosition(), 0.000001);
assertNotSame(swb, compactFix.getSpeed());
- assertEquals(swb, compactFix.getSpeed());
+ PositionAssert.assertSpeedEquals(swb, compactFix.getSpeed(), /* bearing deg delta */ 0.1, /* knot speed delta */ 0.1);
}
@Test
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/ReachingLegTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/ReachingLegTest.java
index d77f4c76acb..1014e9c2ea8 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/ReachingLegTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/ReachingLegTest.java
@@ -338,7 +338,7 @@ public class ReachingLegTest extends TrackBasedTest {
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(plattner, timePointToConsider, WindPositionMode.LEG_MIDDLE);
assertEquals(0., schomaekersDistanceToLeader.getMeters(), 0.00001);
// distance to leading Schomaeker expected to be the entire upwind distance plus the offset distance plus half the downwind
- assertEquals(distanceOfReachingLeg.getMeters()+windwardDistanceOfUpwindLeg.getMeters()*1.5, plattnersDistanceToLeader.getMeters(), 0.001);
+ assertEquals(distanceOfReachingLeg.getMeters()+windwardDistanceOfUpwindLeg.getMeters()*1.5, plattnersDistanceToLeader.getMeters(), 0.01);
}
@Test
@@ -373,9 +373,9 @@ public class ReachingLegTest extends TrackBasedTest {
.getEstimatedPosition(timePointToConsider, /* extrapolate */false)
.getDistance(
getTrackedRace().getTrack(plattner).getEstimatedPosition(timePointToConsider, /* extrapolate */
- false)).getMeters(), 0.00001);
+ false)).getMeters(), 0.01);
// however, projected onto the leg their distance should be 0
Distance plattnersDistanceToLeader = getTrackedRace().getWindwardDistanceToCompetitorFarthestAhead(plattner, timePointToConsider, WindPositionMode.LEG_MIDDLE);
- assertEquals(0., plattnersDistanceToLeader.getMeters(), 0.00001);
+ assertEquals(0., plattnersDistanceToLeader.getMeters(), 0.01);
}
}
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/StarbordSideOfStartLineRecognitionTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/StarbordSideOfStartLineRecognitionTest.java
index c8a621c5707..911ed8fe8a8 100755
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/StarbordSideOfStartLineRecognitionTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/StarbordSideOfStartLineRecognitionTest.java
@@ -141,7 +141,7 @@ public class StarbordSideOfStartLineRecognitionTest {
MockedTrackedRaceImpl trackedRace = createTrackedRaceWithMarkPositions(startPortPosition, startStarboardPosition, windwardPosition);
Position p = trackedRace.getOrCreateTrack(trackedRace.getStartLine(now).getStarboardMarkWhileApproachingLine()).
getEstimatedPosition(now, /* extrapolate */ false);
- assertEquals(startStarboardPosition, p);
+ PositionAssert.assertPositionEquals(startStarboardPosition, p, 0.0000001);
}
@Test
diff --git a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java
index 2f5c7bf7de5..ce1092fcf4e 100644
--- a/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java
+++ b/java/com.sap.sailing.domain.test/src/com/sap/sailing/domain/test/TrackTest.java
@@ -43,7 +43,8 @@ import com.sap.sailing.domain.common.impl.MeterDistance;
import com.sap.sailing.domain.common.impl.MeterPerSecondSpeedWithDegreeBearingImpl;
import com.sap.sailing.domain.common.tracking.GPSFix;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
-import com.sap.sailing.domain.common.tracking.impl.CompactGPSFixMovingImpl;
+import com.sap.sailing.domain.common.tracking.impl.VeryCompactGPSFixMovingImpl;
+import com.sap.sailing.domain.common.tracking.impl.CompactionNotPossibleException;
import com.sap.sailing.domain.common.tracking.impl.GPSFixImpl;
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
import com.sap.sailing.domain.tracking.DynamicGPSFixTrack;
@@ -63,6 +64,7 @@ import com.sap.sse.common.Util.Pair;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class TrackTest {
+ private static final int MILLIS_BETWEEN_FIXES = 3000000;
private DynamicGPSFixTrack track;
private GPSFixMovingImpl gpsFix1;
private GPSFixMovingImpl gpsFix2;
@@ -75,7 +77,7 @@ public class TrackTest {
track = new DynamicGPSFixMovingTrackImpl(new BoatImpl("MyFirstBoat", new BoatClassImpl("505", /* typicallyStartsUpwind */
true), null), /* millisecondsOverWhichToAverage */5000, /* no smoothening */null);
TimePoint now1 = MillisecondsTimePoint.now();
- TimePoint now2 = addMillisToTimepoint(now1, 3);
+ TimePoint now2 = addMillisToTimepoint(now1, MILLIS_BETWEEN_FIXES);
DegreePosition position1 = new DegreePosition(1, 2);
DegreePosition position2 = new DegreePosition(1, 3);
gpsFix1 = new GPSFixMovingImpl(
@@ -84,19 +86,19 @@ public class TrackTest {
new DegreeBearingImpl(90)));
gpsFix2 = new GPSFixMovingImpl(position2, now2, new KnotSpeedWithBearingImpl(position1.getDistance(position2)
.inTime(now2.asMillis() - gpsFix1.getTimePoint().asMillis()).getKnots(), new DegreeBearingImpl(90)));
- TimePoint now3 = addMillisToTimepoint(now2, 3);
+ TimePoint now3 = addMillisToTimepoint(now2, MILLIS_BETWEEN_FIXES);
Position position3 = new DegreePosition(1, 4);
gpsFix3 = new GPSFixMovingImpl(
position3, now3, new KnotSpeedWithBearingImpl(position2.getDistance(position3)
.inTime(now3.asMillis() - gpsFix2.getTimePoint().asMillis()).getKnots(),
new DegreeBearingImpl(0)));
- TimePoint now4 = addMillisToTimepoint(now3, 3);
+ TimePoint now4 = addMillisToTimepoint(now3, MILLIS_BETWEEN_FIXES);
Position position4 = new DegreePosition(3, 4);
gpsFix4 = new GPSFixMovingImpl(
position4, now4, new KnotSpeedWithBearingImpl(position3.getDistance(position4)
.inTime(now4.asMillis() - gpsFix3.getTimePoint().asMillis()).getKnots(),
new DegreeBearingImpl(0)));
- TimePoint now5 = addMillisToTimepoint(now4, 3);
+ TimePoint now5 = addMillisToTimepoint(now4, MILLIS_BETWEEN_FIXES);
Position position5 = new DegreePosition(5, 4);
gpsFix5 = new GPSFixMovingImpl(position5, now5, new KnotSpeedWithBearingImpl(position4.getDistance(position5)
.inTime(now5.asMillis() - gpsFix4.getTimePoint().asMillis()).getKnots(), new DegreeBearingImpl(0)));
@@ -106,6 +108,7 @@ public class TrackTest {
track.addGPSFix(gpsFix4);
track.addGPSFix(gpsFix5);
}
+
/**
* Tests for a incorrect method of estimating Positions
*/
@@ -128,7 +131,6 @@ public class TrackTest {
assertEquals(45, track.getEstimatedPosition(t1.plus(15), true).getLatDeg(), 0.00000001);
assertEquals(60, track.getEstimatedPosition(t1.plus(20), true).getLatDeg(), 0.00000001);
assertEquals(90, track.getEstimatedPosition(t1.plus(30), true).getLatDeg(), 0.00000001);
-
} finally {
track.unlockAfterRead();
}
@@ -221,7 +223,7 @@ public class TrackTest {
now = nextNow;
}
assertEquals(speed.travel(start, now.minus(NUMBER_OF_FIXES_AT_SAME_POSITION * 1000)).getMeters(),
- track.getDistanceTraveled(start, now).getMeters(), 0.00000001);
+ track.getDistanceTraveled(start, now).getMeters(), 0.01);
}
private void addFixesWithSamePositionButProgressingTime(DynamicGPSFixTrack