Issue #704 modify grid reprojection/interpolation code to be more thread safe and dynamic.

Former-commit-id: 603d48a017 [formerly 308f0e8c03ab4237830a91c96c500b6860c6fd36]
Former-commit-id: 682edec2cf
This commit is contained in:
Ben Steffensmeier 2012-06-25 15:22:35 -05:00
parent 12d44ca942
commit 0855e117cb
33 changed files with 1659 additions and 623 deletions

View file

@ -18,6 +18,7 @@ Import-Package: com.raytheon.edex.meteoLib,
com.raytheon.uf.common.datastorage,
com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.geospatial.interpolation,
com.raytheon.uf.common.geospatial.interpolation.data,
com.raytheon.uf.common.localization,
com.raytheon.uf.common.serialization,
com.raytheon.uf.common.serialization.adapters,

View file

@ -30,8 +30,10 @@ import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.Envelope2D;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.interpolation.AbstractInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.GridReprojection;
import com.raytheon.uf.common.geospatial.interpolation.GridSampler;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
@ -275,9 +277,12 @@ public class CrossSectionImageResource extends AbstractCrossSectionResource
return null;
}
AbstractInterpolation interpolation = new BilinearInterpolation(
sliceData, geometry, descriptor.getGridGeometry(), -9998f,
Float.POSITIVE_INFINITY, Float.NaN);
FloatArrayWrapper source = new FloatArrayWrapper(sliceData, geometry);
source.setValidRange(-9998, Double.POSITIVE_INFINITY);
GridSampler sampler = new GridSampler(source,
new BilinearInterpolation());
GridReprojection reproj = new GridReprojection(geometry,
descriptor.getGridGeometry());
IExtent extent = descriptor.getGraph(this).getExtent();
@ -289,7 +294,7 @@ public class CrossSectionImageResource extends AbstractCrossSectionResource
DirectPosition2D dp = new DirectPosition2D(coord.getObject().x,
coord.getObject().y);
descriptor.getGridGeometry().getGridToCRS().transform(dp, dp);
val = interpolation.getReprojectedGridCell((int) dp.x,
val = reproj.reprojectedGridCell(sampler, (int) dp.x,
(int) dp.y);
} catch (Exception e) {
throw new VizException(e);

View file

@ -6,7 +6,8 @@ Bundle-Version: 1.0.0.qualifier
Bundle-Activator: com.raytheon.uf.viz.xy.timeheight.Activator
Bundle-Vendor: RAYTHEON
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.ui;bundle-version="3.4.1"
org.eclipse.ui;bundle-version="3.4.1",
com.raytheon.uf.common.geospatial
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Eclipse-RegisterBuddy: com.raytheon.uf.viz.core, com.raytheon.viz.core

View file

@ -26,8 +26,10 @@ import org.geotools.geometry.DirectPosition2D;
import org.geotools.geometry.Envelope2D;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.interpolation.AbstractInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.GridReprojection;
import com.raytheon.uf.common.geospatial.interpolation.GridSampler;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.PixelCoverage;
@ -261,9 +263,12 @@ public class TimeHeightImageResource extends AbstractTimeHeightResource
if (sliceData == null) {
return null;
}
AbstractInterpolation interpolation = new BilinearInterpolation(
sliceData, geometry, descriptor.getGridGeometry(), -9998f,
Float.POSITIVE_INFINITY, Float.NaN);
FloatArrayWrapper source = new FloatArrayWrapper(sliceData, geometry);
source.setValidRange(-9998, Double.POSITIVE_INFINITY);
GridSampler sampler = new GridSampler(source,
new BilinearInterpolation());
GridReprojection reproj = new GridReprojection(geometry,
descriptor.getGridGeometry());
IExtent extent = descriptor.getGraph(this).getExtent();
@ -271,10 +276,11 @@ public class TimeHeightImageResource extends AbstractTimeHeightResource
if (extent.contains(new double[] { coord.getObject().x,
coord.getObject().y })) {
try {
DirectPosition2D dp = new DirectPosition2D(coord.getObject().x,
coord.getObject().y);
descriptor.getGridGeometry().getGridToCRS().transform(dp, dp);
val = interpolation.getReprojectedGridCell((int) dp.x,
val = reproj.reprojectedGridCell(sampler, (int) dp.x,
(int) dp.y);
} catch (Exception e) {
throw new VizException(e);

View file

@ -59,8 +59,9 @@ import com.raytheon.uf.common.datastorage.StorageException;
import com.raytheon.uf.common.datastorage.records.FloatDataRecord;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.interpolation.AbstractInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.GridReprojection;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
@ -704,11 +705,15 @@ public abstract class AbstractMapVectorResource extends
GridGeometry2D newTarget, GeneralGridGeometry gridGeometry)
throws FactoryException, TransformException {
GridGeometry2D remappedImageGeometry = newTarget;
AbstractInterpolation interp = new BilinearInterpolation(gridGeometry,
remappedImageGeometry, -9998, Float.POSITIVE_INFINITY, -999999);
float[] data = targetDataRecord.getFloatData();
interp.setData(data);
data = interp.getReprojectedGrid();
GridReprojection reproj = new GridReprojection(gridGeometry,
remappedImageGeometry);
FloatArrayWrapper source = new FloatArrayWrapper(
targetDataRecord.getFloatData(), gridGeometry);
source.setValidRange(-9998, Float.POSITIVE_INFINITY);
FloatArrayWrapper dest = new FloatArrayWrapper(remappedImageGeometry);
dest.setFillValue(-999999);
float[] data = reproj.reprojectedGrid(new BilinearInterpolation(),
source, dest).getArray();
FloatDataRecord remapGrid = (FloatDataRecord) targetDataRecord.clone();
remapGrid.setIntSizes(new int[] {
remappedImageGeometry.getGridRange2D().width,

View file

@ -71,9 +71,11 @@ import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.interpolation.AbstractInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.GridReprojection;
import com.raytheon.uf.common.geospatial.interpolation.GridSampler;
import com.raytheon.uf.common.geospatial.interpolation.NearestNeighborInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
@ -293,16 +295,23 @@ public class GridResource extends
.getLocation().getGridGeometry();
GridGeometry2D expectedGridGeometry = this.gridGeometry[0];
if (!realGridGeometry.equals(expectedGridGeometry)) {
AbstractInterpolation interp = new NearestNeighborInterpolation(
realGridGeometry, expectedGridGeometry, -9998,
Float.POSITIVE_INFINITY, -999999);
//interp.setMissingThreshold(1.0f); // Should be used for bi-linear interpolation
NearestNeighborInterpolation interp = new NearestNeighborInterpolation();
GridReprojection reproj = new GridReprojection(
realGridGeometry, expectedGridGeometry);
// interp.setMissingThreshold(1.0f); // Should be used for
// bi-linear interpolation
if (record instanceof FloatDataRecord) {
float[] data = ((FloatDataRecord) record).getFloatData();
record = record.clone();
interp.setData(data);
FloatArrayWrapper source = new FloatArrayWrapper(data,
realGridGeometry);
source.setValidRange(-9998, Double.POSITIVE_INFINITY);
FloatArrayWrapper dest = new FloatArrayWrapper(
expectedGridGeometry);
dest.setFillValue(-999999);
try {
data = interp.getReprojectedGrid();
data = reproj.reprojectedGrid(interp, source, dest)
.getArray();
} catch (Exception e) {
statusHandler.handle(Priority.PROBLEM,
e.getLocalizedMessage(), e);
@ -1040,12 +1049,16 @@ public class GridResource extends
throws VizException {
try {
GridGeometry2D remappedImageGeometry = newTarget;
AbstractInterpolation interp = new NearestNeighborInterpolation(
gridGeometry, remappedImageGeometry, -9998,
Float.POSITIVE_INFINITY, -999999);
NearestNeighborInterpolation interp = new NearestNeighborInterpolation();
GridReprojection reproj = new GridReprojection(gridGeometry,
remappedImageGeometry);
float[] data = targetDataRecord.getFloatData();
interp.setData(data);
data = interp.getReprojectedGrid();
FloatArrayWrapper source = new FloatArrayWrapper(data, gridGeometry);
source.setValidRange(-9998, Double.POSITIVE_INFINITY);
FloatArrayWrapper dest = new FloatArrayWrapper(
remappedImageGeometry);
dest.setFillValue(-999999);
data = reproj.reprojectedGrid(interp, source, dest).getArray();
FloatDataRecord remapGrid = (FloatDataRecord) targetDataRecord
.clone();
remapGrid.setIntSizes(new int[] {
@ -1309,14 +1322,14 @@ public class GridResource extends
double tileCoordinateValue = Double.NaN;
if (getCapability(ImagingCapability.class).isInterpolationState()) {
AbstractInterpolation interp = new BilinearInterpolation(
tile.getLoadedData(), tile.getGridGeometry(),
descriptor.getGridGeometry(), -9998f,
Float.POSITIVE_INFINITY, Float.NaN);
FloatArrayWrapper source = new FloatArrayWrapper(
tile.getLoadedData(), tile.getGridGeometry());
source.setValidRange(-9998, Double.POSITIVE_INFINITY);
GridSampler sampler = new GridSampler(source,
new BilinearInterpolation());
try {
Coordinate pixel = coord.asPixel(descriptor.getGridGeometry());
tileCoordinateValue = interp.getReprojectedGridCell(
(int) pixel.x, (int) pixel.y);
Coordinate pixel = coord.asPixel(tile.getGridGeometry());
tileCoordinateValue = sampler.sample(pixel.x, pixel.y);
UnitConverter converter = getCapability(
ColorMapCapability.class).getColorMapParameters()
.getDataToDisplayConverter();

View file

@ -51,9 +51,10 @@ import com.raytheon.uf.common.geospatial.ISpatialObject;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.PointUtil;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.interpolation.AbstractInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.NearestNeighborInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.GridReprojection;
import com.raytheon.uf.common.geospatial.interpolation.GridSampler;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
@ -102,7 +103,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* when click 'Diff' button.
* 05/08/2012 14828 D. Friedman Use nearest-neighbor interpolation for
* reprojected grids.
* 05/16/2012 14993 D. Friedman Fix "blocky" contours
* 05/16/2012 14993 D. Friedman Fix "blocky" contours
*
* </pre>
*
@ -237,9 +238,9 @@ public class GridVectorResource extends AbstractMapVectorResource implements
descriptor.getGridGeometry().getEnvelope(),
true, 2));
IDataRecord[] newData = new IDataRecord[results.length];
BilinearInterpolation interp = new BilinearInterpolation(
gridGeometry, remappedImageGeometry, -9998,
Float.POSITIVE_INFINITY, -999999);
GridReprojection reproj = new GridReprojection(gridGeometry,
remappedImageGeometry);
BilinearInterpolation interp = new BilinearInterpolation();
interp.setMissingThreshold(1.0f);
/*
@ -282,8 +283,14 @@ public class GridVectorResource extends AbstractMapVectorResource implements
.getFloatData();
}
interp.setData(data);
data = interp.getReprojectedGrid();
FloatArrayWrapper source = new FloatArrayWrapper(data,
gridGeometry);
source.setValidRange(-9998, Double.POSITIVE_INFINITY);
FloatArrayWrapper dest = new FloatArrayWrapper(
remappedImageGeometry);
dest.setFillValue(-999999);
data = reproj.reprojectedGrid(interp, source, dest)
.getArray();
newData[i] = results[i].clone();
newData[i]
.setIntSizes(new int[] {
@ -726,15 +733,13 @@ public class GridVectorResource extends AbstractMapVectorResource implements
if (contourGroup == null || contourGroup.getData() == null) {
return "No Data";
}
AbstractInterpolation interp = new BilinearInterpolation(
GridSampler sampler = new GridSampler(
new BilinearInterpolation());
sampler.setSource(new FloatArrayWrapper(
((FloatDataRecord) contourGroup.getData()[0])
.getFloatData(),
dataGeom, descriptor.getGridGeometry(), -9998f,
Float.POSITIVE_INFINITY, Float.NaN);
Coordinate pixel = coord.asPixel(descriptor.getGridGeometry());
value = interp.getReprojectedGridCell((int) pixel.x,
(int) pixel.y);
.getFloatData(), dataGeom));
Coordinate pixel = coord.asPixel(dataGeom);
value = sampler.sample(pixel.x, pixel.y);
}
// No data here

View file

@ -41,9 +41,10 @@ import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.interpolation.AbstractInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.GridSampler;
import com.raytheon.uf.common.geospatial.interpolation.NearestNeighborInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatBufferWrapper;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
@ -151,7 +152,7 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
/**
* The interpolation used when sampling to sample between data points.
*/
protected AbstractInterpolation sampleInterpolion;
protected GridSampler sampleInterpolion;
protected AbstractGridResource(T resourceData, LoadProperties loadProperties) {
super(resourceData, loadProperties);
@ -365,15 +366,13 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
ImagingCapability imagingCap = this
.getCapability(ImagingCapability.class);
if (imagingCap.isInterpolationState()) {
sampleInterpolion = new BilinearInterpolation(
getGridGeometry(), descriptor.getGridGeometry());
sampleInterpolion = new GridSampler(new BilinearInterpolation());
} else {
sampleInterpolion = new NearestNeighborInterpolation(
getGridGeometry(), descriptor.getGridGeometry());
sampleInterpolion = new GridSampler(
new NearestNeighborInterpolation());
}
} else {
sampleInterpolion = new BilinearInterpolation(getGridGeometry(),
descriptor.getGridGeometry());
sampleInterpolion = new GridSampler(new BilinearInterpolation());
}
if (stylePreferences != null
&& stylePreferences instanceof ImagePreferences) {
@ -698,19 +697,19 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
if (data == null) {
return null;
}
sampleInterpolion.setData(data.getScalarData().array());
sampleInterpolion.setSource(new FloatBufferWrapper(
data.getScalarData(), getGridGeometry()));
float value = Float.NaN;
try {
Coordinate xy = coord.asPixel(descriptor.getGridGeometry());
value = sampleInterpolion.getReprojectedGridCell((int) xy.x,
(int) xy.y);
Coordinate xy = coord.asPixel(getGridGeometry());
value = (float) sampleInterpolion.sample(xy.x, xy.y);
} catch (FactoryException e) {
throw new VizException(e);
} catch (TransformException e) {
throw new VizException(e);
}
sampleInterpolion.setData(null);
sampleInterpolion.setSource(null);
Unit<?> unit = data.getDataUnit();
if (stylePreferences != null) {
@ -734,19 +733,19 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
if (!data.isVector()) {
return null;
}
sampleInterpolion.setData(data.getDirection().array());
sampleInterpolion.setSource(new FloatBufferWrapper(data.getDirection(),
getGridGeometry()));
float value = Float.NaN;
try {
Coordinate xy = coord.asPixel(descriptor.getGridGeometry());
value = sampleInterpolion.getReprojectedGridCell((int) xy.x,
(int) xy.y);
Coordinate xy = coord.asPixel(getGridGeometry());
value = (float) sampleInterpolion.sample(xy.x, xy.y);
} catch (FactoryException e) {
throw new VizException(e);
} catch (TransformException e) {
throw new VizException(e);
}
sampleInterpolion.setData(null);
sampleInterpolion.setSource(null);
return Measure.valueOf(value, NonSI.DEGREE_ANGLE);
}

View file

@ -37,8 +37,12 @@ import com.raytheon.uf.common.dataplugin.grib.spatial.projections.GridCoverage;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.interpolation.AbstractInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.GridReprojection;
import com.raytheon.uf.common.geospatial.interpolation.Interpolation;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatBufferWrapper;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
@ -78,7 +82,7 @@ public class D2DGribGridResource extends GribGridResource<GridResourceData>
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(D2DGribGridResource.class);
private AbstractInterpolation reprojectionInterpolation;
private GridReprojection reprojectionInterpolation;
public D2DGribGridResource(GridResourceData resourceData,
LoadProperties loadProperties) {
@ -140,15 +144,20 @@ public class D2DGribGridResource extends GribGridResource<GridResourceData>
// Now reproject if we need to.
if (reprojectionInterpolation != null) {
try {
Interpolation interp = new BilinearInterpolation();
if (data.isVector()) {
reprojectionInterpolation.setData(data.getUComponent()
.array());
float[] udata = reprojectionInterpolation
.getReprojectedGrid();
reprojectionInterpolation.setData(data.getVComponent()
.array());
float[] vdata = reprojectionInterpolation
.getReprojectedGrid();
DataSource source = new FloatBufferWrapper(
data.getUComponent(), getGridGeometry());
FloatArrayWrapper dest = new FloatArrayWrapper(
reprojectionInterpolation.getTargetGeometry());
float[] udata = reprojectionInterpolation.reprojectedGrid(
interp, source, dest).getArray();
source = new FloatBufferWrapper(data.getVComponent(),
getGridGeometry());
dest = new FloatArrayWrapper(
reprojectionInterpolation.getTargetGeometry());
float[] vdata = reprojectionInterpolation.reprojectedGrid(
interp, source, dest).getArray();
// When reprojecting it is necessary to recalculate the
// direction of vectors based off the change in the "up"
// direction
@ -192,10 +201,12 @@ public class D2DGribGridResource extends GribGridResource<GridResourceData>
data.getDataUnit());
} else {
reprojectionInterpolation.setData(data.getScalarData()
.array());
float[] fdata = reprojectionInterpolation
.getReprojectedGrid();
DataSource source = new FloatBufferWrapper(
data.getScalarData(), getGridGeometry());
FloatArrayWrapper dest = new FloatArrayWrapper(
reprojectionInterpolation.getTargetGeometry());
float[] fdata = reprojectionInterpolation.reprojectedGrid(
interp, source, dest).getArray();
data = GeneralGridData.createScalarData(
FloatBuffer.wrap(fdata), data.getDataUnit());
}
@ -267,8 +278,9 @@ public class D2DGribGridResource extends GribGridResource<GridResourceData>
sourceGeometry, descriptor.getGridGeometry()
.getEnvelope(), true);
}
reprojectionInterpolation = new BilinearInterpolation(
reprojectionInterpolation = new GridReprojection(
sourceGeometry, targetGeometry);
reprojectionInterpolation.computeTransformTable();
clearRequestedData();
} catch (Exception e) {
reprojectionInterpolation = null;

View file

@ -34,8 +34,12 @@ import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.interpolation.AbstractInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.GridReprojection;
import com.raytheon.uf.common.geospatial.interpolation.Interpolation;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatBufferWrapper;
import com.raytheon.uf.common.time.CombinedDataTime;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.viz.core.IGraphicsTarget;
@ -78,9 +82,9 @@ public class DifferenceGridResource extends
private final AbstractGridResource<?> two;
private AbstractInterpolation oneInterpolation;
private GridReprojection oneInterpolation;
private AbstractInterpolation twoInterpolation;
private GridReprojection twoInterpolation;
public DifferenceGridResource(DifferenceGridResourceData resourceData,
LoadProperties loadProperties, AbstractGridResource<?> one,
@ -145,10 +149,8 @@ public class DifferenceGridResource extends
oneEnv.intersection(twoEnv), descriptor.getCRS());
newGeometry = new GridGeometry2D(GRID_ENVELOPE, newEnv);
}
oneInterpolation = new BilinearInterpolation(oneGeometry,
newGeometry);
twoInterpolation = new BilinearInterpolation(twoGeometry,
newGeometry);
oneInterpolation = new GridReprojection(oneGeometry, newGeometry);
twoInterpolation = new GridReprojection(twoGeometry, newGeometry);
}
return GridGeometry2D.wrap(oneInterpolation.getTargetGeometry());
}
@ -181,20 +183,32 @@ public class DifferenceGridResource extends
}
GeneralGridData newData = null;
try {
Interpolation interp = new BilinearInterpolation();
if (oneData.isVector() && twoData.isVector()) {
float[] oneU = oneData.getUComponent().array();
float[] oneV = oneData.getVComponent().array();
float[] twoU = twoData.getUComponent().array();
float[] twoV = twoData.getVComponent().array();
oneInterpolation.setData(oneU);
oneU = oneInterpolation.getReprojectedGrid();
oneInterpolation.setData(oneV);
oneV = oneInterpolation.getReprojectedGrid();
twoInterpolation.setData(twoU);
twoU = twoInterpolation.getReprojectedGrid();
twoInterpolation.setData(twoV);
twoV = twoInterpolation.getReprojectedGrid();
DataSource oneSourceU = new FloatBufferWrapper(
oneData.getUComponent(),
oneInterpolation.getSourceGeometry());
DataSource oneSourceV = new FloatBufferWrapper(
oneData.getVComponent(),
oneInterpolation.getSourceGeometry());
DataSource twoSourceU = new FloatBufferWrapper(
twoData.getUComponent(),
twoInterpolation.getSourceGeometry());
DataSource twoSourceV = new FloatBufferWrapper(
twoData.getVComponent(),
twoInterpolation.getSourceGeometry());
float[] oneU = oneInterpolation.reprojectedGrid(interp,
oneSourceU, new FloatArrayWrapper(getGridGeometry()))
.getArray();
float[] oneV = oneInterpolation.reprojectedGrid(interp,
oneSourceV, new FloatArrayWrapper(getGridGeometry()))
.getArray();
float[] twoU = twoInterpolation.reprojectedGrid(interp,
twoSourceU, new FloatArrayWrapper(getGridGeometry()))
.getArray();
float[] twoV = twoInterpolation.reprojectedGrid(interp,
twoSourceV, new FloatArrayWrapper(getGridGeometry()))
.getArray();
float[] newU = new float[oneU.length];
float[] newV = new float[oneV.length];
for (int i = 0; i < newU.length; i++) {
@ -205,12 +219,18 @@ public class DifferenceGridResource extends
FloatBuffer.wrap(newU), FloatBuffer.wrap(newV),
dataUnit);
} else {
float[] oneScalar = oneData.getScalarData().array();
float[] twoScalar = twoData.getScalarData().array();
oneInterpolation.setData(oneScalar);
oneScalar = oneInterpolation.getReprojectedGrid();
twoInterpolation.setData(twoScalar);
twoScalar = twoInterpolation.getReprojectedGrid();
DataSource oneSource = new FloatBufferWrapper(
oneData.getScalarData(),
oneInterpolation.getSourceGeometry());
DataSource twoSource = new FloatBufferWrapper(
twoData.getScalarData(),
twoInterpolation.getSourceGeometry());
float[] oneScalar = oneInterpolation.reprojectedGrid(interp,
oneSource, new FloatArrayWrapper(getGridGeometry()))
.getArray();
float[] twoScalar = twoInterpolation.reprojectedGrid(interp,
twoSource, new FloatArrayWrapper(getGridGeometry()))
.getArray();
float[] newScalar = new float[oneScalar.length];
for (int i = 0; i < newScalar.length; i++) {
newScalar[i] = oneScalar[i] - twoScalar[i];

View file

@ -48,6 +48,7 @@ Import-Package: com.raytheon.edex.exception,
com.raytheon.uf.common.dataplugin.persist,
com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.geospatial.interpolation,
com.raytheon.uf.common.geospatial.interpolation.data,
com.raytheon.uf.common.localization,
com.raytheon.uf.common.localization.exception,
com.raytheon.uf.common.message,

View file

@ -46,8 +46,10 @@ import com.raytheon.uf.common.dataplugin.gfe.exception.GfeException;
import com.raytheon.uf.common.dataplugin.gfe.grid.Grid2DByte;
import com.raytheon.uf.common.dataplugin.gfe.grid.Grid2DFloat;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.interpolation.AbstractInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.GridReprojection;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
@ -83,7 +85,7 @@ public class RemapGrid {
private Grid2DFloat rotation;
private AbstractInterpolation interp;
private GridReprojection interp;
/**
* Constructs a new RemapGrid with the given input and output grid locations
@ -540,18 +542,17 @@ public class RemapGrid {
rasterData.getMinY(), rasterData.getWidth(),
rasterData.getHeight(), f1);
} else {
GridGeometry2D destGeometry = MapUtil
.getGridGeometry(destinationGloc);
synchronized (this) {
if (interp == null) {
interp = new BilinearInterpolation(sourceGeometry,
MapUtil.getGridGeometry(destinationGloc));
interp = new GridReprojection(sourceGeometry, destGeometry);
interp.computeTransformTable();
}
}
synchronized (interp) {
interp.setData(data);
f1 = interp.getReprojectedGrid();
interp.setData(null);
}
DataSource source = new FloatArrayWrapper(data, sourceGeometry);
f1 = interp.reprojectedGrid(new BilinearInterpolation(), source,
new FloatArrayWrapper(destGeometry)).getArray();
}
// Remap the the output data into a Grid2DFloat object

View file

@ -17,6 +17,7 @@ Require-Bundle: org.geotools;bundle-version="2.5.2";visibility:=reexport,
com.raytheon.uf.common.dataquery;bundle-version="1.0.0"
Export-Package: com.raytheon.uf.common.geospatial,
com.raytheon.uf.common.geospatial.interpolation,
com.raytheon.uf.common.geospatial.interpolation.data,
com.raytheon.uf.common.geospatial.request,
com.raytheon.uf.common.geospatial.spi,
com.raytheon.uf.common.geospatial.util

View file

@ -1,387 +0,0 @@
package com.raytheon.uf.common.geospatial.interpolation;
import java.awt.geom.Point2D;
import java.awt.image.Raster;
import org.apache.commons.lang.Validate;
import org.geotools.coverage.grid.GeneralGridGeometry;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.referencing.operation.DefaultMathTransformFactory;
import org.geotools.referencing.operation.projection.ProjectionException;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.geospatial.MapUtil;
/**
*
* Abstract class for mapping data from one grid geometry to another
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 21, 2011 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public abstract class AbstractInterpolation {
protected float[] data;
protected GeneralGridGeometry sourceGeometry;
protected GeneralGridGeometry targetGeometry;
protected float minValid = Float.NEGATIVE_INFINITY;
protected float maxValid = Float.POSITIVE_INFINITY;
protected float fillValue = Float.NaN;
// The following were extracted out of the geometries and stored for easy
// use
protected CoordinateReferenceSystem targetCRS;
protected CoordinateReferenceSystem sourceCRS;
protected int targetNx;
protected int targetNy;
protected int sourceNx;
protected int sourceNy;
protected MathTransform transform;
protected float[] transformTable = null;
// The number of grid cells needed to wrap source x coordinates around the
// world, or -1 if the source grid does not wrap evenly.
protected int sourceWrapX = -1;
protected AbstractInterpolation(GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry) {
this.sourceGeometry = sourceGeometry;
this.targetGeometry = targetGeometry;
// Extract some local variables
targetCRS = targetGeometry.getCoordinateReferenceSystem();
sourceCRS = sourceGeometry.getCoordinateReferenceSystem();
targetNx = targetGeometry.getGridRange().getSpan(0);
targetNy = targetGeometry.getGridRange().getSpan(1);
sourceNx = sourceGeometry.getGridRange().getSpan(0);
sourceNy = sourceGeometry.getGridRange().getSpan(1);
}
protected AbstractInterpolation(GridCoverage2D gridCoverage,
GeneralGridGeometry targetGeometry) {
this(gridCoverage.getGridGeometry(), targetGeometry);
Raster data = gridCoverage.getRenderedImage().getData();
this.data = data.getPixels(data.getMinX(), data.getMinY(),
data.getWidth(), data.getHeight(), this.data);
}
protected AbstractInterpolation(float[] data,
GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry) {
this(sourceGeometry, targetGeometry);
this.data = data;
}
protected AbstractInterpolation(GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry, float minValid, float maxValid,
float fillValue) {
this(sourceGeometry, targetGeometry);
this.minValid = minValid;
this.maxValid = maxValid;
this.fillValue = fillValue;
}
/**
* Remap data from sourceGeometry to targetGeometry.
*
* @param data
* the raw data
* @param sourceGeometry
* a geometry describing rawData
* @param targetGeometry
* a geometry describing the result of this function
* @param minValid
* the minimum valid value for the data, anything less will be
* treated as NaN, for all real numbers use
* Float.NEGATIVE_INFINITY
* @param maxValid
* the maximum valid value for the data, anything greater will be
* treated as NaN, for all real numbers use
* Float.POSITIVE_INFINITY
* @param fillValue
* the value to fill in for any data out of range, Float.NaN is
* the recommended fill value
*/
protected AbstractInterpolation(float[] data,
GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry, float minValid, float maxValid,
float fillValue) {
this(data, sourceGeometry, targetGeometry);
this.minValid = minValid;
this.maxValid = maxValid;
this.fillValue = fillValue;
}
protected void initTransforms() throws FactoryException, TransformException {
if (transform == null) {
MathTransform grid2crs = targetGeometry
.getGridToCRS(PixelInCell.CELL_CENTER);
MathTransform crs2crs = CRS.findMathTransform(targetCRS, sourceCRS);
MathTransform crs2grid = sourceGeometry.getGridToCRS(
PixelInCell.CELL_CENTER).inverse();
DefaultMathTransformFactory mtf = new DefaultMathTransformFactory();
transform = mtf.createConcatenatedTransform(grid2crs,
mtf.createConcatenatedTransform(crs2crs, crs2grid));
checkForWrappingSource();
}
}
// Attempt to detect the case where a geographic coordinate reference system
// wraps around the world so that values out of range on the X-axis can be
// retrieved from the other side of the grid. If this is the case the
// sourceWrapX value will be set to the number of grid cells that are needed
// to wrap all the way around the world.
private void checkForWrappingSource() {
try {
MathTransform grid2crs = sourceGeometry
.getGridToCRS(PixelInCell.CELL_CENTER);
MathTransform crs2LatLon = CRS.findMathTransform(sourceCRS,
DefaultGeographicCRS.WGS84);
DirectPosition2D corner1 = new DirectPosition2D(sourceNx, 0);
DirectPosition2D corner2 = new DirectPosition2D(sourceNx,
sourceNy - 1);
grid2crs.transform(corner1, corner1);
grid2crs.transform(corner2, corner2);
crs2LatLon.transform(corner1, corner1);
crs2LatLon.transform(corner2, corner2);
corner1.x = MapUtil.correctLon(corner1.x);
corner2.x = MapUtil.correctLon(corner2.x);
crs2LatLon.inverse().transform(corner1, corner1);
crs2LatLon.inverse().transform(corner2, corner2);
grid2crs.inverse().transform(corner1, corner1);
grid2crs.inverse().transform(corner2, corner2);
int sourceWrapX = (int) (sourceNx - corner1.x);
// In order to wrap then the transformed point x value should be on
// the other side of the grid and the y value should not have
// changed significantly. Additionally the wrapped x value should
// fall exactly on a grid cell.
if (corner1.x > sourceNx - 1) {
return;
} else if (Math.abs(corner1.y - 0) > 0.0001) {
return;
} else if (Math.abs(corner2.y - sourceNy + 1) > 0.0001) {
return;
} else if (Math.abs(corner1.x + sourceWrapX - sourceNx) > 0.0001) {
return;
} else if (Math.abs(corner2.x + sourceWrapX - sourceNx) > 0.0001) {
return;
} else {
this.sourceWrapX = sourceWrapX;
}
} catch (Exception e) {
// if anything goes wrong in this process just assume we don't
// wrap the x axis, thats not a big deal and it is normal for
// non geographic coordinate systems.
;
}
}
public float[] getReprojectedGrid() throws FactoryException,
TransformException {
Validate.notNull(data);
float[] newData = new float[targetNx * targetNy];
if (transformTable == null) {
for (int j = 0; j < targetNy; j++) {
for (int i = 0; i < targetNx; i++) {
newData[j * targetNx + i] = getReprojectedGridCell(i, j);
}
}
} else {
// This version is equivalent but faster since it can skip range
// checks
int tIndex = 0;
for (int i = 0; i < newData.length; i++) {
float x = transformTable[tIndex++];
float y = transformTable[tIndex++];
if (!Float.isNaN(x) && !Float.isNaN(y)) {
newData[i] = getInterpolatedValue(x, y);
}
}
}
return newData;
}
/**
*
* @param x
* @param y
* @return
* @throws FactoryException
* @throws TransformException
*/
public float getReprojectedGridCell(int x, int y) throws FactoryException,
TransformException {
Validate.notNull(data);
Point2D.Double dp = null;
try {
dp = getReprojectDataPoint(x, y);
} catch (ProjectionException e) {
// ProjectionException is thrown when a point is outside
// the valid range of the source data, so we will treat
// it like other out of range values and set it to fill
// value.
return fillValue;
}
return getInterpolatedValue(dp.x, dp.y);
}
/**
* Given an x and y in source grid space return the interpolated value or
* fillValue if interpolation fails.
*
* @param x
* @param y
* @return
*/
protected abstract float getInterpolatedValue(double x, double y);
/**
* does range x,y, and data range checking for x and y in source grid space,
* returns a real data value or NaN if out of any bounds.
*
* @param x
* @param y
* @return
*/
protected float getRawDataValue(int x, int y) {
if (y < 0 || y > sourceNy - 1) {
// outside y range
return Float.NaN;
} else if (x < 0 || x > sourceNx - 1) {
// outside x range
if (sourceWrapX > 0) {
// attempt to wrap if this is a wrapping grid.
x = (x + sourceWrapX) % sourceWrapX;
if (x < 0 || x > sourceNx - 1) {
return Float.NaN;
}
} else {
return Float.NaN;
}
}
float val = data[(int) (y * sourceNx + x)];
if (val < minValid || val > maxValid) {
// skip outside valid range
val = Float.NaN;
}
return val;
}
protected Point2D.Double getReprojectDataPoint(int x, int y)
throws TransformException, FactoryException {
initTransforms();
if (transformTable != null && x >= 0 && x < targetNx && y >= 0
&& y < targetNy) {
int index = (y * targetNx + x) * 2;
float xVal = transformTable[index];
float yVal = transformTable[index + 1];
if (!Float.isNaN(xVal) && !Float.isNaN(yVal)) {
return new Point2D.Double(xVal, yVal);
}
}
DirectPosition2D dp = new DirectPosition2D(x, y);
transform.transform(dp, dp);
return dp;
}
/**
* @return the sourceGeometry
*/
public GeneralGridGeometry getSourceGeometry() {
return sourceGeometry;
}
/**
* @return the targetGeometry
*/
public GeneralGridGeometry getTargetGeometry() {
return targetGeometry;
}
/**
* Can be used to run interpolation for the same geometries for multiple
* data sets.
*
* @param data
* the data to set
*/
public void setData(float[] data) {
this.data = data;
}
/**
* This function precomputes the math transform for all grid cells in the
* target grid range. This method is recommended when you are reprojecting
* multiple datasets using the same interpolation. Precalculating this table
* takes time and uses more memory but cuts the time to perform
* interpolation significantly.
*
*
* @return the size in bytes of the extra memory used by the transform
* table.
* @throws FactoryException
* @throws TransformException
*/
public int computeTransformTable() throws FactoryException,
TransformException {
initTransforms();
float[] transformTable = new float[targetNy * targetNx * 2];
int index = 0;
for (int j = 0; j < targetNy; j++) {
for (int i = 0; i < targetNx; i++) {
transformTable[index++] = i;
transformTable[index++] = j;
}
}
try {
transform.transform(transformTable, 0, transformTable, 0, targetNy
* targetNx);
} catch (ProjectionException e) {
;// Ignore, the points in the transformTable that are invalid are
// set to NaN, no other action is necessary.
}
this.transformTable = transformTable;
return transformTable.length * 4;
}
/**
* delete the transform table, freeing up memory but slowing down any future
* reprojections
*/
public void clearTransformTable() {
transformTable = null;
}
}

View file

@ -1,9 +1,27 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation;
import org.geotools.coverage.grid.GeneralGridGeometry;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
/**
*
* bicubic convolusion.
*
* <pre>
@ -17,53 +35,23 @@ import org.geotools.coverage.grid.GeneralGridGeometry;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 29, 2012 bsteffen Initial creation
* Jun 18, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class BicubicInterpolation extends AbstractInterpolation {
public class BicubicInterpolation implements Interpolation {
private double a = -0.5;
public BicubicInterpolation(GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry, float minValid, float maxValid,
float fillValue) {
super(sourceGeometry, targetGeometry, minValid, maxValid, fillValue);
}
public BicubicInterpolation(GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry) {
super(sourceGeometry, targetGeometry);
}
public BicubicInterpolation(float[] data,
GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry, float minValid, float maxValid,
float fillValue) {
super(data, sourceGeometry, targetGeometry, minValid, maxValid,
fillValue);
}
public BicubicInterpolation(float[] data,
GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry) {
super(data, sourceGeometry, targetGeometry);
}
/**
* Should be -0.5, -0.75, or -1.0, or maybe something inbetween?
*
* @param a
*/
public void setA(double a) {
this.a = a;
public BicubicInterpolation() {
}
@Override
protected float getInterpolatedValue(double x, double y) {
public double getInterpolatedValue(DataSource source, double x, double y) {
double value = 0.0f;
double weight = 0.0f;
@ -75,7 +63,7 @@ public class BicubicInterpolation extends AbstractInterpolation {
double xWeight = weight(xd + xi);
double yWeight = weight(yd + yi);
double w = xWeight * yWeight;
double val = getRawDataValue((int) x + xi, (int) y + yi);
double val = source.getDataValue((int) x + xi, (int) y + yi);
value += w * val;
weight += w;
}
@ -97,4 +85,13 @@ public class BicubicInterpolation extends AbstractInterpolation {
}
/**
* Should be -0.5, -0.75, or -1.0, or maybe something inbetween?
*
* @param a
*/
public void setA(double a) {
this.a = a;
}
}

View file

@ -1,9 +1,27 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation;
import org.geotools.coverage.grid.GeneralGridGeometry;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
/**
*
* Bilinear interpolation
*
* <pre>
@ -12,58 +30,34 @@ import org.geotools.coverage.grid.GeneralGridGeometry;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 21, 2011 bsteffen Initial creation
* Jun 18, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class BilinearInterpolation extends AbstractInterpolation {
public class BilinearInterpolation implements Interpolation {
private float missingThreshold = 0.25f;
public BilinearInterpolation(GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry, float minValid, float maxValid,
float fillValue) {
super(sourceGeometry, targetGeometry, minValid, maxValid, fillValue);
}
public BilinearInterpolation(GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry) {
super(sourceGeometry, targetGeometry);
}
public BilinearInterpolation(float[] data,
GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry, float minValid, float maxValid,
float fillValue) {
super(data, sourceGeometry, targetGeometry, minValid, maxValid,
fillValue);
}
public BilinearInterpolation(float[] data,
GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry) {
super(data, sourceGeometry, targetGeometry);
public BilinearInterpolation() {
}
@Override
protected float getInterpolatedValue(double xd, double yd) {
float value = 0.0f;
float missing = 1.0f;
float x = (float) xd;
float y = (float) yd;
public double getInterpolatedValue(DataSource source, double x, double y) {
double value = 0.0f;
double missing = 1.0f;
int xi = (int) x;
int yi = (int) y;
// Upper left corner
float xWeight = 1 - x + xi;
float yWeight = 1 - y + yi;
float weight = xWeight * yWeight;
float val = getRawDataValue(xi, yi);
if (Float.isNaN(val)) {
double xWeight = 1 - x + xi;
double yWeight = 1 - y + yi;
double weight = xWeight * yWeight;
double val = source.getDataValue(xi, yi);
if (Double.isNaN(val)) {
missing -= weight;
} else {
value += weight * val;
@ -73,8 +67,8 @@ public class BilinearInterpolation extends AbstractInterpolation {
xWeight = 1 - xi + x;
yWeight = 1 - y + yi;
weight = xWeight * yWeight;
val = getRawDataValue(xi, yi);
if (Float.isNaN(val)) {
val = source.getDataValue(xi, yi);
if (Double.isNaN(val)) {
missing -= weight;
} else {
value += weight * val;
@ -84,8 +78,8 @@ public class BilinearInterpolation extends AbstractInterpolation {
xWeight = 1 - xi + x;
yWeight = 1 - yi + y;
weight = xWeight * yWeight;
val = getRawDataValue(xi, yi);
if (Float.isNaN(val)) {
val = source.getDataValue(xi, yi);
if (Double.isNaN(val)) {
missing -= weight;
} else {
value += weight * val;
@ -95,8 +89,8 @@ public class BilinearInterpolation extends AbstractInterpolation {
xWeight = 1 - x + xi;
yWeight = 1 - yi + y;
weight = xWeight * yWeight;
val = getRawDataValue(xi, yi);
if (Float.isNaN(val)) {
val = source.getDataValue(xi, yi);
if (Double.isNaN(val)) {
missing -= weight;
} else {
value += weight * val;
@ -107,7 +101,7 @@ public class BilinearInterpolation extends AbstractInterpolation {
return value / missing;
} else {
// If we are too far from the data skip it
return fillValue;
return Double.NaN;
}
}

View file

@ -0,0 +1,196 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation;
import java.awt.geom.Point2D;
import org.geotools.coverage.grid.GeneralGridGeometry;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.referencing.CRS;
import org.geotools.referencing.operation.DefaultMathTransformFactory;
import org.geotools.referencing.operation.projection.ProjectionException;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.geospatial.interpolation.data.DataDestination;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
/**
* Class for mapping data from one grid geometry to another. Uses interfaces for
* source and destination so that reprojection can be done regardless of the
* original format of the raw data or the desired format of new data.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 18, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class GridReprojection {
protected GeneralGridGeometry sourceGeometry;
protected GeneralGridGeometry targetGeometry;
protected int targetNx;
protected int targetNy;
protected MathTransform transform;
protected float[] transformTable = null;
public GridReprojection(GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry) {
this.sourceGeometry = sourceGeometry;
this.targetGeometry = targetGeometry;
this.targetNx = targetGeometry.getGridRange().getSpan(0);
this.targetNy = targetGeometry.getGridRange().getSpan(1);
}
protected void initTransforms() throws FactoryException, TransformException {
if (transform == null) {
CoordinateReferenceSystem targetCRS = targetGeometry
.getCoordinateReferenceSystem();
CoordinateReferenceSystem sourceCRS = sourceGeometry
.getCoordinateReferenceSystem();
MathTransform grid2crs = targetGeometry
.getGridToCRS(PixelInCell.CELL_CENTER);
MathTransform crs2crs = CRS.findMathTransform(targetCRS, sourceCRS);
MathTransform crs2grid = sourceGeometry.getGridToCRS(
PixelInCell.CELL_CENTER).inverse();
DefaultMathTransformFactory mtf = new DefaultMathTransformFactory();
transform = mtf.createConcatenatedTransform(grid2crs,
mtf.createConcatenatedTransform(crs2crs, crs2grid));
}
}
public <T extends DataDestination> T reprojectedGrid(
Interpolation interpolation, DataSource source, T dest)
throws FactoryException, TransformException {
return reprojectedGrid(new GridSampler(source, interpolation), dest);
}
public <T extends DataDestination> T reprojectedGrid(GridSampler sampler,
T dest) throws FactoryException, TransformException {
for (int j = 0; j < targetNy; j++) {
for (int i = 0; i < targetNx; i++) {
dest.setDataValue(reprojectedGridCell(sampler, i, j), i, j);
}
}
return dest;
}
public double reprojectedGridCell(GridSampler sampler, int x, int y)
throws FactoryException, TransformException {
Point2D.Double dp = null;
try {
dp = getReprojectDataPoint(x, y);
} catch (ProjectionException e) {
// ProjectionException is thrown when a point is outside
// the valid range of the source data, so we will treat
// it like other out of range values and set it to fill
// value.
return Double.NaN;
}
return sampler.sample(dp.x, dp.y);
}
protected Point2D.Double getReprojectDataPoint(int x, int y)
throws TransformException, FactoryException {
initTransforms();
if (transformTable != null && x >= 0 && x < targetNx && y >= 0
&& y < targetNy) {
int index = (y * targetNx + x) * 2;
float xVal = transformTable[index];
float yVal = transformTable[index + 1];
if (!Float.isNaN(xVal) && !Float.isNaN(yVal)) {
return new Point2D.Double(xVal, yVal);
}
}
DirectPosition2D dp = new DirectPosition2D(x, y);
transform.transform(dp, dp);
return dp;
}
/**
* This function precomputes the math transform for all grid cells in the
* target grid range. This method is recommended when you are reprojecting
* multiple datasets using the same interpolation. Precalculating this table
* takes time and uses more memory but cuts the time to perform
* interpolation significantly.
*
*
* @return the size in bytes of the extra memory used by the transform
* table.
* @throws FactoryException
* @throws TransformException
*/
public int computeTransformTable() throws FactoryException,
TransformException {
initTransforms();
float[] transformTable = new float[targetNy * targetNx * 2];
int index = 0;
for (int j = 0; j < targetNy; j++) {
for (int i = 0; i < targetNx; i++) {
transformTable[index++] = i;
transformTable[index++] = j;
}
}
try {
transform.transform(transformTable, 0, transformTable, 0, targetNy
* targetNx);
} catch (ProjectionException e) {
;// Ignore, the points in the transformTable that are invalid are
// set to NaN, no other action is necessary.
}
this.transformTable = transformTable;
return transformTable.length * 4;
}
/**
* delete the transform table, freeing up memory but slowing down any future
* reprojections
*/
public void clearTransformTable() {
transformTable = null;
}
public GeneralGridGeometry getSourceGeometry() {
return sourceGeometry;
}
public GeneralGridGeometry getTargetGeometry() {
return targetGeometry;
}
}

View file

@ -0,0 +1,70 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
/**
* Used for sampling data values from a source using an interpolation. It can be
* more convenient to use a sampler rather than a interpolation and a source
* seperatly.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class GridSampler {
private Interpolation interpolation;
private DataSource source;
public GridSampler(Interpolation interpolation) {
this.interpolation = interpolation;
}
public GridSampler(DataSource source, Interpolation interpolation) {
this.interpolation = interpolation;
this.source = source;
}
public double sample(double x, double y) {
return interpolation.getInterpolatedValue(source, x, y);
}
public void setInterpolation(Interpolation interpolation) {
this.interpolation = interpolation;
}
public void setSource(DataSource source) {
this.source = source;
}
}

View file

@ -0,0 +1,46 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
/**
* Provides logic for deriving a value at a single point from a 2D numeric
* source.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 18, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public interface Interpolation {
public abstract double getInterpolatedValue(DataSource source, double x,
double y);
}

View file

@ -1,9 +1,27 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation;
import org.geotools.coverage.grid.GeneralGridGeometry;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
/**
*
* Nearest Neighbor interpolation
*
* <pre>
@ -12,48 +30,22 @@ import org.geotools.coverage.grid.GeneralGridGeometry;
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 21, 2011 bsteffen Initial creation
* Jun 18, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class NearestNeighborInterpolation extends AbstractInterpolation {
public NearestNeighborInterpolation(GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry, float minValid, float maxValid,
float fillValue) {
super(sourceGeometry, targetGeometry, minValid, maxValid, fillValue);
}
public class NearestNeighborInterpolation implements Interpolation {
public NearestNeighborInterpolation(GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry) {
super(sourceGeometry, targetGeometry);
}
public NearestNeighborInterpolation(float[] data,
GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry, float minValid, float maxValid,
float fillValue) {
super(data, sourceGeometry, targetGeometry, minValid, maxValid,
fillValue);
}
public NearestNeighborInterpolation(float[] data,
GeneralGridGeometry sourceGeometry,
GeneralGridGeometry targetGeometry) {
super(data, sourceGeometry, targetGeometry);
public NearestNeighborInterpolation() {
}
@Override
protected float getInterpolatedValue(double x, double y) {
float val = getRawDataValue((int) Math.round(x), (int) Math.round(y));
if (Float.isNaN(val)) {
return fillValue;
} else {
return val;
}
public double getInterpolatedValue(DataSource source, double x, double y) {
return source.getDataValue((int) Math.round(x), (int) Math.round(y));
}
}

View file

@ -0,0 +1,173 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
import org.geotools.coverage.grid.GeneralGridGeometry;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import com.raytheon.uf.common.geospatial.MapUtil;
/**
*
* Abstract class for any data implementation that can act as both a source and
* destination.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public abstract class AbstractDataWrapper implements DataSource,
DataDestination {
protected final int nx;
protected final int ny;
protected int wrapX = -1;
protected double minValid = Double.NEGATIVE_INFINITY;
protected double maxValid = Double.POSITIVE_INFINITY;
protected double fillValue = Double.NaN;
public AbstractDataWrapper(GeneralGridGeometry geometry) {
this.nx = geometry.getGridRange().getSpan(0);
this.ny = geometry.getGridRange().getSpan(1);
checkForWrapping(geometry);
}
public AbstractDataWrapper(int nx, int ny) {
this.nx = nx;
this.ny = ny;
}
public void setValidRange(double minValid, double maxValid) {
this.minValid = minValid;
this.maxValid = maxValid;
}
public void setFillValue(double fillValue) {
this.fillValue = fillValue;
}
@Override
public double getDataValue(int x, int y) {
if (y < 0 || y > ny - 1) {
// outside y range
return Float.NaN;
} else if (x < 0 || x > nx - 1) {
// outside x range
if (wrapX > 0) {
// attempt to wrap if this is a wrapping grid.
x = (x + wrapX) % wrapX;
if (x < 0 || x > nx - 1) {
return Double.NaN;
}
} else {
return Double.NaN;
}
}
double val = getDataValueInternal(x, y);
if (val < minValid || val > maxValid) {
// skip outside valid range
val = Double.NaN;
}
return val;
}
@Override
public void setDataValue(double dataValue, int x, int y) {
if (Double.isNaN(dataValue)) {
dataValue = fillValue;
}
setDataValueInternal(dataValue, x, y);
}
protected abstract double getDataValueInternal(int x, int y);
protected abstract void setDataValueInternal(double dataValue, int x, int y);
// Attempt to detect the case where a geographic coordinate reference
// system wraps around the world so that values out of range on the
// X-axis can be retrieved from the other side of the grid. If this is
// the case the sourceWrapX value will be set to the number of grid
// cells that are needed to wrap all the way around the world.
protected void checkForWrapping(GeneralGridGeometry geometry) {
try {
CoordinateReferenceSystem sourceCRS = geometry
.getCoordinateReferenceSystem();
MathTransform grid2crs = geometry
.getGridToCRS(PixelInCell.CELL_CENTER);
MathTransform crs2LatLon = CRS.findMathTransform(sourceCRS,
DefaultGeographicCRS.WGS84);
DirectPosition2D corner1 = new DirectPosition2D(nx, 0);
DirectPosition2D corner2 = new DirectPosition2D(nx, ny - 1);
grid2crs.transform(corner1, corner1);
grid2crs.transform(corner2, corner2);
crs2LatLon.transform(corner1, corner1);
crs2LatLon.transform(corner2, corner2);
corner1.x = MapUtil.correctLon(corner1.x);
corner2.x = MapUtil.correctLon(corner2.x);
crs2LatLon.inverse().transform(corner1, corner1);
crs2LatLon.inverse().transform(corner2, corner2);
grid2crs.inverse().transform(corner1, corner1);
grid2crs.inverse().transform(corner2, corner2);
int sourceWrapX = (int) (nx - corner1.x);
// In order to wrap then the transformed point x value should be
// on the other side of the grid and the y value should not have
// changed significantly. Additionally the wrapped x value
// should fall exactly on a grid cell.
if (corner1.x > nx - 1) {
return;
} else if (Math.abs(corner1.y - 0) > 0.0001) {
return;
} else if (Math.abs(corner2.y - ny + 1) > 0.0001) {
return;
} else if (Math.abs(corner1.x + sourceWrapX - nx) > 0.0001) {
return;
} else if (Math.abs(corner2.x + sourceWrapX - nx) > 0.0001) {
return;
} else {
this.wrapX = sourceWrapX;
}
} catch (Exception e) {
// if anything goes wrong in this process just assume we don't
// wrap the x axis, thats not a big deal and it is normal for
// non geographic coordinate systems.
;
}
}
}

View file

@ -0,0 +1,82 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
import java.nio.ByteBuffer;
import org.geotools.coverage.grid.GeneralGridGeometry;
/**
*
* ByteBuffer data wrapper
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class ByteBufferWrapper extends DataWrapper1D {
protected final ByteBuffer buffer;
public ByteBufferWrapper(ByteBuffer buffer, GeneralGridGeometry geometry) {
super(geometry);
this.buffer = buffer;
}
public ByteBufferWrapper(ByteBuffer buffer, int nx, int ny) {
super(nx, ny);
this.buffer = buffer;
}
public ByteBufferWrapper(int nx, int ny) {
this(ByteBuffer.allocate(nx * ny), nx, ny);
}
public ByteBufferWrapper(GeneralGridGeometry geometry) {
// assume this is going to be a destination and avoid passing
// geometry to super to save time on checking for wrapping.
this(geometry.getGridRange().getSpan(0), geometry.getGridRange()
.getSpan(1));
}
public ByteBuffer getBuffer() {
return buffer;
}
@Override
protected double getDataValueInternal(int index) {
return buffer.get(index);
}
@Override
public void setDataValueInternal(double dataValue, int index) {
buffer.put(index, (byte) dataValue);
}
}

View file

@ -0,0 +1,43 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
/**
* An abstraction for writing numeric data from a 2D grid of numeric data.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 18, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public interface DataDestination {
public void setDataValue(double dataValue, int x, int y);
}

View file

@ -0,0 +1,43 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
/**
* An abstraction for reading numeric data from a 2D grid of numeric data.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 18, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public interface DataSource {
public double getDataValue(int x, int y);
}

View file

@ -0,0 +1,65 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
import org.geotools.coverage.grid.GeneralGridGeometry;
/**
*
* converts a 2D x,y index pair into an index value.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public abstract class DataWrapper1D extends AbstractDataWrapper {
public DataWrapper1D(GeneralGridGeometry geometry) {
super(geometry);
}
public DataWrapper1D(int nx, int ny) {
super(nx, ny);
}
@Override
protected double getDataValueInternal(int x, int y) {
return getDataValueInternal(x + y * nx);
}
@Override
public void setDataValueInternal(double dataValue, int x, int y) {
setDataValueInternal(dataValue, x + nx * y);
}
protected abstract double getDataValueInternal(int index);
protected abstract void setDataValueInternal(double dataValue, int index);
}

View file

@ -0,0 +1,82 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
import java.nio.DoubleBuffer;
import org.geotools.coverage.grid.GeneralGridGeometry;
/**
*
* DoubleBuffer data wrapper
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class DoubleBufferWrapper extends DataWrapper1D {
protected final DoubleBuffer buffer;
public DoubleBufferWrapper(DoubleBuffer buffer, GeneralGridGeometry geometry) {
super(geometry);
this.buffer = buffer;
}
public DoubleBufferWrapper(DoubleBuffer buffer, int nx, int ny) {
super(nx, ny);
this.buffer = buffer;
}
public DoubleBufferWrapper(int nx, int ny) {
this(DoubleBuffer.allocate(nx * ny), nx, ny);
}
public DoubleBufferWrapper(GeneralGridGeometry geometry) {
// assume this is going to be a destination and avoid passing
// geometry to super to save time on checking for wrapping.
this(geometry.getGridRange().getSpan(0), geometry.getGridRange()
.getSpan(1));
}
public DoubleBuffer getBuffer() {
return buffer;
}
@Override
protected double getDataValueInternal(int index) {
return buffer.get(index);
}
@Override
public void setDataValueInternal(double dataValue, int index) {
buffer.put(index, dataValue);
}
}

View file

@ -0,0 +1,78 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
import org.geotools.coverage.grid.GeneralGridGeometry;
/**
*
* 2-dimensional float array data
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class FloatArray2DWrapper extends AbstractDataWrapper {
protected final float[][] array;
public FloatArray2DWrapper(float[][] array, GeneralGridGeometry geometry) {
super(geometry);
this.array = array;
}
public FloatArray2DWrapper(float[][] array, int nx, int ny) {
super(nx, ny);
this.array = array;
}
public FloatArray2DWrapper(int nx, int ny) {
this(new float[ny][nx], nx, ny);
}
public FloatArray2DWrapper(GeneralGridGeometry geometry) {
this(geometry.getGridRange().getSpan(0), geometry.getGridRange()
.getSpan(1));
}
public float[][] getArray() {
return array;
}
@Override
public void setDataValueInternal(double dataValue, int x, int y) {
array[y][x] = (float) dataValue;
}
@Override
protected double getDataValueInternal(int x, int y) {
return array[y][x];
}
}

View file

@ -0,0 +1,80 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
import org.geotools.coverage.grid.GeneralGridGeometry;
/**
*
* 1-dimensional float array data
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class FloatArrayWrapper extends DataWrapper1D {
protected final float[] array;
public FloatArrayWrapper(float[] array, GeneralGridGeometry geometry) {
super(geometry);
this.array = array;
}
public FloatArrayWrapper(float[] array, int nx, int ny) {
super(nx, ny);
this.array = array;
}
public FloatArrayWrapper(int nx, int ny) {
this(new float[nx * ny], nx, ny);
}
public FloatArrayWrapper(GeneralGridGeometry geometry) {
// assume this is going to be a destination and avoid passing
// geometry to super to save time on checking for wrapping.
this(geometry.getGridRange().getSpan(0), geometry.getGridRange()
.getSpan(1));
}
public float[] getArray() {
return array;
}
@Override
protected double getDataValueInternal(int index) {
return array[index];
}
@Override
public void setDataValueInternal(double dataValue, int index) {
array[index] = (float) dataValue;
}
}

View file

@ -0,0 +1,82 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
import java.nio.FloatBuffer;
import org.geotools.coverage.grid.GeneralGridGeometry;
/**
*
* FloatBuffer data wrapper
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class FloatBufferWrapper extends DataWrapper1D {
protected final FloatBuffer buffer;
public FloatBufferWrapper(FloatBuffer buffer, GeneralGridGeometry geometry) {
super(geometry);
this.buffer = buffer;
}
public FloatBufferWrapper(FloatBuffer buffer, int nx, int ny) {
super(nx, ny);
this.buffer = buffer;
}
public FloatBufferWrapper(int nx, int ny) {
this(FloatBuffer.allocate(nx * ny), nx, ny);
}
public FloatBufferWrapper(GeneralGridGeometry geometry) {
// assume this is going to be a destination and avoid passing
// geometry to super to save time on checking for wrapping.
this(geometry.getGridRange().getSpan(0), geometry.getGridRange()
.getSpan(1));
}
public FloatBuffer getBuffer() {
return buffer;
}
@Override
protected double getDataValueInternal(int index) {
return buffer.get(index);
}
@Override
public void setDataValueInternal(double dataValue, int index) {
buffer.put(index, (float) dataValue);
}
}

View file

@ -0,0 +1,82 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
import java.nio.IntBuffer;
import org.geotools.coverage.grid.GeneralGridGeometry;
/**
*
* IntBuffer data wrapper
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class IntBufferWrapper extends DataWrapper1D {
protected final IntBuffer buffer;
public IntBufferWrapper(IntBuffer buffer, GeneralGridGeometry geometry) {
super(geometry);
this.buffer = buffer;
}
public IntBufferWrapper(IntBuffer buffer, int nx, int ny) {
super(nx, ny);
this.buffer = buffer;
}
public IntBufferWrapper(int nx, int ny) {
this(IntBuffer.allocate(nx * ny), nx, ny);
}
public IntBufferWrapper(GeneralGridGeometry geometry) {
// assume this is going to be a destination and avoid passing
// geometry to super to save time on checking for wrapping.
this(geometry.getGridRange().getSpan(0), geometry.getGridRange()
.getSpan(1));
}
public IntBuffer getBuffer() {
return buffer;
}
@Override
protected double getDataValueInternal(int index) {
return buffer.get(index);
}
@Override
public void setDataValueInternal(double dataValue, int index) {
buffer.put(index, (int) dataValue);
}
}

View file

@ -0,0 +1,82 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
import java.nio.ShortBuffer;
import org.geotools.coverage.grid.GeneralGridGeometry;
/**
*
* ShortBuffer data wrapper
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class ShortBufferWrapper extends DataWrapper1D {
protected final ShortBuffer buffer;
public ShortBufferWrapper(ShortBuffer buffer, GeneralGridGeometry geometry) {
super(geometry);
this.buffer = buffer;
}
public ShortBufferWrapper(ShortBuffer buffer, int nx, int ny) {
super(nx, ny);
this.buffer = buffer;
}
public ShortBufferWrapper(int nx, int ny) {
this(ShortBuffer.allocate(nx * ny), nx, ny);
}
public ShortBufferWrapper(GeneralGridGeometry geometry) {
// assume this is going to be a destination and avoid passing
// geometry to super to save time on checking for wrapping.
this(geometry.getGridRange().getSpan(0), geometry.getGridRange()
.getSpan(1));
}
public ShortBuffer getBuffer() {
return buffer;
}
@Override
protected double getDataValueInternal(int index) {
return buffer.get(index);
}
@Override
public void setDataValueInternal(double dataValue, int index) {
buffer.put(index, (short) dataValue);
}
}

View file

@ -0,0 +1,83 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
import java.nio.ByteBuffer;
import org.geotools.coverage.grid.GeneralGridGeometry;
/**
*
* ByteBuffer data wrapper
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class UnsignedByteBufferWrapper extends DataWrapper1D {
protected final ByteBuffer buffer;
public UnsignedByteBufferWrapper(ByteBuffer buffer,
GeneralGridGeometry geometry) {
super(geometry);
this.buffer = buffer;
}
public UnsignedByteBufferWrapper(ByteBuffer buffer, int nx, int ny) {
super(nx, ny);
this.buffer = buffer;
}
public UnsignedByteBufferWrapper(int nx, int ny) {
this(ByteBuffer.allocate(nx * ny), nx, ny);
}
public UnsignedByteBufferWrapper(GeneralGridGeometry geometry) {
// assume this is going to be a destination and avoid passing
// geometry to super to save time on checking for wrapping.
this(geometry.getGridRange().getSpan(0), geometry.getGridRange()
.getSpan(1));
}
public ByteBuffer getBuffer() {
return buffer;
}
@Override
protected double getDataValueInternal(int index) {
return buffer.get(index) & 0xFF;
}
@Override
public void setDataValueInternal(double dataValue, int index) {
buffer.put(index, (byte) dataValue);
}
}

View file

@ -0,0 +1,83 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.common.geospatial.interpolation.data;
import java.nio.ShortBuffer;
import org.geotools.coverage.grid.GeneralGridGeometry;
/**
*
* ShortBuffer data wrapper
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 20, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class UnsignedShortBufferWrapper extends DataWrapper1D {
protected final ShortBuffer buffer;
public UnsignedShortBufferWrapper(ShortBuffer buffer,
GeneralGridGeometry geometry) {
super(geometry);
this.buffer = buffer;
}
public UnsignedShortBufferWrapper(ShortBuffer buffer, int nx, int ny) {
super(nx, ny);
this.buffer = buffer;
}
public UnsignedShortBufferWrapper(int nx, int ny) {
this(ShortBuffer.allocate(nx * ny), nx, ny);
}
public UnsignedShortBufferWrapper(GeneralGridGeometry geometry) {
// assume this is going to be a destination and avoid passing
// geometry to super to save time on checking for wrapping.
this(geometry.getGridRange().getSpan(0), geometry.getGridRange()
.getSpan(1));
}
public ShortBuffer getBuffer() {
return buffer;
}
@Override
protected double getDataValueInternal(int index) {
return buffer.get(index) & 0xFFFF;
}
@Override
public void setDataValueInternal(double dataValue, int index) {
buffer.put(index, (short) dataValue);
}
}