Issue #2791 Use Data Source for all grid data access.

Former-commit-id: 961c232e35da077ef4fc0b62cb04a8f4cb9fb6f0
This commit is contained in:
Ben Steffensmeier 2014-02-28 16:30:46 -06:00
parent 47255ea9ad
commit 6fa441396f
14 changed files with 650 additions and 297 deletions

View file

@ -0,0 +1,133 @@
package com.raytheon.uf.viz.core.tile;
import java.awt.Rectangle;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import javax.measure.unit.Unit;
import org.geotools.coverage.grid.GeneralGridGeometry;
import com.raytheon.uf.common.colormap.image.ColorMapData;
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
import com.raytheon.uf.common.geospatial.interpolation.data.ByteBufferWrapper;
import com.raytheon.uf.common.geospatial.interpolation.data.DataDestination;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.DataUtilities;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatBufferWrapper;
import com.raytheon.uf.common.geospatial.interpolation.data.IntBufferWrapper;
import com.raytheon.uf.common.geospatial.interpolation.data.OffsetDataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.ShortBufferWrapper;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IGraphicsTarget.RasterMode;
import com.raytheon.uf.viz.core.IMesh;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormappedImageExtension;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.IMapMeshExtension;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
import com.raytheon.uf.viz.core.tile.TileSetRenderable.TileImageCreator;
/**
*
* Create imagery from any source of numeric data.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Feb 25, 2014 2791 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class DataSourceTileImageCreator implements TileImageCreator {
private class DataSourceColorMapRetrievalCallback implements
IColorMapDataRetrievalCallback {
private final Rectangle slice;
private DataSourceColorMapRetrievalCallback(Rectangle slice) {
this.slice = slice;
}
@Override
public ColorMapData getColorMapData() throws VizException {
ColorMapData data = new ColorMapData(dataType, new int[] {
slice.width, slice.height });
Buffer buffer = data.getBuffer();
DataDestination dest = null;
if (buffer instanceof ByteBuffer) {
dest = new ByteBufferWrapper((ByteBuffer) buffer, slice.width,
slice.height);
} else if (buffer instanceof ShortBuffer) {
dest = new ShortBufferWrapper((ShortBuffer) buffer,
slice.width, slice.height);
} else if (buffer instanceof IntBuffer) {
dest = new IntBufferWrapper((IntBuffer) buffer, slice.width,
slice.height);
} else if (buffer instanceof FloatBuffer) {
dest = new FloatBufferWrapper((FloatBuffer) buffer,
slice.width, slice.height);
} else {
throw new VizException("Unsupported data type: "
+ dataType.toString());
}
DataSource sliceSource = source;
if (slice.x != 0 || slice.y != 0) {
sliceSource = new OffsetDataSource(source, slice.x, slice.y);
}
DataUtilities.copy(sliceSource, dest, slice.width, slice.height);
/* Add units */
return new ColorMapData(buffer, new int[] { slice.width,
slice.height }, dataType, unit);
}
}
private final DataSource source;
private final Unit<?> unit;
private final ColorMapCapability cmapCapability;
private final ColorMapDataType dataType;
public DataSourceTileImageCreator(DataSource source, Unit<?> unit,
ColorMapDataType dataType, ColorMapCapability cmapCapability) {
this.source = source;
this.unit = unit;
this.dataType = dataType;
this.cmapCapability = cmapCapability;
}
@Override
public DrawableImage createTileImage(IGraphicsTarget target, Tile tile,
GeneralGridGeometry targetGeometry) throws VizException {
if (tile.tileLevel != 0) {
throw new VizException(getClass().getSimpleName()
+ " only supports single level tiled data");
}
IImage image = target.getExtension(IColormappedImageExtension.class)
.initializeRaster(
new DataSourceColorMapRetrievalCallback(
tile.getRectangle()),
cmapCapability.getColorMapParameters());
IMesh mesh = target.getExtension(IMapMeshExtension.class)
.constructMesh(tile.tileGeometry, targetGeometry);
return new DrawableImage(image, new PixelCoverage(mesh),
RasterMode.ASYNCHRONOUS);
}
}

View file

@ -32,7 +32,7 @@ import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.referencing.operation.MathTransform;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.interpolation.data.DataCopy;
import com.raytheon.uf.common.geospatial.interpolation.data.DataUtilities;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
import com.raytheon.uf.common.style.contour.ContourPreferences;
@ -454,7 +454,7 @@ public abstract class ContourRenderable implements IRenderable {
* contourPrefs.getSmoothingDistance() / (distanceInM / 1000));
FloatArrayWrapper data = new FloatArrayWrapper(gridGeometry);
data.setFillValue(Constants.LEGACY_NAN);
DataCopy.copy(dataRecord[0], data, nx, ny);
DataUtilities.copy(dataRecord[0], data, nx, ny);
float[] dataArray = data.getArray();
dataArray = DistFilter.filter(dataArray, npts, nx, ny, 1);
data = new FloatArrayWrapper(dataArray, gridGeometry);

View file

@ -44,8 +44,9 @@ import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.geospatial.CRSCache;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.interpolation.data.DataCopy;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.DataUtilities;
import com.raytheon.uf.common.geospatial.interpolation.data.DataUtilities.MinMax;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper;
import com.raytheon.uf.common.geospatial.interpolation.data.OffsetDataSource;
import com.raytheon.uf.common.geospatial.util.GridGeometryWrapChecker;
@ -340,7 +341,7 @@ public class ContourSupport {
/* Make contours continous for world wrapping grids. */
int wrapNumber = GridGeometryWrapChecker
.checkForWrapping(imageGridGeometry);
if (wrapNumber - 1 >= szX) {
if (wrapNumber >= szX - 1) {
szX = wrapNumber + 1;
}
@ -350,7 +351,7 @@ public class ContourSupport {
}
if (copyData) {
subgridSource = DataCopy.copy(subgridSource,
subgridSource = DataUtilities.copy(subgridSource,
new FloatArrayWrapper(szX, szY), szX, szY);
}
@ -381,19 +382,9 @@ public class ContourSupport {
// If nothing provided, attempt to get approximately 50 contours
if (prefs == null || prefs.getContourLabeling() == null) {
// TODO this is fairly inefficient to do every time.
float min = Float.POSITIVE_INFINITY;
float max = Float.NEGATIVE_INFINITY;
for (int j = 0; j < szY; j++) {
for (int i = 0; i < szX; i++) {
float f = (float) subgridSource.getDataValue(i, j);
if (!Float.isNaN(f)) {
min = Math.min(min, f);
max = Math.max(max, f);
}
}
}
MinMax mm = DataUtilities.getMinMax(subgridSource, szX, szY);
float interval = XFormFunctions
.newDataIntervalFromZoom((max - min) / 50,
.newDataIntervalFromZoom((float) mm.getSpan() / 50,
(float) (contourGroup.lastDensity * zoom),
true, "", 10);
config.seed = new float[] { interval };
@ -440,18 +431,9 @@ public class ContourSupport {
.getIncrement();
float interval;
if (contourLabeling.getNumberOfContours() > 0) {
float minData = Float.POSITIVE_INFINITY;
float maxData = Float.NEGATIVE_INFINITY;
for (int j = 0; j < szY; j++) {
for (int i = 0; i < szX; i++) {
float f = (float) subgridSource.getDataValue(i, j);
if (!Float.isNaN(f)) {
minData = Math.min(minData, f);
maxData = Math.max(maxData, f);
}
}
}
interval = (maxData - minData)
MinMax mm = DataUtilities.getMinMax(subgridSource, szX,
szY);
interval = (float) mm.getSpan()
/ contourLabeling.getNumberOfContours();
if (interval < 0) {
interval = -interval;

View file

@ -19,7 +19,7 @@
**/
package com.raytheon.viz.grid.rsc;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@ -29,7 +29,8 @@ import java.util.Map;
import org.eclipse.swt.graphics.RGB;
import org.geotools.coverage.grid.GeneralGridGeometry;
import com.raytheon.uf.viz.core.data.prep.IODataPreparer;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.exception.VizException;
@ -53,6 +54,9 @@ import com.vividsolutions.jts.geom.Coordinate;
* Aug 27, 2013 2287 randerso Added densityFactor to allow application
* specific adjustment of density.
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* Feb 28, 2013 2791 bsteffen Use DataSource for data, custom callback
* for image.
*
*
* </pre>
*
@ -62,7 +66,7 @@ import com.vividsolutions.jts.geom.Coordinate;
public class GriddedIconDisplay extends AbstractGriddedDisplay<IImage> {
private float[] values;
private DataSource values;
private Map<Integer, IImage> images = new HashMap<Integer, IImage>();
@ -78,7 +82,7 @@ public class GriddedIconDisplay extends AbstractGriddedDisplay<IImage> {
* @param densityFactor
* adjustment factor to make density match A1
*/
public GriddedIconDisplay(float[] values, IMapDescriptor descriptor,
public GriddedIconDisplay(DataSource values, IMapDescriptor descriptor,
GeneralGridGeometry gridGeometryOfGrid, int imageSize,
double densityFactor) {
super(descriptor, gridGeometryOfGrid, imageSize, densityFactor);
@ -115,9 +119,8 @@ public class GriddedIconDisplay extends AbstractGriddedDisplay<IImage> {
int i = getValue(coord);
IImage image = images.get(i);
if (image == null) {
BufferedImage bImage = iconFactory.getIcon(i);
image = target.initializeRaster(new IODataPreparer(bImage, "icon"
+ bImage, 0), null);
image = target.initializeRaster(new PointIconImageCallback(
iconFactory, i));
images.put(i, image);
// keep around the image that is entirely empty/transparent so we
// can match it up and don't waste time drawing it later
@ -129,8 +132,7 @@ public class GriddedIconDisplay extends AbstractGriddedDisplay<IImage> {
}
private int getValue(Coordinate coord) {
int idx = (int) (coord.x + (coord.y * gridDims[0]));
return (int) values[idx];
return (int) values.getDataValue((int) coord.x, (int) coord.y);
}
@Override
@ -183,4 +185,22 @@ public class GriddedIconDisplay extends AbstractGriddedDisplay<IImage> {
paintProps, images);
}
protected static class PointIconImageCallback implements
IRenderedImageCallback {
private final PointIconFactory iconFactory;
private final int iconIndex;
private PointIconImageCallback(PointIconFactory iconFactory,
int iconIndex) {
this.iconFactory = iconFactory;
this.iconIndex = iconIndex;
}
@Override
public RenderedImage getImage() throws VizException {
return iconFactory.getIcon(iconIndex);
}
}
}

View file

@ -19,7 +19,6 @@
**/
package com.raytheon.viz.grid.rsc;
import java.nio.FloatBuffer;
import java.text.ParsePosition;
import java.util.Map;
@ -28,6 +27,7 @@ import javax.measure.unit.UnitFormat;
import com.raytheon.uf.common.dataplugin.grid.GridRecord;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.viz.grid.rsc.general.D2DGridResource;
@ -43,6 +43,7 @@ import com.raytheon.viz.grid.rsc.general.GeneralGridData;
* ------------- -------- ----------- --------------------------
* Dec 16, 2009 mnash Initial creation
* Feb 07, 2014 2211 bsteffen Fix sampling
* Feb 28, 2791 2211 bsteffen Move data conversion to DataSource
*
* </pre>
*
@ -98,32 +99,41 @@ public class RcmResource extends D2DGridResource {
protected GeneralGridData getData(GridRecord gridRecord)
throws VizException {
GeneralGridData data = super.getData(gridRecord);
FloatBuffer floatData = data.getScalarData();
FloatBuffer newFloatData = FloatBuffer.allocate(floatData.capacity());
floatData.rewind();
newFloatData.rewind();
while (floatData.hasRemaining()) {
float value = floatData.get();
if (value < 1f) {
newFloatData.put(1f);
DataSource source = new RcmDataSource(data.getScalarData());
return GeneralGridData.createScalarData(data.getGridGeometry(), source,
data.getDataUnit());
}
private final class RcmDataSource implements DataSource {
private final DataSource wrappedSource;
public RcmDataSource(DataSource wrappedSource) {
this.wrappedSource = wrappedSource;
}
@Override
public double getDataValue(int x, int y) {
double value = wrappedSource.getDataValue(x, y);
if (value < 1) {
return 1;
} else if (value < 2) {
newFloatData.put(48f);
return 48;
} else if (value < 3) {
newFloatData.put(96f);
return 96;
} else if (value < 4) {
newFloatData.put(128f);
return 128;
} else if (value < 5) {
newFloatData.put(144f);
return 144;
} else if (value < 6) {
newFloatData.put(160f);
return 160;
} else if (value < 7) {
newFloatData.put(176f);
return 176;
} else {
newFloatData.put(0f);
return 0;
}
}
return GeneralGridData.createScalarData(data.getGridGeometry(),
newFloatData, data.getDataUnit());
}
}

View file

@ -31,11 +31,13 @@ import java.util.concurrent.ConcurrentHashMap;
import javax.measure.unit.Unit;
import javax.measure.unit.UnitFormat;
import org.geotools.coverage.grid.GridEnvelope2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters.PersistedParameters;
import com.raytheon.uf.common.dataplugin.PluginDataObject;
@ -44,7 +46,9 @@ import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.GridSampler;
import com.raytheon.uf.common.geospatial.interpolation.Interpolation;
import com.raytheon.uf.common.geospatial.interpolation.NearestNeighborInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatBufferWrapper;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.DataUtilities;
import com.raytheon.uf.common.geospatial.interpolation.data.DataUtilities.MinMax;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
@ -84,13 +88,15 @@ import com.raytheon.uf.viz.core.rsc.capabilities.DisplayTypeCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability;
import com.raytheon.uf.viz.core.tile.DataSourceTileImageCreator;
import com.raytheon.uf.viz.core.tile.TileSetRenderable;
import com.raytheon.uf.viz.core.tile.TileSetRenderable.TileImageCreator;
import com.raytheon.viz.core.contours.ContourRenderable;
import com.raytheon.viz.core.contours.rsc.displays.AbstractGriddedDisplay;
import com.raytheon.viz.core.contours.rsc.displays.GriddedContourDisplay;
import com.raytheon.viz.core.contours.rsc.displays.GriddedStreamlineDisplay;
import com.raytheon.viz.core.contours.rsc.displays.GriddedVectorDisplay;
import com.raytheon.viz.core.contours.util.VectorGraphicsConfig;
import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay2;
import com.raytheon.viz.grid.rsc.GriddedIconDisplay;
import com.vividsolutions.jts.geom.Coordinate;
@ -118,6 +124,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* Sep 23, 2013 2363 bsteffen Add more vector configuration options.
* Jan 14, 2014 2594 bsteffen Switch vector mag/dir to use data source
* instead of raw float data.
* Feb 28, 2014 2791 bsteffen Switch all data to use data source.
*
*
* </pre>
@ -137,6 +144,8 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
/* Unknown source, provides acceptable density. */
private static final double VECTOR_DENSITY_FACTOR = 1.875;
private static final int IMAGE_TILE_SIZE = 1024;
public static final String INTERROGATE_VALUE = "value";
public static final String INTERROGATE_UNIT = "unit";
@ -485,6 +494,8 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
switch (displayType) {
case IMAGE:
ColorMapCapability colorMapCap = getCapability(ColorMapCapability.class);
ImagingCapability imagingCap = getCapability(ImagingCapability.class);
if (renderableMap.isEmpty()) {
ColorMapParameters params = createColorMapParameters(data);
if (params.getColorMap() == null) {
@ -494,15 +505,15 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
params.setColorMap(ColorMapLoader.loadColorMap(params
.getColorMapName()));
}
this.getCapability(ColorMapCapability.class)
.setColorMapParameters(params);
colorMapCap.setColorMapParameters(params);
}
ColorMapParameters params = getCapability(ColorMapCapability.class)
.getColorMapParameters();
data.convert(params.getImageUnit());
GriddedImageDisplay2 imageRenderable = new GriddedImageDisplay2(
data.getScalarData(), gridGeometry, this);
renderable = imageRenderable;
TileImageCreator creator = new DataSourceTileImageCreator(
data.getScalarData(), data.getDataUnit(),
ColorMapDataType.FLOAT, colorMapCap);
TileSetRenderable tsr = new TileSetRenderable(imagingCap,
gridGeometry, creator, 1, IMAGE_TILE_SIZE);
tsr.project(descriptor.getGridGeometry());
renderable = tsr;
break;
case BARB:
case ARROW:
@ -545,9 +556,8 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
renderable = vectorDisplay;
break;
case ICON:
GriddedIconDisplay iconDisplay = new GriddedIconDisplay(data
.getScalarData().array(), descriptor, gridGeometry, 80,
0.75);
GriddedIconDisplay iconDisplay = new GriddedIconDisplay(
data.getScalarData(), descriptor, gridGeometry, 80, 0.75);
iconDisplay.setColor(getCapability(ColorableCapability.class)
.getColor());
iconDisplay.setDensity(getCapability(DensityCapability.class)
@ -608,17 +618,23 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
throws VizException {
ParamLevelMatchCriteria criteria = getMatchCriteria();
ColorMapParameters newParameters;
GridEnvelope2D range = data.getGridGeometry().getGridRange2D();
DataSource source = data.getScalarData();
MinMax mm = DataUtilities.getMinMax(source, range.getSpan(0),
range.getSpan(1));
try {
newParameters = ColorMapParameterFactory.build(data.getScalarData()
.array(), data.getDataUnit(), criteria);
newParameters = ColorMapParameterFactory.build((float) mm.getMin(),
(float) mm.getMax(), data.getDataUnit(), criteria);
} catch (StyleException e) {
throw new VizException("Unable to build colormap parameters", e);
}
ColorMapParameters oldParameters = this.getCapability(
ColorMapCapability.class).getColorMapParameters();
if (oldParameters != null
&& oldParameters.getDataMin() <= newParameters.getDataMin()
&& oldParameters.getDataMax() >= newParameters.getDataMax()) {
&& oldParameters.getColorMapMin() <= newParameters
.getColorMapMin()
&& oldParameters.getColorMapMax() >= newParameters
.getColorMapMax()) {
// if the oldParameters have a larger range than the new parameters,
// reuse the old parameters. This is useful when the resource is
// sharing capabilities, for example in an FFGVizGroupResource.
@ -684,6 +700,7 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
GeneralGridData merged = GeneralGridData
.mergeData(data1, data2);
if (merged != null) {
data1 = merged;
dataList.set(i, merged);
dataList.remove(j);
j -= 1;
@ -709,8 +726,8 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
@Override
public void run() {
if (renderable instanceof GriddedImageDisplay2) {
((GriddedImageDisplay2) renderable).dispose();
if (renderable instanceof TileSetRenderable) {
((TileSetRenderable) renderable).dispose();
} else if (renderable instanceof AbstractGriddedDisplay<?>) {
((AbstractGriddedDisplay<?>) renderable).dispose();
} else if (renderable instanceof ContourRenderable) {
@ -734,7 +751,7 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
List<IRenderable> renderableList = iter.next();
boolean remove = false;
for (IRenderable renderable : renderableList) {
if (!projectRenderable(renderable, crs)) {
if (!projectRenderable(renderable)) {
remove = true;
break;
}
@ -757,14 +774,13 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
* the new projection.
*
* @param renderable
* @param crs
* @return
* @throws VizException
*/
protected boolean projectRenderable(IRenderable renderable,
CoordinateReferenceSystem crs) throws VizException {
if (renderable instanceof GriddedImageDisplay2) {
((GriddedImageDisplay2) renderable).project(descriptor
protected boolean projectRenderable(IRenderable renderable)
throws VizException {
if (renderable instanceof TileSetRenderable) {
((TileSetRenderable) renderable).project(descriptor
.getGridGeometry());
return true;
} else if (renderable instanceof AbstractGriddedDisplay<?>) {
@ -786,7 +802,7 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
return requestData(time);
}
protected Interpolation getInspectInterpolation(GeneralGridData data) {
protected Interpolation getInspectInterpolation() {
Interpolation sampleInterpolion = null;
if (this.hasCapability(ImagingCapability.class)) {
ImagingCapability imagingCap = this
@ -847,13 +863,12 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
throw new VizException(
"Error transforming coordinate for interrogate", e);
}
Interpolation interpolation = getInspectInterpolation(data);
Interpolation interpolation = getInspectInterpolation();
GridSampler sampler = null;
if (data.isVector()) {
sampler = new GridSampler(data.getMagnitude(), interpolation);
} else {
sampler = new GridSampler(new FloatBufferWrapper(
data.getScalarData(), data.getGridGeometry()), interpolation);
sampler = new GridSampler(data.getScalarData(), interpolation);
}
double value = sampler.sample(pixel.x, pixel.y);
if (Double.isNaN(value)) {

View file

@ -45,6 +45,8 @@ import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.Interpolation;
import com.raytheon.uf.common.geospatial.interpolation.NearestNeighborInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatBufferWrapper;
import com.raytheon.uf.common.geospatial.util.GridGeometryWrapChecker;
import com.raytheon.uf.common.geospatial.util.SubGridGeometryCalculator;
import com.raytheon.uf.common.gridcoverage.GridCoverage;
@ -93,6 +95,8 @@ import com.vividsolutions.jts.geom.Coordinate;
* world.
* Feb 04, 2014 2672 bsteffen Extract subgridding logic to geospatial
* plugin.
* Feb 28, 2013 2791 bsteffen Use DataSource instead of FloatBuffers
* for data access
*
* </pre>
*
@ -227,22 +231,24 @@ public class D2DGridResource extends GridResource<GridResourceData> implements
MathTransform crs2ll = MapUtil
.getTransformToLatLon(gridGeometry
.getCoordinateReferenceSystem());
DataSource oldScalar = data.getScalarData();
FloatBufferWrapper newScalar = new FloatBufferWrapper(
gridGeometry);
for (int i = 0; i < gridRange.width; i++) {
for (int j = 0; j < gridRange.height; j++) {
int index = i + (j * gridRange.width);
float dir = data.getScalarData().get(index);
if (dir > -9999) {
DirectPosition2D dp = new DirectPosition2D(i, j);
grid2crs.transform(dp, dp);
crs2ll.transform(dp, dp);
Coordinate ll = new Coordinate(dp.x, dp.y);
float rot = (float) MapUtil.rotation(ll,
gridGeometry);
dir = (dir + rot) % 360;
data.getScalarData().put(index, dir);
}
double dir = oldScalar.getDataValue(i, j);
DirectPosition2D dp = new DirectPosition2D(i, j);
grid2crs.transform(dp, dp);
crs2ll.transform(dp, dp);
Coordinate ll = new Coordinate(dp.x, dp.y);
float rot = (float) MapUtil.rotation(ll,
gridGeometry);
dir = (dir + rot) % 360;
newScalar.setDataValue(dir, i, j);
}
}
data = GeneralGridData.createScalarData(gridGeometry,
newScalar, data.getDataUnit());
} catch (TransformException e) {
throw new VizException(e);
} catch (InvalidGridGeometryException e) {

View file

@ -19,7 +19,6 @@
**/
package com.raytheon.viz.grid.rsc.general;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -32,12 +31,12 @@ import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
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.BilinearInterpolation;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.style.ParamLevelMatchCriteria;
import com.raytheon.uf.common.time.CombinedDataTime;
import com.raytheon.uf.common.time.DataTime;
@ -61,9 +60,11 @@ import com.raytheon.viz.core.rsc.ICombinedResourceData.CombineUtil;
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 16, 2011 bsteffen Initial creation
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Mar 16, 2011 bsteffen Initial creation
* Feb 28, 2013 2791 bsteffen Use DataSource instead of FloatBuffers
* for data access
*
* </pre>
*
@ -120,8 +121,8 @@ public class DifferenceGridResource extends
return super.interrogate(coord);
}
Map<String, Object> myMap = new HashMap<String, Object>();
float oneVal = (Float) oneMap.get(INTERROGATE_VALUE);
float twoVal = (Float) twoMap.get(INTERROGATE_VALUE);
double oneVal = ((Number) oneMap.get(INTERROGATE_VALUE)).doubleValue();
double twoVal = ((Number) twoMap.get(INTERROGATE_VALUE)).doubleValue();
myMap.put(INTERROGATE_VALUE, oneVal - twoVal);
if (oneMap.get(INTERROGATE_UNIT).equals(twoMap.get(INTERROGATE_UNIT))) {
myMap.put(INTERROGATE_UNIT, oneMap.get(INTERROGATE_UNIT));
@ -221,28 +222,17 @@ public class DifferenceGridResource extends
oneData = oneData.reproject(newGeom, new BilinearInterpolation());
twoData = twoData.reproject(newGeom, 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();
float[] newU = new float[oneU.length];
float[] newV = new float[oneV.length];
for (int i = 0; i < newU.length; i++) {
newU[i] = oneU[i] - twoU[i];
newV[i] = oneV[i] - twoV[i];
}
newData = GeneralGridData
.createVectorDataUV(newGeom, FloatBuffer.wrap(newU),
FloatBuffer.wrap(newV), newUnit);
DifferenceDataSource uComponent = new DifferenceDataSource(
oneData.getUComponent(), twoData.getUComponent());
DifferenceDataSource vComponent = new DifferenceDataSource(
oneData.getVComponent(), twoData.getVComponent());
newData = GeneralGridData.createVectorDataUV(newGeom,
uComponent, vComponent, newUnit);
} else {
float[] oneScalar = oneData.getScalarData().array();
float[] twoScalar = twoData.getScalarData().array();
float[] newScalar = new float[oneScalar.length];
for (int i = 0; i < newScalar.length; i++) {
newScalar[i] = oneScalar[i] - twoScalar[i];
}
newData = GeneralGridData.createScalarData(newGeom,
FloatBuffer.wrap(newScalar), newUnit);
DifferenceDataSource data = new DifferenceDataSource(
oneData.getScalarData(), twoData.getScalarData());
newData = GeneralGridData.createScalarData(newGeom, data,
newUnit);
}
} catch (FactoryException e) {
throw new VizException(e);
@ -279,12 +269,32 @@ public class DifferenceGridResource extends
}
@Override
protected boolean projectRenderable(IRenderable renderable,
CoordinateReferenceSystem crs) throws VizException {
protected boolean projectRenderable(IRenderable renderable) {
// Always rebuild the renderables in case we projected into descriptor
// space.
return false;
}
protected static class DifferenceDataSource implements DataSource {
private final DataSource one;
private final DataSource two;
private DifferenceDataSource(DataSource one, DataSource two) {
super();
this.one = one;
this.two = two;
}
@Override
public double getDataValue(int x, int y) {
double oneVal = one.getDataValue(x, y);
double twoVal = two.getDataValue(x, y);
return oneVal - twoVal;
}
}
}

View file

@ -39,12 +39,15 @@ import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.geospatial.MapUtil;
import com.raytheon.uf.common.geospatial.interpolation.GridReprojection;
import com.raytheon.uf.common.geospatial.interpolation.GridReprojectionDataSource;
import com.raytheon.uf.common.geospatial.interpolation.GridSampler;
import com.raytheon.uf.common.geospatial.interpolation.Interpolation;
import com.raytheon.uf.common.geospatial.interpolation.PrecomputedGridReprojection;
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.geospatial.interpolation.data.OffsetDataSource;
import com.raytheon.uf.common.geospatial.interpolation.data.UnitConvertingDataSource;
import com.vividsolutions.jts.geom.Coordinate;
/**
@ -68,8 +71,10 @@ import com.vividsolutions.jts.geom.Coordinate;
* Jan 14, 2014 2661 bsteffen For vectors only keep uComponent and
* vComponent, calculate magnitude and
* direction on demand.
* Feb 03, 2013 2764 bsteffen Ensure that internal buffers are array
* Feb 03, 2014 2764 bsteffen Ensure that internal buffers are array
* backed heap buffers.
* Feb 28, 2013 2791 bsteffen Use DataSource instead of FloatBuffers
* for data access
*
* </pre>
*
@ -80,16 +85,16 @@ public class GeneralGridData {
private GridGeometry2D gridGeometry;
private FloatBufferWrapper scalarData;
private DataSource scalarData;
private FloatBufferWrapper uComponent = null;
private DataSource uComponent = null;
private FloatBufferWrapper vComponent = null;
private DataSource vComponent = null;
private Unit<?> dataUnit;
/**
* Create a scalar grid Data object.
* Create a scalar grid data object from float data.
*
* @param scalarData
* @param dataUnit
@ -98,31 +103,27 @@ public class GeneralGridData {
public static GeneralGridData createScalarData(
GeneralGridGeometry gridGeometry, FloatBuffer scalarData,
Unit<?> dataUnit) {
DataSource scalarSource = new FloatBufferWrapper(scalarData,
gridGeometry);
return createScalarData(gridGeometry, scalarSource, dataUnit);
}
/**
* Create a scalar grid data object from any data source
*
* @param scalarData
* @param dataUnit
* @return
*/
public static GeneralGridData createScalarData(
GeneralGridGeometry gridGeometry, DataSource scalarData,
Unit<?> dataUnit) {
return new GeneralGridData(gridGeometry, scalarData, dataUnit);
}
/**
* Create GridData for a vector. Providing (u,v) and (mag,dir) is redundant
* and it will be assumed that these are equivalent. This should only be
* used when both these representations are readily available to save time
* if one or the other is needed later.
*
* @deprecated Magnitude and direction are ignored, use
* {@link #createVectorDataUV(GeneralGridGeometry, FloatBuffer, FloatBuffer, Unit)}
*/
@Deprecated
@SuppressWarnings("unused")
public static GeneralGridData createVectorData(
GeneralGridGeometry gridGeometry, FloatBuffer magnitude,
FloatBuffer direction, FloatBuffer uComponent,
FloatBuffer vComponent, Unit<?> dataUnit) {
return new GeneralGridData(gridGeometry,
uComponent, vComponent, dataUnit);
}
/**
* Create gridData for a vector by providing the magnitude and direction of
* the vector.
* the vector as floats.
*
* @param magnitude
* @param direction
@ -138,16 +139,17 @@ public class GeneralGridData {
FloatBuffer uComponent = FloatBuffer.allocate(magnitude.capacity());
while (magnitude.hasRemaining()) {
double angle = Math.toRadians(direction.get());
vComponent.put((float) (Math.cos(angle) * magnitude.get()));
uComponent.put((float) (Math.sin(angle) * magnitude.get()));
double mag = magnitude.get();
vComponent.put((float) (Math.cos(angle) * mag));
uComponent.put((float) (Math.sin(angle) * mag));
}
return new GeneralGridData(gridGeometry, uComponent, vComponent,
return createVectorDataUV(gridGeometry, uComponent, vComponent,
dataUnit);
}
/**
* Create gridData for a vector by providing the u and v components of the
* vector
* vector as floats.
*
* @param uComponent
* @param vComponent
@ -157,32 +159,39 @@ public class GeneralGridData {
public static GeneralGridData createVectorDataUV(
GeneralGridGeometry gridGeometry, FloatBuffer uComponent,
FloatBuffer vComponent, Unit<?> dataUnit) {
return new GeneralGridData(gridGeometry, uComponent,
vComponent, dataUnit);
DataSource uSource = new FloatBufferWrapper(uComponent, gridGeometry);
DataSource vSource = new FloatBufferWrapper(vComponent, gridGeometry);
return createVectorDataUV(gridGeometry, uSource, vSource, dataUnit);
}
/**
* Create gridData for a vector by providing the u and v components of the
* vector as any data source.
*
* @param uComponent
* @param vComponent
* @param dataUnit
* @return
*/
public static GeneralGridData createVectorDataUV(
GeneralGridGeometry gridGeometry, DataSource uComponent,
DataSource vComponent, Unit<?> dataUnit) {
return new GeneralGridData(gridGeometry, uComponent, vComponent,
dataUnit);
}
private GeneralGridData(GeneralGridGeometry gridGeometry,
FloatBuffer scalarData, Unit<?> dataUnit) {
DataSource scalarData, Unit<?> dataUnit) {
this.gridGeometry = GridGeometry2D.wrap(gridGeometry);
if (scalarData != null && !scalarData.hasArray()) {
/*
* TODO refactor dispaly code so it doesn't need array instead of
* copying data.
*/
FloatBuffer copy = FloatBuffer.allocate(scalarData.capacity());
scalarData.rewind();
copy.put(scalarData);
scalarData = copy;
}
this.scalarData = new FloatBufferWrapper(scalarData, this.gridGeometry);
this.scalarData = scalarData;
this.dataUnit = dataUnit;
}
private GeneralGridData(GeneralGridGeometry gridGeometry,
FloatBuffer uComponent, FloatBuffer vComponent, Unit<?> dataUnit) {
DataSource uComponent, DataSource vComponent, Unit<?> dataUnit) {
this.gridGeometry = GridGeometry2D.wrap(gridGeometry);
this.uComponent = new FloatBufferWrapper(uComponent, this.gridGeometry);
this.vComponent = new FloatBufferWrapper(vComponent, this.gridGeometry);
this.uComponent = uComponent;
this.vComponent = vComponent;
this.dataUnit = dataUnit;
}
@ -208,39 +217,28 @@ public class GeneralGridData {
return true;
}
if (scalarData != null) {
FloatBuffer oldData = scalarData.getBuffer();
oldData.rewind();
FloatBuffer newData = FloatBuffer.allocate(oldData.capacity());
while (oldData.hasRemaining()) {
newData.put((float) converter.convert(oldData.get()));
}
newData.rewind();
scalarData = new FloatBufferWrapper(newData, gridGeometry);
scalarData = new UnitConvertingDataSource(converter, scalarData);
}
if (uComponent != null) {
FloatBuffer oldData = uComponent.getBuffer();
oldData.rewind();
FloatBuffer newData = FloatBuffer.allocate(oldData.capacity());
while (oldData.hasRemaining()) {
newData.put((float) converter.convert(oldData.get()));
}
newData.rewind();
uComponent = new FloatBufferWrapper(newData, gridGeometry);
uComponent = new UnitConvertingDataSource(converter, uComponent);
}
if (vComponent != null) {
FloatBuffer oldData = vComponent.getBuffer();
oldData.rewind();
FloatBuffer newData = FloatBuffer.allocate(oldData.capacity());
while (oldData.hasRemaining()) {
newData.put((float) converter.convert(oldData.get()));
}
newData.rewind();
vComponent = new FloatBufferWrapper(newData, gridGeometry);
vComponent = new UnitConvertingDataSource(converter, vComponent);
}
dataUnit = unit;
return true;
}
/**
* Create a new GeneralGridData that is a reprojected version of this data.
*
* @param newGridGeometry
* @param interpolation
* @return
* @throws FactoryException
* @throws TransformException
*/
public GeneralGridData reproject(GeneralGridGeometry newGridGeometry,
Interpolation interpolation) throws FactoryException,
TransformException {
@ -249,12 +247,10 @@ public class GeneralGridData {
gridGeometry, newGeom);
GridSampler sampler = new GridSampler(interpolation);
if (isVector()) {
sampler.setSource(new FloatBufferWrapper(getUComponent(),
gridGeometry));
sampler.setSource(getUComponent());
float[] udata = reproj.reprojectedGrid(sampler,
new FloatArrayWrapper(newGeom)).getArray();
sampler.setSource(new FloatBufferWrapper(getVComponent(),
gridGeometry));
sampler.setSource(getVComponent());
float[] vdata = reproj.reprojectedGrid(sampler,
new FloatArrayWrapper(newGeom)).getArray();
// When reprojecting it is necessary to recalculate the
@ -276,29 +272,8 @@ public class GeneralGridData {
Coordinate ll = new Coordinate(dp.x, dp.y);
double rot = MapUtil.rotation(ll, newGeom);
double rot2 = MapUtil.rotation(ll, gridGeometry);
/*
* When code calls into this method, the observed state
* of things is that u and v represent the direction
* the vector is going while mag and dir represent
* the direction the vector is coming from. The extra
* 180 here makes everything consistently represent the
* direction the vector is coming from so that when the
* barbs or arrows are rendered the mag and dir are
* calculated as expected. Overall this is a completely
* rediculous way of doing things. During construction
* everything should be forced to represent the vector
* consistently and we should only be keeping either
* u/v or mag/dir to minimize memory consumption.
* Unfortunately that is a significant change which is
* made high risk by the fact no one documents which
* areas are expecting vectors oriented to vs from. So
* for now I(bsteffen) have chosen to simply add in 180
* so that the behavior will be exactly as it was before
* 2287 because even though it is rediculous it is a well
* tested rediculous(theoretically).
*/
double cos = Math.cos(Math.toRadians(rot - rot2 + 180));
double sin = Math.sin(Math.toRadians(rot - rot2 + 180));
double cos = Math.cos(Math.toRadians(rot - rot2));
double sin = Math.sin(Math.toRadians(rot - rot2));
double u = udata[index];
double v = vdata[index];
udata[index] = (float) (cos * u - sin * v);
@ -309,11 +284,9 @@ public class GeneralGridData {
return createVectorDataUV(newGridGeometry, FloatBuffer.wrap(udata),
FloatBuffer.wrap(vdata), dataUnit);
} else {
sampler.setSource(new FloatBufferWrapper(getScalarData(),
gridGeometry));
FloatBuffer data = reproj.reprojectedGrid(sampler,
new FloatBufferWrapper(newGeom)).getBuffer();
return createScalarData(newGridGeometry, data, dataUnit);
sampler.setSource(getScalarData());
return createScalarData(newGridGeometry,
new GridReprojectionDataSource(reproj, sampler), dataUnit);
}
}
@ -330,20 +303,11 @@ public class GeneralGridData {
return new MagnitudeDataSource(uComponent, vComponent);
}
public FloatBuffer getScalarData() {
public DataSource getScalarData() {
if (isVector()) {
FloatBufferWrapper tmp = new FloatBufferWrapper(gridGeometry);
DataSource mag = getMagnitude();
int w = gridGeometry.getGridRange2D().width;
int h = gridGeometry.getGridRange2D().height;
for (int i = 0; i < w; i += 1) {
for (int j = 0; j < h; j += 1) {
tmp.setDataValue(mag.getDataValue(i, j), i, j);
}
}
return tmp.getBuffer();
return getMagnitude();
} else {
return scalarData.getBuffer();
return scalarData;
}
}
@ -367,12 +331,12 @@ public class GeneralGridData {
return new DirectionToDataSource(uComponent, vComponent);
}
public FloatBuffer getUComponent() {
return uComponent.getBuffer();
public DataSource getUComponent() {
return uComponent;
}
public FloatBuffer getVComponent() {
return vComponent.getBuffer();
public DataSource getVComponent() {
return vComponent;
}
public Unit<?> getDataUnit() {
@ -452,48 +416,27 @@ public class GeneralGridData {
range2.y = (int) Math.round((envelope.getMaxY() - envelope2.getMaxY())
/ dy);
if (data1.isVector() && data2.isVector()) {
FloatBuffer newU = FloatBuffer.allocate(nx * ny);
mergeData(data1.getUComponent(), range1, data2.getUComponent(),
range2, newU, range);
FloatBuffer newV = FloatBuffer.allocate(nx * ny);
mergeData(data1.getVComponent(), range1, data2.getVComponent(),
range2, newV, range);
DataSource newU = mergeData(data1.getUComponent(), range1,
data2.getUComponent(), range2);
DataSource newV = mergeData(data1.getVComponent(), range1,
data2.getVComponent(), range2);
return createVectorDataUV(geometry, newU, newV, data1.getDataUnit());
} else {
FloatBuffer newData = FloatBuffer.allocate(nx * ny);
mergeData(data1.getScalarData(), range1, data2.getScalarData(),
range2, newData, range);
DataSource newData = mergeData(data1.getScalarData(), range1,
data2.getScalarData(), range2);
return createScalarData(geometry, newData, data1.getDataUnit());
}
}
private static void mergeData(FloatBuffer data1, GridEnvelope2D env1,
FloatBuffer data2, GridEnvelope2D env2, FloatBuffer destData,
GridEnvelope2D destEnv) {
data1.rewind();
data2.rewind();
destData.rewind();
for (int y = 0; y < destEnv.height; y++) {
for (int x = 0; x < destEnv.width; x++) {
float v1 = Float.NaN;
float v2 = Float.NaN;
if (env1.contains(x, y)) {
v1 = data1.get();
}
if (env2.contains(x, y)) {
v2 = data2.get();
}
if (Float.isNaN(v1) && Float.isNaN(v2)) {
destData.put(Float.NaN);
} else if (Float.isNaN(v1)) {
destData.put(v2);
} else if (Float.isNaN(v2)) {
destData.put(v1);
} else {
destData.put((v1 + v2) / 2);
}
}
private static DataSource mergeData(DataSource data1, GridEnvelope2D env1,
DataSource data2, GridEnvelope2D env2) {
if (env1.x != 0 || env1.y != 0) {
data1 = new OffsetDataSource(data1, -env1.x, -env1.y);
}
if (env2.x != 0 || env2.y != 0) {
data2 = new OffsetDataSource(data2, -env2.x, -env2.y);
}
return new MergedDataSource(data1, data2);
}
private static abstract class VectorDataSource implements DataSource {
@ -524,7 +467,8 @@ public class GeneralGridData {
private static final class DirectionFromDataSource extends VectorDataSource {
public DirectionFromDataSource(DataSource uComponent, DataSource vComponent) {
public DirectionFromDataSource(DataSource uComponent,
DataSource vComponent) {
super(uComponent, vComponent);
}
@ -535,8 +479,7 @@ public class GeneralGridData {
}
}
private static final class DirectionToDataSource extends
VectorDataSource {
private static final class DirectionToDataSource extends VectorDataSource {
public DirectionToDataSource(DataSource uComponent,
DataSource vComponent) {
@ -549,4 +492,31 @@ public class GeneralGridData {
vComponent.getDataValue(x, y)));
}
}
private static final class MergedDataSource implements DataSource {
DataSource[] sources;
public MergedDataSource(DataSource... sources) {
this.sources = sources;
}
@Override
public double getDataValue(int x, int y) {
int count = 0;
double total = 0;
for (DataSource source : sources) {
double val = source.getDataValue(x, y);
if (Double.isNaN(val) == false) {
total += val;
count += 1;
}
}
if (count == 0) {
return Double.NaN;
} else {
return total / count;
}
}
}
}

View file

@ -27,9 +27,10 @@ package com.raytheon.uf.common.colormap;
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 7, 2013 2492 mschenke Initial creation
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Nov 07, 2013 2492 mschenke Initial creation
* Feb 28, 2013 2791 bsteffen Make EFFECTIVE_ZERO consistent with gl version.
*
* </pre>
*
@ -39,7 +40,7 @@ package com.raytheon.uf.common.colormap;
public class LogConverter {
private static double EFFECTIVE_ZERO = Double.MIN_VALUE;
private static double EFFECTIVE_ZERO = 0.0000001;
public static double valueToIndex(double value, double rangeMin,
double rangeMax) {

View file

@ -0,0 +1,76 @@
/**
* 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.opengis.referencing.FactoryException;
import org.opengis.referencing.operation.TransformException;
import com.raytheon.uf.common.geospatial.interpolation.data.DataSource;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
/**
* Data Source that reprojects from another grid.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Feb 28, 2014 2791 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class GridReprojectionDataSource implements DataSource {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(GridReprojectionDataSource.class);
private final GridReprojection reprojection;
private final GridSampler sampler;
public GridReprojectionDataSource(GridReprojection reprojection,
GridSampler sampler) {
super();
this.reprojection = reprojection;
this.sampler = sampler;
}
@Override
public double getDataValue(int x, int y) {
try {
return reprojection.reprojectedGridCell(sampler, x, y);
} catch (FactoryException e) {
statusHandler.handle(Priority.DEBUG, e.getLocalizedMessage(), e);
return Double.NaN;
} catch (TransformException e) {
statusHandler.handle(Priority.DEBUG, e.getLocalizedMessage(), e);
return Double.NaN;
}
}
}

View file

@ -37,7 +37,7 @@ package com.raytheon.uf.common.geospatial.interpolation.data;
* @version 1.0
*/
public class DataCopy {
public class DataUtilities {
public static final <D extends DataDestination> D copy(DataSource source,
D destination, int nx, int ny) {
@ -48,4 +48,50 @@ public class DataCopy {
}
return destination;
}
public static final MinMax getMinMax(DataSource source, int nx, int ny) {
double minValue = Double.POSITIVE_INFINITY;
double maxValue = Double.NEGATIVE_INFINITY;
for (int i = 0; i < nx; i += 1) {
for (int j = 0; j < ny; j += 1) {
double val = source.getDataValue(i, j);
if (Double.isNaN(val)) {
continue;
}
if (val < minValue) {
minValue = val;
}
if (val > maxValue) {
maxValue = val;
}
}
}
return new MinMax(minValue, maxValue);
}
public static class MinMax {
private final double min;
private final double max;
private MinMax(double min, double max) {
this.min = min;
this.max = max;
}
public double getMin() {
return min;
}
public double getMax() {
return max;
}
public double getSpan() {
return max - min;
}
}
}

View file

@ -0,0 +1,67 @@
/**
* 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 javax.measure.converter.UnitConverter;
/**
*
* Source which wraps another source and converts data on demand.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------- -------- ----------- --------------------------
* Feb 25, 2014 2791 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class UnitConvertingDataSource implements DataSource {
protected UnitConverter unitConverter;
protected DataSource wrappedSource;
/**
* Constructor
*
* @param converter
* the unit converter to apply when setting the values in the
* destination
* @param source
* the source to get values from
*/
public UnitConvertingDataSource(UnitConverter converter, DataSource source) {
this.unitConverter = converter;
this.wrappedSource = source;
}
@Override
public double getDataValue(int x, int y) {
double val = unitConverter.convert(wrappedSource.getDataValue(x, y));
return val;
}
}

View file

@ -51,14 +51,24 @@ import com.raytheon.uf.common.util.GridUtil;
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 25, 2007 chammack Initial Creation.
* Mar 26, 2009 2086 jsanchez Added a entityList to the match criteria.
* Feb 15, 2013 1638 mschenke Moved GRID_FILL_VALUE from edex.common Util into GridUtil
* Jun 24, 2013 2122 mschenke Added method for constructing {@link ColorMapParameters} from {@link StyleRule}
* Sep 24, 2013 2404 bclement moved to common.style from viz.core, added build method that takes ParamLevelMatchCriteria, removed unused methods
* Nov 13, 2013 2492 mschenke Create build that does not take data for adaptive building
* Date Ticket# Engineer Description
* ------------- -------- ----------- -----------------------------------------
* Jul 25, 2007 chammack Initial Creation.
* Mar 26, 2009 2086 jsanchez Added a entityList to the match criteria.
* Feb 15, 2013 1638 mschenke Moved GRID_FILL_VALUE from edex.common
* Util into GridUtil
* Jun 24, 2013 2122 mschenke Added method for constructing
* {@link ColorMapParameters} from
* {@link StyleRule}
* Sep 24, 2013 2404 bclement moved to common.style from viz.core,
* added build method that takes
* ParamLevelMatchCriteria, removed unused
* methods
* Nov 13, 2013 2492 mschenke Create build that does not take data for
* adaptive building
* Feb 28, 2014 2791 bsteffen Add a build method that takes min/max
* data values.
*
* </pre>
*
* @author chammack
@ -118,7 +128,14 @@ public class ColorMapParameterFactory {
return build(sr, data, level, parameterUnits);
}
public static ColorMapParameters build(StyleRule sr, Object data,
public static ColorMapParameters build(float minValue, float maxValue,
Unit<?> parameterUnits, ParamLevelMatchCriteria match)
throws StyleException {
float[] data = { minValue, maxValue };
return build(data, parameterUnits, match);
}
protected static ColorMapParameters build(StyleRule sr, Object data,
SingleLevel level, Unit<?> parameterUnits) {
ColorMapParameters params = new ColorMapParameters();