package au.gov.amsa.geo.distance;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Optional;
import au.gov.amsa.geo.model.SegmentOptions;
import au.gov.amsa.risky.format.Fix;
import au.gov.amsa.util.navigation.Position;
public class EffectiveSpeedChecker {
public static boolean effectiveSpeedOk(Fix a, Fix b, SegmentOptions o) {
return effectiveSpeedOk(a.time(), a.lat(), a.lon(), b.time(), b.lat(), b.lon(), o);
}
public static boolean effectiveSpeedOk(long aTime, double aLat, double aLon, long bTime,
double bLat, double bLon, SegmentOptions o) {
Optional<Double> speedKnots = effectiveSpeedKnots(aTime, aLat, aLon, bTime, bLat, bLon, o);
return !speedKnots.isPresent() || speedKnots.get() <= o.maxSpeedKnots();
}
public static Optional<Double> effectiveSpeedKnots(Fix a, Fix b, SegmentOptions o) {
return effectiveSpeedKnots(a.time(), a.lat(), a.lon(), b.time(), b.lat(), b.lon(), o);
}
public static Optional<Double> effectiveSpeedKnots(long aTime, double aLat, double aLon,
long bTime, double bLat, double bLon, SegmentOptions o) {
long timeDiffMs = Math.abs(aTime - bTime);
if (o.acceptAnyFixAfterHours() != null
&& timeDiffMs >= TimeUnit.HOURS.toMillis(o.acceptAnyFixAfterHours())) {
return Optional.absent();
} else {
double distanceBetweenFixesNm = Position.create(aLat, aLon)
.getDistanceToKm(Position.create(bLat, bLon)) / 1.852;
if (distanceBetweenFixesNm > o.speedCheckDistanceThresholdNm()) {
double timeDiffHoursFloored = (double) Math.max(timeDiffMs,
o.speedCheckMinTimeDiffMs()) / TimeUnit.HOURS.toMillis(1);
double effectiveSpeedKnots = distanceBetweenFixesNm / timeDiffHoursFloored;
return Optional.of(effectiveSpeedKnots);
} else
return Optional.absent();
}
}
}