mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-20 12:45:35 +00:00
bug6076: fixing OutlierFilter, recognize Vakaros timestamp headers
This commit is contained in:
+22
@@ -4,11 +4,16 @@ import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sailing.domain.trackimport.FormatNotSupportedException;
|
||||
import com.sap.sailing.server.trackfiles.impl.ExpeditionExtendedDataImporterImpl;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public class VakarosExtendedDataImporterImpl extends ExpeditionExtendedDataImporterImpl {
|
||||
private static final Logger logger = Logger.getLogger(VakarosExtendedDataImporterImpl.class.getName());
|
||||
|
||||
private static final DateFormat timestampFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
|
||||
private static final String VAKAROS_EXTENDED = "VAKAROS_EXTENDED";
|
||||
|
||||
@@ -22,4 +27,21 @@ public class VakarosExtendedDataImporterImpl extends ExpeditionExtendedDataImpor
|
||||
return TimePoint.of(timestampFormat
|
||||
.parse(lineContentTokens[columnsInFileFromHeader.get(VakarosGPSFixImporter.TIMESTAMP_COLUMN_HEADING)]+"Z"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that all columns in
|
||||
* {@link #columnNamesInFileAndTheirValueIndexInResultingDoubleVectorFix}'s
|
||||
* key set are present in {@code colIndicesInFile}'s key set. If not, an
|
||||
* exception is thrown that reports the columns missing.
|
||||
*/
|
||||
@Override
|
||||
public void validateHeader(Map<String, Integer> colIndicesInFile) throws FormatNotSupportedException {
|
||||
final boolean dateTimeFormatOk;
|
||||
dateTimeFormatOk = colIndicesInFile.containsKey(VakarosGPSFixImporter.TIMESTAMP_COLUMN_HEADING);
|
||||
if (!dateTimeFormatOk) {
|
||||
final String msg = "Missing timestamp header; expected "+VakarosGPSFixImporter.TIMESTAMP_COLUMN_HEADING;
|
||||
logger.log(Level.SEVERE, msg);
|
||||
throw new FormatNotSupportedException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -8,6 +8,7 @@ import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@@ -35,6 +36,8 @@ public class VakarosGPSFixImporter implements GPSFixImporter {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(VakarosGPSFixImporter.class.getName());
|
||||
|
||||
private static final List<String> supportedExpeditionLogFileExtensions = Arrays.asList("csv", "vak", "zip", "gz");
|
||||
|
||||
static final String TIMESTAMP_COLUMN_HEADING = "timestamp";
|
||||
private static final String LAT_COLUMN_HEADING = "latitude";
|
||||
private static final String LON_COLUMN_HEADING = "longitude";
|
||||
@@ -129,7 +132,7 @@ public class VakarosGPSFixImporter implements GPSFixImporter {
|
||||
|
||||
@Override
|
||||
public Iterable<String> getSupportedFileExtensions() {
|
||||
return ExpeditionImportFileHandler.supportedExpeditionLogFileExtensions;
|
||||
return supportedExpeditionLogFileExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-5
@@ -116,7 +116,7 @@ public class OutlierFilter {
|
||||
*/
|
||||
private Pair<GPSFixMoving, Double> isLikelyOutlierWithCorrectableTimepoint(DynamicGPSFixTrack<Competitor, GPSFixMoving> track,
|
||||
GPSFixMoving previous, GPSFixMoving fix, GPSFixMoving next) {
|
||||
final int HOW_MANY_CRITERIA_TO_FULFILL = 3;
|
||||
final int HOW_MANY_CRITERIA_TO_FULFILL = 2;
|
||||
final double DISTANCE_RATIO_TOLERANCE = 0.5; // ratio between cross-track distance and length of closest segment
|
||||
final Pair<GPSFixMoving, Double> adjustedFixAndDistance;
|
||||
int criteriaFulfilled = 0;
|
||||
@@ -129,7 +129,7 @@ public class OutlierFilter {
|
||||
if (hasInconsistentCogSog(previous, fix, next, /* speed ratio tolerance */ 0.1, /* course degree tolerance */ 10)) {
|
||||
criteriaFulfilled++;
|
||||
}
|
||||
if (criteriaFulfilled >= HOW_MANY_CRITERIA_TO_FULFILL-1) {
|
||||
if (criteriaFulfilled >= HOW_MANY_CRITERIA_TO_FULFILL) {
|
||||
final Pair<GPSFixMoving, Double> adjusted = adjust(previous, fix, track);
|
||||
if (adjusted.getB() > DISTANCE_RATIO_TOLERANCE) {
|
||||
adjustedFixAndDistance = null;
|
||||
@@ -140,7 +140,7 @@ public class OutlierFilter {
|
||||
} else {
|
||||
adjustedFixAndDistance = null;
|
||||
}
|
||||
assert criteriaFulfilled >= 3 || adjustedFixAndDistance == null;
|
||||
assert criteriaFulfilled >= HOW_MANY_CRITERIA_TO_FULFILL || adjustedFixAndDistance == null;
|
||||
return adjustedFixAndDistance;
|
||||
}
|
||||
|
||||
@@ -225,10 +225,11 @@ public class OutlierFilter {
|
||||
final Distance alongTrackDistanceFromLastFix = fixPosition.alongTrackDistance(lastFix.getPosition(), bearingFromLastToCurrent);
|
||||
// interpolate the time between the adjacent fixes to whose connection "fix" is closest, splitting the duration
|
||||
// between the adjacent fixes proportionately based on "fix"'s distances to each of the two adjacent fixes:
|
||||
final Distance distanceFromLastFixToCurrentFix = lastFix.getPosition().getDistance(currentFix.getPosition());
|
||||
final TimePoint inferredTimePointForFix = lastFix.getTimePoint().plus(lastFix.getTimePoint().until(currentFix.getTimePoint()).times(
|
||||
alongTrackDistanceFromLastFix.divide(lastFix.getPosition().getDistance(currentFix.getPosition()))));
|
||||
distanceFromLastFixToCurrentFix.equals(Distance.NULL) ? 0.5 : alongTrackDistanceFromLastFix.divide(distanceFromLastFixToCurrentFix)));
|
||||
result = new GPSFixMovingImpl(fixPosition, inferredTimePointForFix, fix.getSpeed(), fix.getOptionalTrueHeading());
|
||||
distanceRatio = distanceFromSegment.divide(lastFix.getPosition().getDistance(currentFix.getPosition()));
|
||||
distanceRatio = distanceFromSegment.divide(distanceFromLastFixToCurrentFix);
|
||||
} else { // we found a minimum after fix:
|
||||
foundMinimum = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user