use of au.gov.amsa.geo.TimedPosition in project risky by amsa-code.
the class DistanceTravelledInEezMain method calculateDistance.
private static Observable<? extends Vessel> calculateDistance(File file, Shapefile eezLine, Shapefile eezPolygon, GroupedObservable<Integer, Fix> o) {
return Observable.defer(() -> {
State state = new State();
state.date = file.getName().substring(0, file.getName().indexOf(".track.gz"));
state.mmsi = o.getKey();
state.location = Location.UNKNOWN;
return //
o.compose(//
Downsample.minTimeStep(5, TimeUnit.MINUTES)).lift(new OperatorEffectiveSpeedChecker(SegmentOptions.builder().acceptAnyFixHours(480L).maxSpeedKnots(50).build())).filter(//
check -> check.isOk()).map(//
check -> check.fix()).doOnNext(fix -> {
// TODO unit test
boolean inside = eezPolygon.contains(fix.lat(), fix.lon());
Location location = inside ? Location.IN : Location.OUT;
if (state.location != Location.UNKNOWN) {
boolean crossed = state.location != location;
if (crossed) {
TimedPosition point = ShapefileUtil.findRegionCrossingPoint(eezLine, state.fix, fix);
final double distance;
if (location == Location.IN) {
distance = distanceKm(fix.lat(), fix.lon(), point.lat, point.lon);
} else {
distance = distanceKm(state.fix.lat(), state.fix.lon(), point.lat, point.lon);
}
state.distanceKm += distance;
double d = distanceKm(state.fix.lat(), state.fix.lon(), fix.lat(), fix.lon());
if (d >= MIN_DISTANCE_KM_TO_ESTIMATE_TIME) {
// we ensure that d is not close to zero so that the time estimate does not get
// blown out by instability in the division.
state.totalTimeMs += distance / d * (fix.time() - state.fix.time());
}
} else if (location == Location.IN) {
state.distanceKm += distanceKm(state.fix.lat(), state.fix.lon(), fix.lat(), fix.lon());
state.totalTimeMs += fix.time() - state.fix.time();
}
}
state.fix = fix;
state.location = location;
}).count().map(count -> new Vessel(count, state));
});
}
Aggregations