use of au.gov.amsa.navigation.VesselPosition in project risky by amsa-code.
the class DriftingLayer method filenameToDriftCandidates.
private static Func1<String, Observable<DriftCandidate>> filenameToDriftCandidates() {
return new Func1<String, Observable<DriftCandidate>>() {
@Override
public Observable<DriftCandidate> call(final String filename) {
return Streams.nmeaFromGzip(filename).compose(AisVesselPositions.positions()).doOnRequest(new Action1<Long>() {
@Override
public void call(Long n) {
// log.info("requested=" + n);
}
}).doOnNext(new Action1<VesselPosition>() {
final long startTime = System.currentTimeMillis();
long lastTime = System.currentTimeMillis();
DecimalFormat df = new DecimalFormat("0");
@Override
public void call(VesselPosition vp) {
long n = 100000;
if (totalCount.incrementAndGet() % n == 0) {
long now = System.currentTimeMillis();
final double rate;
if (now == lastTime)
rate = -1;
else {
rate = n / (double) (now - lastTime) * 1000d;
}
lastTime = now;
final double rateSinceStart;
if (now == startTime)
rateSinceStart = -1;
else
rateSinceStart = totalCount.get() / (double) (now - startTime) * 1000d;
log.info("totalCount=" + totalCount.get() + ", msgsPerSecond=" + df.format(rate) + ", msgPerSecondOverall=" + df.format(rateSinceStart));
}
}
}).compose(DriftDetector.detectDrift()).subscribeOn(Schedulers.computation()).doOnCompleted(new Action0() {
@Override
public void call() {
log.info("finished " + filename);
}
});
}
};
}
use of au.gov.amsa.navigation.VesselPosition in project risky by amsa-code.
the class DriftingLayer method render.
@Override
public void render(Graphics2D g, WmsRequest request) {
log.info("request=" + request);
log.info("drawing " + queue.size() + " positions");
final Projector projector = WmsUtil.getProjector(request);
Position a = projector.toPosition(0, 0);
Position b = projector.toPosition(request.getWidth(), request.getHeight());
Rectangle r = Geometries.rectangle(a.getLon(), b.getLat(), b.getLon(), a.getLat());
Optional<VesselPosition> last = Optional.empty();
Optional<Point> lastPoint = Optional.empty();
// Iterable<VesselPosition> positions = tree
// .search(r)
// .map(new Func1<Entry<VesselPosition,
// com.github.davidmoten.rtree.geometry.Point>, VesselPosition>() {
//
// @Override
// public VesselPosition call(
// Entry<VesselPosition, com.github.davidmoten.rtree.geometry.Point>
// entry) {
// return entry.value();
// }
//
// }).toBlocking().toIterable();
ConcurrentLinkedQueue<VesselPosition> positions = queue;
Point startPoint = null;
for (VesselPosition p : positions) {
// expecting positions to be in mmsi, time order
Point point = projector.toPoint(p.lat(), p.lon());
if (last.isPresent() && p.id().equals(last.get().id()) && p.data().isPresent() && !p.data().get().equals(p.time()) && isOkMovement(p, last.get())) {
// join the last position with this one with a line
g.setColor(Color.gray);
g.drawLine(lastPoint.get().x, lastPoint.get().y, point.x, point.y);
}
if (p.data().get().equals(p.time()) || (last.isPresent() && !isOkMovement(p, last.get()))) {
g.setColor(Color.red);
g.drawRect(point.x, point.y, 1, 1);
startPoint = point;
} else if (startPoint != null) {
// draw intermediate point
g.setColor(Color.darkGray);
g.drawRect(point.x, point.y, 1, 1);
// redraw startPoint so that a slightly moving drift doesn't
// overdraw the startPoint with the color of an intermediate
// point
g.setColor(Color.red);
g.drawRect(startPoint.x, startPoint.y, 1, 1);
}
last = Optional.of(p);
lastPoint = Optional.of(point);
}
log.info("drawn");
}
use of au.gov.amsa.navigation.VesselPosition in project risky by amsa-code.
the class DriftingLayer method getInfo.
@Override
public String getInfo(Date time, WmsRequest request, final Point point, String mimeType) {
final int HOTSPOT_SIZE = 5;
final Projector projector = WmsUtil.getProjector(request);
final StringBuilder response = new StringBuilder();
response.append("<html>");
Observable.from(queue).filter(new Func1<VesselPosition, Boolean>() {
@Override
public Boolean call(VesselPosition p) {
Point pt = projector.toPoint(p.lat(), p.lon());
return Math.abs(point.x - pt.x) <= HOTSPOT_SIZE && Math.abs(point.y - pt.y) <= HOTSPOT_SIZE;
}
}).doOnNext(new Action1<VesselPosition>() {
@Override
public void call(VesselPosition p) {
response.append("<p>");
response.append("<a href=\"https://www.fleetmon.com/en/vessels?s=" + p.id().uniqueId() + "\">mmsi=" + p.id().uniqueId() + "</a>, time=" + new Date(p.time()));
if (p.shipType().isPresent()) {
response.append(", ");
response.append(ShipTypeDecoder.getShipType(p.shipType().get()));
}
response.append("</p>");
response.append("<p>");
response.append(p.toString());
response.append("</p>");
}
}).subscribe();
response.append("</html>");
return response.toString();
}
use of au.gov.amsa.navigation.VesselPosition in project risky by amsa-code.
the class OperatorDriftDistanceCheck method call.
@Override
public Subscriber<? super VesselPosition> call(final Subscriber<? super VesselPosition> child) {
return new Subscriber<VesselPosition>(child) {
Optional<Position> min = empty();
Optional<Position> max = empty();
Optional<Identifier> id = empty();
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();
}
}
};
}
Aggregations