diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/tile/DataSourceTileImageCreator.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/tile/DataSourceTileImageCreator.java new file mode 100644 index 0000000000..6ea2c24117 --- /dev/null +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/tile/DataSourceTileImageCreator.java @@ -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. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer    Description
+ * ------------- -------- ----------- --------------------------
+ * Feb 25, 2014  2791     bsteffen    Initial creation
+ * 
+ * 
+ * + * @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); + } +} diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourRenderable.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourRenderable.java index 87f17ec27c..064bc068b9 100644 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourRenderable.java +++ b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourRenderable.java @@ -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); diff --git a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourSupport.java b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourSupport.java index 5da3822025..067bc02e4e 100644 --- a/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourSupport.java +++ b/cave/com.raytheon.viz.core.contours/src/com/raytheon/viz/core/contours/ContourSupport.java @@ -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; diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GriddedIconDisplay.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GriddedIconDisplay.java index c3cfba24ea..05f9a7f0aa 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GriddedIconDisplay.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/GriddedIconDisplay.java @@ -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. + * * * * @@ -62,7 +66,7 @@ import com.vividsolutions.jts.geom.Coordinate; public class GriddedIconDisplay extends AbstractGriddedDisplay { - private float[] values; + private DataSource values; private Map images = new HashMap(); @@ -78,7 +82,7 @@ public class GriddedIconDisplay extends AbstractGriddedDisplay { * @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 { 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 { } 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 { 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); + } + + } } diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/RcmResource.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/RcmResource.java index 37a18a60c8..6fcf73861d 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/RcmResource.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/RcmResource.java @@ -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 * * * @@ -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()); + } } diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java index 43a2b8a60a..4fc15187db 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/AbstractGridResource.java @@ -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. * * * @@ -137,6 +144,8 @@ public abstract class AbstractGridResource /* 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 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 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 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 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 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 @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 List 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 * 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 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 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)) { diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGridResource.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGridResource.java index c59e6fccf8..195f7c53fb 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGridResource.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/D2DGridResource.java @@ -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 * * * @@ -227,22 +231,24 @@ public class D2DGridResource extends GridResource 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) { diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/DifferenceGridResource.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/DifferenceGridResource.java index 2e90cc8f78..e5803ff30f 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/DifferenceGridResource.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/DifferenceGridResource.java @@ -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 * * * @@ -120,8 +121,8 @@ public class DifferenceGridResource extends return super.interrogate(coord); } Map myMap = new HashMap(); - 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; + } + + } + } diff --git a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/GeneralGridData.java b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/GeneralGridData.java index cac14b0165..c039be8e2b 100644 --- a/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/GeneralGridData.java +++ b/cave/com.raytheon.viz.grid/src/com/raytheon/viz/grid/rsc/general/GeneralGridData.java @@ -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 * * * @@ -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; + } + } + } } diff --git a/edexOsgi/com.raytheon.uf.common.colormap/src/com/raytheon/uf/common/colormap/LogConverter.java b/edexOsgi/com.raytheon.uf.common.colormap/src/com/raytheon/uf/common/colormap/LogConverter.java index f6a88b3bfa..9ffd200088 100644 --- a/edexOsgi/com.raytheon.uf.common.colormap/src/com/raytheon/uf/common/colormap/LogConverter.java +++ b/edexOsgi/com.raytheon.uf.common.colormap/src/com/raytheon/uf/common/colormap/LogConverter.java @@ -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. * * * @@ -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) { diff --git a/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/GridReprojectionDataSource.java b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/GridReprojectionDataSource.java new file mode 100644 index 0000000000..1f0fd61e7d --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/GridReprojectionDataSource.java @@ -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. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer    Description
+ * ------------- -------- ----------- --------------------------
+ * Feb 28, 2014  2791     bsteffen    Initial creation
+ * 
+ * 
+ * + * @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; + } + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/data/DataCopy.java b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/data/DataUtilities.java similarity index 57% rename from edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/data/DataCopy.java rename to edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/data/DataUtilities.java index 20af619104..f26141ee12 100644 --- a/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/data/DataCopy.java +++ b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/data/DataUtilities.java @@ -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 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; + } + + } + } diff --git a/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/data/UnitConvertingDataSource.java b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/data/UnitConvertingDataSource.java new file mode 100644 index 0000000000..e6ed48572f --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.geospatial/src/com/raytheon/uf/common/geospatial/interpolation/data/UnitConvertingDataSource.java @@ -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. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date          Ticket#  Engineer    Description
+ * ------------- -------- ----------- --------------------------
+ * Feb 25, 2014  2791     bsteffen    Initial creation
+ * 
+ * 
+ * + * @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; + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.style/src/com/raytheon/uf/common/style/image/ColorMapParameterFactory.java b/edexOsgi/com.raytheon.uf.common.style/src/com/raytheon/uf/common/style/image/ColorMapParameterFactory.java index f3d0ca7802..a50ff15b26 100644 --- a/edexOsgi/com.raytheon.uf.common.style/src/com/raytheon/uf/common/style/image/ColorMapParameterFactory.java +++ b/edexOsgi/com.raytheon.uf.common.style/src/com/raytheon/uf/common/style/image/ColorMapParameterFactory.java @@ -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. + * * * * @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();