use of au.gov.amsa.geo.model.CellValue in project risky by amsa-code.
the class DistanceTravelledCalculator method saveCalculationResultAsNetcdf.
public static void saveCalculationResultAsNetcdf(Options options, CalculationResult calculationResult, String filename) {
List<CellValue> list = calculationResult.getCells().toList().toBlocking().single();
int maxLonIndex = list.stream().map(cell -> options.getGrid().cellAt(cell.getCentreLat(), cell.getCentreLon())).filter(//
x -> x.isPresent()).map(x -> x.get().getLonIndex()).max(//
Comparator.<Long>naturalOrder()).get().intValue();
int maxLatIndex = list.stream().map(cell -> options.getGrid().cellAt(cell.getCentreLat(), cell.getCentreLon())).filter(x -> x.isPresent()).map(x -> x.get().getLatIndex()).max(Comparator.<Long>naturalOrder()).get().intValue();
File file = new File(filename);
// Create the file.
NetcdfFileWriter f = null;
try {
// Create new netcdf-3 file with the given filename
f = NetcdfFileWriter.createNew(NetcdfFileWriter.Version.netcdf3, file.getPath());
// In addition to the latitude and longitude dimensions, we will
// also create latitude and longitude netCDF variables which will
// hold the actual latitudes and longitudes. Since they hold data
// about the coordinate system, the netCDF term for these is:
// "coordinate variables."
Dimension dimLat = f.addDimension(null, "latitude", maxLatIndex + 1);
Dimension dimLon = f.addDimension(null, "longitude", maxLonIndex + 1);
List<Dimension> dims = new ArrayList<Dimension>();
dims.add(dimLat);
dims.add(dimLon);
// coordinate variables
Variable vLat = f.addVariable(null, "latitude", DataType.DOUBLE, "latitude");
Variable vLon = f.addVariable(null, "longitude", DataType.DOUBLE, "longitude");
// value variables
Variable vDensity = f.addVariable(null, "traffic_density", DataType.DOUBLE, dims);
// Define units attributes for coordinate vars. This attaches a
// text attribute to each of the coordinate variables, containing
// the units.
vLon.addAttribute(new Attribute("units", "degrees_east"));
vLat.addAttribute(new Attribute("units", "degrees_north"));
// Define units attributes for variables.
vDensity.addAttribute(new Attribute("units", "nm-1"));
vDensity.addAttribute(new Attribute("long_name", ""));
// Write the coordinate variable data. This will put the latitudes
// and longitudes of our data grid into the netCDF file.
f.create();
{
Array dataLat = Array.factory(DataType.DOUBLE, new int[] { dimLat.getLength() });
Array dataLon = Array.factory(DataType.DOUBLE, new int[] { dimLon.getLength() });
// set latitudes
for (int i = 0; i <= maxLatIndex; i++) {
dataLat.setDouble(i, options.getGrid().centreLat(i));
}
// set longitudes
for (int i = 0; i <= maxLonIndex; i++) {
dataLon.setDouble(i, options.getGrid().centreLon(i));
}
f.write(vLat, dataLat);
f.write(vLon, dataLon);
}
// write the value variable data
{
int[] iDim = new int[] { dimLat.getLength(), dimLon.getLength() };
Array dataDensity = ArrayDouble.D2.factory(DataType.DOUBLE, iDim);
Index2D idx = new Index2D(iDim);
for (CellValue point : list) {
Optional<Cell> cell = options.getGrid().cellAt(point.getCentreLat(), point.getCentreLon());
if (cell.isPresent()) {
idx.set((int) cell.get().getLatIndex(), (int) cell.get().getLonIndex());
dataDensity.setDouble(idx, point.getValue());
}
}
f.write(vDensity, dataDensity);
}
} catch (IOException | InvalidRangeException e) {
throw new RuntimeException(e);
} finally {
if (f != null) {
try {
f.close();
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
}
}
}
use of au.gov.amsa.geo.model.CellValue in project risky by amsa-code.
the class OperatorCellValuesToBytes method call.
@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;
}
use of au.gov.amsa.geo.model.CellValue in project risky by amsa-code.
the class Renderer method getStatistics.
private static Statistics getStatistics(Observable<CellValue> cells) {
final AtomicDouble sum = new AtomicDouble(0);
final AtomicDouble sumSquares = new AtomicDouble(0);
log.info("calculating mean and sd");
long count = cells.doOnNext(new Action1<CellValue>() {
@Override
public void call(CellValue cell) {
sum.addAndGet(cell.getValue());
sumSquares.addAndGet(cell.getValue() * cell.getValue());
}
}).count().toBlocking().single();
double mean = sum.get() / count;
double variance = sumSquares.get() / count - mean * mean;
double sd = Math.sqrt(variance);
log.info("calculated");
Statistics stats = new Statistics(mean, sd, count);
log.info(stats.toString());
return stats;
}
use of au.gov.amsa.geo.model.CellValue in project risky by amsa-code.
the class OperatorSumCellValues method call.
// private final AtomicLong count = new AtomicLong();
@Override
public Subscriber<? super CellValue> call(final Subscriber<? super CellValue> child) {
Subscriber<CellValue> parent = Subscribers.from(new Observer<CellValue>() {
@Override
public void onCompleted() {
// MapDb.INSTANCE.getDb().commit();
try {
log.info("starting to emit map values");
synchronized (map) {
for (Entry<Position, Double> entry : map.entrySet()) {
CellValue cv = new CellValue(entry.getKey().lat(), entry.getKey().lon(), entry.getValue().doubleValue());
child.onNext(cv);
}
}
child.onCompleted();
} catch (Throwable t) {
onError(t);
}
}
@Override
public void onError(Throwable e) {
child.onError(e);
}
@Override
public void onNext(CellValue cv) {
Position position = new Position((float) cv.getCentreLat(), (float) cv.getCentreLon());
Double val = map.putIfAbsent(position, cv.getValue());
if (val != null)
map.put(position, val + cv.getValue());
}
});
child.add(parent);
return parent;
}
use of au.gov.amsa.geo.model.CellValue in project risky by amsa-code.
the class Renderer method paintMap.
public static void paintMap(final Graphics2D g, Bounds b, final double cellSizeDegrees, double numberStandardDeviationsForHighValue, final int w, final int h, Observable<CellValue> cells, final boolean addLegend, final Func1<Position, Point> locator) {
final Statistics metrics = getStatistics(cells);
final double maxNmForColour = metrics.mean + numberStandardDeviationsForHighValue * metrics.sd;
final double minSaturation = 0.05;
cells.observeOn(Schedulers.immediate()).subscribeOn(Schedulers.immediate()).doOnNext(new Action1<CellValue>() {
@Override
public void call(CellValue cell) {
double topLeftLat = cell.getCentreLat() + cellSizeDegrees / 2;
double topLeftLon = cell.getCentreLon() - cellSizeDegrees / 2;
double bottomRightLat = cell.getCentreLat() - cellSizeDegrees / 2;
double bottomRightLon = cell.getCentreLon() + cellSizeDegrees / 2;
Point topLeft = locator.call(new Position(topLeftLat, topLeftLon));
Point bottomRight = locator.call(new Position(bottomRightLat, bottomRightLon));
double d = cell.getValue();
double prop = Math.min(d, maxNmForColour) / maxNmForColour;
Color color = toColor(minSaturation, prop);
g.setColor(color);
g.fillRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y);
}
}).count().toBlocking().single();
if (addLegend)
paintLegend(g, cellSizeDegrees, metrics, maxNmForColour, minSaturation, w, h);
}
Aggregations