mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-15 10:18:45 +00:00
Merge branch 'master' into jetty-9.4.53.v20231009
This commit is contained in:
+9
-9
@@ -80,13 +80,13 @@ public class TestSegmentsTackType extends StoredTrackBasedTest {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> competitorATrack = trackedRace.getTrack(competitorA);
|
||||
final KnotSpeedWithBearingImpl sogCog = new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(45));
|
||||
TimePoint timePoint = trackedRace.getStartOfTracking().plus(10);
|
||||
GPSFixMovingImpl currentGPS = new GPSFixMovingImpl(new DegreePosition(54.4680424, 10.234451), timePoint, sogCog);
|
||||
GPSFixMovingImpl currentGPS = new GPSFixMovingImpl(new DegreePosition(54.4680424, 10.234451), timePoint, sogCog, /* optionalTrueHeading */ null);
|
||||
final Duration timeBetweenFixes = Duration.ofMillis(490);
|
||||
for (int i=0; i<20; i++) {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCog.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCog);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCog, /* optionalTrueHeading */ null);
|
||||
}
|
||||
TimePoint markPassingTimePoint = trackedRace.getStartOfTracking().plus(20);
|
||||
final List<MarkPassing> markPassingsForCompetitor = new ArrayList<>();
|
||||
@@ -114,13 +114,13 @@ public class TestSegmentsTackType extends StoredTrackBasedTest {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> competitorATrack = trackedRace.getTrack(competitorA);
|
||||
final KnotSpeedWithBearingImpl sogCog = new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(45));
|
||||
TimePoint timePoint = trackedRace.getStartOfTracking().plus(10);
|
||||
GPSFixMovingImpl currentGPS = new GPSFixMovingImpl(new DegreePosition(54.4680424, 10.234451), timePoint, sogCog);
|
||||
GPSFixMovingImpl currentGPS = new GPSFixMovingImpl(new DegreePosition(54.4680424, 10.234451), timePoint, sogCog, /* optionalTrueHeading */ null);
|
||||
final Duration timeBetweenFixes = Duration.ofMillis(490);
|
||||
for (int i=0; i<20; i++) {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCog.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCog);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCog, /* optionalTrueHeading */ null);
|
||||
}
|
||||
// now run the actual test:
|
||||
final Iterable<HasTackTypeSegmentContext> allTTSegments = retrieveData();
|
||||
@@ -138,14 +138,14 @@ public class TestSegmentsTackType extends StoredTrackBasedTest {
|
||||
final Position middleOfStartLine = trackedRace.getApproximatePosition(trackedRace.getRace().getCourse().getFirstWaypoint(), timePoint);
|
||||
final Position topMarkPosition = trackedRace.getApproximatePosition(Util.get(trackedRace.getRace().getCourse().getWaypoints(), 1), timePoint);
|
||||
// start straight "under" the top mark
|
||||
GPSFixMovingImpl currentGPS = new GPSFixMovingImpl(new DegreePosition(middleOfStartLine.getLatDeg(), topMarkPosition.getLngDeg()), timePoint, sogCogPortTackUpwind);
|
||||
GPSFixMovingImpl currentGPS = new GPSFixMovingImpl(new DegreePosition(middleOfStartLine.getLatDeg(), topMarkPosition.getLngDeg()), timePoint, sogCogPortTackUpwind, /* optionalTrueHeading */ null);
|
||||
expectedSegmentStarts.add(timePoint);
|
||||
final Duration timeBetweenFixes = Duration.ofMillis(490);
|
||||
for (int i=0; i<20; i++) {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCogPortTackUpwind.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogPortTackUpwind);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogPortTackUpwind, /* optionalTrueHeading */ null);
|
||||
}
|
||||
// now tack onto starboard tack:
|
||||
final KnotSpeedWithBearingImpl sogCogStarboardTackUpwind = new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(315));
|
||||
@@ -154,7 +154,7 @@ public class TestSegmentsTackType extends StoredTrackBasedTest {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCogStarboardTackUpwind.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogStarboardTackUpwind);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogStarboardTackUpwind, /* optionalTrueHeading */ null);
|
||||
}
|
||||
final List<MarkPassing> markPassingsForCompetitor = new ArrayList<>();
|
||||
final TimePoint startMarkPassingTimePoint = trackedRace.getStartOfTracking().plus(20);
|
||||
@@ -170,7 +170,7 @@ public class TestSegmentsTackType extends StoredTrackBasedTest {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCogStarboardTackDownwind.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogPortTackUpwind);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogPortTackUpwind, /* optionalTrueHeading */ null);
|
||||
}
|
||||
// now gybe onto port tack:
|
||||
final KnotSpeedWithBearingImpl sogCogPortTackDownwind = new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(135));
|
||||
@@ -179,7 +179,7 @@ public class TestSegmentsTackType extends StoredTrackBasedTest {
|
||||
competitorATrack.addGPSFix(currentGPS);
|
||||
final Position currentPosition = sogCogPortTackDownwind.travelTo(currentGPS.getPosition(), timeBetweenFixes);
|
||||
timePoint = timePoint.plus(timeBetweenFixes);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogPortTackDownwind);
|
||||
currentGPS = new GPSFixMovingImpl(currentPosition, timePoint, sogCogPortTackDownwind, /* optionalTrueHeading */ null);
|
||||
}
|
||||
// now run the actual test:
|
||||
final Iterable<HasTackTypeSegmentContext> allTTSegments = retrieveData();
|
||||
|
||||
@@ -5,9 +5,9 @@ Bundle-SymbolicName: com.sap.sailing.domain.bravoadapter
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Import-Package: org.osgi.framework;version="1.8.0"
|
||||
Require-Bundle: org.eclipse.osgi,
|
||||
com.sap.sailing.domain,
|
||||
Import-Package: com.sap.sailing.declination,
|
||||
org.osgi.framework;version="1.8.0"
|
||||
Require-Bundle: com.sap.sailing.domain,
|
||||
com.sap.sailing.server.trackfiles,
|
||||
com.sap.sailing.domain.common,
|
||||
com.sap.sse.common,
|
||||
|
||||
+25
-3
@@ -3,10 +3,14 @@ package com.sap.sailing.domain.bravoadapter.impl;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.ParseException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.declination.DeclinationService;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.sensordata.BravoExtendedSensorDataMetadata;
|
||||
@@ -19,9 +23,12 @@ import com.sap.sailing.domain.trackimport.FormatNotSupportedException;
|
||||
import com.sap.sailing.domain.trackimport.GPSFixImporter;
|
||||
import com.sap.sailing.server.gateway.windimport.bravo.FunnyDegreeConverter;
|
||||
import com.sap.sailing.server.trackfiles.impl.BravoExtendedDataImporterImpl;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
|
||||
public class BravoGPSFixImporter implements GPSFixImporter {
|
||||
private static final Logger logger = Logger.getLogger(BravoGPSFixImporter.class.getName());
|
||||
|
||||
@Override
|
||||
public boolean importFixes(InputStream inputStream, Charset charset, Callback callback, boolean inferSpeedAndBearing, final String filename)
|
||||
throws FormatNotSupportedException, IOException {
|
||||
@@ -30,12 +37,27 @@ public class BravoGPSFixImporter implements GPSFixImporter {
|
||||
new BravoExtendedDataImporterImpl().importFixes(inputStream,
|
||||
charset, (Iterable<DoubleVectorFix> fixes, TrackFileImportDeviceIdentifier deviceIdentifier)->{
|
||||
for (final DoubleVectorFix fix : fixes) {
|
||||
final DegreePosition position = new DegreePosition(FunnyDegreeConverter.funnyLatLng(fix.get(BravoExtendedSensorDataMetadata.LAT.getColumnIndex())),
|
||||
FunnyDegreeConverter.funnyLatLng(fix.get(BravoExtendedSensorDataMetadata.LON.getColumnIndex())));
|
||||
Bearing optionalTrueHeading;
|
||||
if (fix.get(BravoExtendedSensorDataMetadata.EXPEDITION_HDG.getColumnIndex()) != null) {
|
||||
try {
|
||||
optionalTrueHeading = new DegreeBearingImpl(fix.get(BravoExtendedSensorDataMetadata.EXPEDITION_HDG.getColumnIndex())).add(
|
||||
DeclinationService.INSTANCE.getDeclination(fix.getTimePoint(), position, /* timeout for online lookup in millis */ 100)
|
||||
.getBearingCorrectedTo(fix.getTimePoint()));
|
||||
} catch (IOException | ParseException e) {
|
||||
logger.log(Level.WARNING, "Problem looking up magnetic declination for Bravo fix", e);
|
||||
optionalTrueHeading = null;
|
||||
}
|
||||
} else {
|
||||
optionalTrueHeading = null;
|
||||
}
|
||||
GPSFixMoving gpsFix = new GPSFixMovingImpl(
|
||||
new DegreePosition(FunnyDegreeConverter.funnyLatLng(fix.get(BravoExtendedSensorDataMetadata.LAT.getColumnIndex())),
|
||||
FunnyDegreeConverter.funnyLatLng(fix.get(BravoExtendedSensorDataMetadata.LON.getColumnIndex()))),
|
||||
position,
|
||||
fix.getTimePoint(),
|
||||
new KnotSpeedWithBearingImpl(fix.get(BravoExtendedSensorDataMetadata.SOG.getColumnIndex()),
|
||||
new DegreeBearingImpl(fix.get(BravoExtendedSensorDataMetadata.COG.getColumnIndex()))));
|
||||
new DegreeBearingImpl(fix.get(BravoExtendedSensorDataMetadata.COG.getColumnIndex()))),
|
||||
optionalTrueHeading);
|
||||
callback.addFix(gpsFix, device);
|
||||
importedFixes.set(true);
|
||||
}
|
||||
|
||||
+9
@@ -1,6 +1,15 @@
|
||||
package com.sap.sailing.domain.common.tracking;
|
||||
|
||||
import com.sap.sailing.domain.common.Moving;
|
||||
import com.sap.sse.common.Bearing;
|
||||
|
||||
public interface GPSFixMoving extends GPSFix, Moving {
|
||||
/**
|
||||
* Some sensors have a compass or IMU built in that can deliver a true heading. This usually requires a fixed mount
|
||||
* that guarantees a well-defined orientation of the sensor relative to the object it tracks.
|
||||
*
|
||||
* @return a true (free of magnetic declination) heading of the object tracked, e.g., for a boat the true direction
|
||||
* the bow points to; or {@code null} if the sensor did not deliver this attribute
|
||||
*/
|
||||
Bearing getOptionalTrueHeading();
|
||||
}
|
||||
|
||||
+3
-1
@@ -10,6 +10,7 @@ import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.Speed;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util;
|
||||
|
||||
/**
|
||||
* A memory-conserving representation of a {@link GPSFixMoving} object that produces the fine-grained
|
||||
@@ -96,6 +97,7 @@ public abstract class AbstractCompactGPSFixMovingImpl extends AbstractCompactGPS
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return super.equals(other) && other instanceof GPSFixMoving && getSpeed().equals(((GPSFixMoving) other).getSpeed());
|
||||
return super.equals(other) && other instanceof GPSFixMoving && getSpeed().equals(((GPSFixMoving) other).getSpeed())
|
||||
&& Util.equalsWithNull(getOptionalTrueHeading(), ((GPSFixMoving) other).getOptionalTrueHeading());
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -19,4 +19,6 @@ public class FlatSmartphoneUuidAndGPSFixMovingJsonSerializer {
|
||||
public static final String TIME_ISO = "timestamp-iso";
|
||||
public static final String SPEED_M_PER_S = "speed";
|
||||
public static final String BEARING_DEG = "course";
|
||||
public static final String TRUE_HEADING_DEG = "hdt";
|
||||
public static final String MAGNETIC_HEADING_DEG = "hdg";
|
||||
}
|
||||
|
||||
+12
-3
@@ -5,6 +5,7 @@ import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
@@ -12,10 +13,12 @@ import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
public class GPSFixMovingImpl extends GPSFixImpl implements GPSFixMoving {
|
||||
private static final long serialVersionUID = 6508021498142383100L;
|
||||
private final SpeedWithBearing speed;
|
||||
private final Bearing optionalTrueHeading;
|
||||
|
||||
public GPSFixMovingImpl(Position position, TimePoint timePoint, SpeedWithBearing speed) {
|
||||
public GPSFixMovingImpl(Position position, TimePoint timePoint, SpeedWithBearing speed, Bearing optionalTrueHeading) {
|
||||
super(position, timePoint);
|
||||
this.speed = speed;
|
||||
this.optionalTrueHeading = optionalTrueHeading;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -23,6 +26,11 @@ public class GPSFixMovingImpl extends GPSFixImpl implements GPSFixMoving {
|
||||
return speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bearing getOptionalTrueHeading() {
|
||||
return optionalTrueHeading;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString()+" with "+getSpeed();
|
||||
@@ -39,9 +47,10 @@ public class GPSFixMovingImpl extends GPSFixImpl implements GPSFixMoving {
|
||||
}
|
||||
|
||||
public static GPSFixMovingImpl create(double lonDeg, double latDeg, long timeMillis,
|
||||
double speedInKnots, double bearingDeg) {
|
||||
double speedInKnots, double bearingDeg, Double optionalTrueHeadingDeg) {
|
||||
return new GPSFixMovingImpl(new DegreePosition(latDeg, lonDeg),
|
||||
new MillisecondsTimePoint(timeMillis), new KnotSpeedWithBearingImpl(
|
||||
speedInKnots, new DegreeBearingImpl(bearingDeg)));
|
||||
speedInKnots, new DegreeBearingImpl(bearingDeg)),
|
||||
optionalTrueHeadingDeg==null?null:new DegreeBearingImpl(optionalTrueHeadingDeg));
|
||||
}
|
||||
}
|
||||
|
||||
+29
-2
@@ -24,6 +24,12 @@ public class PreciseCompactGPSFixMovingImpl extends AbstractCompactGPSFixMovingI
|
||||
private final double lngDeg;
|
||||
private final double knotSpeed;
|
||||
private final double degBearing;
|
||||
|
||||
/**
|
||||
* Valid only if {@link #trueHeadingDegSet} is {@code true}
|
||||
*/
|
||||
private final double trueHeadingDeg;
|
||||
private final boolean trueHeadingDegSet;
|
||||
|
||||
/**
|
||||
* When <code>{@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0</code>, this field tells the estimated speed's
|
||||
@@ -61,6 +67,15 @@ public class PreciseCompactGPSFixMovingImpl extends AbstractCompactGPSFixMovingI
|
||||
}
|
||||
}
|
||||
|
||||
private class PreciseCompactTrueHeading extends AbstractBearing {
|
||||
private static final long serialVersionUID = -1837422977159746992L;
|
||||
|
||||
@Override
|
||||
public double getDegrees() {
|
||||
return trueHeadingDeg;
|
||||
}
|
||||
}
|
||||
|
||||
public class PreciseCompactPosition extends AbstractPosition {
|
||||
private static final long serialVersionUID = 5621506820766614178L;
|
||||
|
||||
@@ -98,16 +113,23 @@ public class PreciseCompactGPSFixMovingImpl extends AbstractCompactGPSFixMovingI
|
||||
}
|
||||
}
|
||||
|
||||
public PreciseCompactGPSFixMovingImpl(Position position, TimePoint timePoint, SpeedWithBearing speed) {
|
||||
public PreciseCompactGPSFixMovingImpl(Position position, TimePoint timePoint, SpeedWithBearing speed, Bearing optionalTrueHeading) {
|
||||
super(timePoint);
|
||||
latDeg = position.getLatDeg();
|
||||
lngDeg = position.getLngDeg();
|
||||
knotSpeed = speed==null?0:speed.getKnots();
|
||||
degBearing = speed==null?0:speed.getBearing().getDegrees();
|
||||
if (optionalTrueHeading == null) {
|
||||
trueHeadingDegSet = false;
|
||||
trueHeadingDeg = 0.0;
|
||||
} else {
|
||||
trueHeadingDegSet = true;
|
||||
trueHeadingDeg = optionalTrueHeading.getDegrees();
|
||||
}
|
||||
}
|
||||
|
||||
public PreciseCompactGPSFixMovingImpl(GPSFixMoving gpsFixMoving) {
|
||||
this(gpsFixMoving.getPosition(), gpsFixMoving.getTimePoint(), gpsFixMoving.getSpeed());
|
||||
this(gpsFixMoving.getPosition(), gpsFixMoving.getTimePoint(), gpsFixMoving.getSpeed(), gpsFixMoving.getOptionalTrueHeading());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -119,6 +141,11 @@ public class PreciseCompactGPSFixMovingImpl extends AbstractCompactGPSFixMovingI
|
||||
public Position getPosition() {
|
||||
return new PreciseCompactPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bearing getOptionalTrueHeading() {
|
||||
return trueHeadingDegSet ? new PreciseCompactTrueHeading() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpeedWithBearing getCachedEstimatedSpeed() {
|
||||
|
||||
+30
-2
@@ -46,6 +46,13 @@ public class VeryCompactGPSFixMovingImpl extends AbstractCompactGPSFixMovingImpl
|
||||
*/
|
||||
private final short degreeBearingScaled;
|
||||
|
||||
/**
|
||||
* See {@link CompactPositionHelper}; valid if and only if {@link #trueHeadingDegreesSet} is {@code true}.
|
||||
*/
|
||||
private final short trueHeadingDegreesScaled;
|
||||
|
||||
private final boolean trueHeadingDegreesSet;
|
||||
|
||||
/**
|
||||
* When <code>{@link #whatIsCached}&{@link #IS_ESTIMATED_SPEED_CACHED} != 0</code>, this field tells the estimated speed's
|
||||
* true "bearing" (true course over ground) in degrees, scaled into a short value using {@link CompactPositionHelper}.
|
||||
@@ -95,6 +102,15 @@ public class VeryCompactGPSFixMovingImpl extends AbstractCompactGPSFixMovingImpl
|
||||
}
|
||||
}
|
||||
|
||||
private class VeryCompactTrueHeading extends AbstractBearing {
|
||||
private static final long serialVersionUID = 1130980861113826462L;
|
||||
|
||||
@Override
|
||||
public double getDegrees() {
|
||||
return CompactPositionHelper.getDegreeBearing(trueHeadingDegreesScaled);
|
||||
}
|
||||
}
|
||||
|
||||
private class VeryCompactEstimatedSpeedBearing extends AbstractBearing {
|
||||
private static final long serialVersionUID = 8549231429037883121L;
|
||||
|
||||
@@ -118,7 +134,7 @@ public class VeryCompactGPSFixMovingImpl extends AbstractCompactGPSFixMovingImpl
|
||||
}
|
||||
}
|
||||
|
||||
public VeryCompactGPSFixMovingImpl(Position position, TimePoint timePoint, SpeedWithBearing speed) throws CompactionNotPossibleException {
|
||||
public VeryCompactGPSFixMovingImpl(Position position, TimePoint timePoint, SpeedWithBearing speed, Bearing optionalTrueHeading) throws CompactionNotPossibleException {
|
||||
super(timePoint);
|
||||
latDegScaled = CompactPositionHelper.getLatDegScaled(position);
|
||||
lngDegScaled = CompactPositionHelper.getLngDegScaled(position);
|
||||
@@ -129,16 +145,28 @@ public class VeryCompactGPSFixMovingImpl extends AbstractCompactGPSFixMovingImpl
|
||||
speedInKnotsScaled = CompactPositionHelper.getKnotSpeedScaled(speed);
|
||||
degreeBearingScaled = CompactPositionHelper.getDegreeBearingScaled(speed.getBearing());
|
||||
}
|
||||
if (optionalTrueHeading == null) {
|
||||
trueHeadingDegreesSet = false;
|
||||
trueHeadingDegreesScaled = 0;
|
||||
} else {
|
||||
trueHeadingDegreesSet = true;
|
||||
trueHeadingDegreesScaled = CompactPositionHelper.getDegreeBearingScaled(optionalTrueHeading);
|
||||
}
|
||||
}
|
||||
|
||||
public VeryCompactGPSFixMovingImpl(GPSFixMoving gpsFixMoving) throws CompactionNotPossibleException {
|
||||
this(gpsFixMoving.getPosition(), gpsFixMoving.getTimePoint(), gpsFixMoving.getSpeed());
|
||||
this(gpsFixMoving.getPosition(), gpsFixMoving.getTimePoint(), gpsFixMoving.getSpeed(), gpsFixMoving.getOptionalTrueHeading());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpeedWithBearing getSpeed() {
|
||||
return new VeryCompactSpeedWithBearing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bearing getOptionalTrueHeading() {
|
||||
return trueHeadingDegreesSet ? new VeryCompactTrueHeading() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Position getPosition() {
|
||||
|
||||
@@ -10,6 +10,7 @@ Require-Bundle: com.sap.sailing.domain,
|
||||
com.sap.sailing.domain.shared.android,
|
||||
com.sap.sailing.server.trackfiles,
|
||||
com.sap.sse.common
|
||||
Import-Package: org.osgi.framework
|
||||
Import-Package: com.sap.sailing.declination,
|
||||
org.osgi.framework
|
||||
Bundle-Activator: com.sap.sailing.domain.deckmanadapter.impl.Activator
|
||||
Automatic-Module-Name: com.sap.sailing.domain.deckmanadapter
|
||||
|
||||
+17
-1
@@ -1,11 +1,15 @@
|
||||
package com.sap.sailing.domain.deckmanadapter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.declination.DeclinationService;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Positioned;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
@@ -16,12 +20,15 @@ import com.sap.sailing.domain.common.impl.WindImpl;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.deckmanadapter.impl.FieldType;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Timed;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class Record implements Timed, Positioned {
|
||||
private static final Logger logger = Logger.getLogger(Record.class.getName());
|
||||
|
||||
private static final long serialVersionUID = -7939775022865795801L;
|
||||
|
||||
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
||||
@@ -47,9 +54,18 @@ public class Record implements Timed, Positioned {
|
||||
Double.valueOf(this.fieldsAsString.get(FieldType.longitude)));
|
||||
final SpeedWithBearing speed = new KnotSpeedWithBearingImpl(Double.valueOf(this.fieldsAsString.get(FieldType.sog)),
|
||||
new DegreeBearingImpl(Double.valueOf(this.fieldsAsString.get(FieldType.cog))));
|
||||
Bearing optionalTrueHeading;
|
||||
try {
|
||||
optionalTrueHeading = this.fieldsAsString.get(FieldType.heading) == null ? null :
|
||||
new DegreeBearingImpl(Double.valueOf(this.fieldsAsString.get(FieldType.heading))).add(
|
||||
DeclinationService.INSTANCE.getDeclination(timePoint, position, /* timeout in ms */ 1000).getBearingCorrectedTo(timePoint));
|
||||
} catch (NumberFormatException | IOException | ParseException e) {
|
||||
logger.log(Level.WARNING, "Problem obtaining magnetic declination for converting Deckman magnetic heading value to true", e);
|
||||
optionalTrueHeading = null;
|
||||
}
|
||||
wind = new WindImpl(position, timePoint, new KnotSpeedWithBearingImpl(Double.valueOf(this.fieldsAsString
|
||||
.get(FieldType.tws)), new DegreeBearingImpl(Double.valueOf(this.fieldsAsString.get(FieldType.twd)))));
|
||||
gpsFix = new GPSFixMovingImpl(position, timePoint, speed);
|
||||
gpsFix = new GPSFixMovingImpl(position, timePoint, speed, optionalTrueHeading);
|
||||
}
|
||||
|
||||
public String getField(FieldType fieldType) {
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ public class DeckmanGPSFixImporter implements GPSFixImporter {
|
||||
try {
|
||||
for (Iterator<Record> i = deckmanAdapter.parseLogFile(new InputStreamReader(inputStream)); i.hasNext();) {
|
||||
Record record = i.next();
|
||||
callback.addFix(new GPSFixMovingImpl(record.getPosition(), record.getTimePoint(), record.getGpsFix().getSpeed()),
|
||||
callback.addFix(new GPSFixMovingImpl(record.getPosition(), record.getTimePoint(), record.getGpsFix().getSpeed(), record.getGpsFix().getOptionalTrueHeading()),
|
||||
device);
|
||||
importedFixes.set(true);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ Bundle-SymbolicName: com.sap.sailing.domain.expeditionadapter
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Import-Package: org.osgi.framework
|
||||
Import-Package: com.sap.sailing.declination,
|
||||
org.osgi.framework
|
||||
Require-Bundle: com.sap.sailing.server.trackfiles,
|
||||
com.sap.sailing.domain,
|
||||
com.sap.sse.common,
|
||||
|
||||
+23
-2
@@ -5,11 +5,15 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.declination.DeclinationService;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
@@ -21,13 +25,17 @@ import com.sap.sailing.domain.trackimport.GPSFixImporter;
|
||||
import com.sap.sailing.server.trackfiles.impl.CompressedStreamsUtil;
|
||||
import com.sap.sailing.server.trackfiles.impl.ExpeditionExtendedDataImporterImpl;
|
||||
import com.sap.sailing.server.trackfiles.impl.ExpeditionImportFileHandler;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
|
||||
public class ExpeditionGPSFixImporter implements GPSFixImporter {
|
||||
private static final Logger logger = Logger.getLogger(ExpeditionGPSFixImporter.class.getName());
|
||||
|
||||
private static final String LAT_COLUMN_HEADING = ExpeditionExtendedDataImporterImpl.COL_NAME_LAT;
|
||||
private static final String LON_COLUMN_HEADING = ExpeditionExtendedDataImporterImpl.COL_NAME_LON;
|
||||
private static final String COG_COLUMN_HEADING = "cog";
|
||||
private static final String SOG_COLUMN_HEADING = "sog";
|
||||
private static final String HDT_COLUMN_HEADING = "hdt";
|
||||
|
||||
@Override
|
||||
public boolean importFixes(InputStream inputStream, Charset charset, Callback callback,
|
||||
@@ -56,10 +64,23 @@ public class ExpeditionGPSFixImporter implements GPSFixImporter {
|
||||
.parseDouble(columnValues[columns.get(COG_COLUMN_HEADING)]);
|
||||
final double sogKnots = Double
|
||||
.parseDouble(columnValues[columns.get(SOG_COLUMN_HEADING)]);
|
||||
final DegreePosition position = new DegreePosition(latDeg, lonDeg);
|
||||
Bearing optionalTrueHeading;
|
||||
if (columns.containsKey(HDT_COLUMN_HEADING)) {
|
||||
try {
|
||||
optionalTrueHeading = new DegreeBearingImpl(Double.parseDouble(columnValues[columns.get(HDT_COLUMN_HEADING)]))
|
||||
.add(DeclinationService.INSTANCE.getDeclination(timePoint, position, /* timeout ms */ 1000).getBearingCorrectedTo(timePoint));
|
||||
} catch (NumberFormatException | IOException | ParseException e) {
|
||||
logger.log(Level.WARNING, "Problem obtaining declination for Expedition fix heading", e);
|
||||
optionalTrueHeading = null;
|
||||
}
|
||||
} else {
|
||||
optionalTrueHeading = null;
|
||||
}
|
||||
final GPSFixMoving fix = new GPSFixMovingImpl(
|
||||
new DegreePosition(latDeg, lonDeg), timePoint,
|
||||
position, timePoint,
|
||||
new KnotSpeedWithBearingImpl(sogKnots,
|
||||
new DegreeBearingImpl(cogDeg)));
|
||||
new DegreeBearingImpl(cogDeg)), optionalTrueHeading);
|
||||
callback.addFix(fix, device);
|
||||
importedFixes.set(true);
|
||||
});
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ public class OceanRaceGPSFixImporter implements GPSFixImporter {
|
||||
} else {
|
||||
sogInKnots = 0.0;
|
||||
}
|
||||
return new GPSFixMovingImpl(position, timePoint, new KnotSpeedWithBearingImpl(sogInKnots, cog));
|
||||
return new GPSFixMovingImpl(position, timePoint, new KnotSpeedWithBearingImpl(sogInKnots, cog), /* optionalTrueHeading */ null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ package com.sap.sailing.domain.persistence;
|
||||
|
||||
public enum FieldNames {
|
||||
// general:
|
||||
TIME_AS_MILLIS, KNOT_SPEED, DEGREE_BEARING, LAT_DEG, LNG_DEG,
|
||||
TIME_AS_MILLIS, KNOT_SPEED, DEGREE_BEARING, LAT_DEG, LNG_DEG, TRUE_HEADING_DEG,
|
||||
|
||||
FLEET, RACE_IDENTIFIERS,
|
||||
|
||||
|
||||
+10
@@ -389,6 +389,16 @@ public class DomainObjectFactoryImpl implements DomainObjectFactory {
|
||||
return new KnotSpeedWithBearingImpl(((Number) object.get(FieldNames.KNOT_SPEED.name())).doubleValue(),
|
||||
new DegreeBearingImpl(((Number) object.get(FieldNames.DEGREE_BEARING.name())).doubleValue()));
|
||||
}
|
||||
|
||||
public Bearing loadOptionalTrueHeading(Document object) {
|
||||
final Bearing result;
|
||||
if (object.containsKey(FieldNames.TRUE_HEADING_DEG.name())) {
|
||||
result = new DegreeBearingImpl(((Number) object.get(FieldNames.TRUE_HEADING_DEG.name())).doubleValue());
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RaceIdentifier loadRaceIdentifier(Document dbObject) {
|
||||
|
||||
+6
-1
@@ -238,7 +238,12 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
public void storeSpeedWithBearing(SpeedWithBearing speedWithBearing, Document result) {
|
||||
storeSpeed(speedWithBearing, result);
|
||||
storeBearing(speedWithBearing.getBearing(), result);
|
||||
|
||||
}
|
||||
|
||||
public void storeOptionalTrueHeading(Bearing optionalTrueHeading, Document result) {
|
||||
if (optionalTrueHeading != null) {
|
||||
result.put(FieldNames.TRUE_HEADING_DEG.name(), optionalTrueHeading.getDegrees());
|
||||
}
|
||||
}
|
||||
|
||||
public void storeBearing(Bearing bearing, Document result) {
|
||||
|
||||
+11
-7
@@ -1,5 +1,7 @@
|
||||
package com.sap.sailing.domain.persistence.racelog.tracking.impl;
|
||||
|
||||
import static com.sap.sailing.shared.persistence.impl.DomainObjectFactoryImpl.loadPosition;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
@@ -11,7 +13,7 @@ import com.sap.sailing.domain.persistence.MongoObjectFactory;
|
||||
import com.sap.sailing.domain.persistence.impl.DomainObjectFactoryImpl;
|
||||
import com.sap.sailing.domain.persistence.impl.MongoObjectFactoryImpl;
|
||||
import com.sap.sailing.domain.persistence.racelog.tracking.FixMongoHandler;
|
||||
import static com.sap.sailing.shared.persistence.impl.DomainObjectFactoryImpl.loadPosition;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class GPSFixMovingMongoHandlerImpl implements FixMongoHandler<GPSFixMoving> {
|
||||
@@ -27,17 +29,19 @@ public class GPSFixMovingMongoHandlerImpl implements FixMongoHandler<GPSFixMovin
|
||||
public Document transformForth(GPSFixMoving fix) throws IllegalArgumentException {
|
||||
Document result = new Document();
|
||||
mof.storeTimed(fix, result);
|
||||
mof.storePositioned(fix, result);
|
||||
mof.storeSpeedWithBearing(fix.getSpeed(), result);
|
||||
mof.storePositioned(fix, result);
|
||||
mof.storeSpeedWithBearing(fix.getSpeed(), result);
|
||||
mof.storeOptionalTrueHeading(fix.getOptionalTrueHeading(), result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GPSFixMoving transformBack(Document dbObject) {
|
||||
TimePoint timePoint = dof.loadTimePoint(dbObject);
|
||||
Position position = loadPosition(dbObject);
|
||||
SpeedWithBearing speed = dof.loadSpeedWithBearing(dbObject);
|
||||
return new GPSFixMovingImpl(position, timePoint, speed);
|
||||
final TimePoint timePoint = dof.loadTimePoint(dbObject);
|
||||
final Position position = loadPosition(dbObject);
|
||||
final SpeedWithBearing speed = dof.loadSpeedWithBearing(dbObject);
|
||||
final Bearing optionalTrueHeading = dof.loadOptionalTrueHeading(dbObject);
|
||||
return new GPSFixMovingImpl(position, timePoint, speed, optionalTrueHeading);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ public class AbstractGPSFixStoreTest extends RaceLogTrackingTestHelper {
|
||||
|
||||
protected GPSFixMoving createFix(long millis, double lat, double lng, double knots, double degrees) {
|
||||
return new GPSFixMovingImpl(new DegreePosition(lat, lng),
|
||||
new MillisecondsTimePoint(millis), new KnotSpeedWithBearingImpl(knots, new DegreeBearingImpl(degrees)));
|
||||
new MillisecondsTimePoint(millis), new KnotSpeedWithBearingImpl(knots, new DegreeBearingImpl(degrees)), /* optionalTrueHeading */ null);
|
||||
}
|
||||
|
||||
protected GPSFix createFix(long millis, double lat, double lng) {
|
||||
|
||||
+6
-6
@@ -169,9 +169,9 @@ public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
|
||||
private void addFixes0(DeviceIdentifier dev1) throws TransformationException,
|
||||
NoCorrespondingServiceRegisteredException {
|
||||
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(5), new KnotSpeedWithBearingImpl(
|
||||
10, new DegreeBearingImpl(5))));
|
||||
10, new DegreeBearingImpl(5)), /* optionalTrueHeading */ null));
|
||||
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(15), new KnotSpeedWithBearingImpl(
|
||||
10, new DegreeBearingImpl(5))));
|
||||
10, new DegreeBearingImpl(5)), /* optionalTrueHeading */ null));
|
||||
}
|
||||
|
||||
private void addFixes1(TrackedRace race, Competitor comp1, DeviceIdentifier dev1) throws TransformationException,
|
||||
@@ -180,9 +180,9 @@ public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
|
||||
testSize(race.getTrack(comp1), 1);
|
||||
// further fix arrives in race
|
||||
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(7), new KnotSpeedWithBearingImpl(
|
||||
10, new DegreeBearingImpl(5))));
|
||||
10, new DegreeBearingImpl(5)), /* optionalTrueHeading */ null));
|
||||
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(14), new KnotSpeedWithBearingImpl(
|
||||
10, new DegreeBearingImpl(5)))); // outside mapping range
|
||||
10, new DegreeBearingImpl(5)), /* optionalTrueHeading */ null)); // outside mapping range
|
||||
testSize(race.getTrack(comp1), 2);
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
|
||||
testSize(race.getTrack(comp1), 4);
|
||||
// add another fix in new mapping range
|
||||
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(18), new KnotSpeedWithBearingImpl(
|
||||
10, new DegreeBearingImpl(5))));
|
||||
10, new DegreeBearingImpl(5)), /* optionalTrueHeading */ null));
|
||||
testSize(race.getTrack(comp1), 5);
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ public class CreateAndTrackWithRaceLogTest extends RaceLogTrackingTestHelper {
|
||||
NoCorrespondingServiceRegisteredException {
|
||||
// stop tracking, then no more fixes arrive at race
|
||||
sensorFixStore.storeFix(dev1, new GPSFixMovingImpl(new DegreePosition(0, 0), t(8), new KnotSpeedWithBearingImpl(
|
||||
10, new DegreeBearingImpl(5))));
|
||||
10, new DegreeBearingImpl(5)), /* optionalTrueHeading */ null));
|
||||
testSize(race.getTrack(comp1), 5);
|
||||
}
|
||||
|
||||
|
||||
-11
@@ -38,10 +38,6 @@ import com.sap.sailing.domain.base.impl.RegattaImpl;
|
||||
import com.sap.sailing.domain.base.impl.WaypointImpl;
|
||||
import com.sap.sailing.domain.common.CompetitorRegistrationType;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.persistence.PersistenceFactory;
|
||||
import com.sap.sailing.domain.persistence.racelog.tracking.impl.MongoSensorFixStoreImpl;
|
||||
import com.sap.sailing.domain.racelog.RaceLogAndTrackedRaceResolver;
|
||||
@@ -62,8 +58,6 @@ import com.sap.sailing.domain.tracking.impl.DynamicTrackedRaceImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.DynamicTrackedRegattaImpl;
|
||||
import com.sap.sailing.domain.tracking.impl.EmptyWindStore;
|
||||
import com.sap.sse.common.Timed;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class RaceLogFixTrackerManagerTest {
|
||||
protected final MockSmartphoneImeiServiceFinderFactory serviceFinderFactory = new MockSmartphoneImeiServiceFinderFactory();
|
||||
@@ -83,11 +77,6 @@ public class RaceLogFixTrackerManagerTest {
|
||||
protected final AbstractLogEventAuthor author = new LogEventAuthorImpl("author", 0);
|
||||
private DynamicTrackedRace trackedRace;
|
||||
|
||||
protected GPSFixMoving createFix(long millis, double lat, double lng, double knots, double degrees) {
|
||||
return new GPSFixMovingImpl(new DegreePosition(lat, lng), new MillisecondsTimePoint(millis),
|
||||
new KnotSpeedWithBearingImpl(knots, new DegreeBearingImpl(degrees)));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws UnknownHostException, MongoException {
|
||||
raceLog = new RaceLogImpl("racelog");
|
||||
|
||||
+5
-10
@@ -141,11 +141,6 @@ public class SensorFixStoreAndLoadTest {
|
||||
protected final AbstractLogEventAuthor author = new LogEventAuthorImpl("author", 0);
|
||||
private DynamicTrackedRace trackedRace;
|
||||
|
||||
protected GPSFixMoving createFix(long millis, double lat, double lng, double knots, double degrees) {
|
||||
return new GPSFixMovingImpl(new DegreePosition(lat, lng), new MillisecondsTimePoint(millis),
|
||||
new KnotSpeedWithBearingImpl(knots, new DegreeBearingImpl(degrees)));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws UnknownHostException, MongoException {
|
||||
dropPersistedData();
|
||||
@@ -691,11 +686,11 @@ public class SensorFixStoreAndLoadTest {
|
||||
final MillisecondsTimePoint timePoint2 = new MillisecondsTimePoint(FIX_TIMESTAMP2);
|
||||
final MillisecondsTimePoint timePoint3 = new MillisecondsTimePoint(FIX_TIMESTAMP3);
|
||||
final TimePoint timePointBetween2And3 = new MillisecondsTimePoint((FIX_TIMESTAMP2+FIX_TIMESTAMP3)/2);
|
||||
final GPSFixMoving fix1 = new GPSFixMovingImpl(pos1, timePoint, speed);
|
||||
final GPSFixMoving fix1 = new GPSFixMovingImpl(pos1, timePoint, speed, /* optionalTrueHeading */ null);
|
||||
final Position pos2 = pos1.translateGreatCircle(course, speed.travel(timePoint.until(timePoint2)));
|
||||
final GPSFixMoving fix2 = new GPSFixMovingImpl(pos2, timePoint2, speed);
|
||||
final GPSFixMoving fix2 = new GPSFixMovingImpl(pos2, timePoint2, speed, /* optionalTrueHeading */ null);
|
||||
final Position pos3 = pos2.translateGreatCircle(course, speed.travel(timePoint2.until(timePoint3)));
|
||||
final GPSFixMoving fix3 = new GPSFixMovingImpl(pos3, timePoint3, speed);
|
||||
final GPSFixMoving fix3 = new GPSFixMovingImpl(pos3, timePoint3, speed, /* optionalTrueHeading */ null);
|
||||
gpsFixTrack.add(fix1);
|
||||
gpsFixTrack.add(fix2);
|
||||
gpsFixTrack.add(fix3);
|
||||
@@ -710,7 +705,7 @@ public class SensorFixStoreAndLoadTest {
|
||||
final DegreeBearingImpl temporaryCourse = new DegreeBearingImpl(90);
|
||||
final GPSFixMoving fixBetween2And3 = new GPSFixMovingImpl(
|
||||
pos2.translateGreatCircle(temporaryCourse, speed.add(new KnotSpeedWithBearingImpl(5, temporaryCourse)).travel(timePoint2.until(timePointBetween2And3))),
|
||||
timePointBetween2And3, speed);
|
||||
timePointBetween2And3, speed, /* optionalTrueHeading */ null);
|
||||
gpsFixTrack.add(fixBetween2And3);
|
||||
final Distance distanceTraveledDifferently = gpsFixTrack.getDistanceTraveled(timePoint, timePoint3);
|
||||
assertTrue(distanceTraveledDifferently.compareTo(distanceTraveled) > 0);
|
||||
@@ -721,7 +716,7 @@ public class SensorFixStoreAndLoadTest {
|
||||
final SpeedWithBearing doubledSpeed = speed.add(speed);
|
||||
final GPSFixMoving fix3Faster = new GPSFixMovingImpl(
|
||||
pos2.translateGreatCircle(course, doubledSpeed.travel(timePoint2.until(timePoint3))),
|
||||
timePoint3, doubledSpeed);
|
||||
timePoint3, doubledSpeed, /* optionalTrueHeading */ null);
|
||||
gpsFixTrack.add(fix3Faster, /* replace */ true);
|
||||
final Distance distanceTraveledFaster = gpsFixTrack.getDistanceTraveled(timePoint, timePoint3);
|
||||
assertTrue(distanceTraveledFaster.compareTo(distanceTraveled) > 0);
|
||||
|
||||
-10
@@ -18,13 +18,9 @@ import com.mongodb.ReadConcern;
|
||||
import com.mongodb.WriteConcern;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.sap.sailing.domain.common.DeviceIdentifier;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
import com.sap.sailing.domain.common.sensordata.BravoSensorDataMetadata;
|
||||
import com.sap.sailing.domain.common.tracking.DoubleVectorFix;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.impl.DoubleVectorFixImpl;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.persistence.PersistenceFactory;
|
||||
import com.sap.sailing.domain.persistence.impl.CollectionNames;
|
||||
import com.sap.sailing.domain.persistence.racelog.tracking.impl.MongoSensorFixStoreImpl;
|
||||
@@ -35,7 +31,6 @@ import com.sap.sailing.domain.racelog.tracking.test.mock.SmartphoneImeiIdentifie
|
||||
import com.sap.sse.common.NoCorrespondingServiceRegisteredException;
|
||||
import com.sap.sse.common.Timed;
|
||||
import com.sap.sse.common.TransformationException;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
import com.sap.sse.common.impl.TimeRangeImpl;
|
||||
|
||||
@@ -49,11 +44,6 @@ public class SensorFixStoreTest {
|
||||
protected final DeviceIdentifier device2 = new SmartphoneImeiIdentifier("b");
|
||||
protected SensorFixStore store;
|
||||
|
||||
protected GPSFixMoving createFix(long millis, double lat, double lng, double knots, double degrees) {
|
||||
return new GPSFixMovingImpl(new DegreePosition(lat, lng), new MillisecondsTimePoint(millis),
|
||||
new KnotSpeedWithBearingImpl(knots, new DegreeBearingImpl(degrees)));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws UnknownHostException, MongoException {
|
||||
dropPersistedData();
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ public class PostFixes extends AbstractJsonOverHttpTest {
|
||||
lastFix = fix;
|
||||
|
||||
try {
|
||||
recordFix(new GPSFixMovingImpl(fix.getPosition(), fix.getTimePoint(), speed));
|
||||
recordFix(new GPSFixMovingImpl(fix.getPosition(), fix.getTimePoint(), speed, /* optionalTrueHeading */ null));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
+1
-1
@@ -379,7 +379,7 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
@Override
|
||||
public GPSFixMoving createGPSFix(TimePoint timePointOfTransmission, Fix fix) {
|
||||
GPSFixMoving result = new GPSFixMovingImpl(fix.getPosition(), new MillisecondsTimePoint(
|
||||
timePointOfTransmission.asMillis() + fix.getAgeOfDataInMilliseconds()), fix.getSpeed());
|
||||
timePointOfTransmission.asMillis() + fix.getAgeOfDataInMilliseconds()), fix.getSpeed(), /* optionalTrueHeading */ null);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -494,7 +494,7 @@ public class SwissTimingReplayToDomainAdapter extends SwissTimingReplayAdapter i
|
||||
TimePoint raceTimePoint = raceTimePerRaceID.containsKey(currentRaceID) ? raceTimePerRaceID.get(currentRaceID) : referenceTimePoint;
|
||||
Bearing bearing = new DegreeBearingImpl(cog);
|
||||
SpeedWithBearing speed = new KnotSpeedWithBearingImpl(((double) sog_Knots_x10) / 10., bearing);
|
||||
GPSFixMoving fix = new GPSFixMovingImpl(position, raceTimePoint, speed);
|
||||
GPSFixMoving fix = new GPSFixMovingImpl(position, raceTimePoint, speed, /* optionalTrueHeading */ null);
|
||||
Mark mark = markByHashValue.get(hashValue);
|
||||
if (mark != null) {
|
||||
Iterator<Entry<ControlPoint, SpeedWithBearing>> i = windAtControlPoint.entrySet().iterator();
|
||||
|
||||
+3
-3
@@ -188,9 +188,9 @@ public class CandidateFinderImplWhiteBoxTest {
|
||||
final Position beforeStartPosition = startLinePosition.translateGreatCircle(startLineCrossingSpeed.getBearing().reverse(), startLineCrossingSpeed.travel(Duration.ONE_SECOND));
|
||||
final Position atStartPosition = startLinePosition;
|
||||
final Position afterStartPosition = startLinePosition.translateGreatCircle(startLineCrossingSpeed.getBearing(), startLineCrossingSpeed.travel(Duration.ONE_SECOND));
|
||||
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(beforeStartPosition, timeForStartLinePassing.minus(Duration.ONE_SECOND), startLineCrossingSpeed));
|
||||
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(atStartPosition, timeForStartLinePassing, startLineCrossingSpeed));
|
||||
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(afterStartPosition, timeForStartLinePassing.plus(Duration.ONE_SECOND), startLineCrossingSpeed));
|
||||
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(beforeStartPosition, timeForStartLinePassing.minus(Duration.ONE_SECOND), startLineCrossingSpeed, /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(atStartPosition, timeForStartLinePassing, startLineCrossingSpeed, /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(afterStartPosition, timeForStartLinePassing.plus(Duration.ONE_SECOND), startLineCrossingSpeed, /* optionalTrueHeading */ null));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+2
-2
@@ -50,7 +50,7 @@ public class StationarySequenceBasedFilterTest extends AbstractCandidateFilterTe
|
||||
if (previousTimePoint != null) {
|
||||
position = verySmallSpeed.travelTo(position, durationBetweenFixes);
|
||||
}
|
||||
track.add(new GPSFixMovingImpl(position, timePoint, verySmallSpeed));
|
||||
track.add(new GPSFixMovingImpl(position, timePoint, verySmallSpeed, /* optionalTrueHeading */ null));
|
||||
timePoint = timePoint.plus(durationBetweenFixes);
|
||||
}
|
||||
previousTimePoint = candidate.getTimePoint();
|
||||
@@ -88,7 +88,7 @@ public class StationarySequenceBasedFilterTest extends AbstractCandidateFilterTe
|
||||
outlierCourse, StationarySequence.CANDIDATE_FILTER_DISTANCE.scale(2));
|
||||
final TimePoint inBetweenTimePoint = fixAtC2.getTimePoint().plus(fixAtC2.getTimePoint().until(fixAfterFixAtC2.getTimePoint()).divide(2));
|
||||
final Speed outlierSpeed = fixAtC2.getPosition().getDistance(outlierPosition).inTime(fixAtC2.getTimePoint().until(inBetweenTimePoint));
|
||||
final GPSFixMoving fixInBetween = new GPSFixMovingImpl(outlierPosition, inBetweenTimePoint, new KnotSpeedWithBearingImpl(outlierSpeed.getKnots(), outlierCourse));
|
||||
final GPSFixMoving fixInBetween = new GPSFixMovingImpl(outlierPosition, inBetweenTimePoint, new KnotSpeedWithBearingImpl(outlierSpeed.getKnots(), outlierCourse), /* optionalTrueHeading */ null);
|
||||
track.add(fixInBetween);
|
||||
TreeSet<Candidate> candidatesEffectivelyAdded = new TreeSet<>(candidateComparator);
|
||||
TreeSet<Candidate> candidatesEffectivelyRemoved = new TreeSet<>(candidateComparator);
|
||||
|
||||
+3
-3
@@ -69,7 +69,7 @@ public class StationarySequenceTest extends AbstractCandidateFilterTestSupport {
|
||||
if (previousTimePoint != null) {
|
||||
position = verySmallSpeed.travelTo(position, durationBetweenFixes);
|
||||
}
|
||||
track.add(new GPSFixMovingImpl(position, timePoint, verySmallSpeed));
|
||||
track.add(new GPSFixMovingImpl(position, timePoint, verySmallSpeed, /* optionalTrueHeading */ null));
|
||||
timePoint = timePoint.plus(durationBetweenFixes);
|
||||
}
|
||||
previousTimePoint = candidate.getTimePoint();
|
||||
@@ -108,7 +108,7 @@ public class StationarySequenceTest extends AbstractCandidateFilterTestSupport {
|
||||
final Position originalPosition = track.getEstimatedPosition(timePointForNewFix, /* extrapolate */ false);
|
||||
final Position westPosition = originalPosition.translateGreatCircle(new DegreeBearingImpl(270), StationarySequence.CANDIDATE_FILTER_DISTANCE.scale(0.5));
|
||||
final Position eastPosition = originalPosition.translateGreatCircle(new DegreeBearingImpl(90), StationarySequence.CANDIDATE_FILTER_DISTANCE.scale(0.5));
|
||||
final GPSFixMovingImpl westFix = new GPSFixMovingImpl(westPosition, timePointForNewFix, originalPosition.getSpeedWithBearingToReachOnGreatCircle(westPosition, c2.getTimePoint().until(timePointForNewFix)));
|
||||
final GPSFixMovingImpl westFix = new GPSFixMovingImpl(westPosition, timePointForNewFix, originalPosition.getSpeedWithBearingToReachOnGreatCircle(westPosition, c2.getTimePoint().until(timePointForNewFix)), /* optionalTrueHeading */ null);
|
||||
track.add(westFix);
|
||||
final Set<Candidate> candidatesEffectivelyAdded = new HashSet<>();
|
||||
final Set<Candidate> candidatesEffectivelyRemoved = new HashSet<>();
|
||||
@@ -118,7 +118,7 @@ public class StationarySequenceTest extends AbstractCandidateFilterTestSupport {
|
||||
assertEquals(3, Util.size(stationarySequence.getAllCandidates())); // and all candidates should still be part of the sequence
|
||||
assertTrue(candidatesEffectivelyAdded.isEmpty());
|
||||
assertTrue(candidatesEffectivelyRemoved.isEmpty());
|
||||
final GPSFixMovingImpl eastFix = new GPSFixMovingImpl(eastPosition, timePointForNewFix, originalPosition.getSpeedWithBearingToReachOnGreatCircle(eastPosition, c2.getTimePoint().until(timePointForNewFix)));
|
||||
final GPSFixMovingImpl eastFix = new GPSFixMovingImpl(eastPosition, timePointForNewFix, originalPosition.getSpeedWithBearingToReachOnGreatCircle(eastPosition, c2.getTimePoint().until(timePointForNewFix)), /* optionalTrueHeading */ null);
|
||||
track.add(eastFix, /* replace */ true);
|
||||
final StationarySequence resultForEastFix = stationarySequence.tryToAddFix(eastFix, candidatesEffectivelyAdded, candidatesEffectivelyRemoved, stationarySequenceSetToUpdate, /* isReplacement */ true);
|
||||
assertNull(resultForEastFix); // again no split should have been necessary
|
||||
|
||||
+8
-8
@@ -232,7 +232,7 @@ public class TestCrossFleetScoring extends LeaderboardScoringAndRankingTestBase
|
||||
Competitor competitor = competitors.get(competitorName);
|
||||
MarkPassingImpl markPassing = new MarkPassingImpl(startOfRace, start, competitor);
|
||||
GPSFixMovingImpl gpsFix = new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(45)));
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(45)), /* optionalTrueHeading */ null);
|
||||
addMarkPassingAndGPSFix(competitorsAndMarkPassingsWithGpsFixes, competitor, markPassing, gpsFix);
|
||||
|
||||
}
|
||||
@@ -257,7 +257,7 @@ public class TestCrossFleetScoring extends LeaderboardScoringAndRankingTestBase
|
||||
Map<Competitor, Pair<List<MarkPassing>, List<GPSFixMovingImpl>>> competitorsAndMarkPassingsWithGpsFixes,
|
||||
String competitorName, DegreePosition position, TimePoint timePoint) {
|
||||
GPSFixMovingImpl gpsFix = new GPSFixMovingImpl(position, timePoint,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(45)));
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(45)), /* optionalTrueHeading */ null);
|
||||
competitorsAndMarkPassingsWithGpsFixes.get(competitors.get(competitorName)).getB().add(gpsFix);
|
||||
|
||||
}
|
||||
@@ -478,13 +478,13 @@ public class TestCrossFleetScoring extends LeaderboardScoringAndRankingTestBase
|
||||
Competitor fastYellow = competitors.get("FastYellowBoat");
|
||||
MarkPassingImpl markPassingFastYellow = new MarkPassingImpl(markRounding, windward, fastYellow);
|
||||
GPSFixMovingImpl gpsFixFastYellow = new GPSFixMovingImpl(new DegreePosition(1.0, 0), markRounding,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)));
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)), /* optionalTrueHeading */ null);
|
||||
addMarkPassingAndGPSFix(competitorsAndMarkPassingsWithGpsFixes, fastYellow, markPassingFastYellow, gpsFixFastYellow);
|
||||
// markRounding for SlowYellow
|
||||
Competitor slowYellow = competitors.get("SlowYellowBoat");
|
||||
MarkPassingImpl markPassingSlowYellow = new MarkPassingImpl(markRounding, windward, slowYellow);
|
||||
GPSFixMovingImpl gpsFixSlowYellow = new GPSFixMovingImpl(new DegreePosition(1.0, 0), markRounding,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)));
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)), /* optionalTrueHeading */ null);
|
||||
addMarkPassingAndGPSFix(competitorsAndMarkPassingsWithGpsFixes, slowYellow, markPassingSlowYellow, gpsFixSlowYellow);
|
||||
// add current Position
|
||||
appendGPSFixForCompetitor(competitorsAndMarkPassingsWithGpsFixes, "FastYellowBoat", new DegreePosition(0.4, 0),
|
||||
@@ -516,25 +516,25 @@ public class TestCrossFleetScoring extends LeaderboardScoringAndRankingTestBase
|
||||
Competitor fastYellow = competitors.get("FastYellowBoat");
|
||||
MarkPassingImpl markPassingFastYellow = new MarkPassingImpl(markRounding, windward, fastYellow);
|
||||
GPSFixMovingImpl gpsFixFastYellow = new GPSFixMovingImpl(new DegreePosition(1.0, 0), markRounding,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)));
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)), /* optionalTrueHeading */ null);
|
||||
addMarkPassingAndGPSFix(competitorsAndMarkPassingsWithGpsFixes, fastYellow, markPassingFastYellow, gpsFixFastYellow);
|
||||
// markRounding for SlowYellow
|
||||
Competitor slowYellow = competitors.get("SlowYellowBoat");
|
||||
MarkPassingImpl markPassingSlowYellow = new MarkPassingImpl(markRounding, windward, slowYellow);
|
||||
GPSFixMovingImpl gpsFixSlowYellow = new GPSFixMovingImpl(new DegreePosition(1.0, 0), markRounding,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)));
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)), /* optionalTrueHeading */ null);
|
||||
addMarkPassingAndGPSFix(competitorsAndMarkPassingsWithGpsFixes, slowYellow, markPassingSlowYellow, gpsFixSlowYellow);
|
||||
// markRounding for FastBlue
|
||||
Competitor fastBlue = competitors.get("FastYellowBoat");
|
||||
MarkPassingImpl markPassingFastBlue = new MarkPassingImpl(markRounding, windward, fastBlue);
|
||||
GPSFixMovingImpl gpsFixFastBlue = new GPSFixMovingImpl(new DegreePosition(1.0, 0), markRounding,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)));
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)), /* optionalTrueHeading */ null);
|
||||
addMarkPassingAndGPSFix(competitorsAndMarkPassingsWithGpsFixes, fastBlue, markPassingFastBlue, gpsFixFastBlue);
|
||||
// markRounding for SlowYellow
|
||||
Competitor slowBlue = competitors.get("SlowYellowBoat");
|
||||
MarkPassingImpl markPassingSlowslowBlue = new MarkPassingImpl(markRounding, windward, slowBlue);
|
||||
GPSFixMovingImpl gpsFixSlowslowBlue = new GPSFixMovingImpl(new DegreePosition(1.0, 0), markRounding,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)));
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(180)), /* optionalTrueHeading */ null);
|
||||
addMarkPassingAndGPSFix(competitorsAndMarkPassingsWithGpsFixes, slowBlue, markPassingSlowslowBlue, gpsFixSlowslowBlue);
|
||||
// add current Position
|
||||
appendGPSFixForCompetitor(competitorsAndMarkPassingsWithGpsFixes, "FastYellowBoat", new DegreePosition(0.1, 0),
|
||||
|
||||
+10
-10
@@ -154,16 +154,16 @@ public class TestFarthestAheadWithSkippedMarkPassing {
|
||||
Arrays.<MarkPassing> asList(new MarkPassingImpl(startOfRace, start, c1)));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
// Both boats have climbed half of the first upwind beat; c1 is rated the faster boat (2.0), c2 has time-on-time factor 1.0.
|
||||
// Therefore, c2 is expected to lead after applying the corrections.
|
||||
final RankingInfo rankingInfo = rankingMetric.getRankingInfo(middleOfFirstLeg);
|
||||
@@ -192,24 +192,24 @@ public class TestFarthestAheadWithSkippedMarkPassing {
|
||||
// they both start at the start line
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
// both round the windward mark at the same time
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(1.0, 0), endOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(1.0, 0), endOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
// c2 is further down the wind already at the middle of the second leg:
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfSecondLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(180))));
|
||||
new DegreeBearingImpl(180)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.2, 0), middleOfSecondLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(180))));
|
||||
new DegreeBearingImpl(180)), /* optionalTrueHeading */ null));
|
||||
// Assert that c2 is the boat farthest ahead
|
||||
final RankingInfo rankingInfo = rankingMetric.getRankingInfo(middleOfSecondLeg);
|
||||
assertSame(c2, rankingInfo.getCompetitorFarthestAhead());
|
||||
|
||||
+16
-16
@@ -129,16 +129,16 @@ public class TestSimpleTimeOnTimeRankingWithOneUpwindLeg {
|
||||
.getFirstWaypoint(), c2)));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
// Both boats have climbed half of the first upwind beat; c1 is rated the faster boat (2.0), c2 has time-on-time factor 1.0.
|
||||
// Therefore, c2 is expected to lead after applying the corrections.
|
||||
Comparator<Competitor> comparator = tot.getRaceRankingComparator(middleOfFirstLeg);
|
||||
@@ -160,16 +160,16 @@ public class TestSimpleTimeOnTimeRankingWithOneUpwindLeg {
|
||||
.getFirstWaypoint(), c2)));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(1.0, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
// Using a white-box test, assert that the ranking-relevant numbers are sufficiently close to each other
|
||||
final RankingMetric.RankingInfo rankingInfo = tot.getRankingInfo(middleOfFirstLeg);
|
||||
assertSame(c1, rankingInfo.getCompetitorFarthestAhead());
|
||||
@@ -195,16 +195,16 @@ public class TestSimpleTimeOnTimeRankingWithOneUpwindLeg {
|
||||
.getFirstWaypoint(), c2)));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
// Both boats have climbed half of the first upwind beat; c1 is rated the faster boat (2.0), c2 has time-on-time factor 1.0.
|
||||
// Therefore, c2 is expected to lead after applying the corrections.
|
||||
Comparator<Competitor> comparator = tot.getRaceRankingComparator(middleOfFirstLeg);
|
||||
@@ -226,16 +226,16 @@ public class TestSimpleTimeOnTimeRankingWithOneUpwindLeg {
|
||||
.getFirstWaypoint(), c2)));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.0, 0), startOfRace, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c1).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(1.0, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(45))));
|
||||
new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
trackedRace.getTrack(c2).add(
|
||||
new GPSFixMovingImpl(new DegreePosition(0.5, 0), middleOfFirstLeg, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(315))));
|
||||
new DegreeBearingImpl(315)), /* optionalTrueHeading */ null));
|
||||
// Using a white-box test, assert that the ranking-relevant numbers are sufficiently close to each other,
|
||||
// in this case .05 seconds per nautical mile for the reciproke VMG measured in seconds per nautical mile
|
||||
final RankingMetric.RankingInfo rankingInfo = tot.getRankingInfo(middleOfFirstLeg);
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ public class BravoFixTrackFoiledDistanceCacheTest {
|
||||
|
||||
private GPSFixMoving createGPSFix(long timePointAsMillis, double lat, double lng, double cogInDeg, double sogInKnots) {
|
||||
return new GPSFixMovingImpl(new DegreePosition(lat, lng), new MillisecondsTimePoint(timePointAsMillis),
|
||||
new KnotSpeedWithBearingImpl(sogInKnots, new DegreeBearingImpl(cogInDeg)));
|
||||
new KnotSpeedWithBearingImpl(sogInKnots, new DegreeBearingImpl(cogInDeg)), /* optionalTrueHeading */ null);
|
||||
}
|
||||
|
||||
private MillisecondsTimePoint t(long timePointAsMillis) {
|
||||
|
||||
+2
-2
@@ -61,12 +61,12 @@ public class CourseChangeBasedTrackApproximationTest {
|
||||
}
|
||||
|
||||
private GPSFixMoving fix(long timepoint, double lat, double lon, double speedInKnots, double cogDeg) {
|
||||
return new GPSFixMovingImpl(new DegreePosition(lat, lon), new MillisecondsTimePoint(timepoint), new KnotSpeedWithBearingImpl(speedInKnots, new DegreeBearingImpl(cogDeg)));
|
||||
return new GPSFixMovingImpl(new DegreePosition(lat, lon), new MillisecondsTimePoint(timepoint), new KnotSpeedWithBearingImpl(speedInKnots, new DegreeBearingImpl(cogDeg)), /* optionalTrueHeading */ null);
|
||||
}
|
||||
|
||||
private GPSFixMoving travel(GPSFixMoving fix, long durationInMillis, double speedInKnots, double cogDeg) {
|
||||
return new GPSFixMovingImpl(fix.getPosition().translateGreatCircle(new DegreeBearingImpl(cogDeg), new KnotSpeedImpl(speedInKnots).travel(new MillisecondsDurationImpl(durationInMillis))),
|
||||
fix.getTimePoint().plus(durationInMillis), new KnotSpeedWithBearingImpl(speedInKnots, new DegreeBearingImpl(cogDeg)));
|
||||
fix.getTimePoint().plus(durationInMillis), new KnotSpeedWithBearingImpl(speedInKnots, new DegreeBearingImpl(cogDeg)), /* optionalTrueHeading */ null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -57,9 +57,9 @@ public class DistanceCacheInvalidationAfterLoadingFinishedTest extends TrackBase
|
||||
final Position startPos = new DegreePosition(0, 0);
|
||||
final DegreeBearingImpl bearing = new DegreeBearingImpl(10);
|
||||
final KnotSpeedWithBearingImpl speed = new KnotSpeedWithBearingImpl(10, bearing);
|
||||
trackedRace.recordFix(competitor, new GPSFixMovingImpl(startPos, now, speed));
|
||||
trackedRace.recordFix(competitor, new GPSFixMovingImpl(startPos, now, speed, /* optionalTrueHeading */ null));
|
||||
final Distance distance = speed.travel(Duration.ONE_SECOND);
|
||||
trackedRace.recordFix(competitor, new GPSFixMovingImpl(startPos.translateGreatCircle(bearing, distance), now.plus(Duration.ONE_SECOND), speed));
|
||||
trackedRace.recordFix(competitor, new GPSFixMovingImpl(startPos.translateGreatCircle(bearing, distance), now.plus(Duration.ONE_SECOND), speed, /* optionalTrueHeading */ null));
|
||||
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.01); // ask 1s after the second fix
|
||||
}
|
||||
|
||||
+2
-2
@@ -70,7 +70,7 @@ public class LineAnalysisTest extends TrackBasedTest {
|
||||
final Position lineMiddle = leftPos.translateGreatCircle(lineBearingFromLeftToRight, leftPos.getDistance(rightPos).scale(0.5));
|
||||
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))));
|
||||
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(behindMiddleOfLine, now, new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
assertEquals(distanceBehindLine.getMeters(), trackedRace.getDistanceToStartLine(competitor, now).getMeters(), 0.01);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public class LineAnalysisTest extends TrackBasedTest {
|
||||
final Position outsideOfLine = rightPos.translateGreatCircle(lineBearingFromLeftToRight, new MeterDistance(30)); // 30m right of start boat
|
||||
final Distance distanceBehindLine = new MeterDistance(10);
|
||||
final Position behindOutsideOfLine = outsideOfLine.translateGreatCircle(awayFromCourseSideOrthogonalToLine, distanceBehindLine);
|
||||
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(behindOutsideOfLine, now, new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(45))));
|
||||
trackedRace.getTrack(competitor).add(new GPSFixMovingImpl(behindOutsideOfLine, now, new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
// 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.01);
|
||||
}
|
||||
|
||||
+5
-5
@@ -51,7 +51,7 @@ public class MarkPositionTimeFilterTest {
|
||||
@Test
|
||||
public void testAddFixForMark() {
|
||||
trackedRace.recordFix(m, new GPSFixMovingImpl(new DegreePosition(12, 13), MillisecondsTimePoint.now(),
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123))), /* onlyWhenInTrackingInterval */ true);
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null), /* onlyWhenInTrackingInterval */ true);
|
||||
track.lockForRead();
|
||||
try {
|
||||
assertEquals(1, track.getRawFixes().size());
|
||||
@@ -68,7 +68,7 @@ public class MarkPositionTimeFilterTest {
|
||||
when(trackedRace.getStartOfTracking()).thenReturn(start);
|
||||
when(trackedRace.getEndOfTracking()).thenReturn(end);
|
||||
trackedRace.recordFix(m, new GPSFixMovingImpl(new DegreePosition(12, 13), fix,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123))), /* onlyWhenInTrackingInterval */ true);
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null), /* onlyWhenInTrackingInterval */ true);
|
||||
track.lockForRead();
|
||||
try {
|
||||
assertEquals(1, track.getRawFixes().size());
|
||||
@@ -85,7 +85,7 @@ public class MarkPositionTimeFilterTest {
|
||||
when(trackedRace.getStartOfTracking()).thenReturn(start);
|
||||
when(trackedRace.getEndOfTracking()).thenReturn(end);
|
||||
trackedRace.recordFix(m, new GPSFixMovingImpl(new DegreePosition(12, 13), fix,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123))), /* onlyWhenInTrackingInterval */ true);
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null), /* onlyWhenInTrackingInterval */ true);
|
||||
track.lockForRead();
|
||||
try {
|
||||
assertTrue(track.getRawFixes().isEmpty());
|
||||
@@ -102,7 +102,7 @@ public class MarkPositionTimeFilterTest {
|
||||
when(trackedRace.getStartOfTracking()).thenReturn(start);
|
||||
when(trackedRace.getEndOfTracking()).thenReturn(end);
|
||||
trackedRace.recordFix(m, new GPSFixMovingImpl(new DegreePosition(12, 13), fix,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123))), /* onlyWhenInTrackingInterval */ true);
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null), /* onlyWhenInTrackingInterval */ true);
|
||||
track.lockForRead();
|
||||
try {
|
||||
assertTrue(track.getRawFixes().isEmpty());
|
||||
@@ -111,7 +111,7 @@ public class MarkPositionTimeFilterTest {
|
||||
}
|
||||
when(trackedRace.getEndOfTracking()).thenReturn(fix.plus(10000));
|
||||
trackedRace.recordFix(m, new GPSFixMovingImpl(new DegreePosition(12, 13), fix,
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123))), /* onlyWhenInTrackingInterval */ true);
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null), /* onlyWhenInTrackingInterval */ true);
|
||||
track.lockForRead();
|
||||
try {
|
||||
assertEquals(1, track.getRawFixes().size());
|
||||
|
||||
@@ -64,7 +64,7 @@ public class PositionTest {
|
||||
public void testEqualityBetweenCompactAndVerboseSpeedWithBearing() throws CompactionNotPossibleException {
|
||||
Position p1 = new DegreePosition(49.2, 008.3);
|
||||
SpeedWithBearing swb = new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123));
|
||||
VeryCompactGPSFixMovingImpl compactFix = new VeryCompactGPSFixMovingImpl(p1, MillisecondsTimePoint.now(), swb);
|
||||
VeryCompactGPSFixMovingImpl compactFix = new VeryCompactGPSFixMovingImpl(p1, MillisecondsTimePoint.now(), swb, /* optionalTrueHeading */ null);
|
||||
assertNotSame(p1, compactFix.getPosition());
|
||||
PositionAssert.assertPositionEquals(p1, compactFix.getPosition(), 0.000001);
|
||||
assertNotSame(swb, compactFix.getSpeed());
|
||||
|
||||
+13
-13
@@ -193,11 +193,11 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
getTrackedRace().recordFix(
|
||||
hunger,
|
||||
new GPSFixMovingImpl(offsetMarkPos, timePointInReaching, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(270))));
|
||||
new DegreeBearingImpl(270)), /* optionalTrueHeading */ null));
|
||||
getTrackedRace().recordFix(
|
||||
plattner,
|
||||
new GPSFixMovingImpl(windwardMarkPos, timePointInReaching, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(270))));
|
||||
new DegreeBearingImpl(270)), /* optionalTrueHeading */ null));
|
||||
assertEquals(0.,
|
||||
getTrackedRace().getTrack(hunger).getEstimatedPosition(timePointInReaching, /* extrapolate */false)
|
||||
.getDistance(offsetMarkPos).getMeters(), 0.00001);
|
||||
@@ -223,11 +223,11 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
getTrackedRace().recordFix(
|
||||
hunger,
|
||||
new GPSFixMovingImpl(offsetMarkPos, timePointInReaching, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(270))));
|
||||
new DegreeBearingImpl(270)), /* optionalTrueHeading */ null));
|
||||
getTrackedRace().recordFix(
|
||||
plattner,
|
||||
new GPSFixMovingImpl(windwardMarkPos, timePointInReaching, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(270))));
|
||||
new DegreeBearingImpl(270)), /* optionalTrueHeading */ null));
|
||||
assertEquals(0.,
|
||||
getTrackedRace().getTrack(hunger).getEstimatedPosition(timePointInReaching, /* extrapolate */false)
|
||||
.getDistance(offsetMarkPos).getMeters(), 0.00001);
|
||||
@@ -253,11 +253,11 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
getTrackedRace().recordFix(
|
||||
hunger,
|
||||
new GPSFixMovingImpl(offsetMarkPos, timePointInReaching, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(270))));
|
||||
new DegreeBearingImpl(270)), /* optionalTrueHeading */ null));
|
||||
getTrackedRace().recordFix(
|
||||
plattner,
|
||||
new GPSFixMovingImpl(windwardMarkPos, timePointInReaching, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(270))));
|
||||
new DegreeBearingImpl(270)), /* optionalTrueHeading */ null));
|
||||
assertEquals(0.,
|
||||
getTrackedRace().getTrack(hunger).getEstimatedPosition(timePointInReaching, /* extrapolate */false)
|
||||
.getDistance(offsetMarkPos).getMeters(), 0.00001);
|
||||
@@ -288,11 +288,11 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
getTrackedRace().recordFix(
|
||||
hunger,
|
||||
new GPSFixMovingImpl(offsetMarkPos, timePointToConsider, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(270))));
|
||||
new DegreeBearingImpl(270)), /* optionalTrueHeading */ null));
|
||||
getTrackedRace().recordFix(
|
||||
plattner,
|
||||
new GPSFixMovingImpl(leewardPos, timePointToConsider, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(0))));
|
||||
new DegreeBearingImpl(0)), /* optionalTrueHeading */ null));
|
||||
assertEquals(0.,
|
||||
getTrackedRace().getTrack(hunger).getEstimatedPosition(timePointToConsider, /* extrapolate */false)
|
||||
.getDistance(offsetMarkPos).getMeters(), 0.00001);
|
||||
@@ -326,17 +326,17 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
getTrackedRace().recordFix(
|
||||
hunger,
|
||||
new GPSFixMovingImpl(offsetMarkPos, timePointToConsider, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(270))));
|
||||
new DegreeBearingImpl(270)), /* optionalTrueHeading */ null));
|
||||
getTrackedRace().recordFix(
|
||||
schomaeker,
|
||||
new GPSFixMovingImpl(offsetMarkPos.translateGreatCircle(
|
||||
offsetMarkPos.getBearingGreatCircle(leewardPos), offsetMarkPos.getDistance(leewardPos)
|
||||
.scale(0.5)), timePointToConsider, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(180))));
|
||||
new DegreeBearingImpl(180)), /* optionalTrueHeading */ null));
|
||||
getTrackedRace().recordFix(
|
||||
plattner,
|
||||
new GPSFixMovingImpl(leewardPos, timePointToConsider, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(0))));
|
||||
new DegreeBearingImpl(0)), /* optionalTrueHeading */ null));
|
||||
assertEquals(0.,
|
||||
getTrackedRace().getTrack(hunger).getEstimatedPosition(timePointToConsider, /* extrapolate */false)
|
||||
.getDistance(offsetMarkPos).getMeters(), 0.00001);
|
||||
@@ -367,13 +367,13 @@ public class ReachingLegTest extends TrackBasedTest {
|
||||
hunger,
|
||||
new GPSFixMovingImpl(windwardMarkPos.translateGreatCircle(new DegreeBearingImpl(reachingLegBearing.getDegrees()-45),
|
||||
distanceOfReachingLeg.scale(1./Math.sqrt(2.))), timePointToConsider, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(270))));
|
||||
new DegreeBearingImpl(270)), /* optionalTrueHeading */ null));
|
||||
// Plattner turns right after the windward mark; both travel the same distance projected along the leg
|
||||
getTrackedRace().recordFix(
|
||||
plattner,
|
||||
new GPSFixMovingImpl(windwardMarkPos.translateGreatCircle(new DegreeBearingImpl(reachingLegBearing.getDegrees()+45),
|
||||
distanceOfReachingLeg.scale(1./Math.sqrt(2.))), timePointToConsider, new KnotSpeedWithBearingImpl(12,
|
||||
new DegreeBearingImpl(270))));
|
||||
new DegreeBearingImpl(270)), /* optionalTrueHeading */ null));
|
||||
// with 90deg separating them, traveling 1/sqrt(2) the distance of the leg should put them the distance of the leg apart geometrically
|
||||
assertEquals(
|
||||
distanceOfReachingLeg.getMeters(),
|
||||
|
||||
+1
-1
@@ -124,7 +124,7 @@ public abstract class StoredTrackBasedTest extends TrackBasedTest {
|
||||
TimePoint timePoint = new MillisecondsTimePoint(oi.readLong());
|
||||
Position position = new DegreePosition(oi.readDouble(), oi.readDouble());
|
||||
SpeedWithBearing speedWithBearing = new KnotSpeedWithBearingImpl(oi.readDouble(), new DegreeBearingImpl(oi.readDouble()));
|
||||
return new GPSFixMovingImpl(position, timePoint, speedWithBearing);
|
||||
return new GPSFixMovingImpl(position, timePoint, speedWithBearing, /* optionalTrueHeading */ null); // legacy fixes only; no need to worry about true heading
|
||||
}
|
||||
|
||||
protected void storeTrack(Competitor competitor, Boat boat, DynamicGPSFixTrack<Competitor, GPSFixMoving> track, String regattaName)
|
||||
|
||||
@@ -67,7 +67,7 @@ public class TackTest extends StoredTrackBasedTestWithTrackedRace {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> hassosTrack = getTrackedRace().getTrack(competitor);
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
hassosTrack.addGPSFix(new GPSFixMovingImpl(new DegreePosition(54.4680424, 10.234451), now,
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(45))));
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(45)), /* optionalTrueHeading */ null));
|
||||
assertEquals(Tack.PORT, getTrackedRace().getTack(competitor, now));
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public class TackTest extends StoredTrackBasedTestWithTrackedRace {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> hassosTrack = getTrackedRace().getTrack(competitor);
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
hassosTrack.addGPSFix(new GPSFixMovingImpl(new DegreePosition(54.4680424, 10.234451), now,
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(270))));
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(270)), /* optionalTrueHeading */ null));
|
||||
assertEquals(Tack.STARBOARD, getTrackedRace().getTack(competitor, now));
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ public class TackTest extends StoredTrackBasedTestWithTrackedRace {
|
||||
DynamicGPSFixTrack<Competitor, GPSFixMoving> hassosTrack = getTrackedRace().getTrack(competitor);
|
||||
TimePoint now = MillisecondsTimePoint.now();
|
||||
hassosTrack.addGPSFix(new GPSFixMovingImpl(new DegreePosition(54.4680424, 10.234451), now,
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(180))));
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(180)), /* optionalTrueHeading */ null));
|
||||
assertEquals(Tack.PORT, getTrackedRace().getTack(competitor, now));
|
||||
}
|
||||
|
||||
|
||||
@@ -85,25 +85,25 @@ public class TrackTest {
|
||||
gpsFix1 = new GPSFixMovingImpl(
|
||||
position1, now1, new KnotSpeedWithBearingImpl(position1.getDistance(position2)
|
||||
.inTime(now2.asMillis() - now1.asMillis()).getKnots(),
|
||||
new DegreeBearingImpl(90)));
|
||||
new DegreeBearingImpl(90)), /* optionalTrueHeading */ null);
|
||||
gpsFix2 = new GPSFixMovingImpl(position2, now2, new KnotSpeedWithBearingImpl(position1.getDistance(position2)
|
||||
.inTime(now2.asMillis() - gpsFix1.getTimePoint().asMillis()).getKnots(), new DegreeBearingImpl(90)));
|
||||
.inTime(now2.asMillis() - gpsFix1.getTimePoint().asMillis()).getKnots(), new DegreeBearingImpl(90)), /* optionalTrueHeading */ null);
|
||||
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)));
|
||||
new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
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)));
|
||||
new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
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)));
|
||||
.inTime(now5.asMillis() - gpsFix4.getTimePoint().asMillis()).getKnots(), new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(gpsFix1);
|
||||
track.addGPSFix(gpsFix2);
|
||||
track.addGPSFix(gpsFix3);
|
||||
@@ -136,8 +136,8 @@ public class TrackTest {
|
||||
DegreePosition p2 = new DegreePosition(90, 0);
|
||||
TimePoint t1 = MillisecondsTimePoint.now();
|
||||
TimePoint t2 = t1.plus(30);
|
||||
gpsFix1 = new GPSFixMovingImpl(p1, t1, new KnotSpeedWithBearingImpl(0, new DegreeBearingImpl(0)));
|
||||
gpsFix2 = new GPSFixMovingImpl(p2, t2, new KnotSpeedWithBearingImpl(0, new DegreeBearingImpl(0)));
|
||||
gpsFix1 = new GPSFixMovingImpl(p1, t1, new KnotSpeedWithBearingImpl(0, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
gpsFix2 = new GPSFixMovingImpl(p2, t2, new KnotSpeedWithBearingImpl(0, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(gpsFix1);
|
||||
track.addGPSFix(gpsFix2);
|
||||
track.lockForRead();
|
||||
@@ -246,7 +246,7 @@ public class TrackTest {
|
||||
TimePoint start, Position pos, SpeedWithBearing speed, int numberOfFixes) {
|
||||
TimePoint now = start;
|
||||
for (int i = 0; i < numberOfFixes; i++) {
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(pos, now, speed);
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(pos, now, speed, /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix1);
|
||||
now = now.plus(1000);
|
||||
}
|
||||
@@ -299,7 +299,7 @@ public class TrackTest {
|
||||
}
|
||||
};
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(0), new KnotSpeedWithBearingImpl(
|
||||
1, new DegreeBearingImpl(123)));
|
||||
1, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix1);
|
||||
// The following getMaximumSpeedOverGround call will trigger a computeMaxSpeed(...) and a cache(...) call
|
||||
new Thread(()->
|
||||
@@ -308,17 +308,17 @@ public class TrackTest {
|
||||
// now don't release the cacheBarrier as yet but add more fixes
|
||||
new Thread(() -> {
|
||||
GPSFixMoving fix2 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(3600000),
|
||||
new KnotSpeedWithBearingImpl(2, new DegreeBearingImpl(123)));
|
||||
new KnotSpeedWithBearingImpl(2, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix2);
|
||||
}).start();
|
||||
new Thread(() -> {
|
||||
GPSFixMoving fix3 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(7200000),
|
||||
new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(123)));
|
||||
new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix3);
|
||||
}).start();
|
||||
new Thread(() -> {
|
||||
GPSFixMoving fix4 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(10800000),
|
||||
new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(123)));
|
||||
new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix4);
|
||||
}).start();
|
||||
cacheBarrier.await(); // releasing the creation of the cache entry from way above; this would now add a stale entry
|
||||
@@ -375,18 +375,18 @@ public class TrackTest {
|
||||
public void testMaxSpeedForMovingTrackWithFixAtIntervalBoundary() {
|
||||
DynamicGPSFixMovingTrackImpl<Object> track = new DynamicGPSFixMovingTrackImpl<Object>(new Object(), /* millisecondsOverWhichToAverage */ 30000l);
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(0), new KnotSpeedWithBearingImpl(
|
||||
1, new DegreeBearingImpl(123)));
|
||||
1, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix1);
|
||||
GPSFixMoving fix2 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(3600000), new KnotSpeedWithBearingImpl(
|
||||
2, new DegreeBearingImpl(123)));
|
||||
2, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix2);
|
||||
GPSFixMoving fix3 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(7200000), new KnotSpeedWithBearingImpl(
|
||||
1, new DegreeBearingImpl(123)));
|
||||
1, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix3);
|
||||
assertEquals(2., track.getMaximumSpeedOverGround(new MillisecondsTimePoint(0), new MillisecondsTimePoint(7200000)).
|
||||
getB().getKnots(), 0.01); // produces a cache entry that ends
|
||||
GPSFixMoving fix4 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(10800000), new KnotSpeedWithBearingImpl(
|
||||
1, new DegreeBearingImpl(123)));
|
||||
1, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix4);
|
||||
assertEquals(2., track.getMaximumSpeedOverGround(new MillisecondsTimePoint(0), new MillisecondsTimePoint(10800000)).
|
||||
getB().getKnots(), 0.01);
|
||||
@@ -396,9 +396,9 @@ public class TrackTest {
|
||||
public void testMaxSpeedForFixOverwrittenWithLowerSpeed() {
|
||||
DynamicGPSFixMovingTrackImpl<Object> track = new DynamicGPSFixMovingTrackImpl<Object>(new Object(), /* millisecondsOverWhichToAverage */ 30000l);
|
||||
GPSFixMoving slow = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(3600000), new KnotSpeedWithBearingImpl(
|
||||
1, new DegreeBearingImpl(123)));
|
||||
1, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fast = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(3600000), new KnotSpeedWithBearingImpl(
|
||||
2, new DegreeBearingImpl(123)));
|
||||
2, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fast);
|
||||
assertEquals(2., track.getMaximumSpeedOverGround(new MillisecondsTimePoint(0), new MillisecondsTimePoint(10800000)).
|
||||
getB().getKnots(), 0.01);
|
||||
@@ -417,18 +417,18 @@ public class TrackTest {
|
||||
public void testMaxSpeedForMovingTrackWithFixAtIntervalBoundaryAfterQuery() {
|
||||
DynamicGPSFixMovingTrackImpl<Object> track = new DynamicGPSFixMovingTrackImpl<Object>(new Object(), /* millisecondsOverWhichToAverage */ 30000l);
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(0), new KnotSpeedWithBearingImpl(
|
||||
1, new DegreeBearingImpl(123)));
|
||||
1, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix1);
|
||||
GPSFixMoving fix2 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(3600000), new KnotSpeedWithBearingImpl(
|
||||
2, new DegreeBearingImpl(123)));
|
||||
2, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix2);
|
||||
assertEquals(2., track.getMaximumSpeedOverGround(new MillisecondsTimePoint(0), new MillisecondsTimePoint(7200000)).
|
||||
getB().getKnots(), 0.01); // produces a cache entry that ends
|
||||
GPSFixMoving fix3 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(7200000), new KnotSpeedWithBearingImpl(
|
||||
1, new DegreeBearingImpl(123)));
|
||||
1, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix3);
|
||||
GPSFixMoving fix4 = new GPSFixMovingImpl(new DegreePosition(0, 0), new MillisecondsTimePoint(10800000), new KnotSpeedWithBearingImpl(
|
||||
1, new DegreeBearingImpl(123)));
|
||||
1, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix4);
|
||||
assertEquals(2., track.getMaximumSpeedOverGround(new MillisecondsTimePoint(0), new MillisecondsTimePoint(10800000)).
|
||||
getB().getKnots(), 0.01);
|
||||
@@ -489,9 +489,9 @@ public class TrackTest {
|
||||
TimePoint t1 = new MillisecondsTimePoint(1000);
|
||||
TimePoint t2 = new MillisecondsTimePoint(2000);
|
||||
TimePoint t3 = new MillisecondsTimePoint(3000);
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(1./3600.*1./60., 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(2./3600.*1./60., 0), t2, new KnotSpeedWithBearingImpl(150, new DegreeBearingImpl(0))); // outrageous speed; to be ignored by getEstimatedSpeed
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(3./3600.*1./60., 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(1./3600.*1./60., 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(2./3600.*1./60., 0), t2, new KnotSpeedWithBearingImpl(150, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null); // outrageous speed; to be ignored by getEstimatedSpeed
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(3./3600.*1./60., 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(f1);
|
||||
track.addGPSFix(f2);
|
||||
track.addGPSFix(f3);
|
||||
@@ -504,9 +504,9 @@ public class TrackTest {
|
||||
TimePoint t1 = new MillisecondsTimePoint(1000);
|
||||
TimePoint t2 = new MillisecondsTimePoint(2000);
|
||||
TimePoint t3 = new MillisecondsTimePoint(3000);
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(1./3600.*1./60., 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(150./3600.*1./60., 0), t2, new KnotSpeedWithBearingImpl(150, new DegreeBearingImpl(0))); // outrageous speed; to be ignored by getEstimatedSpeed
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(3./3600.*1./60., 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(1./3600.*1./60., 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(150./3600.*1./60., 0), t2, new KnotSpeedWithBearingImpl(150, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null); // outrageous speed; to be ignored by getEstimatedSpeed
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(3./3600.*1./60., 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(f1);
|
||||
track.addGPSFix(f2);
|
||||
track.addGPSFix(f3);
|
||||
@@ -519,9 +519,9 @@ public class TrackTest {
|
||||
TimePoint t1 = new MillisecondsTimePoint(1000);
|
||||
TimePoint t2 = new MillisecondsTimePoint(2000);
|
||||
TimePoint t3 = new MillisecondsTimePoint(3000);
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(1./3600.*1./60., 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(2./3600.*1./60., 0), t2, new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(0))); // outrageous speed; to be ignored by getEstimatedSpeed
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(3./3600.*1./60., 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(1./3600.*1./60., 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(2./3600.*1./60., 0), t2, new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null); // outrageous speed; to be ignored by getEstimatedSpeed
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(3./3600.*1./60., 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(f1);
|
||||
track.addGPSFix(f2);
|
||||
track.addGPSFix(f3);
|
||||
@@ -535,9 +535,9 @@ public class TrackTest {
|
||||
TimePoint t1 = new MillisecondsTimePoint(1000);
|
||||
TimePoint t2 = new MillisecondsTimePoint(2000);
|
||||
TimePoint t3 = new MillisecondsTimePoint(3000);
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(1./3600.*1./60., 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(2./3600.*1./60., 0), t2, new KnotSpeedWithBearingImpl(150, new DegreeBearingImpl(0))); // outrageous speed; to be ignored by getEstimatedSpeed
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(3./3600.*1./60., 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(1./3600.*1./60., 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(2./3600.*1./60., 0), t2, new KnotSpeedWithBearingImpl(150, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null); // outrageous speed; to be ignored by getEstimatedSpeed
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(3./3600.*1./60., 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(f1);
|
||||
track.addGPSFix(f2);
|
||||
track.addGPSFix(f3);
|
||||
@@ -552,9 +552,9 @@ public class TrackTest {
|
||||
TimePoint t1 = new MillisecondsTimePoint(1000);
|
||||
TimePoint t2 = new MillisecondsTimePoint(2000);
|
||||
TimePoint t3 = new MillisecondsTimePoint(3000);
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(0, 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(45)));
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(0.00001, 0.00001), t2, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)));
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(0.00002, 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(315)));
|
||||
GPSFixMoving f1 = new GPSFixMovingImpl(new DegreePosition(0, 0), t1, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(45)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving f2 = new GPSFixMovingImpl(new DegreePosition(0.00001, 0.00001), t2, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving f3 = new GPSFixMovingImpl(new DegreePosition(0.00002, 0), t3, new KnotSpeedWithBearingImpl(1, new DegreeBearingImpl(315)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(f1);
|
||||
track.addGPSFix(f2);
|
||||
track.addGPSFix(f3);
|
||||
@@ -582,7 +582,7 @@ public class TrackTest {
|
||||
// now add a fix:
|
||||
TimePoint now6 = addMillisToTimepoint(gpsFix5.getTimePoint(), 3);
|
||||
track.addGPSFix(new GPSFixMovingImpl(
|
||||
new DegreePosition(6, 5), now6, new KnotSpeedWithBearingImpl(2, new DegreeBearingImpl(0))));
|
||||
new DegreePosition(6, 5), now6, new KnotSpeedWithBearingImpl(2, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null));
|
||||
try {
|
||||
GPSFixMoving secondOfSubset = subsetIter.next();
|
||||
PositionAssert.assertGPSFixEquals(gpsFix3, secondOfSubset, /* pos deg delta */ 0.000001, /* bearing deg delta */ 0.01, /* knot delta */ 0.01);
|
||||
@@ -903,7 +903,7 @@ public class TrackTest {
|
||||
TimePoint next = null;
|
||||
GPSFixMoving fix = null;
|
||||
for (int i=0; i<steps; i++) {
|
||||
fix = new GPSFixMovingImpl(p, start, speed);
|
||||
fix = new GPSFixMovingImpl(p, start, speed, /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix);
|
||||
next = start.plus(timeBetweenFixesInMillis);
|
||||
p = p.translateGreatCircle(bearing, speed.travel(start, next));
|
||||
@@ -918,7 +918,7 @@ public class TrackTest {
|
||||
assertEquals(distance1, distance3); // no progress after time point "next" because no further fixes are known
|
||||
assertEquals(distance1, distance4); // no progress after time point "next" because no further fixes are known
|
||||
// now add one more fix
|
||||
fix = new GPSFixMovingImpl(p, start, speed);
|
||||
fix = new GPSFixMovingImpl(p, start, speed, /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(fix);
|
||||
Distance distance1_new = track.getDistanceTraveled(now, next.minus(timeBetweenFixesInMillis));
|
||||
Distance distance2_new = track.getDistanceTraveled(now, next.minus(2*timeBetweenFixesInMillis/3));
|
||||
@@ -1065,7 +1065,7 @@ public class TrackTest {
|
||||
SpeedWithBearing estimatedSpeed = track.getEstimatedSpeed(normalFixesTime);
|
||||
GPSFixMovingImpl gpsFixFarInTheFuture = new GPSFixMovingImpl(
|
||||
new DegreePosition(89, 180), new MillisecondsTimePoint(
|
||||
System.currentTimeMillis()+10000000l), new KnotSpeedWithBearingImpl(200000, new DegreeBearingImpl(0)));
|
||||
System.currentTimeMillis()+10000000l), new KnotSpeedWithBearingImpl(200000, new DegreeBearingImpl(0)), /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(gpsFixFarInTheFuture);
|
||||
Position estimatedPosNew = track.getEstimatedPosition(normalFixesTime, /* extrapolate */ false);
|
||||
// expecting to get the coordinates of gpsFix2's position
|
||||
@@ -1084,8 +1084,8 @@ public class TrackTest {
|
||||
AbstractBearing bearing = new DegreeBearingImpl(90);
|
||||
Position position1 = new DegreePosition(1, 2);
|
||||
Position position2 = position1.translateGreatCircle(bearing, new MeterDistance(1));
|
||||
GPSFixMovingImpl myGpsFix1 = new GPSFixMovingImpl(position1, now1, new MeterPerSecondSpeedWithDegreeBearingImpl(1, bearing));
|
||||
GPSFixMovingImpl myGpsFix2 = new GPSFixMovingImpl(position2, now2, new MeterPerSecondSpeedWithDegreeBearingImpl(1, bearing));
|
||||
GPSFixMovingImpl myGpsFix1 = new GPSFixMovingImpl(position1, now1, new MeterPerSecondSpeedWithDegreeBearingImpl(1, bearing), /* optionalTrueHeading */ null);
|
||||
GPSFixMovingImpl myGpsFix2 = new GPSFixMovingImpl(position2, now2, new MeterPerSecondSpeedWithDegreeBearingImpl(1, bearing), /* optionalTrueHeading */ null);
|
||||
myTrack.addGPSFix(myGpsFix1);
|
||||
myTrack.addGPSFix(myGpsFix2);
|
||||
myTrack.lockForRead();
|
||||
@@ -1105,8 +1105,8 @@ public class TrackTest {
|
||||
AbstractBearing bearing = new DegreeBearingImpl(90);
|
||||
Position position1 = new DegreePosition(1, 2);
|
||||
Position position2 = position1.translateGreatCircle(bearing, new MeterDistance(1));
|
||||
GPSFixMovingImpl myGpsFix1 = new GPSFixMovingImpl(position1, now1, new MeterPerSecondSpeedWithDegreeBearingImpl(10, bearing));
|
||||
GPSFixMovingImpl myGpsFix2 = new GPSFixMovingImpl(position2, now2, new MeterPerSecondSpeedWithDegreeBearingImpl(10, bearing));
|
||||
GPSFixMovingImpl myGpsFix1 = new GPSFixMovingImpl(position1, now1, new MeterPerSecondSpeedWithDegreeBearingImpl(10, bearing), /* optionalTrueHeading */ null);
|
||||
GPSFixMovingImpl myGpsFix2 = new GPSFixMovingImpl(position2, now2, new MeterPerSecondSpeedWithDegreeBearingImpl(10, bearing), /* optionalTrueHeading */ null);
|
||||
myTrack.addGPSFix(myGpsFix1);
|
||||
myTrack.addGPSFix(myGpsFix2);
|
||||
myTrack.lockForRead();
|
||||
@@ -1126,8 +1126,8 @@ public class TrackTest {
|
||||
AbstractBearing bearing = new DegreeBearingImpl(90);
|
||||
Position position1 = new DegreePosition(1, 2);
|
||||
Position position2 = position1.translateGreatCircle(bearing, new MeterDistance(1));
|
||||
GPSFixMovingImpl myGpsFix1 = new GPSFixMovingImpl(position1, now1, new MeterPerSecondSpeedWithDegreeBearingImpl(0.1, bearing));
|
||||
GPSFixMovingImpl myGpsFix2 = new GPSFixMovingImpl(position2, now2, new MeterPerSecondSpeedWithDegreeBearingImpl(0.1, bearing));
|
||||
GPSFixMovingImpl myGpsFix1 = new GPSFixMovingImpl(position1, now1, new MeterPerSecondSpeedWithDegreeBearingImpl(0.1, bearing), /* optionalTrueHeading */ null);
|
||||
GPSFixMovingImpl myGpsFix2 = new GPSFixMovingImpl(position2, now2, new MeterPerSecondSpeedWithDegreeBearingImpl(0.1, bearing), /* optionalTrueHeading */ null);
|
||||
myTrack.addGPSFix(myGpsFix1);
|
||||
myTrack.addGPSFix(myGpsFix2);
|
||||
myTrack.lockForRead();
|
||||
@@ -1155,7 +1155,7 @@ public class TrackTest {
|
||||
TimePoint slightlyBeforeFirstFix = firstFixSoFar.getTimePoint().minus(timespan);
|
||||
Position newPosition = firstFixSoFar.getPosition().translateGreatCircle(speed.getBearing().reverse(),
|
||||
speed.travel(firstFixSoFar.getTimePoint(), firstFixSoFar.getTimePoint().plus(timespan)));
|
||||
GPSFixMoving newFirstFix = new GPSFixMovingImpl(newPosition, slightlyBeforeFirstFix, speed);
|
||||
GPSFixMoving newFirstFix = new GPSFixMovingImpl(newPosition, slightlyBeforeFirstFix, speed, /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(newFirstFix);
|
||||
TimeRange intervalAffected = track.getEstimatedPositionTimePeriodAffectedBy(newFirstFix);
|
||||
Position newPositionAtBeginningOfTime = track.getEstimatedPosition(beginningOfTime, /* extrapolate */false);
|
||||
@@ -1174,7 +1174,7 @@ public class TrackTest {
|
||||
TimePoint slightlyAfterLastFix = lastFixSoFar.getTimePoint().plus(timespan);
|
||||
Position newPosition = lastFixSoFar.getPosition().translateGreatCircle(speed.getBearing(),
|
||||
speed.travel(lastFixSoFar.getTimePoint(), lastFixSoFar.getTimePoint().plus(timespan)));
|
||||
GPSFixMoving newLastFix = new GPSFixMovingImpl(newPosition, slightlyAfterLastFix, speed);
|
||||
GPSFixMoving newLastFix = new GPSFixMovingImpl(newPosition, slightlyAfterLastFix, speed, /* optionalTrueHeading */ null);
|
||||
track.addGPSFix(newLastFix);
|
||||
TimeRange intervalAffected = track.getEstimatedPositionTimePeriodAffectedBy(newLastFix);
|
||||
Position newPositionAtEndOfTime = track.getEstimatedPosition(endOfTime, /* extrapolate */false);
|
||||
@@ -1192,7 +1192,7 @@ public class TrackTest {
|
||||
Position positionAtEndOfTime = myTrack.getEstimatedPosition(endOfTime, /* extrapolate */false);
|
||||
assertNull(positionAtBeginningOfTime);
|
||||
assertNull(positionAtEndOfTime);
|
||||
GPSFixMoving newFix = new GPSFixMovingImpl(new DegreePosition(12, 34), now, new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)));
|
||||
GPSFixMoving newFix = new GPSFixMovingImpl(new DegreePosition(12, 34), now, new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
myTrack.addGPSFix(newFix);
|
||||
TimeRange intervalAffected = myTrack.getEstimatedPositionTimePeriodAffectedBy(newFix);
|
||||
Position newPositionAtBeginningOfTime = myTrack.getEstimatedPosition(beginningOfTime, /* extrapolate */false);
|
||||
@@ -1273,7 +1273,7 @@ public class TrackTest {
|
||||
TimePoint timePoint = new MillisecondsTimePoint(dateFormatter.parse(isoDateTime));
|
||||
Position position = new DegreePosition(lat, lng);
|
||||
SpeedWithBearing speed = new KnotSpeedWithBearingImpl(knotSpeed, new DegreeBearingImpl(bearingDeg));
|
||||
GPSFixMoving fix = new GPSFixMovingImpl(position, timePoint, speed);
|
||||
GPSFixMoving fix = new GPSFixMovingImpl(position, timePoint, speed, /* optionalTrueHeading */ null);
|
||||
return fix;
|
||||
}
|
||||
|
||||
@@ -1286,7 +1286,7 @@ public class TrackTest {
|
||||
@Test
|
||||
public void testEstimatedSpeedCaching() throws CompactionNotPossibleException {
|
||||
GPSFixMoving originalFix = new GPSFixMovingImpl(new DegreePosition(12, 34), MillisecondsTimePoint.now(),
|
||||
new KnotSpeedWithBearingImpl(9, new DegreeBearingImpl(123)));
|
||||
new KnotSpeedWithBearingImpl(9, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix = new VeryCompactGPSFixMovingImpl(originalFix);
|
||||
assertFalse(fix.isEstimatedSpeedCached());
|
||||
final KnotSpeedWithBearingImpl estimatedSpeed = new KnotSpeedWithBearingImpl(9.1, new DegreeBearingImpl(124));
|
||||
@@ -1309,7 +1309,7 @@ public class TrackTest {
|
||||
/* bearing deg delta */ 0.1, /* knot speed delta */ 0.1); // fetch again from the cache
|
||||
// assuming that all test fixes are within a few milliseconds and the averaging interval is much larger than that,
|
||||
// adding a single fix in the middle should invalidate the cache
|
||||
track.add(new GPSFixMovingImpl(gpsFix3.getPosition(), gpsFix3.getTimePoint().plus(1), gpsFix3.getSpeed()));
|
||||
track.add(new GPSFixMovingImpl(gpsFix3.getPosition(), gpsFix3.getTimePoint().plus(1), gpsFix3.getSpeed(), /* optionalTrueHeading */ null));
|
||||
assertFalse(compactFix3.isEstimatedSpeedCached());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ public class WindEstimationOnConstructedTracksTest extends StoredTrackBasedTest
|
||||
} finally {
|
||||
competitorTrack.unlockAfterRead();
|
||||
}
|
||||
competitorTrack.addGPSFix(new GPSFixMovingImpl(position, timePoint, speed));
|
||||
competitorTrack.addGPSFix(new GPSFixMovingImpl(position, timePoint, speed, /* optionalTrueHeading */ null));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -157,7 +157,7 @@ public abstract class AbstractExportedPositionsBasedTest {
|
||||
GPSFixMoving fix = new GPSFixMovingImpl(new DegreePosition((Double) fixAsJson.get("lat-deg"), (Double) fixAsJson.get("lng-deg")),
|
||||
new MillisecondsTimePoint((Long) fixAsJson.get("timepoint-ms")),
|
||||
new KnotSpeedWithBearingImpl((Double) fixAsJson.get("speed-kts"),
|
||||
new DegreeBearingImpl((Double) fixAsJson.get("truebearing-deg"))));
|
||||
new DegreeBearingImpl((Double) fixAsJson.get("truebearing-deg"))), /* optionalTrueHeading */ null);
|
||||
fixes.add(fix);
|
||||
}
|
||||
result.put(competitor, fixes);
|
||||
|
||||
+1
-1
@@ -104,6 +104,6 @@ public class MarkPassingCalculatorPerformanceTest extends AbstractMockedRaceMark
|
||||
0.0002 - rnd.nextDouble() * 0.0004);
|
||||
final TimePoint p = new MillisecondsTimePoint((long) (rnd.nextDouble() * 200000));
|
||||
final SpeedWithBearing speed = new KnotSpeedWithBearingImpl(rnd.nextInt(11), new DegreeBearingImpl(rnd.nextInt(360)));
|
||||
return new GPSFixMovingImpl(position, p, speed);
|
||||
return new GPSFixMovingImpl(position, p, speed, /* optionalTrueHeading */ null);
|
||||
}
|
||||
}
|
||||
|
||||
+25
-25
@@ -41,13 +41,13 @@ public class MarkPassingWhiteBoxTest extends AbstractMockedRaceMarkPassingTest {
|
||||
public void testNormalPassingAndSuppressingPassings() {
|
||||
// Normal Passing of Single mark
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(new DegreePosition(0.000003, 0.000049), new MillisecondsTimePoint(
|
||||
40000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(330)));
|
||||
40000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(330)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix2 = new GPSFixMovingImpl(new DegreePosition(0.000062, 0.000029), new MillisecondsTimePoint(
|
||||
44000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(270)));
|
||||
44000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(270)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix3 = new GPSFixMovingImpl(new DegreePosition(0.000026, -0.000024), new MillisecondsTimePoint(
|
||||
47000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(225)));
|
||||
47000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(225)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix4 = new GPSFixMovingImpl(new DegreePosition(-0.000056, -0.000049), new MillisecondsTimePoint(
|
||||
50000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(190)));
|
||||
50000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(190)), /* optionalTrueHeading */ null);
|
||||
race.recordFix(ron, fix1);
|
||||
race.recordFix(ron, fix2);
|
||||
CandidateFinder finder = new CandidateFinderImpl(race);
|
||||
@@ -85,11 +85,11 @@ public class MarkPassingWhiteBoxTest extends AbstractMockedRaceMarkPassingTest {
|
||||
public void testDistance() {
|
||||
// 3 fixes all on one side of crossing Bearing, therefore no XTE-Candidate
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(new DegreePosition(-0.000155, 0.000103), new MillisecondsTimePoint(
|
||||
60000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(330)));
|
||||
60000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(330)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix2 = new GPSFixMovingImpl(new DegreePosition(0.000038, 0.000021), new MillisecondsTimePoint(
|
||||
65000), new KnotSpeedWithBearingImpl(4, new DegreeBearingImpl(280)));
|
||||
65000), new KnotSpeedWithBearingImpl(4, new DegreeBearingImpl(280)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix3 = new GPSFixMovingImpl(new DegreePosition(-0.000268, 0.000135), new MillisecondsTimePoint(
|
||||
80000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(170)));
|
||||
80000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(170)), /* optionalTrueHeading */ null);
|
||||
CandidateFinderImpl finder = new CandidateFinderImpl(race);
|
||||
|
||||
race.recordFix(tom, fix1);
|
||||
@@ -115,13 +115,13 @@ public class MarkPassingWhiteBoxTest extends AbstractMockedRaceMarkPassingTest {
|
||||
public void testPastGate() {
|
||||
// Competitor sails closely past one mark of gate and rounds the other mark further away
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(new DegreePosition(-0.000967, -0.000124), new MillisecondsTimePoint(
|
||||
100000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(100)));
|
||||
100000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix2 = new GPSFixMovingImpl(new DegreePosition(-0.000989, -0.000001), new MillisecondsTimePoint(
|
||||
110000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(160)));
|
||||
110000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(160)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix3 = new GPSFixMovingImpl(new DegreePosition(-0.001079, 0.000045), new MillisecondsTimePoint(
|
||||
115000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(90)));
|
||||
115000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(90)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix4 = new GPSFixMovingImpl(new DegreePosition(-0.000982, 0.000143), new MillisecondsTimePoint(
|
||||
125000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(45)));
|
||||
125000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(45)), /* optionalTrueHeading */ null);
|
||||
CandidateFinderImpl finder = new CandidateFinderImpl(race);
|
||||
race.recordFix(tom, fix1);
|
||||
race.recordFix(tom, fix2);
|
||||
@@ -157,9 +157,9 @@ public class MarkPassingWhiteBoxTest extends AbstractMockedRaceMarkPassingTest {
|
||||
public void testGateAfterLine() {
|
||||
// The problem of passing a gate right after the start line is crossed, solved by the distance estimation
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(new DegreePosition(-0.001051, -0.000008), new MillisecondsTimePoint(
|
||||
10000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(5)));
|
||||
10000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(5)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix2 = new GPSFixMovingImpl(new DegreePosition(-0.000942, 0.000022), new MillisecondsTimePoint(
|
||||
14000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(15)));
|
||||
14000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(15)), /* optionalTrueHeading */ null);
|
||||
race.recordFix(tom, fix1);
|
||||
race.recordFix(tom, fix2);
|
||||
Candidate c1 = new CandidateImpl(1, new MillisecondsTimePoint(11000), 0.99, waypoints.get(0));
|
||||
@@ -181,15 +181,15 @@ public class MarkPassingWhiteBoxTest extends AbstractMockedRaceMarkPassingTest {
|
||||
public void testSailingInFrontAndAroundMark() {
|
||||
CandidateFinder finder = new CandidateFinderImpl(race);
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(new DegreePosition(-0.000037, -0.000126), new MillisecondsTimePoint(
|
||||
40000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(80)));
|
||||
40000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(80)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix2 = new GPSFixMovingImpl(new DegreePosition(-0.000022, 0.000001), new MillisecondsTimePoint(
|
||||
43000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(45)));
|
||||
43000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(45)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix3 = new GPSFixMovingImpl(new DegreePosition(0.000018, 0.000038), new MillisecondsTimePoint(
|
||||
46000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(330)));
|
||||
46000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(330)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix4 = new GPSFixMovingImpl(new DegreePosition(0.000084, -0.000004), new MillisecondsTimePoint(
|
||||
49000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(260)));
|
||||
49000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(260)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix5 = new GPSFixMovingImpl(new DegreePosition(0.000054, -0.000153), new MillisecondsTimePoint(
|
||||
52000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(200)));
|
||||
52000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(200)), /* optionalTrueHeading */ null);
|
||||
race.recordFix(ben, fix1);
|
||||
race.recordFix(ben, fix2);
|
||||
race.recordFix(ben, fix3);
|
||||
@@ -208,15 +208,15 @@ public class MarkPassingWhiteBoxTest extends AbstractMockedRaceMarkPassingTest {
|
||||
|
||||
public void fixAndUnfixMarkPassing() {
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(new DegreePosition(-0.001027, -0.000001), new MillisecondsTimePoint(
|
||||
11000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(340)));
|
||||
11000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(340)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix2 = new GPSFixMovingImpl(new DegreePosition(-0.000396, -0.000602), new MillisecondsTimePoint(
|
||||
35000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(315)));
|
||||
35000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(315)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix3 = new GPSFixMovingImpl(new DegreePosition(0.000164, -0.000012), new MillisecondsTimePoint(
|
||||
60000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(90)));
|
||||
60000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(90)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix4 = new GPSFixMovingImpl(new DegreePosition(-0.000402, 0.00043), new MillisecondsTimePoint(
|
||||
85000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(135)));
|
||||
85000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(135)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix5 = new GPSFixMovingImpl(new DegreePosition(-0.001027, -0.000001), new MillisecondsTimePoint(
|
||||
115000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(90)));
|
||||
115000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(90)), /* optionalTrueHeading */ null);
|
||||
|
||||
race.recordFix(tom, fix1);
|
||||
race.recordFix(tom, fix2);
|
||||
@@ -259,9 +259,9 @@ public class MarkPassingWhiteBoxTest extends AbstractMockedRaceMarkPassingTest {
|
||||
@Test
|
||||
public void testAddingAndRemovingWaypointToFinder() {
|
||||
GPSFixMoving fix1 = new GPSFixMovingImpl(new DegreePosition(-0.00045, -0.00052), new MillisecondsTimePoint(
|
||||
40000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(200)));
|
||||
40000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(200)), /* optionalTrueHeading */ null);
|
||||
GPSFixMoving fix2 = new GPSFixMovingImpl(new DegreePosition(-0.0006, -0.00052),
|
||||
new MillisecondsTimePoint(44000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(160)));
|
||||
new MillisecondsTimePoint(44000), new KnotSpeedWithBearingImpl(5, new DegreeBearingImpl(160)), /* optionalTrueHeading */ null);
|
||||
|
||||
race.recordFix(ron, fix1);
|
||||
race.recordFix(ron, fix2);
|
||||
|
||||
+1
-1
@@ -245,7 +245,7 @@ public class MarkPassingRaceFingerprintJsonSerializationTest extends OnlineTracT
|
||||
Position pos = firstFix.getPosition();
|
||||
TimePoint tp = firstFix.getTimePoint();
|
||||
DegreePosition degPos = new DegreePosition(pos.getLatDeg() + 0.05, pos.getLngDeg() + 0.05);
|
||||
GPSFixMoving gpsM = new GPSFixMovingImpl(degPos, tp, speed);
|
||||
GPSFixMoving gpsM = new GPSFixMovingImpl(degPos, tp, speed, /* optionalTrueHeading */ null);
|
||||
testRace.getTrack(firstCompetitor).add(gpsM, true);
|
||||
MarkPassingRaceFingerprint fingerprint2 = factory.createFingerprint(testRace);
|
||||
assertFalse(fingerprint1.matches(testRace));
|
||||
|
||||
+5
-5
@@ -37,7 +37,7 @@ public class PositionInterpolationAndExtrapolationWithSpeedInfoTest extends Posi
|
||||
|
||||
@Test
|
||||
public void testFixBeforeNow() {
|
||||
final GPSFixMoving fixBeforeNow = new GPSFixMovingImpl(p1, now.minus(Duration.ONE_HOUR), speed);
|
||||
final GPSFixMoving fixBeforeNow = new GPSFixMovingImpl(p1, now.minus(Duration.ONE_HOUR), speed, /* optionalTrueHeading */ null);
|
||||
getTrack().add(fixBeforeNow);
|
||||
assertPos(p1, /* extrapolate */ false);
|
||||
assertPos(p1.translateGreatCircle(speed.getBearing(), speed.travel(now.minus(Duration.ONE_HOUR), now)), /* extrapolate */ true);
|
||||
@@ -45,7 +45,7 @@ public class PositionInterpolationAndExtrapolationWithSpeedInfoTest extends Posi
|
||||
|
||||
@Test
|
||||
public void testFixAfterNow() {
|
||||
GPSFixMoving fixAfterNow = new GPSFixMovingImpl(p1, now.plus(Duration.ONE_HOUR), speed);
|
||||
GPSFixMoving fixAfterNow = new GPSFixMovingImpl(p1, now.plus(Duration.ONE_HOUR), speed, /* optionalTrueHeading */ null);
|
||||
getTrack().add(fixAfterNow);
|
||||
assertPos(p1, /* extrapolate */ false);
|
||||
assertPos(p1.translateGreatCircle(speed.getBearing().reverse() /* travel backwards */, speed.travel(now.minus(Duration.ONE_HOUR), now)), /* extrapolate */ true);
|
||||
@@ -53,7 +53,7 @@ public class PositionInterpolationAndExtrapolationWithSpeedInfoTest extends Posi
|
||||
|
||||
@Test
|
||||
public void testExactMatch() {
|
||||
GPSFixMoving fixNow = new GPSFixMovingImpl(p1, now, speed);
|
||||
GPSFixMoving fixNow = new GPSFixMovingImpl(p1, now, speed, /* optionalTrueHeading */ null);
|
||||
getTrack().add(fixNow);
|
||||
assertPos(p1, /* extrapolate */ false);
|
||||
assertPos(p1, /* extrapolate */ true);
|
||||
@@ -61,9 +61,9 @@ public class PositionInterpolationAndExtrapolationWithSpeedInfoTest extends Posi
|
||||
|
||||
@Test
|
||||
public void testInBetween() {
|
||||
GPSFixMoving fixBeforeNow = new GPSFixMovingImpl(p1, now.minus(Duration.ONE_HOUR), speed);
|
||||
GPSFixMoving fixBeforeNow = new GPSFixMovingImpl(p1, now.minus(Duration.ONE_HOUR), speed, /* optionalTrueHeading */ null);
|
||||
getTrack().add(fixBeforeNow);
|
||||
GPSFixMoving fixAfterNow = new GPSFixMovingImpl(p2, now.plus(Duration.ONE_HOUR), speed);
|
||||
GPSFixMoving fixAfterNow = new GPSFixMovingImpl(p2, now.plus(Duration.ONE_HOUR), speed, /* optionalTrueHeading */ null);
|
||||
getTrack().add(fixAfterNow);
|
||||
Position middle = p1.translateGreatCircle(p1.getBearingGreatCircle(p2), p1.getDistance(p2).scale(0.5));
|
||||
assertPos(middle, /* extrapolate */ false);
|
||||
|
||||
+2
-1
@@ -187,7 +187,8 @@ public class DomainFactoryImpl implements DomainFactory {
|
||||
@Override
|
||||
public GPSFixMoving createGPSFixMoving(IPosition position) {
|
||||
GPSFixMoving result = new GPSFixMovingImpl(createPosition(position), new MillisecondsTimePoint(position.getTimestamp()),
|
||||
new KilometersPerHourSpeedWithBearingImpl(position.getSpeed(), new DegreeBearingImpl(position.getDirection())));
|
||||
new KilometersPerHourSpeedWithBearingImpl(position.getSpeed(), new DegreeBearingImpl(position.getDirection())),
|
||||
position.getTrueHeading() == null ? null : new DegreeBearingImpl(position.getTrueHeading()));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -344,7 +344,7 @@ public class Simulator {
|
||||
|
||||
private <T> void scheduleFixRecording(final T object, GPSFixMoving fix, final RecordGPSFix<T> recorder) {
|
||||
final TimePoint transformedTimepoint = advance(fix.getTimePoint());
|
||||
final GPSFixMoving transformedFix = new GPSFixMovingImpl(fix.getPosition(), transformedTimepoint, fix.getSpeed());
|
||||
final GPSFixMoving transformedFix = new GPSFixMovingImpl(fix.getPosition(), transformedTimepoint, fix.getSpeed(), fix.getOptionalTrueHeading());
|
||||
long waitTime = getWaitTimeInMillisUntil(transformedFix.getTimePoint());
|
||||
if (waitTime <= 0) {
|
||||
recorder.recordFix(object, transformedFix);
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ public class TeamPosition implements Timed {
|
||||
}
|
||||
|
||||
public GPSFixMoving getGPSFixMoving() {
|
||||
return new GPSFixMovingImpl(getPosition(), getTimePoint(), getMotionVector());
|
||||
return new GPSFixMovingImpl(getPosition(), getTimePoint(), getMotionVector(), /* optionalTrueHeading */ null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -207,7 +207,7 @@ implements TrackingDataLoader {
|
||||
for (final TeamPositions teamPositions : storedData.getTeams()) {
|
||||
progressCallback.ifPresent(cb->cb.accept((double) i[0]++ / numberOfTeams));
|
||||
for (final TeamPosition position : teamPositions.getPositions()) {
|
||||
final GPSFixMoving fix = new GPSFixMovingImpl(position.getPosition(), position.getTimePoint(), position.getMotionVector());
|
||||
final GPSFixMoving fix = new GPSFixMovingImpl(position.getPosition(), position.getTimePoint(), position.getMotionVector(), /* optionalTrueHeading */ null);
|
||||
final int deviceSerialNumber = teamPositions.getDeviceSerialNumber();
|
||||
trackedRace.getTrack(competitorByDeviceSerialNumber.get(deviceSerialNumber)).add(fix);
|
||||
updateTimePointOfLastFixPerDeviceSerialNumber(deviceSerialNumber, position.getTimePoint());
|
||||
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
package com.sap.sailing.domain.maneuverdetection.impl;
|
||||
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.Wind;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sailing.domain.maneuverdetection.GpsFixWithEstimationData;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.Distance;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Vladislav Chumak (D069712)
|
||||
*
|
||||
*/
|
||||
public class GpsFixWithEstimationDataImpl extends GPSFixMovingImpl implements GpsFixWithEstimationData {
|
||||
|
||||
private static final long serialVersionUID = -6952863819352430365L;
|
||||
|
||||
private Wind wind;
|
||||
private Bearing relativeBearingToNextMarkAfterManeuver;
|
||||
private Distance distanceToClosestMark;
|
||||
|
||||
public GpsFixWithEstimationDataImpl(Position position, TimePoint timePoint, SpeedWithBearing speedWithBearing,
|
||||
Wind wind, Bearing relativeBearingToNextMarkAfterManeuver, Distance distanceToClosestMark) {
|
||||
super(position, timePoint, speedWithBearing);
|
||||
this.wind = wind;
|
||||
this.relativeBearingToNextMarkAfterManeuver = relativeBearingToNextMarkAfterManeuver;
|
||||
this.distanceToClosestMark = distanceToClosestMark;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wind getWind() {
|
||||
return wind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bearing getRelativeBearingToNextMarkAfterManeuver() {
|
||||
return relativeBearingToNextMarkAfterManeuver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Distance getDistanceToClosestMark() {
|
||||
return distanceToClosestMark;
|
||||
}
|
||||
|
||||
}
|
||||
+16
-5
@@ -11,6 +11,7 @@ import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.logging.Level;
|
||||
@@ -71,7 +72,7 @@ public class MarkPassingCalculator {
|
||||
* This CALCULATOR_VERSION variable indicates the Version of the {@link MarkPassingCalculator} and must be changed
|
||||
* manually when changing the calculator. It should be changed by adding +1;
|
||||
*/
|
||||
public static final int CALCULATOR_VERSION = 1;
|
||||
public static final int CALCULATOR_VERSION = 2;
|
||||
|
||||
/**
|
||||
* An "end marker" that can be {@link #enqueueUpdate(StorePositionUpdateStrategy) enqueued} in order to tell the
|
||||
@@ -592,6 +593,7 @@ public class MarkPassingCalculator {
|
||||
suspended = false;
|
||||
} else {
|
||||
suspended = false;
|
||||
final CountDownLatch latchForRunningListenRun = new CountDownLatch(1);
|
||||
enqueueUpdate(new StorePositionUpdateStrategy() {
|
||||
@Override
|
||||
public void storePositionUpdate(Map<Competitor, List<GPSFixMoving>> competitorFixes,
|
||||
@@ -603,14 +605,23 @@ public class MarkPassingCalculator {
|
||||
List<Pair<Competitor, Integer>> suppressedMarkPassings,
|
||||
List<Competitor> unSuppressedMarkPassings, CandidateFinder candidateFinder,
|
||||
CandidateChooser candidateChooser) {
|
||||
latchForRunningListenRun.countDown();
|
||||
assert latchForRunningListenRun.getCount() == 0;
|
||||
}
|
||||
});
|
||||
if (markPassingRaceFingerprintRegistry != null) {
|
||||
// FIXME bug5971: the thread must not be started before Listen.run() has obtained the MarkPassingCalculator's write lock!
|
||||
new Thread(()->{
|
||||
final Map<Competitor, Map<Waypoint, MarkPassing>> markPassings = race.getMarkPassings(/* waitForLatestUpdates */ true);
|
||||
markPassingRaceFingerprintRegistry.storeMarkPassings(race.getRaceIdentifier(),
|
||||
MarkPassingRaceFingerprintFactory.INSTANCE.createFingerprint(race),
|
||||
markPassings, race.getRace().getCourse());
|
||||
try {
|
||||
latchForRunningListenRun.await();
|
||||
final Map<Competitor, Map<Waypoint, MarkPassing>> markPassings = race.getMarkPassings(/* waitForLatestUpdates */ true);
|
||||
markPassingRaceFingerprintRegistry.storeMarkPassings(race.getRaceIdentifier(),
|
||||
MarkPassingRaceFingerprintFactory.INSTANCE.createFingerprint(race),
|
||||
markPassings, race.getRace().getCourse());
|
||||
} catch (InterruptedException e) {
|
||||
logger.log(Level.SEVERE, "Exception while waiting for Listen.run() to start processing in MarkPassingCalculator for "+
|
||||
race.getName(), e);
|
||||
}
|
||||
}, "Waiting for mark passings for "+race.getName()+" after having resumed to store the results in registry")
|
||||
.start();
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.sap.sailing.domain.tracking;
|
||||
|
||||
import com.sap.sailing.domain.base.Mark;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
|
||||
public interface MarkGPSFix extends GPSFixMoving {
|
||||
Mark getMark();
|
||||
}
|
||||
+1
-1
@@ -431,7 +431,7 @@ public class CourseChangeBasedTrackApproximation implements Serializable, GPSTra
|
||||
}
|
||||
|
||||
private GPSFixMovingImpl createDummyFix(TimePoint timePoint) {
|
||||
return new GPSFixMovingImpl(/* position */ null, timePoint, /* speed */ null);
|
||||
return new GPSFixMovingImpl(/* position */ null, timePoint, /* speed */ null, /* optionalTrueHeading */ null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -227,7 +227,7 @@ public class OutlierFilter {
|
||||
// between the adjacent fixes proportionately based on "fix"'s distances to each of the two adjacent fixes:
|
||||
final TimePoint inferredTimePointForFix = lastFix.getTimePoint().plus(lastFix.getTimePoint().until(currentFix.getTimePoint()).times(
|
||||
alongTrackDistanceFromLastFix.divide(lastFix.getPosition().getDistance(currentFix.getPosition()))));
|
||||
result = new GPSFixMovingImpl(fixPosition, inferredTimePointForFix, fix.getSpeed());
|
||||
result = new GPSFixMovingImpl(fixPosition, inferredTimePointForFix, fix.getSpeed(), fix.getOptionalTrueHeading());
|
||||
distanceRatio = distanceFromSegment.divide(lastFix.getPosition().getDistance(currentFix.getPosition()));
|
||||
} else { // we found a minimum after fix:
|
||||
foundMinimum = true;
|
||||
|
||||
+22
-2
@@ -1,5 +1,7 @@
|
||||
package com.sap.sailing.expeditionconnector.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.GregorianCalendar;
|
||||
@@ -8,7 +10,10 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.TreeSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.declination.DeclinationService;
|
||||
import com.sap.sailing.domain.common.SpeedWithBearing;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
|
||||
@@ -23,6 +28,8 @@ import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class ExpeditionMessageImpl implements ExpeditionMessage {
|
||||
private static final Logger logger = Logger.getLogger(ExpeditionMessageImpl.class.getName());
|
||||
|
||||
private final String originalMessage;
|
||||
private final int boatID;
|
||||
private final Map<Integer, Double> values;
|
||||
@@ -148,8 +155,21 @@ public class ExpeditionMessageImpl implements ExpeditionMessage {
|
||||
if (hasValue(ID_GPS_LAT) && hasValue(ID_GPS_LNG)) {
|
||||
final SpeedWithBearing cogSog = getSpeedOverGround();
|
||||
if (cogSog != null) {
|
||||
result = new GPSFixMovingImpl(new DegreePosition(getValue(ID_GPS_LAT), getValue(ID_GPS_LNG)), getTimePoint(),
|
||||
getSpeedOverGround());
|
||||
final DegreePosition position = new DegreePosition(getValue(ID_GPS_LAT), getValue(ID_GPS_LNG));
|
||||
Bearing optionalTrueHeading;
|
||||
if (hasValue(ID_HEADING)) {
|
||||
try {
|
||||
optionalTrueHeading = new DegreeBearingImpl(getValue(ID_HEADING)).add(
|
||||
DeclinationService.INSTANCE.getDeclination(getTimePoint(), position, /* timeoutForOnlineFetchInMilliseconds */ 1000).getBearingCorrectedTo(getTimePoint()));
|
||||
} catch (IOException | ParseException e) {
|
||||
logger.log(Level.WARNING, "Problem obtaining the magnetic declination for Expedition fix", e);
|
||||
optionalTrueHeading = null;
|
||||
}
|
||||
} else {
|
||||
optionalTrueHeading = null;
|
||||
}
|
||||
result = new GPSFixMovingImpl(position, getTimePoint(),
|
||||
getSpeedOverGround(), optionalTrueHeading);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
|
||||
+3
-3
@@ -28,7 +28,7 @@ public final class PreciseCompactGPSFixMovingImpl {
|
||||
final double latDeg = streamReader.readDouble();
|
||||
final double lngDeg = streamReader.readDouble();
|
||||
return (PreciseCompactPosition) new com.sap.sailing.domain.common.tracking.impl.PreciseCompactGPSFixMovingImpl(
|
||||
new DegreePosition(latDeg, lngDeg), /* timePoint */null, /* speedWithBearing */ null).getPosition();
|
||||
new DegreePosition(latDeg, lngDeg), /* timePoint */null, /* speedWithBearing */ null, /* optionalTrueHeading */ null).getPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,7 +70,7 @@ public final class PreciseCompactGPSFixMovingImpl {
|
||||
final double speedInKnots = streamReader.readDouble();
|
||||
final double bearingDeg = streamReader.readDouble();
|
||||
return (PreciseCompactSpeedWithBearing) new com.sap.sailing.domain.common.tracking.impl.PreciseCompactGPSFixMovingImpl(
|
||||
/* dummy position */ new DegreePosition(0, 0), /* timePoint */null, new KnotSpeedWithBearingImpl(speedInKnots, new DegreeBearingImpl(bearingDeg))).getSpeed();
|
||||
/* dummy position */ new DegreePosition(0, 0), /* timePoint */null, new KnotSpeedWithBearingImpl(speedInKnots, new DegreeBearingImpl(bearingDeg)), /* optionalTrueHeading */ null).getSpeed();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -113,7 +113,7 @@ public final class PreciseCompactGPSFixMovingImpl {
|
||||
final double bearingDeg = streamReader.readDouble();
|
||||
final KnotSpeedWithBearingImpl speed = new KnotSpeedWithBearingImpl(speedInKnots, new DegreeBearingImpl(bearingDeg));
|
||||
final com.sap.sailing.domain.common.tracking.impl.PreciseCompactGPSFixMovingImpl preciseCompactGPSFixMovingImpl = new com.sap.sailing.domain.common.tracking.impl.PreciseCompactGPSFixMovingImpl(
|
||||
/* dummy position */ new DegreePosition(0, 0), /* timePoint */null, speed);
|
||||
/* dummy position */ new DegreePosition(0, 0), /* timePoint */null, speed, /* optionalTrueHeading */ null);
|
||||
preciseCompactGPSFixMovingImpl.cacheEstimatedSpeed(speed);
|
||||
return (PreciseCompactEstimatedSpeed) preciseCompactGPSFixMovingImpl.getSpeed();
|
||||
}
|
||||
|
||||
+3
-3
@@ -35,7 +35,7 @@ public final class VeryCompactGPSFixMovingImpl {
|
||||
final double lngDeg = streamReader.readDouble();
|
||||
try {
|
||||
return (VeryCompactPosition) new com.sap.sailing.domain.common.tracking.impl.VeryCompactGPSFixMovingImpl(
|
||||
new DegreePosition(latDeg, lngDeg), /* timePoint */null, /* speed with bearing */ null).getPosition();
|
||||
new DegreePosition(latDeg, lngDeg), /* timePoint */null, /* speed with bearing */ null, /* optionalTrueHeading */ null).getPosition();
|
||||
} catch (CompactionNotPossibleException e) {
|
||||
logger.log(Level.SEVERE, "Internal error: an object that was a very compact position and was serialized "+
|
||||
"couldn't be de-serialized again as such an object", e);
|
||||
@@ -83,7 +83,7 @@ public final class VeryCompactGPSFixMovingImpl {
|
||||
final double bearingDeg = streamReader.readDouble();
|
||||
try {
|
||||
return (VeryCompactSpeedWithBearing) new com.sap.sailing.domain.common.tracking.impl.VeryCompactGPSFixMovingImpl(
|
||||
/* position */ null, /* timePoint */null, new KnotSpeedWithBearingImpl(knotSpeed, new DegreeBearingImpl(bearingDeg))).getSpeed();
|
||||
/* position */ null, /* timePoint */null, new KnotSpeedWithBearingImpl(knotSpeed, new DegreeBearingImpl(bearingDeg)), /* optionalTrueHeading */ null).getSpeed();
|
||||
} catch (CompactionNotPossibleException e) {
|
||||
logger.log(Level.SEVERE, "Internal error: an object that was a very compact position and was serialized "+
|
||||
"couldn't be de-serialized again as such an object", e);
|
||||
@@ -132,7 +132,7 @@ public final class VeryCompactGPSFixMovingImpl {
|
||||
try {
|
||||
final KnotSpeedWithBearingImpl speed = new KnotSpeedWithBearingImpl(knotSpeed, new DegreeBearingImpl(bearingDeg));
|
||||
com.sap.sailing.domain.common.tracking.impl.VeryCompactGPSFixMovingImpl fix = new com.sap.sailing.domain.common.tracking.impl.VeryCompactGPSFixMovingImpl(
|
||||
/* dummy position */ new DegreePosition(0, 0), /* timePoint */null, speed);
|
||||
/* dummy position */ new DegreePosition(0, 0), /* timePoint */null, speed, /* optionalTrueHeading */ null);
|
||||
fix.cacheEstimatedSpeed(speed);
|
||||
return (VeryCompactEstimatedSpeed) fix.getCachedEstimatedSpeed();
|
||||
} catch (CompactionNotPossibleException e) {
|
||||
|
||||
+14
-1
@@ -15,6 +15,8 @@ import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.gwt.ui.shared.GPSFixDTOWithSpeedWindTackAndLegType;
|
||||
import com.sap.sailing.gwt.ui.shared.GPSFixDTOWithSpeedWindTackAndLegTypeIterable;
|
||||
import com.sap.sailing.gwt.ui.shared.SpeedWithBearingDTO;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
|
||||
/**
|
||||
* Serializes the {@link GPSFixDTOWithSpeedWindTackAndLegType} objects one by one, writing only primitive values to the
|
||||
@@ -33,6 +35,7 @@ public class GPSFixDTOWithSpeedWindTackAndLegTypeIterable_CustomFieldSerializer
|
||||
private static final int MASK_HAS_TACK = 1 << 4;
|
||||
private static final int MASK_HAS_POSITION = 1 << 5;
|
||||
private static final int MASK_HAS_TIMEPOINT = 1 << 6;
|
||||
private static final int MASK_HAS_TRUE_HEADING = 1 << 7;
|
||||
|
||||
@Override
|
||||
public void serializeInstance(SerializationStreamWriter streamWriter, GPSFixDTOWithSpeedWindTackAndLegTypeIterable instance)
|
||||
@@ -68,6 +71,9 @@ public class GPSFixDTOWithSpeedWindTackAndLegTypeIterable_CustomFieldSerializer
|
||||
if (fix.timepoint != null) {
|
||||
streamWriter.writeLong(fix.timepoint.getTime());
|
||||
}
|
||||
if (fix.optionalTrueHeading != null) {
|
||||
streamWriter.writeDouble(fix.optionalTrueHeading.getDegrees());
|
||||
}
|
||||
}
|
||||
streamWriter.writeInt(-1); // encodes a "mask" that marks the end of the iterable
|
||||
}
|
||||
@@ -124,7 +130,13 @@ public class GPSFixDTOWithSpeedWindTackAndLegTypeIterable_CustomFieldSerializer
|
||||
} else {
|
||||
timepoint = null;
|
||||
}
|
||||
list.add(new GPSFixDTOWithSpeedWindTackAndLegType(timepoint, position, speedWithBearing, degreesBoatToTheWind, tack, legType, extrapolated, detailValue));
|
||||
final Bearing optionalTrueHeading;
|
||||
if ((mask & MASK_HAS_TRUE_HEADING) != 0) {
|
||||
optionalTrueHeading = new DegreeBearingImpl(streamReader.readDouble());
|
||||
} else {
|
||||
optionalTrueHeading = null;
|
||||
}
|
||||
list.add(new GPSFixDTOWithSpeedWindTackAndLegType(timepoint, position, speedWithBearing, optionalTrueHeading, degreesBoatToTheWind, tack, legType, extrapolated, detailValue));
|
||||
}
|
||||
return new GPSFixDTOWithSpeedWindTackAndLegTypeIterable(list);
|
||||
}
|
||||
@@ -138,6 +150,7 @@ public class GPSFixDTOWithSpeedWindTackAndLegTypeIterable_CustomFieldSerializer
|
||||
| (fix.tack == null ? 0 : MASK_HAS_TACK)
|
||||
| (fix.position == null ? 0 : MASK_HAS_POSITION)
|
||||
| (fix.timepoint == null ? 0 : MASK_HAS_TIMEPOINT)
|
||||
| (fix.optionalTrueHeading == null ? 0 : MASK_HAS_TRUE_HEADING)
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -10,6 +10,10 @@
|
||||
<li>Fixed an issue for users with event update rights that resulted in them being
|
||||
unable to see the media tab of single regatta events for events without
|
||||
pre-existing media objects.</li>
|
||||
<li>When connectors support providing a heading (magnetic as in HDG, or true as
|
||||
in HDT), the heading will be used for the boat orientation on the map. The
|
||||
TracTrac connector, starting with its version 3.15.2, does support this if
|
||||
the trackers in use provide a true heading value.</li>
|
||||
</ul>
|
||||
<h5 class="articleSubheadline">January 2024</h5>
|
||||
<ul class="bulletList">
|
||||
|
||||
+1
-1
@@ -614,7 +614,7 @@ public class EditMarkPositionPanel extends AbstractRaceChart<AbstractSettings> i
|
||||
}
|
||||
|
||||
public void addMarkFix(final MarkDTO mark, final Date timepoint, final Position fixPosition) {
|
||||
final GPSFixDTOWithSpeedWindTackAndLegType fix = new GPSFixDTOWithSpeedWindTackAndLegType(timepoint, fixPosition, null, new WindDTO(), null, null, false);
|
||||
final GPSFixDTOWithSpeedWindTackAndLegType fix = new GPSFixDTOWithSpeedWindTackAndLegType(timepoint, fixPosition, null, /* optionalTrueHeading */ null, new WindDTO(), null, null, false);
|
||||
markPositionService.addMarkFix(
|
||||
raceIdentifierToLeaderboardRaceColumnAndFleetMapper.getLeaderboardNameAndRaceColumnNameAndFleetName(selectedRaceIdentifier),
|
||||
mark, fix, new AsyncCallback<Void>() {
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ public class FixPositionChooser {
|
||||
fix = new GPSFixDTO(oldFix.timepoint, oldFix.position);
|
||||
this.moveOverlay = new FixOverlay(map, overlay.getZIndex(), fix, overlay.getType(), "#f00", coordinateSystem, stringMessages.dragToChangePosition());
|
||||
} else {
|
||||
fix = new GPSFixDTOWithSpeedWindTackAndLegType(editMarkPositionPanel.getTimepoint(), coordinateSystem.getPosition(startPos), null, new WindDTO(), null, null, false);
|
||||
fix = new GPSFixDTOWithSpeedWindTackAndLegType(editMarkPositionPanel.getTimepoint(), coordinateSystem.getPosition(startPos), null, /* optionalTrueHeading */ null, new WindDTO(), null, null, false);
|
||||
this.moveOverlay = new FixOverlay(map, EditMarkPositionPanel.FIX_OVERLAY_Z_ORDER+1, fix, FixType.BUOY, "#f00", coordinateSystem, stringMessages.dragToChangePosition());
|
||||
}
|
||||
redTimeLine.setValue(fix.timepoint.getTime());
|
||||
|
||||
+4
-6
@@ -12,7 +12,6 @@ import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.common.dto.BoatClassDTO;
|
||||
import com.sap.sailing.domain.common.dto.BoatDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.GPSFixDTOWithSpeedWindTackAndLegType;
|
||||
import com.sap.sailing.gwt.ui.shared.SpeedWithBearingDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.BoatClassVectorGraphics;
|
||||
import com.sap.sailing.gwt.ui.shared.racemap.CanvasOverlayV3;
|
||||
import com.sap.sse.common.Color;
|
||||
@@ -99,11 +98,10 @@ public class BoatOverlay extends CanvasOverlayV3 {
|
||||
setCanvasPosition(boatPositionInPx.getX() - getCanvas().getCoordinateSpaceWidth() / 2,
|
||||
boatPositionInPx.getY() - getCanvas().getCoordinateSpaceHeight() / 2);
|
||||
// now rotate the canvas accordingly
|
||||
SpeedWithBearingDTO speedWithBearing = boatFix.speedWithBearing;
|
||||
if (speedWithBearing == null) {
|
||||
speedWithBearing = new SpeedWithBearingDTO(0, 0);
|
||||
}
|
||||
updateDrawingAngleAndSetCanvasRotation(coordinateSystem.mapDegreeBearing(speedWithBearing.bearingInDegrees - ORIGINAL_BOAT_IMAGE_ROTATIION_ANGLE));
|
||||
final double trueHeadingInDegrees = boatFix.optionalTrueHeading != null
|
||||
? boatFix.optionalTrueHeading.getDegrees()
|
||||
: (boatFix.speedWithBearing == null ? 0 : boatFix.speedWithBearing.bearingInDegrees);
|
||||
updateDrawingAngleAndSetCanvasRotation(coordinateSystem.mapDegreeBearing(trueHeadingInDegrees - ORIGINAL_BOAT_IMAGE_ROTATIION_ANGLE));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-3
@@ -3011,7 +3011,7 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
final GPSFixDTOWithSpeedWindTackAndLegType result;
|
||||
final List<GPSFixDTOWithSpeedWindTackAndLegType> competitorFixes = fixesAndTails.getFixes(competitorDTO);
|
||||
if (competitorFixes != null && !competitorFixes.isEmpty()) {
|
||||
int i = Collections.binarySearch(competitorFixes, new GPSFixDTOWithSpeedWindTackAndLegType(date, null, null, (WindDTO) null, null, null, false),
|
||||
int i = Collections.binarySearch(competitorFixes, new GPSFixDTOWithSpeedWindTackAndLegType(date, null, null, /* optionalTrueHeading */ null, (WindDTO) null, null, null, false),
|
||||
new Comparator<GPSFixDTOWithSpeedWindTackAndLegType>() {
|
||||
@Override
|
||||
public int compare(GPSFixDTOWithSpeedWindTackAndLegType o1, GPSFixDTOWithSpeedWindTackAndLegType o2) {
|
||||
@@ -3060,8 +3060,9 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
factorForBefore*(fixBefore.speedWithBearing==null?0:fixBefore.speedWithBearing.speedInKnots) +
|
||||
factorForAfter*(fixAfter.speedWithBearing==null?0:fixAfter.speedWithBearing.speedInKnots),
|
||||
betweenBearing);
|
||||
result = new GPSFixDTOWithSpeedWindTackAndLegType(date, betweenPosition, betweenSpeed, closer.degreesBoatToTheWind,
|
||||
closer.tack, closer.legType, fixBefore.extrapolated || fixAfter.extrapolated);
|
||||
result = new GPSFixDTOWithSpeedWindTackAndLegType(date, betweenPosition, betweenSpeed,
|
||||
interpolateOptionalTrueHeading(fixBefore, factorForBefore, fixAfter, factorForAfter),
|
||||
closer.degreesBoatToTheWind, closer.tack, closer.legType, fixBefore.extrapolated || fixAfter.extrapolated);
|
||||
}
|
||||
} else {
|
||||
// perfect match
|
||||
@@ -3073,6 +3074,16 @@ public class RaceMap extends AbstractCompositeComponent<RaceMapSettings> impleme
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Bearing interpolateOptionalTrueHeading(GPSFixDTOWithSpeedWindTackAndLegType fixBefore, double factorForBefore, GPSFixDTOWithSpeedWindTackAndLegType fixAfter, double factorForAfter) {
|
||||
assert fixBefore != null && fixAfter != null;
|
||||
return (fixBefore == null || fixBefore.optionalTrueHeading == null) ? (fixAfter == null || fixAfter.optionalTrueHeading == null)
|
||||
? null
|
||||
: fixAfter.optionalTrueHeading
|
||||
: (fixAfter == null || fixAfter.optionalTrueHeading == null)
|
||||
? fixBefore.optionalTrueHeading
|
||||
: new DegreeBearingImpl(factorForBefore * fixBefore.optionalTrueHeading.getDegrees() + factorForAfter * fixAfter.optionalTrueHeading.getDegrees());
|
||||
}
|
||||
|
||||
public RaceMapSettings getSettings() {
|
||||
return settings;
|
||||
|
||||
+5
-4
@@ -1912,9 +1912,10 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
.getBearing().getDegrees());
|
||||
}
|
||||
|
||||
public GPSFixDTOWithSpeedWindTackAndLegType createGPSFixDTO(GPSFix fix, SpeedWithBearing speedWithBearing, WindDTO windDTO, Tack tack, LegType legType, boolean extrapolated, Double detailValue) {
|
||||
public GPSFixDTOWithSpeedWindTackAndLegType createGPSFixDTO(GPSFix fix, SpeedWithBearing speedWithBearing,
|
||||
Bearing optionalTrueHeading, WindDTO windDTO, Tack tack, LegType legType, boolean extrapolated, Double detailValue) {
|
||||
return new GPSFixDTOWithSpeedWindTackAndLegType(fix.getTimePoint().asDate(), fix.getPosition()==null?null:fix.getPosition(),
|
||||
speedWithBearing==null?null:createSpeedWithBearingDTO(speedWithBearing), windDTO, tack, legType, extrapolated, detailValue);
|
||||
speedWithBearing==null?null:createSpeedWithBearingDTO(speedWithBearing), optionalTrueHeading, windDTO, tack, legType, extrapolated, detailValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3241,8 +3242,8 @@ public class SailingServiceImpl extends ResultCachingProxiedRemoteServiceServlet
|
||||
trackedLegOfCompetitor.getLeg()).getLegType(fix.getTimePoint());
|
||||
Wind wind = trackedRace.getWind(fix.getPosition(), fix.getTimePoint());
|
||||
WindDTO windDTO = createWindDTOFromAlreadyAveraged(wind, fix.getTimePoint());
|
||||
GPSFixDTOWithSpeedWindTackAndLegType fixDTO = createGPSFixDTO(fix, speedWithBearing, windDTO, tack, legType, /* extrapolated */
|
||||
false, null);
|
||||
GPSFixDTOWithSpeedWindTackAndLegType fixDTO = createGPSFixDTO(fix, speedWithBearing, /* optionalTrueHeading */ null, windDTO, tack, /* extrapolated */
|
||||
legType, false, null);
|
||||
return fixDTO;
|
||||
}
|
||||
|
||||
|
||||
+21
-16
@@ -6,10 +6,13 @@ import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sse.common.Bearing;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
|
||||
public class GPSFixDTOWithSpeedWindTackAndLegType extends GPSFixDTO implements IsSerializable {
|
||||
public SpeedWithBearingDTO speedWithBearing;
|
||||
|
||||
public Bearing optionalTrueHeading;
|
||||
|
||||
/**
|
||||
* tells if this fix was computed by extrapolation instead of having been captured by a device directly
|
||||
@@ -37,33 +40,35 @@ public class GPSFixDTOWithSpeedWindTackAndLegType extends GPSFixDTO implements I
|
||||
|
||||
public Double detailValue;
|
||||
|
||||
public GPSFixDTOWithSpeedWindTackAndLegType() {}
|
||||
@Deprecated // GWT serialization only
|
||||
GPSFixDTOWithSpeedWindTackAndLegType() {}
|
||||
|
||||
public GPSFixDTOWithSpeedWindTackAndLegType(Date timepoint, Position position, SpeedWithBearingDTO speedWithBearing, WindDTO wind,
|
||||
Tack tack, LegType legType, boolean extrapolated) {
|
||||
this(timepoint, position, speedWithBearing, (speedWithBearing != null && wind != null) ?
|
||||
new DegreeBearingImpl(speedWithBearing.bearingInDegrees).getDifferenceTo(
|
||||
new DegreeBearingImpl(wind.dampenedTrueWindFromDeg)).getDegrees() : null, tack, legType, extrapolated);
|
||||
public GPSFixDTOWithSpeedWindTackAndLegType(Date timepoint, Position position, SpeedWithBearingDTO speedWithBearing, Bearing optionalTrueHeading,
|
||||
WindDTO wind, Tack tack, LegType legType, boolean extrapolated) {
|
||||
this(timepoint, position, speedWithBearing, optionalTrueHeading, (speedWithBearing != null && wind != null) ?
|
||||
new DegreeBearingImpl(speedWithBearing.bearingInDegrees).getDifferenceTo(
|
||||
new DegreeBearingImpl(wind.dampenedTrueWindFromDeg)).getDegrees() : null, tack, legType, extrapolated);
|
||||
}
|
||||
|
||||
public GPSFixDTOWithSpeedWindTackAndLegType(Date timepoint, Position position, SpeedWithBearingDTO speedWithBearing, WindDTO wind,
|
||||
Tack tack, LegType legType, boolean extrapolated, Double detailValue) {
|
||||
this(timepoint, position, speedWithBearing, (speedWithBearing != null && wind != null) ?
|
||||
new DegreeBearingImpl(speedWithBearing.bearingInDegrees).getDifferenceTo(
|
||||
new DegreeBearingImpl(wind.dampenedTrueWindFromDeg)).getDegrees() : null, tack, legType, extrapolated, detailValue);
|
||||
public GPSFixDTOWithSpeedWindTackAndLegType(Date timepoint, Position position, SpeedWithBearingDTO speedWithBearing, Bearing optionalTrueHeading,
|
||||
WindDTO wind, Tack tack, LegType legType, boolean extrapolated, Double detailValue) {
|
||||
this(timepoint, position, speedWithBearing, optionalTrueHeading, (speedWithBearing != null && wind != null) ?
|
||||
new DegreeBearingImpl(speedWithBearing.bearingInDegrees).getDifferenceTo(
|
||||
new DegreeBearingImpl(wind.dampenedTrueWindFromDeg)).getDegrees() : null, tack, legType, extrapolated, detailValue);
|
||||
}
|
||||
|
||||
public GPSFixDTOWithSpeedWindTackAndLegType(Date timepoint, Position position, SpeedWithBearingDTO speedWithBearing, Double degreesBoatToTheWind,
|
||||
Tack tack, LegType legType, boolean extrapolated) {
|
||||
this(timepoint, position, speedWithBearing, degreesBoatToTheWind, tack, legType, extrapolated, /* detailValue */ null);
|
||||
public GPSFixDTOWithSpeedWindTackAndLegType(Date timepoint, Position position, SpeedWithBearingDTO speedWithBearing, Bearing optionalTrueHeading,
|
||||
Double degreesBoatToTheWind, Tack tack, LegType legType, boolean extrapolated) {
|
||||
this(timepoint, position, speedWithBearing, optionalTrueHeading, degreesBoatToTheWind, tack, legType, extrapolated, /* detailValue */ null);
|
||||
}
|
||||
|
||||
public GPSFixDTOWithSpeedWindTackAndLegType(Date timepoint, Position position, SpeedWithBearingDTO speedWithBearing, Double degreesBoatToTheWind,
|
||||
Tack tack, LegType legType, boolean extrapolated, Double detailValue) {
|
||||
public GPSFixDTOWithSpeedWindTackAndLegType(Date timepoint, Position position, SpeedWithBearingDTO speedWithBearing, Bearing optionalTrueHeading,
|
||||
Double degreesBoatToTheWind, Tack tack, LegType legType, boolean extrapolated, Double detailValue) {
|
||||
super(timepoint, position);
|
||||
this.timepoint = timepoint;
|
||||
this.position = position;
|
||||
this.speedWithBearing = speedWithBearing;
|
||||
this.optionalTrueHeading = optionalTrueHeading;
|
||||
this.tack = tack;
|
||||
this.legType = legType;
|
||||
this.extrapolated = extrapolated;
|
||||
|
||||
+5
-4
@@ -213,7 +213,7 @@ public class GPSFixDTOWithSpeedWindTackAndLegTypeIterable implements IsSerializa
|
||||
Position estimatedPosition = track.getEstimatedPosition(middle, extrapolate);
|
||||
SpeedWithBearing estimatedSpeed = track.getEstimatedSpeed(middle);
|
||||
if (estimatedPosition != null && estimatedSpeed != null) {
|
||||
GPSFixMoving estimatedFix = new GPSFixMovingImpl(estimatedPosition, middle, estimatedSpeed);
|
||||
GPSFixMoving estimatedFix = new GPSFixMovingImpl(estimatedPosition, middle, estimatedSpeed, /* optionalTrueHeading */ null); // TODO bug5970: could try to estimate heading from neighboring fixes
|
||||
if (logger.getLevel() != null && logger.getLevel().equals(Level.FINEST)) {
|
||||
logger.finest(""+competitor.getName()+": " + estimatedFix+" (estimated)");
|
||||
}
|
||||
@@ -282,7 +282,8 @@ public class GPSFixDTOWithSpeedWindTackAndLegTypeIterable implements IsSerializa
|
||||
detailValue = null;
|
||||
}
|
||||
}
|
||||
result = sailingService.createGPSFixDTO(fix, estimatedSpeed, windDTO, tack, legType, /* extrapolate */ extrapolatedFixes.contains(fix), detailValue);
|
||||
result = sailingService.createGPSFixDTO(fix, estimatedSpeed, fix.getOptionalTrueHeading(), windDTO,
|
||||
tack, legType, /* extrapolate */ extrapolatedFixes.contains(fix), detailValue);
|
||||
} else if (isExtrapolate()) {
|
||||
final TrackedLegOfCompetitor trackedLegOfCompetitor = trackedRace.getTrackedLeg(competitor, lastFix.getTimePoint());
|
||||
Position position = track.getEstimatedPosition(toTimePointExcluding, extrapolate);
|
||||
@@ -312,8 +313,8 @@ public class GPSFixDTOWithSpeedWindTackAndLegTypeIterable implements IsSerializa
|
||||
WindDTO windDTO2 = wind2 == null ? null : sailingService.createWindDTOFromAlreadyAveraged(wind2, toTimePointExcluding);
|
||||
result = new GPSFixDTOWithSpeedWindTackAndLegType(
|
||||
toTimePointExcluding.asDate(), position==null?null:position,
|
||||
estimatedSpeed2==null?null:sailingService.createSpeedWithBearingDTO(estimatedSpeed2), windDTO2,
|
||||
tack2, legType2, /* extrapolated */ true);
|
||||
estimatedSpeed2==null?null:sailingService.createSpeedWithBearingDTO(estimatedSpeed2), /* optionalTrueHeading */ null, // no heading for extrapolated fixes
|
||||
windDTO2, tack2, legType2, /* extrapolated */ true);
|
||||
} else {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
+1
-3
@@ -25,11 +25,9 @@ public class GPSFixMovingJsonDeserializerTest {
|
||||
|
||||
@Test
|
||||
public void testGPSFixMovingDeserializer() throws ParseException, JsonDeserializationException {
|
||||
GPSFixMoving gpsFix = GPSFixMovingImpl.create(8.0, 55.0, System.currentTimeMillis(), 5.0, 14.0);
|
||||
|
||||
GPSFixMoving gpsFix = GPSFixMovingImpl.create(8.0, 55.0, System.currentTimeMillis(), 5.0, 14.0, /* optionalTrueHeadingDeg */ 15.0);
|
||||
JSONObject gpsFixSerialized = serializer.serialize(gpsFix);
|
||||
GPSFixMoving gpsFixDeserialized = deserializer.deserialize(gpsFixSerialized);
|
||||
|
||||
assertEquals(gpsFix, gpsFixDeserialized);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -31,14 +31,14 @@ public class FlatSmartphoneUuidAndGPSFixMovingJsonDeserializerTest {
|
||||
" \"latitude\" : 54.325246,\n" +
|
||||
" \"longitude\" : 10.148556,\n" +
|
||||
" \"speed\" : 3.61,\n" +
|
||||
" \"course\" : 258.11,\n" +
|
||||
" \"course\" : 258.11\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"timestamp\" : 14144168490000,\n" +
|
||||
" \"latitude\" : 55.12456,\n" +
|
||||
" \"longitude\" : 8.03456,\n" +
|
||||
" \"speed\" : 5.1,\n" +
|
||||
" \"course\" : 14.2,\n" +
|
||||
" \"course\" : 14.2\n" +
|
||||
" },\n" +
|
||||
" {\n" +
|
||||
" \"timestamp-iso\" : \"2418-03-18T15:41:30Z\",\n" +
|
||||
@@ -46,19 +46,19 @@ public class FlatSmartphoneUuidAndGPSFixMovingJsonDeserializerTest {
|
||||
" \"longitude\" : -2.03456,\n" +
|
||||
" \"speed\" : 19.3,\n" +
|
||||
" \"course\" : 359.99,\n" +
|
||||
" \"hdt\" : 358.57\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
"}";
|
||||
JsonDeserializer<Pair<UUID, List<GPSFixMoving>>> deserializer =
|
||||
new FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer();
|
||||
|
||||
Pair<UUID, List<GPSFixMoving>> result =
|
||||
deserializer.deserialize(Helpers.toJSONObjectSafe(JSONValue.parseWithException(json)));
|
||||
assertThat("uuid", result.getA(), equalTo(UUID.fromString("af855a56-9726-4a9c-a77e-da955bd289bf")));
|
||||
assertThat("number of fixes", result.getB().size(), equalTo(3));
|
||||
|
||||
TimePoint tp3 = result.getB().get(2).getTimePoint();
|
||||
assertThat(tp3.asMillis(), equalTo(14144168490000L));
|
||||
assertThat(result.getB().get(2).getOptionalTrueHeading().getDegrees(), equalTo(358.57));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -6,6 +6,7 @@ Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Vendor: SAP
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Import-Package:
|
||||
com.sap.sailing.declination,
|
||||
org.json.simple
|
||||
Require-Bundle: com.sap.sailing.domain.common,
|
||||
com.sap.sailing.domain.shared.android,
|
||||
|
||||
+29
-3
@@ -1,19 +1,27 @@
|
||||
package com.sap.sailing.server.gateway.deserialization.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import com.sap.sailing.declination.DeclinationService;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sailing.domain.common.impl.MeterPerSecondSpeedImpl;
|
||||
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
|
||||
import com.sap.sailing.domain.common.tracking.impl.FlatSmartphoneUuidAndGPSFixMovingJsonSerializer;
|
||||
import com.sap.sailing.domain.common.tracking.impl.GPSFixMovingImpl;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.Util.Pair;
|
||||
import com.sap.sse.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sse.shared.json.JsonDeserializationException;
|
||||
import com.sap.sse.shared.json.JsonDeserializer;
|
||||
|
||||
@@ -23,8 +31,10 @@ import com.sap.sse.shared.json.JsonDeserializer;
|
||||
* @author Fredrik Teschke
|
||||
*
|
||||
*/
|
||||
public class FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer implements
|
||||
JsonDeserializer<Pair<UUID, List<GPSFixMoving>>> {
|
||||
public class FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer
|
||||
implements JsonDeserializer<Pair<UUID, List<GPSFixMoving>>> {
|
||||
private static final Logger logger = Logger.getLogger(FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer.class.getName());
|
||||
|
||||
public static final String ACCURACY = "accuracy";
|
||||
|
||||
@Override
|
||||
@@ -40,7 +50,23 @@ public class FlatSmartphoneUuidAndGPSFixMovingJsonDeserializer implements
|
||||
double speedMperS = Double.parseDouble(fixObject.get(FlatSmartphoneUuidAndGPSFixMovingJsonSerializer.SPEED_M_PER_S).toString());
|
||||
double speedKnots = new MeterPerSecondSpeedImpl(speedMperS).getKnots();
|
||||
double bearingDeg = Double.parseDouble(fixObject.get(FlatSmartphoneUuidAndGPSFixMovingJsonSerializer.BEARING_DEG).toString());
|
||||
GPSFixMoving fix = GPSFixMovingImpl.create(lonDeg, latDeg, timeMillis, speedKnots, bearingDeg);
|
||||
Double optionalTrueHeadingDeg;
|
||||
if (fixObject.containsKey(FlatSmartphoneUuidAndGPSFixMovingJsonSerializer.TRUE_HEADING_DEG)) {
|
||||
optionalTrueHeadingDeg = Double.parseDouble(fixObject.get(FlatSmartphoneUuidAndGPSFixMovingJsonSerializer.TRUE_HEADING_DEG).toString());
|
||||
} else if (fixObject.containsKey(FlatSmartphoneUuidAndGPSFixMovingJsonSerializer.MAGNETIC_HEADING_DEG)) {
|
||||
final TimePoint timePoint = TimePoint.of(timeMillis);
|
||||
try {
|
||||
optionalTrueHeadingDeg = new DegreeBearingImpl(Double.parseDouble(fixObject.get(FlatSmartphoneUuidAndGPSFixMovingJsonSerializer.MAGNETIC_HEADING_DEG).toString()))
|
||||
.add(DeclinationService.INSTANCE.getDeclination(timePoint, new DegreePosition(latDeg, lonDeg), /* timeout in ms */ 1000)
|
||||
.getBearingCorrectedTo(timePoint)).getDegrees();
|
||||
} catch (NumberFormatException | IOException | ParseException e) {
|
||||
logger.log(Level.WARNING, "Problem obtaining magnetic declination for heading provided in JSON fix", e);
|
||||
optionalTrueHeadingDeg = null;
|
||||
}
|
||||
} else {
|
||||
optionalTrueHeadingDeg = null;
|
||||
}
|
||||
GPSFixMoving fix = GPSFixMovingImpl.create(lonDeg, latDeg, timeMillis, speedKnots, bearingDeg, optionalTrueHeadingDeg);
|
||||
fixes.add(fix);
|
||||
}
|
||||
|
||||
|
||||
+15
-8
@@ -17,19 +17,26 @@ public class GPSFixMovingJsonDeserializer extends TypeBasedJsonDeserializer<GPSF
|
||||
|
||||
public static final String FIELD_BEARING_DEG = "bearing_deg";
|
||||
public static final String FIELD_SPEED_KNOTS = "speed_knots";
|
||||
public static final Object FIELD_TRUE_HEADING_DEG = "true_heading_deg";
|
||||
|
||||
@Override
|
||||
protected GPSFixMoving deserializeAfterCheckingType(JSONObject object) throws JsonDeserializationException {
|
||||
double bearingDeg = (Double) object.get(FIELD_BEARING_DEG);
|
||||
double speedKnots = (Double) object.get(FIELD_SPEED_KNOTS);
|
||||
JSONObject clone = (JSONObject) object.clone();
|
||||
final double bearingDeg = (Double) object.get(FIELD_BEARING_DEG);
|
||||
final double speedKnots = (Double) object.get(FIELD_SPEED_KNOTS);
|
||||
final JSONObject clone = (JSONObject) object.clone();
|
||||
clone.put(TypeBasedJsonDeserializer.FIELD_TYPE, GPSFixJsonDeserializer.TYPE);
|
||||
GPSFix baseFix = new GPSFixJsonDeserializer().deserialize(clone);
|
||||
Bearing bearing = new DegreeBearingImpl(bearingDeg);
|
||||
SpeedWithBearing speed = new KnotSpeedWithBearingImpl(
|
||||
final GPSFix baseFix = new GPSFixJsonDeserializer().deserialize(clone);
|
||||
final Bearing bearing = new DegreeBearingImpl(bearingDeg);
|
||||
final SpeedWithBearing speed = new KnotSpeedWithBearingImpl(
|
||||
speedKnots, bearing);
|
||||
GPSFixMoving fix = new GPSFixMovingImpl(baseFix.getPosition(),
|
||||
baseFix.getTimePoint(), speed);
|
||||
final Bearing optionalTrueHeading;
|
||||
if (object.containsKey(FIELD_TRUE_HEADING_DEG)) {
|
||||
optionalTrueHeading = new DegreeBearingImpl((Double) object.get(FIELD_TRUE_HEADING_DEG));
|
||||
} else {
|
||||
optionalTrueHeading = null;
|
||||
}
|
||||
final GPSFixMoving fix = new GPSFixMovingImpl(baseFix.getPosition(),
|
||||
baseFix.getTimePoint(), speed, optionalTrueHeading);
|
||||
return fix;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -21,7 +21,9 @@ public class GPSFixMovingJsonSerializer implements JsonSerializer<GPSFixMoving>
|
||||
result.put(TypeBasedJsonDeserializer.FIELD_TYPE, GPSFixMovingJsonDeserializer.TYPE);
|
||||
result.put(GPSFixMovingJsonDeserializer.FIELD_BEARING_DEG, speedWithCourse.getBearing().getDegrees());
|
||||
result.put(GPSFixMovingJsonDeserializer.FIELD_SPEED_KNOTS, speedWithCourse.getKnots());
|
||||
|
||||
if (object.getOptionalTrueHeading() != null) {
|
||||
result.put(GPSFixMovingJsonDeserializer.FIELD_TRUE_HEADING_DEG, object.getOptionalTrueHeading().getDegrees());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,13 +75,15 @@ These can be mapped to a competitor or a mark via the DeviceMappings in the Race
|
||||
"longitude" : 10.148556,
|
||||
"speed" : 3.61,
|
||||
"course" : 258.11,
|
||||
"hdt" : 259.0
|
||||
},
|
||||
{
|
||||
"timestamp" : 14144168490000,
|
||||
"latitude" : 55.12456,
|
||||
"longitude" : 8.03456,
|
||||
"speed" : 5.1,
|
||||
"course" : 14.2,
|
||||
"course" : 14.2
|
||||
"hdt" : 14.7
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -89,7 +91,10 @@ These can be mapped to a competitor or a mark via the DeviceMappings in the Race
|
||||
</td>
|
||||
</tr>
|
||||
Note that the "speed" field is provided in meters per second (m/s). The course is the course over ground (COG) in
|
||||
true degrees.
|
||||
true degrees. The "hdt" field is optional and may be used to represent a true (not magnetic) heading in degrees.
|
||||
Note how this is different from "hdg" which can be used instead of "hdt" to specify a magnetic heading in degrees.
|
||||
The magnetic declination at time and location of the fix will be used then to convert this internally to a true
|
||||
heading.
|
||||
</table>
|
||||
<div style="height: 1em;"></div>
|
||||
<a href="index.html">Back to Web Service Overview</a>
|
||||
|
||||
+1
-1
@@ -526,7 +526,7 @@ public class ImportMasterDataOperation extends
|
||||
if (fixToAdd instanceof VeryCompactGPSFixMovingImpl) {
|
||||
VeryCompactGPSFixMovingImpl gpsFix = (VeryCompactGPSFixMovingImpl) fixToAdd;
|
||||
fixToAdd = new GPSFixMovingImpl(gpsFix.getPosition(), fixToAdd.getTimePoint(),
|
||||
((VeryCompactGPSFixMovingImpl) fixToAdd).getSpeed());
|
||||
((VeryCompactGPSFixMovingImpl) fixToAdd).getSpeed(), gpsFix.getOptionalTrueHeading());
|
||||
} else if (fixToAdd instanceof VeryCompactGPSFixImpl) {
|
||||
VeryCompactGPSFixImpl gpsFix = (VeryCompactGPSFixImpl) fixToAdd;
|
||||
fixToAdd = new GPSFixImpl(gpsFix.getPosition(), fixToAdd.getTimePoint());
|
||||
|
||||
+1
-1
@@ -128,7 +128,7 @@ public class BoatReplicationTest extends AbstractServerReplicationTest {
|
||||
EmptyWindStore.INSTANCE, /* delayToLiveInMillis */ 3000,
|
||||
/* millisecondsOverWhichToAverageWind */ 30000l, /* millisecondsOverWhichToAverageSpeed */ 30000l, null));
|
||||
trackedRace.getTrack(competitor).addGPSFix(new GPSFixMovingImpl(new DegreePosition(49.425, 8.293), MillisecondsTimePoint.now(),
|
||||
new KnotSpeedWithBearingImpl(12.3, new DegreeBearingImpl(242.3))));
|
||||
new KnotSpeedWithBearingImpl(12.3, new DegreeBearingImpl(242.3)), /* optionalTrueHeading */ null));
|
||||
Thread.sleep(1000);
|
||||
TrackedRace replicatedTrackedRace = replica.getTrackedRace(raceIdentifier);
|
||||
assertNotNull(replicatedTrackedRace);
|
||||
|
||||
+1
-1
@@ -148,7 +148,7 @@ public class CompetitorReplicationTest extends AbstractServerReplicationTest {
|
||||
EmptyWindStore.INSTANCE, /* delayToLiveInMillis */ 3000,
|
||||
/* millisecondsOverWhichToAverageWind */ 30000l, /* millisecondsOverWhichToAverageSpeed */ 30000l, null));
|
||||
trackedRace.getTrack(competitor).addGPSFix(new GPSFixMovingImpl(new DegreePosition(49.425, 8.293), MillisecondsTimePoint.now(),
|
||||
new KnotSpeedWithBearingImpl(12.3, new DegreeBearingImpl(242.3))));
|
||||
new KnotSpeedWithBearingImpl(12.3, new DegreeBearingImpl(242.3)), /* optionalTrueHeading */ null));
|
||||
Thread.sleep(1000);
|
||||
TrackedRace replicatedTrackedRace = replica.getTrackedRace(raceIdentifier);
|
||||
assertNotNull(replicatedTrackedRace);
|
||||
|
||||
+6
-4
@@ -127,7 +127,7 @@ public class TrackedRaceContentsReplicationTest extends AbstractServerReplicatio
|
||||
@Test
|
||||
public void testGPSFixReplication() throws InterruptedException {
|
||||
final GPSFixMovingImpl fix = new GPSFixMovingImpl(new DegreePosition(1, 2), new MillisecondsTimePoint(12345),
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)));
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)), /* optionalTrueHeading */ new DegreeBearingImpl(124));
|
||||
trackedRace.recordFix(competitor, fix);
|
||||
Thread.sleep(1000);
|
||||
TrackedRace replicaTrackedRace = replica.getTrackedRace(raceIdentifier);
|
||||
@@ -137,8 +137,10 @@ public class TrackedRaceContentsReplicationTest extends AbstractServerReplicatio
|
||||
competitorTrack.lockForRead();
|
||||
try {
|
||||
assertEquals(1, Util.size(competitorTrack.getRawFixes()));
|
||||
PositionAssert.assertGPSFixEquals(fix, competitorTrack.getRawFixes().iterator().next(), /* pos deg delta */ 0.0000001, /* bearing deg delta */ 0.01, /* knot speed delta */ 0.01);
|
||||
assertNotSame(fix, competitorTrack.getRawFixes().iterator().next());
|
||||
final GPSFixMoving replicatedFix = competitorTrack.getRawFixes().iterator().next();
|
||||
PositionAssert.assertGPSFixEquals(fix, replicatedFix, /* pos deg delta */ 0.0000001, /* bearing deg delta */ 0.01, /* knot speed delta */ 0.01);
|
||||
assertEquals(fix.getOptionalTrueHeading().getDegrees(), replicatedFix.getOptionalTrueHeading().getDegrees(), 0.01);
|
||||
assertNotSame(fix, replicatedFix);
|
||||
} finally {
|
||||
competitorTrack.unlockAfterRead();
|
||||
}
|
||||
@@ -166,7 +168,7 @@ public class TrackedRaceContentsReplicationTest extends AbstractServerReplicatio
|
||||
@Test
|
||||
public void testMarkFixReplication() throws InterruptedException {
|
||||
final GPSFixMovingImpl fix = new GPSFixMovingImpl(new DegreePosition(2, 3), new MillisecondsTimePoint(3456),
|
||||
new KnotSpeedWithBearingImpl(13, new DegreeBearingImpl(234)));
|
||||
new KnotSpeedWithBearingImpl(13, new DegreeBearingImpl(234)), /* optionalTrueHeading */ null);
|
||||
final Mark masterMark = trackedRace.getRace().getCourse().getFirstWaypoint().getMarks().iterator().next();
|
||||
trackedRace.recordFix(masterMark, fix);
|
||||
Thread.sleep(1000);
|
||||
|
||||
+1
-1
@@ -153,7 +153,7 @@ public class TrackedRaceWithSensorFixStoreContentsReplicationTest extends Abstra
|
||||
@Test
|
||||
public void testGPSFixReplication() throws InterruptedException {
|
||||
final GPSFixMovingImpl fix = new GPSFixMovingImpl(new DegreePosition(1, 2), new MillisecondsTimePoint(12345),
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)));
|
||||
new KnotSpeedWithBearingImpl(12, new DegreeBearingImpl(123)), /* optionalTrueHeading */ null);
|
||||
trackedRace.recordFix(competitor, fix);
|
||||
Thread.sleep(1000);
|
||||
final TrackedRace replicaTrackedRace = replica.getTrackedRace(raceIdentifier);
|
||||
|
||||
+11
-11
@@ -112,47 +112,47 @@ public class StatisticsTest {
|
||||
public void testTrackedRaceStatisticsCacheWithFixes() throws Exception {
|
||||
trackedRace.recordFix(comp,
|
||||
new GPSFixMovingImpl(new DegreePosition(49.295970, 8.638958), new MillisecondsTimePoint(START_OF_RACE),
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100))));
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null));
|
||||
trackedRace.recordFix(comp,
|
||||
new GPSFixMovingImpl(new DegreePosition(49.295911, 8.638971),
|
||||
new MillisecondsTimePoint(START_OF_RACE + 10),
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100))));
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null));
|
||||
trackedRace.recordFix(comp,
|
||||
new GPSFixMovingImpl(new DegreePosition(49.295866, 8.638986),
|
||||
new MillisecondsTimePoint(START_OF_RACE + 20),
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100))));
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null));
|
||||
trackedRace.recordFix(comp,
|
||||
new GPSFixMovingImpl(new DegreePosition(49.295822, 8.639010),
|
||||
new MillisecondsTimePoint(START_OF_RACE + 30),
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100))));
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null));
|
||||
trackedRace.recordFix(comp,
|
||||
new GPSFixMovingImpl(new DegreePosition(49.295785, 8.639057),
|
||||
new MillisecondsTimePoint(START_OF_RACE + 40),
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100))));
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null));
|
||||
trackedRace.recordFix(comp,
|
||||
new GPSFixMovingImpl(new DegreePosition(49.295768, 8.639108),
|
||||
new MillisecondsTimePoint(START_OF_RACE + 50),
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100))));
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null));
|
||||
trackedRace.recordFix(comp,
|
||||
new GPSFixMovingImpl(new DegreePosition(49.295761, 8.639180),
|
||||
new MillisecondsTimePoint(START_OF_RACE + 60),
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100))));
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null));
|
||||
trackedRace.recordFix(comp,
|
||||
new GPSFixMovingImpl(new DegreePosition(49.295765, 8.639278),
|
||||
new MillisecondsTimePoint(START_OF_RACE + 70),
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100))));
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null));
|
||||
trackedRace.recordFix(comp,
|
||||
new GPSFixMovingImpl(new DegreePosition(49.295785, 8.639353),
|
||||
new MillisecondsTimePoint(START_OF_RACE + 80),
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100))));
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null));
|
||||
trackedRace.recordFix(comp,
|
||||
new GPSFixMovingImpl(new DegreePosition(49.295817, 8.639406),
|
||||
new MillisecondsTimePoint(START_OF_RACE + 90),
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100))));
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null));
|
||||
trackedRace.recordFix(comp,
|
||||
new GPSFixMovingImpl(new DegreePosition(49.295861, 8.639449),
|
||||
new MillisecondsTimePoint(START_OF_RACE + 100),
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100))));
|
||||
new KilometersPerHourSpeedWithBearingImpl(1, new DegreeBearingImpl(100)), /* optionalTrueHeading */ null));
|
||||
|
||||
List<MarkPassing> markPassings = new ArrayList<>();
|
||||
markPassings.add(new MarkPassingImpl(new MillisecondsTimePoint(START_OF_RACE), waypoint1, comp));
|
||||
|
||||
+2
-2
@@ -360,7 +360,7 @@ public class MasterDataImportTest {
|
||||
logTimePoint3);
|
||||
regatta.getRegattaLog().add(mappingEvent);
|
||||
GPSFix gpsFix = new GPSFixMovingImpl(new DegreePosition(54.333, 10.133), logTimePoint2,
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(90)));
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(90)), /* optionalTrueHeading */ null);
|
||||
sourceService.getSensorFixStore().storeFix(deviceIdentifier, gpsFix);
|
||||
// test to check that batch-import of fixes works as intended
|
||||
DeviceIdentifier deviceBatch1 = addDeviceMappingWithFixes(sourceService, regatta, competitor, logTimePoint, logTimePoint3, logTimePoint4, "x", 4999);
|
||||
@@ -524,7 +524,7 @@ public class MasterDataImportTest {
|
||||
List<GPSFix> fixesToSave = new ArrayList<>(numFixes);
|
||||
for(int i = 1; i <= numFixes; i++) {
|
||||
fixesToSave.add(new GPSFixMovingImpl(new DegreePosition(54.333, 10.133), logTimePoint.plus(i),
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(90))));
|
||||
new KnotSpeedWithBearingImpl(10, new DegreeBearingImpl(90)), /* optionalTrueHeading */ null));
|
||||
}
|
||||
sourceService.getSensorFixStore().storeFixes(deviceIdentifier, fixesToSave, /* returnManeuverUpdate */ false, /* returnLiveDelay */ false);
|
||||
return deviceIdentifier;
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ public abstract class BaseGPSFixImporterImpl implements GPSFixImporter {
|
||||
return;
|
||||
}
|
||||
SpeedWithBearing speedWithBearing = previousFix.getSpeedAndBearingRequiredToReach(fix);
|
||||
fix = new GPSFixMovingImpl(fix.getPosition(), fix.getTimePoint(), speedWithBearing);
|
||||
fix = new GPSFixMovingImpl(fix.getPosition(), fix.getTimePoint(), speedWithBearing, /* optionalTrueHeading */ null);
|
||||
}
|
||||
previousFix = fix;
|
||||
callback.addFix(fix, device);
|
||||
|
||||
+1
-1
@@ -209,7 +209,7 @@ public class RouteConverterGPSFixImporterImpl extends BaseRouteConverterGPSFixIm
|
||||
if (speedInKilometersPerHour != null && heading != null) {
|
||||
SpeedWithBearing speedWithBearing = new KilometersPerHourSpeedWithBearingImpl(
|
||||
speedInKilometersPerHour, new DegreeBearingImpl(heading));
|
||||
result = new GPSFixMovingImpl(pos, timePoint, speedWithBearing);
|
||||
result = new GPSFixMovingImpl(pos, timePoint, speedWithBearing, /* optionalTrueHeading */ null); // we assume the Wgs84Position.getHeading() method returns COG, not HDG/HDT
|
||||
} else {
|
||||
result = new GPSFixImpl(pos, timePoint);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
<ul class="bulletList">
|
||||
<li>The TracTrac API now offers <tt>STP</tt> and <tt>SCP</tt> as new race competitor status values
|
||||
that we now map to our corresponding "IRM" / penalty codes.</li>
|
||||
<li>A bug in the way mark passing calculation results were stored persistently lead to some races
|
||||
"losing" their mark passings when the server was re-started. This bug is fixed now.</li>
|
||||
</ul>
|
||||
<h2 class="articleSubheadline">January 2024</h2>
|
||||
<ul class="bulletList">
|
||||
|
||||
@@ -36,7 +36,6 @@ Export-Package: com.tractrac.asio.lib.api,
|
||||
com.tractrac.dataflow.lib.prov.live.ascii,
|
||||
com.tractrac.dataflow.lib.prov.live.provider,
|
||||
com.tractrac.dataflow.lib.prov.live.server,
|
||||
com.tractrac.dataflow.lib.prov.live.tcp,
|
||||
com.tractrac.dataflow.lib.prov.live.tcp.provider,
|
||||
com.tractrac.dataflow.lib.prov.live.tcp.server,
|
||||
com.tractrac.dataflow.lib.prov.stored.mtb,
|
||||
|
||||
Reference in New Issue
Block a user