using Index to quickly and elegantly iterate through Array

Change-Id: Ibdb2abd9027bc2f64442fdea000e8d68afbefa40
This commit is contained in:
Axel Uhl
2017-02-08 14:12:13 +01:00
parent a360cd2db4
commit 32b3944311
3 changed files with 20 additions and 16 deletions
@@ -240,7 +240,7 @@ public abstract class AbstractGribWindFieldImpl implements GribWindField {
* Instead of using {@link GridDatatype#readDataSlice(int, int, int, int)} which really reads from the file(s),
* use an already read {@link Array} of mass data here.
*/
protected double getValue(Array gridData, int timeIndex, int zIndex, final int x, final int y) throws IOException {
protected double getValue(Array gridData, int zIndex, final int x, final int y) throws IOException {
final double valueAsFloat;
if (gridData.getRank() == 3) { // includes z dimension
valueAsFloat = gridData.getDouble(Index.factory(new int[] { zIndex, y, x }));
@@ -252,23 +252,23 @@ public abstract class AbstractGribWindFieldImpl implements GribWindField {
@FunctionalInterface
static interface ValueForCoordinateProvider<T> {
T getValue(Array gridData, int timeIndex, int x, int y, TimePoint timePoint, Position position);
T getValue(Array gridData, int timeIndex, Index index, TimePoint timePoint, Position position);
}
protected <T> Iterable<T> foreach(GridDatatype grid, ValueForCoordinateProvider<T> provider) throws IOException {
final List<T> result = new ArrayList<>();
final GridCoordSystem coordinateSystem = grid.getCoordinateSystem();
final int timeDimLength = grid.getTimeDimension().getLength();
final int xDimLength = grid.getXDimension().getLength();
final int yDimLength = grid.getYDimension().getLength();
for (int t=0; t<timeDimLength; t++) {
final Array gridData = grid.readVolumeData(t);
final TimePoint timePoint = toTimePoint(coordinateSystem.getTimeAxis1D().getCalendarDate(t));
for (int x=0; x<xDimLength; x++) {
for (int y=0; y<yDimLength; y++) {
final Position position = toPosition(coordinateSystem.getLatLon(x, y));
result.add(provider.getValue(gridData, t, x, y, timePoint, position));
}
final Array gridData = grid.readVolumeData(t);
final long arraySize = gridData.getSize();
final Index index = gridData.getIndex();
for (long i=0; i<arraySize; i++) {
final Position position = toPosition(coordinateSystem.getLatLon(/* x */ index.getCurrentCounter()[index.getCurrentCounter().length-1],
/* y */ index.getCurrentCounter()[index.getCurrentCounter().length-2]));
result.add(provider.getValue(gridData, t, index, timePoint, position));
index.incr();
}
}
return result;
@@ -20,6 +20,7 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Triple;
import ucar.ma2.Array;
import ucar.ma2.Index;
import ucar.nc2.dt.GridDatatype;
import ucar.nc2.dt.grid.GridDataset;
import ucar.nc2.ft.FeatureDataset;
@@ -118,7 +119,7 @@ public class SpeedAndDirectionWindField extends AbstractGribWindFieldImpl {
if (directionGrid != null && speedGrid != null) {
final GridDatatype finalSpeedGrid = speedGrid;
final Map<Integer, Array> speedGridDataCache = new HashMap<>();
for (final Wind wind : foreach(directionGrid, (Array directionGridData, int timeIndex, int x, int y, TimePoint timePoint, Position position)->{
for (final Wind wind : foreach(directionGrid, (Array directionGridData, int timeIndex, Index index, TimePoint timePoint, Position position)->{
try {
final Wind wind;
Array speedGridData = speedGridDataCache.get(timeIndex);
@@ -126,8 +127,8 @@ public class SpeedAndDirectionWindField extends AbstractGribWindFieldImpl {
speedGridData = finalSpeedGrid.readVolumeData(timeIndex);
speedGridDataCache.put(timeIndex, speedGridData);
}
double speedInMetersPerSecond = getValue(speedGridData, timeIndex, /* zIndex */ 0, x, y);
double trueDirectionFromInDeg = getValue(directionGridData, timeIndex, /* zIndex */ 0, x, y);
double speedInMetersPerSecond = speedGridData.getDouble(index);
double trueDirectionFromInDeg = directionGridData.getDouble(index);
if (!Double.isNaN(speedInMetersPerSecond) && !Double.isNaN(trueDirectionFromInDeg)) {
wind = createWindFixFromDirectionAndSpeed(position, timePoint, speedInMetersPerSecond, trueDirectionFromInDeg);
} else {
@@ -2,6 +2,7 @@ package com.sap.sailing.grib.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -20,6 +21,7 @@ import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Triple;
import ucar.ma2.Array;
import ucar.ma2.Index;
import ucar.nc2.dt.GridDatatype;
import ucar.nc2.dt.grid.GridDataset;
import ucar.nc2.ft.FeatureDataset;
@@ -108,7 +110,8 @@ public class UVWindField extends AbstractGribWindFieldImpl {
if (uGrid != null && vGrid != null) {
final GridDatatype finalVGrid = vGrid;
final Map<Integer, Array> vGridDataCache = new HashMap<>();
for (final Wind wind : foreach(uGrid, (Array uGridData, int timeIndex, int x, int y, TimePoint timePoint, Position position)->{
for (final Wind wind : foreach(uGrid, (Array uGridData, int timeIndex, Index index, TimePoint timePoint, Position position)->{
assert Arrays.equals(index.getShape(), uGridData.getShape());
try {
final Wind wind;
Array vGridData = vGridDataCache.get(timeIndex);
@@ -116,8 +119,8 @@ public class UVWindField extends AbstractGribWindFieldImpl {
vGridData = finalVGrid.readVolumeData(timeIndex);
vGridDataCache.put(timeIndex, vGridData);
}
double uComponentInMetersPerSecond = getValue(uGridData, timeIndex, /* zIndex */ 0, x, y);
double vComponentInMetersPerSecond = getValue(vGridData, timeIndex, /* zIndex */ 0, x, y);
double uComponentInMetersPerSecond = uGridData.getDouble(index);
double vComponentInMetersPerSecond = vGridData.getDouble(index);
if (!Double.isNaN(uComponentInMetersPerSecond) && !Double.isNaN(vComponentInMetersPerSecond)) {
wind = createWindFixFromUAndV(position, timePoint, uComponentInMetersPerSecond, vComponentInMetersPerSecond);
} else {