package au.gov.amsa.geo; import java.nio.ByteBuffer; import java.util.concurrent.atomic.AtomicBoolean; import rx.Observable.Operator; import rx.Observer; import rx.Subscriber; import rx.observers.Subscribers; import au.gov.amsa.geo.model.Bounds; import au.gov.amsa.geo.model.CellValue; import au.gov.amsa.geo.model.Options; public class OperatorCellValuesToBytes implements Operator<byte[], CellValue> { private final Options options; public OperatorCellValuesToBytes(Options options) { this.options = options; } @Override public Subscriber<? super CellValue> call( final Subscriber<? super byte[]> child) { Subscriber<CellValue> parent = Subscribers .from(new Observer<CellValue>() { final AtomicBoolean first = new AtomicBoolean(true); @Override public void onCompleted() { child.onCompleted(); } @Override public void onError(Throwable e) { child.onError(e); } @Override public void onNext(CellValue cv) { if (first.getAndSet(false)) child.onNext(toBytes(options)); child.onNext(toBytes(cv)); } }); child.add(parent); return parent; } private static byte[] toBytes(Options options) { ByteBuffer bb = ByteBuffer.allocate(40); Bounds b = options.getBounds(); bb.putDouble(options.getCellSizeDegreesAsDouble()); bb.putDouble(b.getTopLeftLat()); bb.putDouble(b.getTopLeftLon()); bb.putDouble(b.getBottomRightLat()); bb.putDouble(b.getBottomRightLon()); return bb.array(); } private static byte[] toBytes(CellValue cv) { ByteBuffer bb = ByteBuffer.allocate(16); bb.putFloat((float) cv.getCentreLat()); bb.putFloat((float) cv.getCentreLon()); bb.putDouble(cv.getValue()); return bb.array(); } }