use of au.gov.amsa.geo.model.Cell in project risky by amsa-code.
the class DistanceTravelledCalculator method calculateDistanceByCellFromFiles.
/**
* Returns distinct cells and the the total nautical miles travelled in that
* cell. Uses RxJava {@link Observable}s to maximize throughput and will
* scale to use all available processors and to handle a large number of
* files (number of open file handles should be limited by number of
* available processors).
*
* @param files
* @return
*/
public Observable<CellAndDistance> calculateDistanceByCellFromFiles(Observable<File> files) {
// use a map-reduce approach where the parallel method shares out
// ('maps') the fixes by craft to multiple threads (number determined by
// available processors) and is passed the 'reduce'
// calculateDistanceByCellFromFile() method to combine the results.
int numFiles = files.count().toBlocking().single();
log.info("numFiles=" + numFiles);
AtomicLong fileCount = new AtomicLong();
AtomicLong cellCount = new AtomicLong(1);
return files.buffer(Math.max(1, (int) Math.round(Math.ceil(numFiles / Runtime.getRuntime().availableProcessors())))).flatMap(fileList -> extractCellDistances(fileCount, cellCount, fileList)).collect(bigMapFactory(), collectCellDistances()).flatMap(listCellDistances()).doOnNext(sumNauticalMiles());
}
use of au.gov.amsa.geo.model.Cell 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.Cell in project risky by amsa-code.
the class OperatorSumCellDistances method call.
@Override
public Subscriber<? super CellAndDistance> call(final Subscriber<? super Map<Cell, Double>> child) {
Subscriber<CellAndDistance> parent = new Subscriber<CellAndDistance>(child) {
@Override
public void onCompleted() {
try {
child.onNext(Collections.unmodifiableMap(map));
child.onCompleted();
} catch (Throwable t) {
onError(t);
}
}
@Override
public void onError(Throwable e) {
child.onError(e);
}
@Override
public void onNext(CellAndDistance cd) {
Cell key = cd.getCell();
Double val = map.putIfAbsent(key, cd.getDistanceNm());
if (val != null) {
map.put(key, val + cd.getDistanceNm());
request(1);
} else {
if (map.size() == maxSize) {
Map<Cell, Double> m = map;
map = createMap();
child.onNext(Collections.unmodifiableMap(m));
} else
request(1);
}
}
};
return parent;
}
Aggregations