use of ucar.ma2.Index2D 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);
}
}
}
}
Aggregations