package au.gov.amsa.craft.analyzer.wms; import static com.google.common.base.Optional.absent; import java.util.LinkedList; import java.util.List; import rx.Observable.Operator; import rx.Subscriber; import au.gov.amsa.navigation.Identifier; import au.gov.amsa.navigation.VesselPosition; import com.github.davidmoten.grumpy.core.Position; import com.google.common.base.Optional; public class OperatorDriftDistanceCheck implements Operator<VesselPosition, VesselPosition> { protected static final double MIN_DISTANCE_THRESHOLD_KM = 5 * 1.852; @Override public Subscriber<? super VesselPosition> call(final Subscriber<? super VesselPosition> child) { return new Subscriber<VesselPosition>(child) { Optional<Position> min = absent(); Optional<Position> max = absent(); Optional<Identifier> id = absent(); List<VesselPosition> buffer = new LinkedList<VesselPosition>(); @Override public void onCompleted() { buffer.clear(); child.onCompleted(); } @Override public void onError(Throwable e) { buffer.clear(); child.onError(e); } @Override public void onNext(VesselPosition vp) { if (!id.isPresent() || (id.isPresent() && vp.id().uniqueId() != id.get().uniqueId()) || vp.data().get().equals(vp.time())) { min = Optional.of(Position.create(vp.lat(), vp.lon())); max = Optional.of(Position.create(vp.lat(), vp.lon())); id = Optional.of(vp.id()); buffer.clear(); } else { min = Optional.of(min(min.get(), Position.create(vp.lat(), vp.lon()))); max = Optional.of(max(max.get(), Position.create(vp.lat(), vp.lon()))); } buffer.add(vp); if (distanceKm(min.get(), max.get()) >= MIN_DISTANCE_THRESHOLD_KM) { for (VesselPosition p : buffer) { child.onNext(p); } buffer.clear(); } } }; } private double distanceKm(Position a, Position b) { return a.getDistanceToKm(b); } private static Position min(Position a, Position b) { return Position.create(Math.min(a.getLat(), b.getLat()), Math.min(a.getLon(), b.getLon())); } private static Position max(Position a, Position b) { return Position.create(Math.max(a.getLat(), b.getLat()), Math.max(a.getLon(), b.getLon())); } }