Merge branch 'development_on_RHEL5' (GOES-R) into development
Conflicts: cave/com.raytheon.viz.satellite/src/com/raytheon/viz/satellite/rsc/SatBlendedResource.java nativeLib/edexBridge/edexBridge.cpp rpms/build/i386/build.sh rpms/build/x86_64/build.sh Former-commit-id:7969ef9648
[formerly760f215e8c
] [formerly f6787c0b9f2cb0cae1c07a2111e91ecfc12f31f5 [formerlyf5f75ec629
]] [formerlye82e1137f9
[formerlyf5f75ec629
[formerly 039d9ecb587338801cdab9cad11b06890517d6a4]]] Former-commit-id:e82e1137f9
Former-commit-id: cecc12c190bbaa908cbfe835a5a9a64a5ba96dba [formerly94994868fa
] Former-commit-id:ee03dcf505
This commit is contained in:
commit
2cafd3a81b
31 changed files with 1362 additions and 667 deletions
|
@ -76,10 +76,12 @@ import com.vividsolutions.jts.geom.Coordinate;
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------- -------- ----------- --------------------------
|
||||||
* Jul 18, 2011 2190 mschenke Initial creation
|
* Jul 18, 2011 2190 mschenke Initial creation
|
||||||
* Oct 2, 2013 2333 mschenke Converted to use IGridGeometryProvider
|
* Oct 2, 2013 2333 mschenke Converted to use IGridGeometryProvider
|
||||||
|
* Nov 20, 2013 2492 bsteffen Refactor deprecated references to
|
||||||
|
* ColorMapParameters.getDataUnit
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -389,8 +391,8 @@ public class CloudHeightResource extends
|
||||||
if (rsc != null && rsc.hasCapability(ColorMapCapability.class)) {
|
if (rsc != null && rsc.hasCapability(ColorMapCapability.class)) {
|
||||||
ColorMapParameters params = rsc.getCapability(
|
ColorMapParameters params = rsc.getCapability(
|
||||||
ColorMapCapability.class).getColorMapParameters();
|
ColorMapCapability.class).getColorMapParameters();
|
||||||
if (params != null && params.getDataUnit() != null
|
if (params != null && params.getColorMapUnit() != null
|
||||||
&& TEMP_UNIT.isCompatible(params.getDataUnit())) {
|
&& TEMP_UNIT.isCompatible(params.getColorMapUnit())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ import com.raytheon.uf.viz.core.maps.scales.MapScales.MapScale;
|
||||||
import com.raytheon.uf.viz.core.maps.scales.MapScalesManager.ManagedMapScale;
|
import com.raytheon.uf.viz.core.maps.scales.MapScalesManager.ManagedMapScale;
|
||||||
import com.raytheon.uf.viz.core.procedures.Bundle;
|
import com.raytheon.uf.viz.core.procedures.Bundle;
|
||||||
import com.raytheon.uf.viz.core.rsc.ResourceList;
|
import com.raytheon.uf.viz.core.rsc.ResourceList;
|
||||||
|
import com.raytheon.uf.viz.core.rsc.ResourceProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MapRenderableDisplay associated with a {@link MapScale}
|
* MapRenderableDisplay associated with a {@link MapScale}
|
||||||
|
@ -47,10 +48,11 @@ import com.raytheon.uf.viz.core.rsc.ResourceList;
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------- -------- ----------- --------------------------
|
||||||
* Mar 22, 2013 mschenke Initial creation
|
* Mar 22, 2013 mschenke Initial creation
|
||||||
* Oct 10, 2013 2104 mschenke Switched to use MapScalesManager
|
* Oct 10, 2013 2104 mschenke Switched to use MapScalesManager
|
||||||
|
* Nov 20, 2013 2492 bsteffen Recycle resources in clear.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -133,9 +135,13 @@ public class MapScaleRenderableDisplay extends PlainMapRenderableDisplay
|
||||||
// non-map/system layers and reset display
|
// non-map/system layers and reset display
|
||||||
ResourceList list = descriptor.getResourceList();
|
ResourceList list = descriptor.getResourceList();
|
||||||
for (ResourcePair rp : list) {
|
for (ResourcePair rp : list) {
|
||||||
if (rp.getProperties().isMapLayer() == false
|
ResourceProperties props = rp.getProperties();
|
||||||
&& rp.getProperties().isSystemResource() == false) {
|
if (props.isMapLayer() == false
|
||||||
|
&& props.isSystemResource() == false) {
|
||||||
list.remove(rp);
|
list.remove(rp);
|
||||||
|
} else {
|
||||||
|
props.setVisible(true);
|
||||||
|
rp.getResource().recycle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.measure.unit.Unit;
|
import javax.measure.unit.Unit;
|
||||||
import javax.measure.unit.UnitFormat;
|
|
||||||
|
|
||||||
import org.geotools.coverage.grid.GridEnvelope2D;
|
import org.geotools.coverage.grid.GridEnvelope2D;
|
||||||
import org.geotools.coverage.grid.GridGeometry2D;
|
import org.geotools.coverage.grid.GridGeometry2D;
|
||||||
|
@ -71,11 +70,13 @@ import com.vividsolutions.jts.geom.Coordinate;
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------- -------- ----------- --------------------------
|
||||||
* Jun 19, 2013 2122 mschenke Initial creation.
|
* Jun 19, 2013 2122 mschenke Initial creation.
|
||||||
* Oct 16, 2013 2333 mschenke Added method for auto-unit conversion
|
* Oct 16, 2013 2333 mschenke Added method for auto-unit conversion
|
||||||
* interrogating
|
* interrogating
|
||||||
|
* Nov 20, 2013 2492 bsteffen Move unit converting interrogate into
|
||||||
|
* TileSetRenderable.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -369,61 +370,12 @@ public class RecordTileSetRenderable extends TileSetRenderable {
|
||||||
return interrogate(coordinate, parameters.getNoDataValue());
|
return interrogate(coordinate, parameters.getNoDataValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Returns the raw image value from tile image that contains the lat/lon
|
public double interrogate(Coordinate coordinate, Unit<?> resultUnit)
|
||||||
* coordinate in units of desiredUnit
|
|
||||||
*
|
|
||||||
* @param coordinate
|
|
||||||
* in lat/lon space
|
|
||||||
* @param desiredUnit
|
|
||||||
* unit to convert data value to if not nanValue
|
|
||||||
* @return
|
|
||||||
* @throws VizException
|
|
||||||
*/
|
|
||||||
public double interrogate(Coordinate coordinate, Unit<?> desiredUnit)
|
|
||||||
throws VizException {
|
throws VizException {
|
||||||
ColorMapParameters parameters = colormapping.getColorMapParameters();
|
ColorMapParameters parameters = colormapping.getColorMapParameters();
|
||||||
return interrogate(coordinate, parameters.getNoDataValue(), desiredUnit);
|
return super.interrogate(coordinate, resultUnit,
|
||||||
}
|
parameters.getNoDataValue());
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the raw image value from tile image that contains the lat/lon
|
|
||||||
* coordinate in units of desiredUnit
|
|
||||||
*
|
|
||||||
* @param coordinate
|
|
||||||
* in lat/lon space
|
|
||||||
* @param nanValue
|
|
||||||
* if interrogated value is equal to nanValue, {@link Double#NaN}
|
|
||||||
* will be returned
|
|
||||||
* @param desiredUnit
|
|
||||||
* unit to convert data value to if not nanValue
|
|
||||||
* @return
|
|
||||||
* @throws VizException
|
|
||||||
*/
|
|
||||||
public double interrogate(Coordinate coordinate, double nanValue,
|
|
||||||
Unit<?> desiredUnit) throws VizException {
|
|
||||||
double dataValue = super.interrogate(coordinate, nanValue);
|
|
||||||
if (Double.isNaN(dataValue) == false) {
|
|
||||||
ColorMapParameters params = colormapping.getColorMapParameters();
|
|
||||||
Unit<?> dataUnit = params.getDataUnit();
|
|
||||||
if (dataUnit != null && desiredUnit != null
|
|
||||||
&& dataUnit != desiredUnit) {
|
|
||||||
if (dataUnit.isCompatible(desiredUnit)) {
|
|
||||||
dataValue = dataUnit.getConverterTo(desiredUnit).convert(
|
|
||||||
dataValue);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unable to interrogate tile set. "
|
|
||||||
+ String.format(
|
|
||||||
"Desired unit (%s) is not compatible with data unit (%s).",
|
|
||||||
UnitFormat.getUCUMInstance()
|
|
||||||
.format(desiredUnit),
|
|
||||||
UnitFormat.getUCUMInstance()
|
|
||||||
.format(dataUnit)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dataValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,6 +27,9 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import javax.measure.unit.Unit;
|
||||||
|
import javax.measure.unit.UnitFormat;
|
||||||
|
|
||||||
import org.geotools.coverage.grid.GeneralGridGeometry;
|
import org.geotools.coverage.grid.GeneralGridGeometry;
|
||||||
import org.geotools.coverage.grid.GridGeometry2D;
|
import org.geotools.coverage.grid.GridGeometry2D;
|
||||||
import org.geotools.referencing.crs.DefaultGeographicCRS;
|
import org.geotools.referencing.crs.DefaultGeographicCRS;
|
||||||
|
@ -66,7 +69,8 @@ import com.vividsolutions.jts.geom.Coordinate;
|
||||||
* May 28, 2013 2037 njensen Made imageMap concurrent to fix leak
|
* May 28, 2013 2037 njensen Made imageMap concurrent to fix leak
|
||||||
* Jun 20, 2013 2122 mschenke Fixed null pointer in interrogate and made
|
* Jun 20, 2013 2122 mschenke Fixed null pointer in interrogate and made
|
||||||
* canceling jobs safer
|
* canceling jobs safer
|
||||||
* Oct 16, 2013 2333 mschenke Added auto NaN checking for interrogation
|
* Oct 16, 2013 2333 mschenke Added auto NaN checking for interrogation
|
||||||
|
* Nov 14, 2013 2492 mschenke Added more interrogate methods that take units
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -475,12 +479,33 @@ public class TileSetRenderable implements IRenderable {
|
||||||
* @throws VizException
|
* @throws VizException
|
||||||
*/
|
*/
|
||||||
public double interrogate(Coordinate coordinate) throws VizException {
|
public double interrogate(Coordinate coordinate) throws VizException {
|
||||||
return interrogate(coordinate, Double.NaN);
|
return interrogate(coordinate, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the raw image value from tile image that contains the lat/lon
|
* Returns the raw image value from tile image that contains the lat/lon
|
||||||
* coordinate. Any values matching nanValue will return {@link Double#NaN}
|
* coordinate
|
||||||
|
*
|
||||||
|
* @param coordinate
|
||||||
|
* in lat/lon space
|
||||||
|
* @param resultUnit
|
||||||
|
* unit result from interrogate will be returned is. If unit is
|
||||||
|
* not compatible with data unit, {@link Double#NaN} will be
|
||||||
|
* returned. Null indicates data will not be converted
|
||||||
|
* @param nanValue
|
||||||
|
* if interrogated value is equal to nanValue, {@link Double#NaN}
|
||||||
|
* will be returned
|
||||||
|
* @return
|
||||||
|
* @throws VizException
|
||||||
|
*/
|
||||||
|
public double interrogate(Coordinate coordinate, Unit<?> resultUnit)
|
||||||
|
throws VizException {
|
||||||
|
return interrogate(coordinate, resultUnit, Double.NaN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw image value from tile image that contains the lat/lon
|
||||||
|
* coordinate
|
||||||
*
|
*
|
||||||
* @param coordinate
|
* @param coordinate
|
||||||
* in lat/lon space
|
* in lat/lon space
|
||||||
|
@ -492,6 +517,27 @@ public class TileSetRenderable implements IRenderable {
|
||||||
*/
|
*/
|
||||||
public double interrogate(Coordinate coordinate, double nanValue)
|
public double interrogate(Coordinate coordinate, double nanValue)
|
||||||
throws VizException {
|
throws VizException {
|
||||||
|
return interrogate(coordinate, null, nanValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw image value from tile image that contains the lat/lon
|
||||||
|
* coordinate. Any values matching nanValue will return {@link Double#NaN}
|
||||||
|
*
|
||||||
|
* @param coordinate
|
||||||
|
* in lat/lon space
|
||||||
|
* @param resultUnit
|
||||||
|
* unit result from interrogate will be returned is. If unit is
|
||||||
|
* not compatible with data unit, {@link Double#NaN} will be
|
||||||
|
* returned. Null indicates data will not be converted
|
||||||
|
* @param nanValue
|
||||||
|
* if interrogated value is equal to nanValue, {@link Double#NaN}
|
||||||
|
* will be returned
|
||||||
|
* @return
|
||||||
|
* @throws VizException
|
||||||
|
*/
|
||||||
|
public double interrogate(Coordinate coordinate, Unit<?> resultUnit,
|
||||||
|
double nanValue) throws VizException {
|
||||||
double dataValue = Double.NaN;
|
double dataValue = Double.NaN;
|
||||||
try {
|
try {
|
||||||
double[] local = new double[2];
|
double[] local = new double[2];
|
||||||
|
@ -515,8 +561,27 @@ public class TileSetRenderable implements IRenderable {
|
||||||
% tileSize);
|
% tileSize);
|
||||||
if (dataValue == nanValue) {
|
if (dataValue == nanValue) {
|
||||||
dataValue = Double.NaN;
|
dataValue = Double.NaN;
|
||||||
|
} else {
|
||||||
|
Unit<?> dataUnit = cmapImage.getDataUnit();
|
||||||
|
if (resultUnit != null && dataUnit != null
|
||||||
|
&& dataUnit.equals(resultUnit) == false) {
|
||||||
|
if (resultUnit.isCompatible(dataUnit)) {
|
||||||
|
dataValue = dataUnit.getConverterTo(
|
||||||
|
resultUnit).convert(dataValue);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unable to interrogate tile set. "
|
||||||
|
+ String.format(
|
||||||
|
"Desired unit (%s) is not compatible with data unit (%s).",
|
||||||
|
UnitFormat
|
||||||
|
.getUCUMInstance()
|
||||||
|
.format(resultUnit),
|
||||||
|
UnitFormat
|
||||||
|
.getUCUMInstance()
|
||||||
|
.format(dataUnit)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ vec4 applyColorBand(int colorband) {
|
||||||
vec2((xy.x / width), (xy.y / height)));
|
vec2((xy.x / width), (xy.y / height)));
|
||||||
|
|
||||||
// Lookup raw data value
|
// Lookup raw data value
|
||||||
float dataValue = getDataValue(rawData, gl_TexCoord[0].st);
|
float dataValue = textureToDataValue(rawData, gl_TexCoord[0].st);
|
||||||
|
|
||||||
float r = curVal.r;
|
float r = curVal.r;
|
||||||
float g = curVal.g;
|
float g = curVal.g;
|
||||||
|
|
|
@ -232,8 +232,7 @@ public class GLTrueColorImagingExtension extends AbstractGLSLImagingExtension
|
||||||
parameters.put(colorMapParameters, null);
|
parameters.put(colorMapParameters, null);
|
||||||
|
|
||||||
GLSLStructFactory.createDataTexture(program, "rawData", 0,
|
GLSLStructFactory.createDataTexture(program, "rawData", 0,
|
||||||
cmapImage.getDataFormat(),
|
cmapImage);
|
||||||
colorMapParameters.getNoDataValue());
|
|
||||||
|
|
||||||
int numMappingValues = 0;
|
int numMappingValues = 0;
|
||||||
GLDataMapping mapping = cmapImage.getDataMapping();
|
GLDataMapping mapping = cmapImage.getDataMapping();
|
||||||
|
|
|
@ -7,7 +7,7 @@ uniform ColorMapping colorMapping;
|
||||||
uniform ColorModifiers modifiers;
|
uniform ColorModifiers modifiers;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
float dataValue = getDataValue(rawData, gl_TexCoord[0].st);
|
float dataValue = textureToDataValue(rawData, gl_TexCoord[0].st);
|
||||||
|
|
||||||
// No data check/special NaN check
|
// No data check/special NaN check
|
||||||
if (dataValue == rawData.noDataValue || dataValue != dataValue) {
|
if (dataValue == rawData.noDataValue || dataValue != dataValue) {
|
||||||
|
|
|
@ -14,6 +14,8 @@ struct DataTexture {
|
||||||
int isScaled;
|
int isScaled;
|
||||||
float scaleMin;
|
float scaleMin;
|
||||||
float scaleMax;
|
float scaleMax;
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,7 +53,7 @@ struct ColorMapping {
|
||||||
/**
|
/**
|
||||||
* Returns the data value for the DataTexture at location.
|
* Returns the data value for the DataTexture at location.
|
||||||
*/
|
*/
|
||||||
float getDataValue(DataTexture texture, vec2 location) {
|
float textureToDataValue(DataTexture texture, vec2 location) {
|
||||||
vec4 textureValue = texture2D(texture.rawTex, location);
|
vec4 textureValue = texture2D(texture.rawTex, location);
|
||||||
float dataValue = textureValue.r;
|
float dataValue = textureValue.r;
|
||||||
|
|
||||||
|
@ -63,6 +65,18 @@ float getDataValue(DataTexture texture, vec2 location) {
|
||||||
return dataValue;
|
return dataValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the data value for the DataTexture at location.
|
||||||
|
*/
|
||||||
|
float dataToTextureValue(DataTexture texture, float dataValue) {
|
||||||
|
float textureValue = dataValue;
|
||||||
|
if (texture.isScaled == 1) {
|
||||||
|
textureValue = (dataValue - texture.scaleMin)
|
||||||
|
/ (texture.scaleMax - texture.scaleMin);
|
||||||
|
}
|
||||||
|
return textureValue;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up a value in a mapping texture given an index [0-numMappingValues).
|
* Looks up a value in a mapping texture given an index [0-numMappingValues).
|
||||||
*/
|
*/
|
||||||
|
@ -80,7 +94,7 @@ float dataToColorMapValue(float dataValue, DataMapping mapping) {
|
||||||
// Short circuit if no mapping is needed
|
// Short circuit if no mapping is needed
|
||||||
return dataValue;
|
return dataValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to colormap value
|
// Convert to colormap value
|
||||||
int lowIndex = 0;
|
int lowIndex = 0;
|
||||||
int highIndex = numMappingValues - 1;
|
int highIndex = numMappingValues - 1;
|
||||||
|
@ -103,8 +117,8 @@ float dataToColorMapValue(float dataValue, DataMapping mapping) {
|
||||||
int nextIndex = lowIndex + ((highIndex - lowIndex) / 2);
|
int nextIndex = lowIndex + ((highIndex - lowIndex) / 2);
|
||||||
if (nextIndex > lowIndex && nextIndex < highIndex) {
|
if (nextIndex > lowIndex && nextIndex < highIndex) {
|
||||||
// Look up next value and determine if it is a high or low
|
// Look up next value and determine if it is a high or low
|
||||||
float nextValue = lookupMappingValue(mapping.dataMappingValues, nextIndex,
|
float nextValue = lookupMappingValue(mapping.dataMappingValues,
|
||||||
numMappingValues);
|
nextIndex, numMappingValues);
|
||||||
if (nextValue < dataValue) {
|
if (nextValue < dataValue) {
|
||||||
if (reversed == 0) {
|
if (reversed == 0) {
|
||||||
lowIndex = nextIndex;
|
lowIndex = nextIndex;
|
||||||
|
@ -132,10 +146,10 @@ float dataToColorMapValue(float dataValue, DataMapping mapping) {
|
||||||
factor = 1.0 - factor;
|
factor = 1.0 - factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
float lowCmapValue = lookupMappingValue(mapping.colorMappingValues, lowIndex,
|
float lowCmapValue = lookupMappingValue(mapping.colorMappingValues,
|
||||||
numMappingValues);
|
lowIndex, numMappingValues);
|
||||||
float highCmapValue = lookupMappingValue(mapping.colorMappingValues, highIndex,
|
float highCmapValue = lookupMappingValue(mapping.colorMappingValues,
|
||||||
numMappingValues);
|
highIndex, numMappingValues);
|
||||||
|
|
||||||
return lowCmapValue + (highCmapValue - lowCmapValue) * factor;
|
return lowCmapValue + (highCmapValue - lowCmapValue) * factor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,27 @@
|
||||||
// this shader program sets values into a mosaic texture
|
// this shader program sets values into a mosaic texture
|
||||||
// which is the same size as the screen (frame buffer)
|
// which is the same size as the screen (frame buffer)
|
||||||
|
|
||||||
uniform sampler2D imageData;
|
#include <mapping>
|
||||||
uniform sampler2D mosaicTexture;
|
|
||||||
uniform int height;
|
|
||||||
uniform int width;
|
|
||||||
|
|
||||||
void main(void)
|
uniform DataTexture imageData;
|
||||||
{
|
uniform DataMapping imageToMosaic;
|
||||||
vec2 xy = gl_FragCoord.xy;
|
uniform DataTexture mosaicData;
|
||||||
vec4 imageVal = texture2D(imageData,gl_TexCoord[0].st);
|
|
||||||
vec4 curVal = texture2D(mosaicTexture, vec2((xy.x / float(width)), (xy.y / float(height))));
|
void main(void) {
|
||||||
if ( imageVal.r > curVal.r ) {
|
float imageValue = textureToDataValue(imageData, gl_TexCoord[0].st);
|
||||||
gl_FragColor = vec4(imageVal.r,0.0,0.0,1.0);
|
vec2 frag_xy = gl_FragCoord.xy;
|
||||||
} else {
|
float mosaicValue = textureToDataValue(mosaicData,
|
||||||
gl_FragColor = vec4(curVal.r,0.0,0.0,1.0);
|
vec2(frag_xy.x / mosaicData.width, frag_xy.y / mosaicData.height));
|
||||||
|
|
||||||
|
float newValue = mosaicValue;
|
||||||
|
// No data check/special NaN check
|
||||||
|
if (imageValue != imageData.noDataValue && imageValue == imageValue) {
|
||||||
|
// Convert image value to mosaic value
|
||||||
|
imageValue = dataToColorMapValue(imageValue, imageToMosaic);
|
||||||
|
if (imageValue > mosaicValue) {
|
||||||
|
newValue = imageValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
gl_FragColor = vec4(dataToTextureValue(mosaicData, newValue), 0.0, 0.0,
|
||||||
|
1.0);
|
||||||
}
|
}
|
|
@ -1,20 +1,26 @@
|
||||||
// this shader program sets values into a mosaic texture
|
// this shader program sets values into a mosaic texture
|
||||||
// which is the same size as the screen (frame buffer)
|
// which is the same size as the screen (frame buffer)
|
||||||
|
|
||||||
uniform sampler2D imageData;
|
#include <mapping>
|
||||||
uniform sampler2D mosaicTexture;
|
|
||||||
uniform int height;
|
|
||||||
uniform int width;
|
|
||||||
|
|
||||||
void main(void)
|
uniform DataTexture imageData;
|
||||||
{
|
uniform DataMapping imageToMosaic;
|
||||||
vec2 xy = gl_FragCoord.xy;
|
uniform DataTexture mosaicData;
|
||||||
vec4 imageVal = texture2D(imageData,gl_TexCoord[0].st);
|
|
||||||
vec4 curVal = texture2D(mosaicTexture, vec2((xy.x / float(width)), (xy.y / float(height))));
|
void main(void) {
|
||||||
// assume 0 or NaN is No Data and should be replaced if another image has better values.
|
float imageValue = textureToDataValue(imageData, gl_TexCoord[0].st);
|
||||||
if ( imageVal.r != 0.0 && imageVal.r == imageVal.r) {
|
vec2 frag_xy = gl_FragCoord.xy;
|
||||||
gl_FragColor = vec4(imageVal.r,0.0,0.0,1.0);
|
float mosaicValue = textureToDataValue(mosaicData,
|
||||||
|
vec2(frag_xy.x / mosaicData.width, frag_xy.y / mosaicData.height));
|
||||||
|
|
||||||
|
float newValue;
|
||||||
|
// No data check/special NaN check
|
||||||
|
if (imageValue == imageData.noDataValue || imageValue != imageValue) {
|
||||||
|
// Use existing value
|
||||||
|
newValue = mosaicValue;
|
||||||
} else {
|
} else {
|
||||||
gl_FragColor = vec4(curVal.r,0.0,0.0,1.0);
|
newValue = dataToColorMapValue(imageValue, imageToMosaic);
|
||||||
}
|
}
|
||||||
|
gl_FragColor = vec4(dataToTextureValue(mosaicData, newValue), 0.0, 0.0,
|
||||||
|
1.0);
|
||||||
}
|
}
|
|
@ -53,9 +53,6 @@
|
||||||
<graphicsExtension
|
<graphicsExtension
|
||||||
class="com.raytheon.viz.core.gl.ext.imaging.GLDefaultImagingExtension">
|
class="com.raytheon.viz.core.gl.ext.imaging.GLDefaultImagingExtension">
|
||||||
</graphicsExtension>
|
</graphicsExtension>
|
||||||
<graphicsExtension
|
|
||||||
class="com.raytheon.viz.core.gl.internal.ext.mosaic.GLMosaicImageExtension">
|
|
||||||
</graphicsExtension>
|
|
||||||
<graphicsExtension
|
<graphicsExtension
|
||||||
class="com.raytheon.viz.core.gl.internal.ext.mosaic.GLMosaicMaxValImageExtension">
|
class="com.raytheon.viz.core.gl.internal.ext.mosaic.GLMosaicMaxValImageExtension">
|
||||||
</graphicsExtension>
|
</graphicsExtension>
|
||||||
|
|
|
@ -54,14 +54,16 @@ import com.raytheon.viz.core.gl.objects.GLTextureObject;
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------- -------- ----------- --------------------------
|
||||||
* Nov 18, 2011 mschenke Initial creation
|
* Nov 18, 2011 mschenke Initial creation
|
||||||
* Feb 14, 2013 1616 bsteffen Add option for interpolation of colormap
|
* Feb 14, 2013 1616 bsteffen Add option for interpolation of colormap
|
||||||
* parameters, disable colormap interpolation
|
* parameters, disable colormap interpolation
|
||||||
* by default.
|
* by default.
|
||||||
* Oct 16, 2013 2333 mschenke Cleaned up load shader method, used isScaled.
|
* Oct 16, 2013 2333 mschenke Cleaned up load shader method, used isScaled.
|
||||||
* Added support for colormapping in non-data unit.
|
* Added support for colormapping in non-data unit.
|
||||||
|
* Nov 20, 2013 2492 bsteffen Mosaic in image units.
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -174,7 +176,8 @@ public class GLColormappedImageExtension extends AbstractGLSLImagingExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up a {@link GLDataMapping} for use in image rendering
|
* Sets up a {@link GLDataMapping} for use in image rendering. Data will be
|
||||||
|
* mapped to the image's {@link ColorMapParameters#getColorMapUnit()}
|
||||||
*
|
*
|
||||||
* @param gl
|
* @param gl
|
||||||
* @param glImage
|
* @param glImage
|
||||||
|
@ -185,14 +188,32 @@ public class GLColormappedImageExtension extends AbstractGLSLImagingExtension
|
||||||
public static void setupDataMapping(GL gl,
|
public static void setupDataMapping(GL gl,
|
||||||
AbstractGLColormappedImage glImage, int dataMappedTexBinding,
|
AbstractGLColormappedImage glImage, int dataMappedTexBinding,
|
||||||
int colorMappedTexBinding) throws VizException {
|
int colorMappedTexBinding) throws VizException {
|
||||||
|
setupDataMapping(gl, glImage, glImage.getColorMapParameters()
|
||||||
|
.getColorMapUnit(), dataMappedTexBinding, colorMappedTexBinding);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up a {@link GLDataMapping} for use in image renderingData will be
|
||||||
|
* mapped to the unit provided
|
||||||
|
*
|
||||||
|
* @param gl
|
||||||
|
* @param glImage
|
||||||
|
* @param colorMapUnit
|
||||||
|
* @param dataMappedTexBinding
|
||||||
|
* @param colorMappedTexBinding
|
||||||
|
* @throws VizException
|
||||||
|
*/
|
||||||
|
public static void setupDataMapping(GL gl,
|
||||||
|
AbstractGLColormappedImage glImage, Unit<?> colorMapUnit,
|
||||||
|
int dataMappedTexBinding, int colorMappedTexBinding)
|
||||||
|
throws VizException {
|
||||||
ColorMapParameters colorMapParameters = glImage.getColorMapParameters();
|
ColorMapParameters colorMapParameters = glImage.getColorMapParameters();
|
||||||
// Get GLDataMapping and generate if datamapping is not set. If
|
// Get GLDataMapping and generate if datamapping is not set. If
|
||||||
// datamapping is not set, the data has already been mapped to
|
// datamapping is not set, the data has already been mapped to
|
||||||
// colorMapUnits and we need not do anything
|
// colorMapUnits and we need not do anything
|
||||||
GLDataMapping dataMapping = glImage.getDataMapping();
|
GLDataMapping dataMapping = glImage.getDataMapping();
|
||||||
if (dataMapping == null && colorMapParameters.getDataMapping() == null) {
|
if (dataMapping == null && colorMapParameters.getDataMapping() == null) {
|
||||||
Unit<?> colorMapUnit = colorMapParameters.getColorMapUnit();
|
Unit<?> dataUnit = glImage.getDataUnit();
|
||||||
Unit<?> dataUnit = colorMapParameters.getDataUnit();
|
|
||||||
int colorMapSize = colorMapParameters.getColorMap().getSize();
|
int colorMapSize = colorMapParameters.getColorMap().getSize();
|
||||||
float colorMapMin = colorMapParameters.getColorMapMin();
|
float colorMapMin = colorMapParameters.getColorMapMin();
|
||||||
float colorMapMax = colorMapParameters.getColorMapMax();
|
float colorMapMax = colorMapParameters.getColorMapMax();
|
||||||
|
@ -290,8 +311,7 @@ public class GLColormappedImageExtension extends AbstractGLSLImagingExtension
|
||||||
|
|
||||||
ColorMapParameters colorMapParameters = image.getColorMapParameters();
|
ColorMapParameters colorMapParameters = image.getColorMapParameters();
|
||||||
|
|
||||||
GLSLStructFactory.createDataTexture(program, "rawData", 0,
|
GLSLStructFactory.createDataTexture(program, "rawData", 0, image);
|
||||||
image.getDataFormat(), colorMapParameters.getNoDataValue());
|
|
||||||
|
|
||||||
int numMappingValues = 0;
|
int numMappingValues = 0;
|
||||||
GLDataMapping mapping = image.getDataMapping();
|
GLDataMapping mapping = image.getDataMapping();
|
||||||
|
|
|
@ -21,6 +21,7 @@ package com.raytheon.viz.core.gl.glsl;
|
||||||
|
|
||||||
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
||||||
import com.raytheon.viz.core.gl.dataformat.AbstractGLColorMapDataFormat;
|
import com.raytheon.viz.core.gl.dataformat.AbstractGLColorMapDataFormat;
|
||||||
|
import com.raytheon.viz.core.gl.images.AbstractGLColormappedImage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for creating API defined GLSL structs in a {@link GLShaderProgram}.
|
* Factory for creating API defined GLSL structs in a {@link GLShaderProgram}.
|
||||||
|
@ -49,14 +50,15 @@ public class GLSLStructFactory {
|
||||||
* @param program
|
* @param program
|
||||||
* @param name
|
* @param name
|
||||||
* @param texBinding
|
* @param texBinding
|
||||||
* @param dataFormat
|
* @param image
|
||||||
* @param noDataValue
|
|
||||||
*/
|
*/
|
||||||
public static void createDataTexture(GLShaderProgram program, String name,
|
public static void createDataTexture(GLShaderProgram program, String name,
|
||||||
int texBinding, AbstractGLColorMapDataFormat dataFormat,
|
int texBinding, AbstractGLColormappedImage image) {
|
||||||
double noDataValue) {
|
ColorMapParameters parameters = image.getColorMapParameters();
|
||||||
|
AbstractGLColorMapDataFormat dataFormat = image.getDataFormat();
|
||||||
setFieldUniform(program, name, "rawTex", texBinding);
|
setFieldUniform(program, name, "rawTex", texBinding);
|
||||||
setFieldUniform(program, name, "noDataValue", noDataValue);
|
setFieldUniform(program, name, "noDataValue",
|
||||||
|
parameters.getNoDataValue());
|
||||||
setFieldUniform(program, name, "isScaled", dataFormat.isScaled());
|
setFieldUniform(program, name, "isScaled", dataFormat.isScaled());
|
||||||
if (dataFormat.isScaled()) {
|
if (dataFormat.isScaled()) {
|
||||||
setFieldUniform(program, name, "scaleMin",
|
setFieldUniform(program, name, "scaleMin",
|
||||||
|
@ -64,6 +66,8 @@ public class GLSLStructFactory {
|
||||||
setFieldUniform(program, name, "scaleMax",
|
setFieldUniform(program, name, "scaleMax",
|
||||||
dataFormat.getDataFormatMax());
|
dataFormat.getDataFormatMax());
|
||||||
}
|
}
|
||||||
|
setFieldUniform(program, name, "width", (float) image.getWidth());
|
||||||
|
setFieldUniform(program, name, "height", (float) image.getHeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -33,8 +33,12 @@ import com.raytheon.uf.viz.core.drawables.PaintProperties;
|
||||||
import com.raytheon.uf.viz.core.drawables.ext.IMosaicImageExtension;
|
import com.raytheon.uf.viz.core.drawables.ext.IMosaicImageExtension;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
import com.raytheon.viz.core.gl.ext.GLOffscreenRenderingExtension;
|
import com.raytheon.viz.core.gl.ext.GLOffscreenRenderingExtension;
|
||||||
|
import com.raytheon.viz.core.gl.ext.imaging.GLColormappedImageExtension;
|
||||||
|
import com.raytheon.viz.core.gl.ext.imaging.GLDataMappingFactory.GLDataMapping;
|
||||||
import com.raytheon.viz.core.gl.glsl.AbstractGLSLImagingExtension;
|
import com.raytheon.viz.core.gl.glsl.AbstractGLSLImagingExtension;
|
||||||
|
import com.raytheon.viz.core.gl.glsl.GLSLStructFactory;
|
||||||
import com.raytheon.viz.core.gl.glsl.GLShaderProgram;
|
import com.raytheon.viz.core.gl.glsl.GLShaderProgram;
|
||||||
|
import com.raytheon.viz.core.gl.images.AbstractGLColormappedImage;
|
||||||
import com.raytheon.viz.core.gl.images.AbstractGLImage;
|
import com.raytheon.viz.core.gl.images.AbstractGLImage;
|
||||||
import com.raytheon.viz.core.gl.images.GLColormappedImage;
|
import com.raytheon.viz.core.gl.images.GLColormappedImage;
|
||||||
import com.raytheon.viz.core.gl.images.GLOffscreenColormappedImage;
|
import com.raytheon.viz.core.gl.images.GLOffscreenColormappedImage;
|
||||||
|
@ -46,13 +50,14 @@ import com.raytheon.viz.core.gl.images.GLOffscreenColormappedImage;
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------- -------- ----------- --------------------------
|
||||||
* Dec 16, 2011 mschenke Initial creation
|
* Dec 16, 2011 mschenke Initial creation
|
||||||
* Mar 21, 2013 1806 bsteffen Update GL mosaicing to use dynamic data
|
* Mar 21, 2013 1806 bsteffen Update GL mosaicing to use dynamic data
|
||||||
* format for offscreen textures.
|
* format for offscreen textures.
|
||||||
* Oct 16, 2013 2333 mschenke Cleaned up render logic, switched to
|
* Oct 16, 2013 2333 mschenke Cleaned up render logic, switched to use
|
||||||
* use GLOffscreenColormappedImage
|
* GLOffscreenColormappedImage
|
||||||
|
* Nov 20, 2013 2492 bsteffen Mosaic in image units.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -60,8 +65,8 @@ import com.raytheon.viz.core.gl.images.GLOffscreenColormappedImage;
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class GLMosaicImageExtension extends AbstractGLSLImagingExtension
|
public abstract class GLMosaicImageExtension extends
|
||||||
implements IMosaicImageExtension {
|
AbstractGLSLImagingExtension implements IMosaicImageExtension {
|
||||||
|
|
||||||
private GLOffscreenColormappedImage writeToImage;
|
private GLOffscreenColormappedImage writeToImage;
|
||||||
|
|
||||||
|
@ -75,19 +80,6 @@ public class GLMosaicImageExtension extends AbstractGLSLImagingExtension
|
||||||
imageExtent, this.getClass());
|
imageExtent, this.getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* com.raytheon.viz.core.gl.ext.AbstractGLImagingExtension#getShaderProgramName
|
|
||||||
* ()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getShaderProgramName() {
|
|
||||||
// Default mosaicing algorithm glsl program
|
|
||||||
return "mosaicOrdered";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
@ -142,16 +134,20 @@ public class GLMosaicImageExtension extends AbstractGLSLImagingExtension
|
||||||
new DrawableImage(mosaicImage.getWrappedImage(),
|
new DrawableImage(mosaicImage.getWrappedImage(),
|
||||||
coverage));
|
coverage));
|
||||||
}
|
}
|
||||||
// Don't actually render this image now since we just did it
|
} else if (image instanceof AbstractGLColormappedImage) {
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
GL gl = target.getGl();
|
GL gl = target.getGl();
|
||||||
// activate on texture2 as 0 is radar image and 1 is colormap
|
// activate on texture2 as 0 is radar image and 1 is colormap
|
||||||
gl.glActiveTexture(GL.GL_TEXTURE1);
|
gl.glActiveTexture(GL.GL_TEXTURE1);
|
||||||
gl.glBindTexture(writeToImage.getTextureStorageType(),
|
gl.glBindTexture(writeToImage.getTextureStorageType(),
|
||||||
writeToImage.getTextureid());
|
writeToImage.getTextureid());
|
||||||
|
|
||||||
|
GLColormappedImageExtension.setupDataMapping(gl,
|
||||||
|
(AbstractGLColormappedImage) image,
|
||||||
|
writeToImage.getDataUnit(), 2, 3);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
// Fall through here, no actual rendering will occur
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GLOffscreenColormappedImage getWriteToImage(
|
private GLOffscreenColormappedImage getWriteToImage(
|
||||||
|
@ -208,6 +204,12 @@ public class GLMosaicImageExtension extends AbstractGLSLImagingExtension
|
||||||
// activate on texture2 as 0 is radar image
|
// activate on texture2 as 0 is radar image
|
||||||
gl.glActiveTexture(GL.GL_TEXTURE1);
|
gl.glActiveTexture(GL.GL_TEXTURE1);
|
||||||
gl.glBindTexture(writeToImage.getTextureStorageType(), 0);
|
gl.glBindTexture(writeToImage.getTextureStorageType(), 0);
|
||||||
|
|
||||||
|
gl.glActiveTexture(GL.GL_TEXTURE2);
|
||||||
|
gl.glBindTexture(GL.GL_TEXTURE_1D, 0);
|
||||||
|
|
||||||
|
gl.glActiveTexture(GL.GL_TEXTURE3);
|
||||||
|
gl.glBindTexture(GL.GL_TEXTURE_1D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -220,14 +222,27 @@ public class GLMosaicImageExtension extends AbstractGLSLImagingExtension
|
||||||
* com.raytheon.uf.viz.core.drawables.PaintProperties)
|
* com.raytheon.uf.viz.core.drawables.PaintProperties)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void loadShaderData(GLShaderProgram program, IImage image,
|
public void loadShaderData(GLShaderProgram program, IImage iimage,
|
||||||
PaintProperties paintProps) throws VizException {
|
PaintProperties paintProps) throws VizException {
|
||||||
program.setUniform("imageData", 0);
|
AbstractGLColormappedImage image = null;
|
||||||
program.setUniform("mosaicTexture", 1);
|
if (iimage instanceof AbstractGLColormappedImage == false) {
|
||||||
|
throw new VizException(
|
||||||
|
"Cannot apply glsl mosaicing shader to non gl colormap image");
|
||||||
|
}
|
||||||
|
image = (AbstractGLColormappedImage) iimage;
|
||||||
|
|
||||||
// pass in width and height
|
GLSLStructFactory.createDataTexture(program, "imageData", 0, image);
|
||||||
program.setUniform("height", writeToImage.getHeight());
|
|
||||||
program.setUniform("width", writeToImage.getWidth());
|
int numMappingValues = 0;
|
||||||
|
GLDataMapping mapping = image.getDataMapping();
|
||||||
|
if (mapping != null && mapping.isValid()) {
|
||||||
|
numMappingValues = mapping.getNumMappingValues();
|
||||||
|
}
|
||||||
|
GLSLStructFactory.createDataMapping(program, "imageToMosaic", 2, 3,
|
||||||
|
numMappingValues);
|
||||||
|
|
||||||
|
GLSLStructFactory.createDataTexture(program, "mosaicData", 1,
|
||||||
|
writeToImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.measure.Measure;
|
||||||
|
|
||||||
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||||
|
|
||||||
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
||||||
|
@ -64,6 +66,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
||||||
* only check for NaN. SatResource handles fill
|
* only check for NaN. SatResource handles fill
|
||||||
* values and returns NaN now
|
* values and returns NaN now
|
||||||
* Nov 18, 2013 2544 bsteffen Override recycleInternal
|
* Nov 18, 2013 2544 bsteffen Override recycleInternal
|
||||||
|
* Nov 20, 2013 2492 bsteffen Update inspect to use Measure objects
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -291,10 +294,12 @@ public class SatBlendedResource extends
|
||||||
for (int i = list.size() - 1; i >= 0; --i) {
|
for (int i = list.size() - 1; i >= 0; --i) {
|
||||||
AbstractVizResource<?, ?> rsc = list.get(i).getResource();
|
AbstractVizResource<?, ?> rsc = list.get(i).getResource();
|
||||||
Map<String, Object> dataMap = rsc.interrogate(coord);
|
Map<String, Object> dataMap = rsc.interrogate(coord);
|
||||||
if (dataMap.get(SatResource.RAW_VALUE) instanceof Number) {
|
Measure<?, ?> value = (Measure<?, ?>) dataMap
|
||||||
double value = ((Number) dataMap.get(SatResource.RAW_VALUE))
|
.get(SatResource.SATELLITE_DATA_INTERROGATE_ID);
|
||||||
|
if (value != null && value.getValue() instanceof Number) {
|
||||||
|
double measuredValue = ((Number) value.getValue())
|
||||||
.doubleValue();
|
.doubleValue();
|
||||||
if (Double.isNaN(value) == false) {
|
if (Double.isNaN(measuredValue) == false) {
|
||||||
// use this resource
|
// use this resource
|
||||||
inspectString = rsc.inspect(coord);
|
inspectString = rsc.inspect(coord);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import javax.measure.Measure;
|
import javax.measure.Measure;
|
||||||
import javax.measure.converter.UnitConverter;
|
import javax.measure.converter.UnitConverter;
|
||||||
|
import javax.measure.quantity.Temperature;
|
||||||
import javax.measure.unit.Unit;
|
import javax.measure.unit.Unit;
|
||||||
|
|
||||||
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||||
|
@ -41,18 +42,14 @@ import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||||
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
|
import com.raytheon.uf.common.dataplugin.satellite.SatMapCoverage;
|
||||||
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
|
import com.raytheon.uf.common.dataplugin.satellite.SatelliteRecord;
|
||||||
import com.raytheon.uf.common.dataplugin.satellite.units.SatelliteUnits;
|
import com.raytheon.uf.common.dataplugin.satellite.units.SatelliteUnits;
|
||||||
import com.raytheon.uf.common.dataplugin.satellite.units.generic.GenericPixel;
|
|
||||||
import com.raytheon.uf.common.dataplugin.satellite.units.water.BlendedTPWPixel;
|
|
||||||
import com.raytheon.uf.common.geospatial.IGridGeometryProvider;
|
import com.raytheon.uf.common.geospatial.IGridGeometryProvider;
|
||||||
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
|
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
|
||||||
import com.raytheon.uf.common.style.ParamLevelMatchCriteria;
|
import com.raytheon.uf.common.style.ParamLevelMatchCriteria;
|
||||||
import com.raytheon.uf.common.style.StyleException;
|
import com.raytheon.uf.common.style.StyleException;
|
||||||
import com.raytheon.uf.common.style.StyleManager;
|
import com.raytheon.uf.common.style.StyleManager;
|
||||||
import com.raytheon.uf.common.style.StyleRule;
|
import com.raytheon.uf.common.style.StyleRule;
|
||||||
import com.raytheon.uf.common.style.image.ColorMapParameterFactory;
|
import com.raytheon.uf.common.style.image.ColorMapParameterFactory;
|
||||||
|
import com.raytheon.uf.common.style.image.DataScale;
|
||||||
import com.raytheon.uf.common.style.image.ImagePreferences;
|
import com.raytheon.uf.common.style.image.ImagePreferences;
|
||||||
import com.raytheon.uf.common.style.image.SamplePreferences;
|
import com.raytheon.uf.common.style.image.SamplePreferences;
|
||||||
import com.raytheon.uf.common.style.level.Level;
|
import com.raytheon.uf.common.style.level.Level;
|
||||||
|
@ -82,19 +79,25 @@ import com.vividsolutions.jts.geom.Coordinate;
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------- -------- ----------- --------------------------
|
||||||
* Mar 1, 2007 chammack Initial Creation.
|
* Mar 01, 2007 chammack Initial Creation.
|
||||||
* 02/17/2009 njensen Refactored to new rsc architecture.
|
* Feb 17, 2009 njensen Refactored to new rsc architecture.
|
||||||
* 03/02/2009 2032 jsanchez Added check for displayedDate if no data.
|
* Mar 02, 2009 2032 jsanchez Added check for displayedDate if no
|
||||||
* 03/25/2009 2086 jsanchez Mapped correct converter to parameter type.
|
* data.
|
||||||
* Updated the call to ColormapParametersFactory.build
|
* Mar 25, 2009 2086 jsanchez Mapped correct converter to parameter
|
||||||
* 03/30/2009 2169 jsanchez Updated numLevels handling.
|
* type. Updated the call to
|
||||||
* - AWIPS2 Baseline Repository --------
|
* ColormapParametersFactory.build
|
||||||
* 07/17/2012 798 jkorman Use decimationLevels from SatelliteRecord. Removed hard-coded
|
* Mar 30, 2009 2169 jsanchez Updated numLevels handling.
|
||||||
* data set names.
|
* Jul 17, 2012 798 jkorman Use decimationLevels from
|
||||||
* 06/20/2013 2122 mschenke Modified to use SatTileSetRenderable
|
* SatelliteRecord. Removed hard-coded
|
||||||
* 07/31/2013 2190 mschenke Switched to use Measure objects for interrogation
|
* data set names.
|
||||||
|
* Jun 20, 2013 2122 mschenke Modified to use SatTileSetRenderable
|
||||||
|
* Jul 31, 2013 2190 mschenke Switched to use Measure objects for
|
||||||
|
* interrogation
|
||||||
|
* Nov 20, 2013 2492 bsteffen Always get min/max values from style
|
||||||
|
* rules.
|
||||||
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author chammack
|
* @author chammack
|
||||||
|
@ -103,11 +106,6 @@ import com.vividsolutions.jts.geom.Coordinate;
|
||||||
public class SatResource extends
|
public class SatResource extends
|
||||||
AbstractPluginDataObjectResource<SatResourceData, IMapDescriptor> {
|
AbstractPluginDataObjectResource<SatResourceData, IMapDescriptor> {
|
||||||
|
|
||||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
|
||||||
.getHandler(SatResource.class);
|
|
||||||
|
|
||||||
public static String RAW_VALUE = "rawValue";
|
|
||||||
|
|
||||||
/** String id to look for satellite-provided data values */
|
/** String id to look for satellite-provided data values */
|
||||||
public static final String SATELLITE_DATA_INTERROGATE_ID = "satelliteDataValue";
|
public static final String SATELLITE_DATA_INTERROGATE_ID = "satelliteDataValue";
|
||||||
|
|
||||||
|
@ -215,12 +213,12 @@ public class SatResource extends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public InterrogationResult interrogate(Coordinate latLon)
|
public InterrogationResult interrogate(Coordinate latLon,
|
||||||
throws VizException {
|
Unit<?> requestUnit) throws VizException {
|
||||||
InterrogationResult result = null;
|
InterrogationResult result = null;
|
||||||
synchronized (tileMap) {
|
synchronized (tileMap) {
|
||||||
for (SatTileSetRenderable renderable : tileMap.values()) {
|
for (SatTileSetRenderable renderable : tileMap.values()) {
|
||||||
double rValue = renderable.interrogate(latLon, fillValue);
|
double rValue = renderable.interrogate(latLon, requestUnit);
|
||||||
if (Double.isNaN(rValue) == false) {
|
if (Double.isNaN(rValue) == false) {
|
||||||
result = new InterrogationResult(
|
result = new InterrogationResult(
|
||||||
renderable.getSatelliteRecord(), rValue);
|
renderable.getSatelliteRecord(), rValue);
|
||||||
|
@ -235,7 +233,8 @@ public class SatResource extends
|
||||||
|
|
||||||
protected SamplePreferences sampleRange;
|
protected SamplePreferences sampleRange;
|
||||||
|
|
||||||
protected double fillValue = 0;
|
/** Flag to avoid reinitializing ColorMapParameters from style rules */
|
||||||
|
private boolean initialized = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -249,21 +248,19 @@ public class SatResource extends
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DataTime getDataObjectTime(PluginDataObject pdo) {
|
protected DataTime getDataObjectTime(PluginDataObject pdo) {
|
||||||
SatelliteRecord record = (SatelliteRecord) pdo;
|
if (initialized == false) {
|
||||||
if (dataTimes.isEmpty()) {
|
|
||||||
try {
|
try {
|
||||||
initializeFirstFrame(record);
|
initializeFirstFrame((SatelliteRecord) pdo);
|
||||||
} catch (VizException e) {
|
} catch (VizException e) {
|
||||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
throw new IllegalStateException(
|
||||||
e);
|
"Unable to initialize the satellite resource");
|
||||||
}
|
}
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataTime pdoTime = pdo.getDataTime();
|
DataTime pdoTime = pdo.getDataTime();
|
||||||
if (resourceData.getBinOffset() != null) {
|
if (resourceData.getBinOffset() != null) {
|
||||||
pdoTime = resourceData.getBinOffset().getNormalizedTime(pdoTime);
|
pdoTime = resourceData.getBinOffset().getNormalizedTime(pdoTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pdoTime;
|
return pdoTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +283,6 @@ public class SatResource extends
|
||||||
}
|
}
|
||||||
|
|
||||||
SingleLevel level = new SingleLevel(Level.LevelType.SURFACE);
|
SingleLevel level = new SingleLevel(Level.LevelType.SURFACE);
|
||||||
Unit<?> unit = SatDataRetriever.getRecordUnit(record);
|
|
||||||
String physicalElement = null;
|
String physicalElement = null;
|
||||||
DerivedParameterRequest request = (DerivedParameterRequest) record
|
DerivedParameterRequest request = (DerivedParameterRequest) record
|
||||||
.getMessageData();
|
.getMessageData();
|
||||||
|
@ -301,25 +297,42 @@ public class SatResource extends
|
||||||
match.setParameterName(Arrays.asList(physicalElement));
|
match.setParameterName(Arrays.asList(physicalElement));
|
||||||
match.setLevels(Arrays.asList((Level) level));
|
match.setLevels(Arrays.asList((Level) level));
|
||||||
match.setCreatingEntityNames(Arrays.asList(record.getCreatingEntity()));
|
match.setCreatingEntityNames(Arrays.asList(record.getCreatingEntity()));
|
||||||
StyleRule sr;
|
Unit<?> unit = SatDataRetriever.getRecordUnit(record);
|
||||||
try {
|
try {
|
||||||
sr = StyleManager.getInstance().getStyleRule(
|
StyleRule sr = StyleManager.getInstance().getStyleRule(
|
||||||
StyleManager.StyleType.IMAGERY, match);
|
StyleManager.StyleType.IMAGERY, match);
|
||||||
} catch (StyleException e) {
|
|
||||||
throw new VizException(e.getLocalizedMessage(), e);
|
ImagePreferences preferences = null;
|
||||||
}
|
if (sr == null
|
||||||
if (sr != null && sr.getPreferences() instanceof ImagePreferences) {
|
|| sr.getPreferences() instanceof ImagePreferences == false) {
|
||||||
sampleRange = ((ImagePreferences) sr.getPreferences())
|
// No style rule, this is a best guess at what might look good.
|
||||||
.getSamplePrefs();
|
preferences = new ImagePreferences();
|
||||||
String lg = ((ImagePreferences) sr.getPreferences()).getLegend();
|
if (unit != null && unit.isCompatible(Temperature.UNIT)) {
|
||||||
|
preferences.setDefaultColormap("Sat/IR/CIRA (IR Default)");
|
||||||
|
} else {
|
||||||
|
preferences.setDefaultColormap("Sat/VIS/ZA (Vis Default)");
|
||||||
|
}
|
||||||
|
DataScale range = new DataScale();
|
||||||
|
range.setScaleType(DataScale.Type.LINEAR);
|
||||||
|
range.setMinValue(0.0);
|
||||||
|
range.setMaxValue(255.0);
|
||||||
|
preferences.setDataScale(range);
|
||||||
|
} else {
|
||||||
|
preferences = (ImagePreferences) sr.getPreferences();
|
||||||
|
}
|
||||||
|
colorMapParameters = ColorMapParameterFactory.build(preferences,
|
||||||
|
unit);
|
||||||
|
|
||||||
|
sampleRange = preferences.getSamplePrefs();
|
||||||
|
String lg = preferences.getLegend();
|
||||||
// test, so legend is not over written with empty string
|
// test, so legend is not over written with empty string
|
||||||
if (lg != null && !lg.trim().isEmpty()) {
|
if (lg != null && !lg.trim().isEmpty()) {
|
||||||
legend = lg;
|
legend = lg;
|
||||||
}
|
}
|
||||||
|
} catch (StyleException e) {
|
||||||
|
throw new VizException(e.getLocalizedMessage(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
colorMapParameters = ColorMapParameterFactory.build(sr, null, level,
|
|
||||||
unit);
|
|
||||||
// If null, set from style rules
|
// If null, set from style rules
|
||||||
if (cmName == null) {
|
if (cmName == null) {
|
||||||
cmName = colorMapParameters.getColorMapName();
|
cmName = colorMapParameters.getColorMapName();
|
||||||
|
@ -343,26 +356,7 @@ public class SatResource extends
|
||||||
if (persisted != null) {
|
if (persisted != null) {
|
||||||
colorMapParameters.applyPersistedParameters(persisted);
|
colorMapParameters.applyPersistedParameters(persisted);
|
||||||
}
|
}
|
||||||
|
colorMapParameters.setNoDataValue(0);
|
||||||
// TODO: Figure out data/color map min/max values better
|
|
||||||
if (unit == null) {
|
|
||||||
colorMapParameters.setColorMapMin(0.0f);
|
|
||||||
colorMapParameters.setColorMapMax(255.0f);
|
|
||||||
}
|
|
||||||
if (unit instanceof GenericPixel) {
|
|
||||||
// Derived parameter data will be signed
|
|
||||||
colorMapParameters.setDataMin(-128.0f);
|
|
||||||
colorMapParameters.setDataMax(127.0f);
|
|
||||||
} else if (unit instanceof BlendedTPWPixel) {
|
|
||||||
colorMapParameters.setDataMin(0.0f);
|
|
||||||
colorMapParameters.setDataMax(252.0f);
|
|
||||||
|
|
||||||
colorMapParameters.setColorMapMin(0.0f);
|
|
||||||
colorMapParameters.setColorMapMax(252.0f);
|
|
||||||
} else {
|
|
||||||
colorMapParameters.setDataMin(0.0f);
|
|
||||||
colorMapParameters.setDataMax(255.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
getCapability(ColorMapCapability.class).setColorMapParameters(
|
getCapability(ColorMapCapability.class).setColorMapParameters(
|
||||||
colorMapParameters);
|
colorMapParameters);
|
||||||
|
@ -389,10 +383,11 @@ public class SatResource extends
|
||||||
ColorMapParameters parameters = getCapability(ColorMapCapability.class)
|
ColorMapParameters parameters = getCapability(ColorMapCapability.class)
|
||||||
.getColorMapParameters();
|
.getColorMapParameters();
|
||||||
double dataValue = Double.NaN;
|
double dataValue = Double.NaN;
|
||||||
|
Unit<?> dataUnit = parameters.getColorMapUnit();
|
||||||
if (renderable != null) {
|
if (renderable != null) {
|
||||||
try {
|
try {
|
||||||
InterrogationResult result = renderable.interrogate(coord
|
InterrogationResult result = renderable.interrogate(
|
||||||
.asLatLon());
|
coord.asLatLon(), dataUnit);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
dataValue = result.getValue();
|
dataValue = result.getValue();
|
||||||
dataMap.put(IGridGeometryProvider.class.toString(), result
|
dataMap.put(IGridGeometryProvider.class.toString(), result
|
||||||
|
@ -403,9 +398,8 @@ public class SatResource extends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dataMap.put(RAW_VALUE, dataValue);
|
|
||||||
dataMap.put(SATELLITE_DATA_INTERROGATE_ID,
|
dataMap.put(SATELLITE_DATA_INTERROGATE_ID,
|
||||||
Measure.valueOf(dataValue, parameters.getDataUnit()));
|
Measure.valueOf(dataValue, dataUnit));
|
||||||
|
|
||||||
return dataMap;
|
return dataMap;
|
||||||
}
|
}
|
||||||
|
@ -413,8 +407,14 @@ public class SatResource extends
|
||||||
@Override
|
@Override
|
||||||
public String inspect(ReferencedCoordinate coord) throws VizException {
|
public String inspect(ReferencedCoordinate coord) throws VizException {
|
||||||
Map<String, Object> dataMap = interrogate(coord);
|
Map<String, Object> dataMap = interrogate(coord);
|
||||||
Double value = (Double) dataMap.get(RAW_VALUE);
|
|
||||||
if (value == null || value.isNaN()) {
|
Measure<?, ?> value = (Measure<?, ?>) dataMap
|
||||||
|
.get(SATELLITE_DATA_INTERROGATE_ID);
|
||||||
|
double measuredValue = Double.NaN;
|
||||||
|
if (value != null && value.getValue() instanceof Double) {
|
||||||
|
measuredValue = (Double) value.getValue();
|
||||||
|
}
|
||||||
|
if (Double.isNaN(measuredValue)) {
|
||||||
return "NO DATA";
|
return "NO DATA";
|
||||||
}
|
}
|
||||||
ColorMapParameters cmp = getCapability(ColorMapCapability.class)
|
ColorMapParameters cmp = getCapability(ColorMapCapability.class)
|
||||||
|
@ -425,18 +425,21 @@ public class SatResource extends
|
||||||
if (dataMapping != null) {
|
if (dataMapping != null) {
|
||||||
// if the pixel value matches the data mapping entry use that
|
// if the pixel value matches the data mapping entry use that
|
||||||
// label instead
|
// label instead
|
||||||
String label = dataMapping.getLabelValueForDataValue(value);
|
String label = dataMapping.getLabelValueForDataValue(measuredValue);
|
||||||
if (label != null) {
|
if (label != null) {
|
||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UnitConverter dataToDisplay = cmp.getDataToDisplayConverter();
|
Unit<?> unit = cmp.getDisplayUnit();
|
||||||
if (dataToDisplay != null) {
|
Unit<?> measuredUnit = value.getUnit();
|
||||||
value = dataToDisplay.convert(value);
|
if (unit != null && measuredUnit != null) {
|
||||||
|
UnitConverter dataToDisplay = measuredUnit.getConverterTo(unit);
|
||||||
|
if (dataToDisplay != null) {
|
||||||
|
measuredValue = dataToDisplay.convert(measuredValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit<?> unit = cmp.getDisplayUnit();
|
|
||||||
// Had to use 'bit' as the display unit because
|
// Had to use 'bit' as the display unit because
|
||||||
// counts was not an acceptable unit.
|
// counts was not an acceptable unit.
|
||||||
String unitString = unit == null ? ""
|
String unitString = unit == null ? ""
|
||||||
|
@ -447,13 +450,13 @@ public class SatResource extends
|
||||||
f1 = sampleRange.getMaxValue();
|
f1 = sampleRange.getMaxValue();
|
||||||
f2 = sampleRange.getMinValue();
|
f2 = sampleRange.getMinValue();
|
||||||
}
|
}
|
||||||
if (value > f1 && value > f2) {
|
if (measuredValue > f1 && measuredValue > f2) {
|
||||||
return String.format(">%.1f%s", Math.max(f1, f2), unitString);
|
return String.format(">%.1f%s", Math.max(f1, f2), unitString);
|
||||||
}
|
}
|
||||||
if (value < f1 && value < f2) {
|
if (measuredValue < f1 && measuredValue < f2) {
|
||||||
return String.format("<%.1f%s", Math.min(f1, f2), unitString);
|
return String.format("<%.1f%s", Math.min(f1, f2), unitString);
|
||||||
}
|
}
|
||||||
return String.format("%.1f%s", value, unitString);
|
return String.format("%.1f%s", measuredValue, unitString);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getLegend(PluginDataObject record) {
|
private String getLegend(PluginDataObject record) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.nio.ByteBuffer;
|
||||||
import java.nio.ShortBuffer;
|
import java.nio.ShortBuffer;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.ParsePosition;
|
import java.text.ParsePosition;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.measure.unit.Unit;
|
import javax.measure.unit.Unit;
|
||||||
import javax.measure.unit.UnitFormat;
|
import javax.measure.unit.UnitFormat;
|
||||||
|
@ -60,7 +61,9 @@ import com.raytheon.viz.satellite.SatelliteConstants;
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Jun 20, 2013 2122 mschenke Initial creation
|
* Jun 20, 2013 2122 mschenke Initial creation
|
||||||
|
* Nov 13, 2013 2492 mschenke Added extraction of scale/offset from
|
||||||
|
* data record attributes for unit
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -92,8 +95,8 @@ public class SatDataRetriever implements IColorMapDataRetrievalCallback {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ColorMapData getColorMapData() {
|
public ColorMapData getColorMapData() {
|
||||||
// TODO: Read scale/offset out of attributes?
|
|
||||||
Buffer data = null;
|
Buffer data = null;
|
||||||
|
Unit<?> dataUnit = Unit.ONE;
|
||||||
boolean signed = false;
|
boolean signed = false;
|
||||||
Request req = Request.buildSlab(new int[] { this.datasetBounds.x,
|
Request req = Request.buildSlab(new int[] { this.datasetBounds.x,
|
||||||
this.datasetBounds.y }, new int[] {
|
this.datasetBounds.y }, new int[] {
|
||||||
|
@ -112,6 +115,7 @@ public class SatDataRetriever implements IColorMapDataRetrievalCallback {
|
||||||
}
|
}
|
||||||
Unit<?> recordUnit = getRecordUnit(this.record);
|
Unit<?> recordUnit = getRecordUnit(this.record);
|
||||||
signed = recordUnit instanceof GenericPixel;
|
signed = recordUnit instanceof GenericPixel;
|
||||||
|
dataUnit = getDataUnit(recordUnit, record);
|
||||||
}
|
}
|
||||||
} catch (VizDataCubeException e) {
|
} catch (VizDataCubeException e) {
|
||||||
statusHandler.handle(Priority.SIGNIFICANT,
|
statusHandler.handle(Priority.SIGNIFICANT,
|
||||||
|
@ -134,7 +138,7 @@ public class SatDataRetriever implements IColorMapDataRetrievalCallback {
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ColorMapData(data, new int[] { datasetBounds.width,
|
return new ColorMapData(data, new int[] { datasetBounds.width,
|
||||||
datasetBounds.height }, dataType);
|
datasetBounds.height }, dataType, dataUnit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -150,7 +154,8 @@ public class SatDataRetriever implements IColorMapDataRetrievalCallback {
|
||||||
physicalElement = request.getParameterAbbreviation();
|
physicalElement = request.getParameterAbbreviation();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (record.getUnits() != null && record.getUnits().isEmpty() == false && request == null) {
|
if (record.getUnits() != null && record.getUnits().isEmpty() == false
|
||||||
|
&& request == null) {
|
||||||
try {
|
try {
|
||||||
recordUnit = UnitFormat.getUCUMInstance().parseProductUnit(
|
recordUnit = UnitFormat.getUCUMInstance().parseProductUnit(
|
||||||
record.getUnits(), new ParsePosition(0));
|
record.getUnits(), new ParsePosition(0));
|
||||||
|
@ -180,7 +185,38 @@ public class SatDataRetriever implements IColorMapDataRetrievalCallback {
|
||||||
|
|
||||||
return recordUnit;
|
return recordUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the data units for the data record given the PDO's base unit
|
||||||
|
*
|
||||||
|
* @param recordUnit
|
||||||
|
* @param dataRecord
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static Unit<?> getDataUnit(Unit<?> recordUnit,
|
||||||
|
IDataRecord dataRecord) {
|
||||||
|
Unit<?> units = recordUnit != null ? recordUnit : Unit.ONE;
|
||||||
|
Map<String, Object> attrs = dataRecord.getDataAttributes();
|
||||||
|
if (attrs != null) {
|
||||||
|
Number offset = (Number) attrs.get(SatelliteRecord.SAT_ADD_OFFSET);
|
||||||
|
Number scale = (Number) attrs.get(SatelliteRecord.SAT_SCALE_FACTOR);
|
||||||
|
|
||||||
|
if (offset != null) {
|
||||||
|
double offsetVal = offset.doubleValue();
|
||||||
|
if (offsetVal != 0.0) {
|
||||||
|
units = units.plus(offsetVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (scale != null) {
|
||||||
|
double scaleVal = scale.doubleValue();
|
||||||
|
if (scaleVal != 0.0) {
|
||||||
|
units = units.times(scaleVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return units;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class ColorMapSliderComp extends Composite {
|
||||||
|
|
||||||
private static final int SLIDER_MIN = 0;
|
private static final int SLIDER_MIN = 0;
|
||||||
|
|
||||||
private static final int SLIDER_MAX = 255;
|
private static final int SLIDER_MAX = 250;
|
||||||
|
|
||||||
private static final int SLIDER_INC = 1;
|
private static final int SLIDER_INC = 1;
|
||||||
|
|
||||||
|
@ -79,9 +79,9 @@ public class ColorMapSliderComp extends Composite {
|
||||||
|
|
||||||
private Text maxValueText;
|
private Text maxValueText;
|
||||||
|
|
||||||
private final float cmapAbsoluteMin;
|
private float cmapAbsoluteMin;
|
||||||
|
|
||||||
private final float cmapAbsoluteMax;
|
private float cmapAbsoluteMax;
|
||||||
|
|
||||||
private final float origCmapMin;
|
private final float origCmapMin;
|
||||||
|
|
||||||
|
@ -93,8 +93,6 @@ public class ColorMapSliderComp extends Composite {
|
||||||
|
|
||||||
private final DecimalFormat format;
|
private final DecimalFormat format;
|
||||||
|
|
||||||
private final boolean dataInverted;
|
|
||||||
|
|
||||||
private UnitConverter displayToColorMap;
|
private UnitConverter displayToColorMap;
|
||||||
|
|
||||||
private UnitConverter colorMapToDisplay;
|
private UnitConverter colorMapToDisplay;
|
||||||
|
@ -106,8 +104,10 @@ public class ColorMapSliderComp extends Composite {
|
||||||
public ColorMapSliderComp(Composite parent, ColorMapParameters cmap) {
|
public ColorMapSliderComp(Composite parent, ColorMapParameters cmap) {
|
||||||
super(parent, SWT.NONE);
|
super(parent, SWT.NONE);
|
||||||
this.cmap = cmap;
|
this.cmap = cmap;
|
||||||
this.currentCmapMin = this.origCmapMin = cmap.getColorMapMin();
|
this.cmapAbsoluteMin = this.currentCmapMin = this.origCmapMin = cmap
|
||||||
this.currentCmapMax = this.origCmapMax = cmap.getColorMapMax();
|
.getColorMapMin();
|
||||||
|
this.cmapAbsoluteMax = this.currentCmapMax = this.origCmapMax = cmap
|
||||||
|
.getColorMapMax();
|
||||||
this.displayToColorMap = cmap.getDisplayToColorMapConverter();
|
this.displayToColorMap = cmap.getDisplayToColorMapConverter();
|
||||||
this.colorMapToDisplay = cmap.getColorMapToDisplayConverter();
|
this.colorMapToDisplay = cmap.getColorMapToDisplayConverter();
|
||||||
if (displayToColorMap == null) {
|
if (displayToColorMap == null) {
|
||||||
|
@ -116,34 +116,9 @@ public class ColorMapSliderComp extends Composite {
|
||||||
if (colorMapToDisplay == null) {
|
if (colorMapToDisplay == null) {
|
||||||
colorMapToDisplay = Unit.ONE.getConverterTo(Unit.ONE);
|
colorMapToDisplay = Unit.ONE.getConverterTo(Unit.ONE);
|
||||||
}
|
}
|
||||||
float cmapAbsoluteMin, cmapAbsoluteMax;
|
|
||||||
if (cmap.getDataMapping() != null) {
|
|
||||||
cmapAbsoluteMin = cmap.getColorMapMin();
|
|
||||||
cmapAbsoluteMax = cmap.getColorMapMax();
|
|
||||||
} else {
|
|
||||||
UnitConverter dataToColorMap = cmap.getDataToColorMapConverter();
|
|
||||||
cmapAbsoluteMin = cmap.getDataMin();
|
|
||||||
cmapAbsoluteMax = cmap.getDataMax();
|
|
||||||
if (dataToColorMap != null) {
|
|
||||||
cmapAbsoluteMin = (float) dataToColorMap.convert(cmap
|
|
||||||
.getDataMin());
|
|
||||||
cmapAbsoluteMax = (float) dataToColorMap.convert(cmap
|
|
||||||
.getDataMax());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.cmapAbsoluteMin = cmapAbsoluteMin;
|
updateAbsolutes(cmapAbsoluteMin, cmapAbsoluteMax);
|
||||||
this.cmapAbsoluteMax = cmapAbsoluteMax;
|
|
||||||
|
|
||||||
boolean dataInverted = false;
|
|
||||||
if ((cmapAbsoluteMin > cmapAbsoluteMax && cmap.getDataMin() < cmap
|
|
||||||
.getDataMax())
|
|
||||||
|| (cmapAbsoluteMin < cmapAbsoluteMax && cmap.getDataMin() > cmap
|
|
||||||
.getDataMax())) {
|
|
||||||
dataInverted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dataInverted = dataInverted;
|
|
||||||
this.format = getTextFormat();
|
this.format = getTextFormat();
|
||||||
|
|
||||||
initializeComponents();
|
initializeComponents();
|
||||||
|
@ -205,6 +180,7 @@ public class ColorMapSliderComp extends Composite {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
minSlider.addSelectionListener(new SelectionAdapter() {
|
minSlider.addSelectionListener(new SelectionAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void widgetSelected(SelectionEvent e) {
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
@ -217,8 +193,7 @@ public class ColorMapSliderComp extends Composite {
|
||||||
@Override
|
@Override
|
||||||
public void keyPressed(KeyEvent e) {
|
public void keyPressed(KeyEvent e) {
|
||||||
if (e.character == SWT.CR) {
|
if (e.character == SWT.CR) {
|
||||||
setColorMapMax(textToColorMapValue(maxValueText.getText()
|
updateMinMaxFromText(maxValueText);
|
||||||
.trim()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -227,8 +202,7 @@ public class ColorMapSliderComp extends Composite {
|
||||||
@Override
|
@Override
|
||||||
public void keyPressed(KeyEvent e) {
|
public void keyPressed(KeyEvent e) {
|
||||||
if (e.character == SWT.CR) {
|
if (e.character == SWT.CR) {
|
||||||
setColorMapMin(textToColorMapValue(minValueText.getText()
|
updateMinMaxFromText(minValueText);
|
||||||
.trim()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -237,6 +211,48 @@ public class ColorMapSliderComp extends Composite {
|
||||||
setColorMapMax(currentCmapMax);
|
setColorMapMax(currentCmapMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateMinMaxFromText(Text text) {
|
||||||
|
float newCmapValue = textToColorMapValue(text);
|
||||||
|
if (Float.isNaN(newCmapValue)) {
|
||||||
|
// Change nothing
|
||||||
|
if (text == minValueText) {
|
||||||
|
newCmapValue = currentCmapMin;
|
||||||
|
} else {
|
||||||
|
newCmapValue = currentCmapMax;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Update colormap range
|
||||||
|
if (text == minValueText) {
|
||||||
|
currentCmapMin = newCmapValue;
|
||||||
|
} else {
|
||||||
|
currentCmapMax = newCmapValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAbsolutes(currentCmapMin, currentCmapMax);
|
||||||
|
|
||||||
|
setColorMapMin(currentCmapMin);
|
||||||
|
setColorMapMax(currentCmapMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void updateAbsolutes(float cmapAbsoluteMin, float cmapAbsoluteMax) {
|
||||||
|
double displayAbsMax = colorMapToDisplay.convert(cmapAbsoluteMax);
|
||||||
|
double displayAbsMin = colorMapToDisplay.convert(cmapAbsoluteMin);
|
||||||
|
if (displayAbsMax < displayAbsMin) {
|
||||||
|
float tmp = cmapAbsoluteMax;
|
||||||
|
cmapAbsoluteMax = cmapAbsoluteMin;
|
||||||
|
cmapAbsoluteMin = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a 1/16 buffer on either side for fine tuning
|
||||||
|
float buffer = (cmapAbsoluteMax - cmapAbsoluteMin) * .0625f;
|
||||||
|
this.cmapAbsoluteMin = cmapAbsoluteMin - buffer;
|
||||||
|
this.cmapAbsoluteMax = cmapAbsoluteMax + buffer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a slider selection index to a colormap value
|
* Converts a slider selection index to a colormap value
|
||||||
*
|
*
|
||||||
|
@ -246,9 +262,6 @@ public class ColorMapSliderComp extends Composite {
|
||||||
private float selectionToColorMapValue(int selection) {
|
private float selectionToColorMapValue(int selection) {
|
||||||
double indexValue = Colormapper.getLinearIndex(selection, SLIDER_MIN,
|
double indexValue = Colormapper.getLinearIndex(selection, SLIDER_MIN,
|
||||||
SLIDER_MAX);
|
SLIDER_MAX);
|
||||||
if (dataInverted) {
|
|
||||||
indexValue = 1 - indexValue;
|
|
||||||
}
|
|
||||||
double colorMapValue = cmapAbsoluteMin
|
double colorMapValue = cmapAbsoluteMin
|
||||||
+ (cmapAbsoluteMax - cmapAbsoluteMin) * indexValue;
|
+ (cmapAbsoluteMax - cmapAbsoluteMin) * indexValue;
|
||||||
return (float) colorMapValue;
|
return (float) colorMapValue;
|
||||||
|
@ -263,9 +276,6 @@ public class ColorMapSliderComp extends Composite {
|
||||||
private int colorMapValueToSelection(float colorMapValue) {
|
private int colorMapValueToSelection(float colorMapValue) {
|
||||||
double indexValue = Colormapper.getLinearIndex(colorMapValue,
|
double indexValue = Colormapper.getLinearIndex(colorMapValue,
|
||||||
cmapAbsoluteMin, cmapAbsoluteMax);
|
cmapAbsoluteMin, cmapAbsoluteMax);
|
||||||
if (dataInverted) {
|
|
||||||
indexValue = 1 - indexValue;
|
|
||||||
}
|
|
||||||
return (int) (SLIDER_MIN + (SLIDER_MAX - SLIDER_MIN) * indexValue);
|
return (int) (SLIDER_MIN + (SLIDER_MAX - SLIDER_MIN) * indexValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +285,8 @@ public class ColorMapSliderComp extends Composite {
|
||||||
* @param text
|
* @param text
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private float textToColorMapValue(String text) {
|
private float textToColorMapValue(Text textControl) {
|
||||||
|
String text = textControl.getText().trim();
|
||||||
if (cmap.getDataMapping() != null && text.isEmpty() == false) {
|
if (cmap.getDataMapping() != null && text.isEmpty() == false) {
|
||||||
// First check for data mapping entries
|
// First check for data mapping entries
|
||||||
for (DataMappingEntry entry : cmap.getDataMapping().getEntries()) {
|
for (DataMappingEntry entry : cmap.getDataMapping().getEntries()) {
|
||||||
|
@ -285,13 +296,28 @@ public class ColorMapSliderComp extends Composite {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (NaN_STRING.equals(text)) {
|
if (NaN_STRING.equals(text)) {
|
||||||
// If special NaN String, try to find first NaN value
|
// If special NaN String, try to find closest NaN value
|
||||||
|
float currentColorMapValue = textControl == maxValueText ? currentCmapMax
|
||||||
|
: currentCmapMin;
|
||||||
|
int currentSliderValue = colorMapValueToSelection(currentColorMapValue);
|
||||||
|
int minDist = Integer.MAX_VALUE;
|
||||||
|
float bestNanValue = currentColorMapValue;
|
||||||
for (int i = SLIDER_MIN; i < SLIDER_MAX; i += SLIDER_INC) {
|
for (int i = SLIDER_MIN; i < SLIDER_MAX; i += SLIDER_INC) {
|
||||||
float colorMapValue = selectionToColorMapValue(i);
|
float colorMapValue = selectionToColorMapValue(i);
|
||||||
if (Double.isNaN(colorMapToDisplay.convert(colorMapValue))) {
|
if (Double.isNaN(colorMapToDisplay.convert(colorMapValue))) {
|
||||||
return colorMapValue;
|
int dist = Math.abs(i - currentSliderValue);
|
||||||
|
if (dist < minDist) {
|
||||||
|
minDist = dist;
|
||||||
|
bestNanValue = colorMapValue;
|
||||||
|
} else if (i > currentSliderValue) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// For now, assume NaN will live on low end of slider
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return bestNanValue;
|
||||||
} else {
|
} else {
|
||||||
// Attempt to parse and convert
|
// Attempt to parse and convert
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -26,13 +26,14 @@ import javax.measure.converter.UnitConverter;
|
||||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a temperature value in Kelvin to a pixel value from 0 to 255
|
* Converts a temperature value in Kelvin to a pixel value.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------- -------- ----------- --------------------------
|
||||||
* Aug 29, 2007 njensen Initial creation
|
* Aug 29, 2007 njensen Initial creation
|
||||||
|
* Nov 20, 2013 2492 bsteffen Make conversion unbounded.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -40,45 +41,39 @@ import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||||
*/
|
*/
|
||||||
public class IRTempToPixelConverter extends UnitConverter {
|
public class IRTempToPixelConverter extends UnitConverter {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double convert(double aTemperature) throws ConversionException {
|
public double convert(double aTemperature) throws ConversionException {
|
||||||
double result = 0.0;
|
double result = 0.0;
|
||||||
|
|
||||||
if (aTemperature < 238.15) {
|
if (aTemperature < 238.15) {
|
||||||
result = 418.15 - aTemperature;
|
result = 418.15 - aTemperature;
|
||||||
} else {
|
} else {
|
||||||
result = 656.3 - (2.0 * aTemperature);
|
result = 656.3 - (2.0 * aTemperature);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result < 0) {
|
return result;
|
||||||
result = 0.0;
|
}
|
||||||
} else if (result > 255) {
|
|
||||||
result = 255.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
@Override
|
||||||
}
|
public boolean equals(Object aConverter) {
|
||||||
|
return (aConverter instanceof IRTempToPixelConverter);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object aConverter) {
|
public int hashCode() {
|
||||||
return (aConverter instanceof IRTempToPixelConverter);
|
return HashCodeBuilder.reflectionHashCode(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public UnitConverter inverse() {
|
||||||
return HashCodeBuilder.reflectionHashCode(this);
|
return new IRPixelToTempConverter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UnitConverter inverse() {
|
public boolean isLinear() {
|
||||||
return new IRPixelToTempConverter();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLinear() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,118 +0,0 @@
|
||||||
/**
|
|
||||||
* 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.dataplugin.satellite.units.water;
|
|
||||||
|
|
||||||
import javax.measure.converter.ConversionException;
|
|
||||||
import javax.measure.converter.UnitConverter;
|
|
||||||
import javax.measure.unit.SI;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO Add Description
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Mar 18, 2010 jsanchez Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author jsanchez
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class BlendedTPWLengthToPixelConverter extends UnitConverter {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private static UnitConverter meterToMillimeter = SI.METRE.getConverterTo(SI
|
|
||||||
.MILLI(SI.METRE));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see javax.measure.converter.UnitConverter#convert( double)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public double convert(double aLength) throws ConversionException {
|
|
||||||
|
|
||||||
double result = 0.0;
|
|
||||||
|
|
||||||
aLength = meterToMillimeter.convert(aLength);
|
|
||||||
|
|
||||||
if (aLength < 1) {
|
|
||||||
result = 176;
|
|
||||||
} else {
|
|
||||||
result = aLength + 176;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result < 0) {
|
|
||||||
result = 0;
|
|
||||||
} else if (result > 255) {
|
|
||||||
result = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see javax.measure.converter.UnitConverter#equals(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object aConverter) {
|
|
||||||
return (aConverter instanceof BlendedTPWLengthToPixelConverter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see javax.measure.converter.UnitConverter#hashCode()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return HashCodeBuilder.reflectionHashCode(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see javax.measure.converter.UnitConverter#inverse()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public UnitConverter inverse() {
|
|
||||||
return new BlendedTPWPixelToLengthConverter();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see javax.measure.converter.UnitConverter#isLinear()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isLinear() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -19,6 +19,7 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.common.dataplugin.satellite.units.water;
|
package com.raytheon.uf.common.dataplugin.satellite.units.water;
|
||||||
|
|
||||||
|
import javax.measure.converter.AddConverter;
|
||||||
import javax.measure.converter.UnitConverter;
|
import javax.measure.converter.UnitConverter;
|
||||||
import javax.measure.quantity.Length;
|
import javax.measure.quantity.Length;
|
||||||
import javax.measure.unit.DerivedUnit;
|
import javax.measure.unit.DerivedUnit;
|
||||||
|
@ -28,20 +29,22 @@ import javax.measure.unit.Unit;
|
||||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO Add Description
|
* Represents a pixel value on a satellite blended total precipitable water(TPW)
|
||||||
|
* image.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------- -------- ----------- --------------------------
|
||||||
* Mar 18, 2010 jsanchez Initial creation
|
* Mar 18, 2010 jsanchez Initial creation
|
||||||
*
|
* Nov 20, 2013 2492 bsteffen Make conversion unbounded.
|
||||||
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jsanchez
|
* @author jsanchez
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class BlendedTPWPixel extends DerivedUnit<Length> {
|
public class BlendedTPWPixel extends DerivedUnit<Length> {
|
||||||
|
@ -66,6 +69,7 @@ public class BlendedTPWPixel extends DerivedUnit<Length> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UnitConverter toStandardUnit() {
|
public UnitConverter toStandardUnit() {
|
||||||
return new BlendedTPWPixelToLengthConverter();
|
return SI.MILLI(SI.METRE).getConverterTo(SI.METRE)
|
||||||
|
.concatenate(new AddConverter(-176));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,111 +0,0 @@
|
||||||
/**
|
|
||||||
* 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.dataplugin.satellite.units.water;
|
|
||||||
|
|
||||||
import javax.measure.converter.ConversionException;
|
|
||||||
import javax.measure.converter.UnitConverter;
|
|
||||||
import javax.measure.unit.SI;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO Add Description
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
*
|
|
||||||
* SOFTWARE HISTORY
|
|
||||||
*
|
|
||||||
* Date Ticket# Engineer Description
|
|
||||||
* ------------ ---------- ----------- --------------------------
|
|
||||||
* Mar 18, 2010 jsanchez Initial creation
|
|
||||||
*
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @author jsanchez
|
|
||||||
* @version 1.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class BlendedTPWPixelToLengthConverter extends UnitConverter {
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
private static UnitConverter millimeterToMeter = (SI.MILLI(SI.METRE))
|
|
||||||
.getConverterTo(SI.METRE);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see javax.measure.converter.UnitConverter#convert(double)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public double convert(double aPixel) throws ConversionException {
|
|
||||||
double result = 0.0;
|
|
||||||
|
|
||||||
if (aPixel <= 176) {
|
|
||||||
result = 0.0;
|
|
||||||
} else {
|
|
||||||
result = aPixel - 176;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = millimeterToMeter.convert(result);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see javax.measure.converter.UnitConverter#equals(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object aConverter) {
|
|
||||||
return (aConverter instanceof BlendedTPWPixelToLengthConverter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see javax.measure.converter.UnitConverter#hashCode()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return HashCodeBuilder.reflectionHashCode(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see javax.measure.converter.UnitConverter#inverse()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public UnitConverter inverse() {
|
|
||||||
return new BlendedTPWLengthToPixelConverter();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see javax.measure.converter.UnitConverter#isLinear()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean isLinear() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -43,8 +43,8 @@
|
||||||
</paramLevelMatches>
|
</paramLevelMatches>
|
||||||
<imageStyle>
|
<imageStyle>
|
||||||
<range scale="LINEAR">
|
<range scale="LINEAR">
|
||||||
<minValue>1</minValue>
|
<minValue>0</minValue>
|
||||||
<maxValue>254</maxValue>
|
<maxValue>255</maxValue>
|
||||||
</range>
|
</range>
|
||||||
<defaultColormap>Sat/WV/Gray Scale Water Vapor</defaultColormap>
|
<defaultColormap>Sat/WV/Gray Scale Water Vapor</defaultColormap>
|
||||||
</imageStyle>
|
</imageStyle>
|
||||||
|
@ -75,8 +75,8 @@
|
||||||
</paramLevelMatches>
|
</paramLevelMatches>
|
||||||
<imageStyle>
|
<imageStyle>
|
||||||
<range scale="LINEAR">
|
<range scale="LINEAR">
|
||||||
<minValue>1</minValue>
|
<minValue>0</minValue>
|
||||||
<maxValue>254</maxValue>
|
<maxValue>255</maxValue>
|
||||||
</range>
|
</range>
|
||||||
<defaultColormap>Sat/VIS/ZA (Vis Default)</defaultColormap>
|
<defaultColormap>Sat/VIS/ZA (Vis Default)</defaultColormap>
|
||||||
</imageStyle>
|
</imageStyle>
|
||||||
|
@ -199,8 +199,8 @@
|
||||||
</paramLevelMatches>
|
</paramLevelMatches>
|
||||||
<imageStyle>
|
<imageStyle>
|
||||||
<range scale="LINEAR">
|
<range scale="LINEAR">
|
||||||
<minValue>1</minValue>
|
<minValue>0</minValue>
|
||||||
<maxValue>254</maxValue>
|
<maxValue>255</maxValue>
|
||||||
</range>
|
</range>
|
||||||
<defaultColormap>Sat/WV/Gray Scale Water Vapor</defaultColormap>
|
<defaultColormap>Sat/WV/Gray Scale Water Vapor</defaultColormap>
|
||||||
</imageStyle>
|
</imageStyle>
|
||||||
|
@ -211,8 +211,8 @@
|
||||||
</paramLevelMatches>
|
</paramLevelMatches>
|
||||||
<imageStyle>
|
<imageStyle>
|
||||||
<range scale="LINEAR">
|
<range scale="LINEAR">
|
||||||
<minValue>1</minValue>
|
<minValue>0</minValue>
|
||||||
<maxValue>254</maxValue>
|
<maxValue>255</maxValue>
|
||||||
</range>
|
</range>
|
||||||
<defaultColormap>Sat/WV/Gray Scale Water Vapor</defaultColormap>
|
<defaultColormap>Sat/WV/Gray Scale Water Vapor</defaultColormap>
|
||||||
</imageStyle>
|
</imageStyle>
|
||||||
|
@ -223,8 +223,8 @@
|
||||||
</paramLevelMatches>
|
</paramLevelMatches>
|
||||||
<imageStyle>
|
<imageStyle>
|
||||||
<range scale="LINEAR">
|
<range scale="LINEAR">
|
||||||
<minValue>1</minValue>
|
<minValue>0</minValue>
|
||||||
<maxValue>254</maxValue>
|
<maxValue>255</maxValue>
|
||||||
</range>
|
</range>
|
||||||
<defaultColormap>Sat/WV/Gray Scale Water Vapor</defaultColormap>
|
<defaultColormap>Sat/WV/Gray Scale Water Vapor</defaultColormap>
|
||||||
</imageStyle>
|
</imageStyle>
|
||||||
|
@ -235,10 +235,10 @@
|
||||||
</paramLevelMatches>
|
</paramLevelMatches>
|
||||||
<imageStyle>
|
<imageStyle>
|
||||||
<range scale="LINEAR">
|
<range scale="LINEAR">
|
||||||
<minValue>1</minValue>
|
<minValue>0</minValue>
|
||||||
<maxValue>254</maxValue>
|
<maxValue>255</maxValue>
|
||||||
</range>
|
</range>
|
||||||
<defaultColormap>Sat/VIS/ZA (Vis Default)</defaultColormap>
|
<defaultColormap>Sat/VIS/ZA (Vis Default)</defaultColormap>
|
||||||
</imageStyle>
|
</imageStyle>
|
||||||
</styleRule>
|
</styleRule>
|
||||||
<styleRule>
|
<styleRule>
|
||||||
|
@ -248,8 +248,8 @@
|
||||||
<imageStyle>
|
<imageStyle>
|
||||||
<displayUnits>C</displayUnits>
|
<displayUnits>C</displayUnits>
|
||||||
<range scale="LINEAR">
|
<range scale="LINEAR">
|
||||||
<minValue>1</minValue>
|
<minValue>0</minValue>
|
||||||
<maxValue>254</maxValue>
|
<maxValue>255</maxValue>
|
||||||
</range>
|
</range>
|
||||||
<defaultColormap>Sat/IR/CIRA (IR Default)</defaultColormap>
|
<defaultColormap>Sat/IR/CIRA (IR Default)</defaultColormap>
|
||||||
<colorbarLabeling>
|
<colorbarLabeling>
|
||||||
|
@ -264,8 +264,8 @@
|
||||||
<imageStyle>
|
<imageStyle>
|
||||||
<displayUnits>C</displayUnits>
|
<displayUnits>C</displayUnits>
|
||||||
<range scale="LINEAR">
|
<range scale="LINEAR">
|
||||||
<minValue>1</minValue>
|
<minValue>0</minValue>
|
||||||
<maxValue>254</maxValue>
|
<maxValue>255</maxValue>
|
||||||
</range>
|
</range>
|
||||||
<defaultColormap>Sat/IR/CIRA (IR Default)</defaultColormap>
|
<defaultColormap>Sat/IR/CIRA (IR Default)</defaultColormap>
|
||||||
<colorbarLabeling>
|
<colorbarLabeling>
|
||||||
|
@ -436,7 +436,7 @@
|
||||||
<imageStyle>
|
<imageStyle>
|
||||||
<displayUnits>mm</displayUnits>
|
<displayUnits>mm</displayUnits>
|
||||||
<range scale="LINEAR">
|
<range scale="LINEAR">
|
||||||
<minValue>0</minValue>
|
<minValue>-176</minValue>
|
||||||
<maxValue>76</maxValue>
|
<maxValue>76</maxValue>
|
||||||
</range>
|
</range>
|
||||||
<defaultColormap>Sat/Precip Water/Blended Total Precip Water</defaultColormap>
|
<defaultColormap>Sat/Precip Water/Blended Total Precip Water</defaultColormap>
|
||||||
|
@ -492,8 +492,8 @@
|
||||||
</paramLevelMatches>
|
</paramLevelMatches>
|
||||||
<imageStyle>
|
<imageStyle>
|
||||||
<range scale="LINEAR">
|
<range scale="LINEAR">
|
||||||
<minValue>1</minValue>
|
<minValue>0</minValue>
|
||||||
<maxValue>254</maxValue>
|
<maxValue>255</maxValue>
|
||||||
</range>
|
</range>
|
||||||
<defaultColormap>Sat/VIS/ZA (Vis Default)</defaultColormap>
|
<defaultColormap>Sat/VIS/ZA (Vis Default)</defaultColormap>
|
||||||
</imageStyle>
|
</imageStyle>
|
||||||
|
@ -530,5 +530,4 @@
|
||||||
</colorbarLabeling>
|
</colorbarLabeling>
|
||||||
</imageStyle>
|
</imageStyle>
|
||||||
</styleRule>
|
</styleRule>
|
||||||
|
|
||||||
</styleRuleset>
|
</styleRuleset>
|
|
@ -49,10 +49,11 @@ import org.opengis.referencing.operation.MathTransform;
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
*
|
*
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------- -------- ----------- --------------------------
|
||||||
* Jun 27, 2013 mschenke Initial creation
|
* Jun 27, 2013 mschenke Initial creation
|
||||||
* Oct 02, 2013 2333 mschenke Converted from libproj to CGMS algorithm
|
* Oct 02, 2013 2333 mschenke Converted from libproj to CGMS algorithm
|
||||||
|
* Nov 18, 2013 2528 bsteffen Add hashCode/equals.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -212,6 +213,34 @@ public class Geostationary extends MapProjection {
|
||||||
return ptDst;
|
return ptDst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
long temp;
|
||||||
|
temp = Double.doubleToLongBits(orbitalHeight);
|
||||||
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
|
result = prime * result + (swapAxis ? 1231 : 1237);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (!super.equals(obj))
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Geostationary other = (Geostationary) obj;
|
||||||
|
if (Double.doubleToLongBits(orbitalHeight) != Double
|
||||||
|
.doubleToLongBits(other.orbitalHeight))
|
||||||
|
return false;
|
||||||
|
if (swapAxis != other.swapAxis)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Provider extends AbstractProvider {
|
public static class Provider extends AbstractProvider {
|
||||||
|
|
||||||
private static final long serialVersionUID = 3868187206568280453L;
|
private static final long serialVersionUID = 3868187206568280453L;
|
||||||
|
|
|
@ -0,0 +1,416 @@
|
||||||
|
/**
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.geotools.geometry.jts.JTS;
|
||||||
|
import org.geotools.geometry.jts.ReferencedEnvelope;
|
||||||
|
import org.opengis.geometry.Envelope;
|
||||||
|
import org.opengis.geometry.MismatchedDimensionException;
|
||||||
|
import org.opengis.referencing.FactoryException;
|
||||||
|
import org.opengis.referencing.operation.MathTransform;
|
||||||
|
import org.opengis.referencing.operation.TransformException;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||||
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
|
import com.vividsolutions.jts.geom.CoordinateSequence;
|
||||||
|
import com.vividsolutions.jts.geom.Geometry;
|
||||||
|
import com.vividsolutions.jts.geom.GeometryFactory;
|
||||||
|
import com.vividsolutions.jts.geom.Polygon;
|
||||||
|
import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves the problem of intersecting two envelopes in different coordinate
|
||||||
|
* systems by reprojecting a grid of points and building polygons out of
|
||||||
|
* adjacent grid cells. This can be significantly slower than other algorithms
|
||||||
|
* but will always produce the best result possible for a given width and
|
||||||
|
* height. Increasing the width/height will slow the algorithm but give better
|
||||||
|
* results.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------- -------- ----------- --------------------------
|
||||||
|
* Nov 14, 2013 2528 bsteffen Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author bsteffen
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
class BruteForceEnvelopeIntersection {
|
||||||
|
|
||||||
|
private final ReferencedEnvelope sourceEnvelope;
|
||||||
|
|
||||||
|
private final ReferencedEnvelope targetEnvelope;
|
||||||
|
|
||||||
|
private final WorldWrapChecker wwc;
|
||||||
|
|
||||||
|
private final int width;
|
||||||
|
|
||||||
|
private final int height;
|
||||||
|
|
||||||
|
private final MathTransform latLonToTargetCRS;
|
||||||
|
|
||||||
|
private final CoordinateSequence latLonCoords;
|
||||||
|
|
||||||
|
private final CoordinateSequence targetCoords;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new intersection. This will calculate all fields including
|
||||||
|
* reprojecting all points in the grid.
|
||||||
|
*/
|
||||||
|
private BruteForceEnvelopeIntersection(Envelope sourceEnvelope,
|
||||||
|
Envelope targetEnvelope, int width, int height)
|
||||||
|
throws FactoryException, TransformException {
|
||||||
|
if (sourceEnvelope instanceof ReferencedEnvelope) {
|
||||||
|
this.sourceEnvelope = (ReferencedEnvelope) sourceEnvelope;
|
||||||
|
} else {
|
||||||
|
this.sourceEnvelope = new ReferencedEnvelope(sourceEnvelope);
|
||||||
|
}
|
||||||
|
if (targetEnvelope instanceof ReferencedEnvelope) {
|
||||||
|
this.targetEnvelope = (ReferencedEnvelope) targetEnvelope;
|
||||||
|
} else {
|
||||||
|
this.targetEnvelope = new ReferencedEnvelope(targetEnvelope);
|
||||||
|
}
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
wwc = new WorldWrapChecker(this.targetEnvelope);
|
||||||
|
|
||||||
|
double[] latLonCoords = buildLatLonCoords();
|
||||||
|
this.latLonCoords = new PackedCoordinateSequence.Double(latLonCoords, 2);
|
||||||
|
|
||||||
|
latLonToTargetCRS = MapUtil
|
||||||
|
.getTransformFromLatLon(targetEnvelope
|
||||||
|
.getCoordinateReferenceSystem());
|
||||||
|
double[] targetCoords = new double[latLonCoords.length];
|
||||||
|
latLonToTargetCRS.transform(latLonCoords, 0, targetCoords, 0, width
|
||||||
|
* height);
|
||||||
|
this.targetCoords = new PackedCoordinateSequence.Double(targetCoords, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a grid of coordinates and reproject to lat/lon CRS.
|
||||||
|
*/
|
||||||
|
private double[] buildLatLonCoords() throws FactoryException,
|
||||||
|
TransformException {
|
||||||
|
MathTransform sourceCRSToLatLon = MapUtil
|
||||||
|
.getTransformToLatLon(sourceEnvelope
|
||||||
|
.getCoordinateReferenceSystem());
|
||||||
|
double worldMinX = this.sourceEnvelope.getMinX();
|
||||||
|
double worldMinY = this.sourceEnvelope.getMinY();
|
||||||
|
double dXWorld = this.sourceEnvelope.getWidth() / (width - 1);
|
||||||
|
double dYWorld = this.sourceEnvelope.getHeight() / (height - 1);
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
double[] coordinates = new double[width * height * 2];
|
||||||
|
|
||||||
|
for (int j = 0; j < height; ++j) {
|
||||||
|
double y = worldMinY + j * dYWorld;
|
||||||
|
for (int i = 0; i < width; ++i) {
|
||||||
|
coordinates[index++] = worldMinX + i * dXWorld;
|
||||||
|
coordinates[index++] = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sourceCRSToLatLon.transform(coordinates, 0, coordinates, 0, width
|
||||||
|
* height);
|
||||||
|
return coordinates;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the actual intersection operation by merging all {@link Cell}s
|
||||||
|
* into {@link SimplePolygon} and finally converting those into Polygons.
|
||||||
|
*/
|
||||||
|
public Geometry reproject() throws MismatchedDimensionException,
|
||||||
|
TransformException {
|
||||||
|
/*
|
||||||
|
* Loop over each cell and split into two groups. First group is the
|
||||||
|
* "simple" cases that do not world wrap and can all be merged into one
|
||||||
|
* or more polygons. Second group contains the cells that need to be
|
||||||
|
* world wrap corrected.
|
||||||
|
*/
|
||||||
|
List<SimplePolygon> simpleCases = new ArrayList<SimplePolygon>();
|
||||||
|
List<Cell> worldWrappCells = new ArrayList<Cell>();
|
||||||
|
for (int j = 1; j < height; ++j) {
|
||||||
|
for (int i = 1; i < width; ++i) {
|
||||||
|
Cell cell = new Cell(i, j);
|
||||||
|
if (!cell.isValid()) {
|
||||||
|
// skip it
|
||||||
|
} else if (cell.worldWrapCheck(wwc)) {
|
||||||
|
worldWrappCells.add(cell);
|
||||||
|
} else {
|
||||||
|
for (SimplePolygon poly : simpleCases) {
|
||||||
|
if (poly.merge(cell)) {
|
||||||
|
cell = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cell != null) {
|
||||||
|
simpleCases.add(new SimplePolygon(cell));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Convert all simple case polygons into JTS polygons */
|
||||||
|
GeometryFactory gf = new GeometryFactory();
|
||||||
|
List<Geometry> geoms = new ArrayList<Geometry>(simpleCases.size() + worldWrappCells.size() *2);
|
||||||
|
for (SimplePolygon poly : simpleCases) {
|
||||||
|
geoms.add(poly.asGeometry(gf));
|
||||||
|
}
|
||||||
|
if(!worldWrappCells.isEmpty()){
|
||||||
|
/*
|
||||||
|
* World wrap correct the cells that need it and transform the
|
||||||
|
* corrected geometries.
|
||||||
|
*/
|
||||||
|
WorldWrapCorrector corrector = new WorldWrapCorrector(
|
||||||
|
targetEnvelope);
|
||||||
|
for (Cell cell : worldWrappCells) {
|
||||||
|
Geometry geom = cell.asLatLonGeometry(gf);
|
||||||
|
geom = corrector.correct(geom);
|
||||||
|
geom = JTS.transform(geom, latLonToTargetCRS);
|
||||||
|
if (geom.isValid() && !geom.isEmpty()) {
|
||||||
|
geoms.add(geom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gf.createGeometryCollection(geoms.toArray(new Geometry[0]))
|
||||||
|
.buffer(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A cell represents four connected grid points that form a continous piece
|
||||||
|
* of an intersecting polygons. Most of the time a cell represents a
|
||||||
|
* quadrilateral but for cases where one of the corners is invalid in the
|
||||||
|
* target CRS a cell may represent a triangle. If any more points are
|
||||||
|
* invalid then the cell is invalid.
|
||||||
|
*/
|
||||||
|
private final class Cell {
|
||||||
|
|
||||||
|
private final int[] indices;
|
||||||
|
|
||||||
|
public Cell(int x, int y) {
|
||||||
|
int[] indices = new int[] { y * width + x - 1,
|
||||||
|
(y - 1) * width + x - 1,
|
||||||
|
(y - 1) * width + x, y * width + x};
|
||||||
|
int nanCount = 0;
|
||||||
|
for (int index : indices) {
|
||||||
|
if (isNaN(index)) {
|
||||||
|
nanCount += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nanCount == 0) {
|
||||||
|
this.indices = indices;
|
||||||
|
} else if (nanCount == 1) {
|
||||||
|
this.indices = new int[3];
|
||||||
|
int i = 0;
|
||||||
|
for (int index : indices) {
|
||||||
|
if (!isNaN(index)) {
|
||||||
|
this.indices[i++] = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.indices = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNaN(int index){
|
||||||
|
return Double.isNaN(targetCoords.getOrdinate(index, 0))
|
||||||
|
|| Double.isNaN(targetCoords.getOrdinate(index, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return indices != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean worldWrapCheck(WorldWrapChecker wwc) {
|
||||||
|
double prevLon = latLonCoords.getOrdinate(
|
||||||
|
indices[indices.length - 1], 0);
|
||||||
|
for (int index : indices) {
|
||||||
|
double lon = latLonCoords.getOrdinate(index, 0);
|
||||||
|
if (wwc.check(prevLon, lon)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
prevLon = lon;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Coordinate> getTargetCoords() {
|
||||||
|
List<Coordinate> result = new ArrayList<Coordinate>(4);
|
||||||
|
for (int index : indices) {
|
||||||
|
result.add(targetCoords.getCoordinate(index));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Polygon asLatLonGeometry(GeometryFactory gf) {
|
||||||
|
Coordinate[] coordinates = new Coordinate[indices.length + 1];
|
||||||
|
for (int i = 0; i < indices.length; i += 1) {
|
||||||
|
coordinates[i] = latLonCoords.getCoordinate(indices[i]);
|
||||||
|
}
|
||||||
|
coordinates[coordinates.length - 1] = coordinates[0];
|
||||||
|
return gf.createPolygon(gf.createLinearRing(coordinates), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coordinate getTargetCoord(int index) {
|
||||||
|
return targetCoords.getCoordinate(indices[index % indices.length]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int indexOfTarget(Coordinate c) {
|
||||||
|
for (int i = 0; i < targetCoords.size(); i += 1) {
|
||||||
|
if (targetCoords.getOrdinate(indices[i], 0) == c.x
|
||||||
|
&& targetCoords.getOrdinate(indices[i], 1) == c.y) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return indices.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to represent a Polygon with no holes. Additionally it
|
||||||
|
* provides fast method for merging a cell because it can safely assume that
|
||||||
|
* any points it shares with the cell are identical.
|
||||||
|
*/
|
||||||
|
private static final class SimplePolygon {
|
||||||
|
|
||||||
|
private List<Coordinate> coords;
|
||||||
|
|
||||||
|
public SimplePolygon(Cell cell) {
|
||||||
|
this.coords = cell.getTargetCoords();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean merge(Cell cell) {
|
||||||
|
List<Coordinate> toCheck = cell.getTargetCoords();
|
||||||
|
/*
|
||||||
|
* Walk coords in order, if any identical coords are found we can
|
||||||
|
* ceck nearby points to eliminate the duplicates
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < coords.size() - 1; i += 1) {
|
||||||
|
if (toCheck.remove(coords.get(i))) {
|
||||||
|
int lastFoundIndex = -1;
|
||||||
|
if (i == 0 && toCheck.remove(coords.get(coords.size() - 1))) {
|
||||||
|
/*
|
||||||
|
* For the 0 index the end of coords must be checked,
|
||||||
|
* all other indices do not need to check previous
|
||||||
|
* coords.
|
||||||
|
*/
|
||||||
|
while (toCheck.remove(coords.get(coords.size() - 2))) {
|
||||||
|
coords.remove(coords.size() - 1);
|
||||||
|
}
|
||||||
|
lastFoundIndex = 0;
|
||||||
|
} else if (i + 1 < coords.size()
|
||||||
|
&& toCheck.remove(coords.get(i + 1))) {
|
||||||
|
/* This check ensures 2 points match. */
|
||||||
|
lastFoundIndex = i + 1;
|
||||||
|
}
|
||||||
|
if (lastFoundIndex != -1) {
|
||||||
|
while (lastFoundIndex + 1 < coords.size()
|
||||||
|
&& toCheck.remove(coords
|
||||||
|
.get(lastFoundIndex + 1))) {
|
||||||
|
/*
|
||||||
|
* If more than two points match, remove the common
|
||||||
|
* interior points.
|
||||||
|
*/
|
||||||
|
coords.remove(lastFoundIndex);
|
||||||
|
}
|
||||||
|
if (!toCheck.isEmpty()) {
|
||||||
|
/*
|
||||||
|
* Add any exterior remaining points from the cell
|
||||||
|
* into this.
|
||||||
|
*/
|
||||||
|
int cellLastFoundIndex = cell.indexOfTarget(coords
|
||||||
|
.get(lastFoundIndex));
|
||||||
|
int prevIndex = cellLastFoundIndex + cell.size() - 1;
|
||||||
|
int nextIndex = cellLastFoundIndex + 1;
|
||||||
|
if (toCheck
|
||||||
|
.contains(cell.getTargetCoord(nextIndex))) {
|
||||||
|
coords.add(lastFoundIndex,
|
||||||
|
cell.getTargetCoord(nextIndex));
|
||||||
|
for (int j = nextIndex + 1; j < prevIndex; j += 1) {
|
||||||
|
Coordinate c = cell.getTargetCoord(j);
|
||||||
|
if (toCheck.contains(c)) {
|
||||||
|
coords.add(lastFoundIndex, c);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (toCheck.contains(cell
|
||||||
|
.getTargetCoord(prevIndex))) {
|
||||||
|
coords.add(lastFoundIndex,
|
||||||
|
cell.getTargetCoord(prevIndex));
|
||||||
|
for (int j = prevIndex - 1; j > nextIndex; j -= 1) {
|
||||||
|
Coordinate c = cell.getTargetCoord(j);
|
||||||
|
if (toCheck.contains(c)) {
|
||||||
|
coords.add(lastFoundIndex, c);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Polygon asGeometry(GeometryFactory gf) {
|
||||||
|
Coordinate[] coordinates = new Coordinate[this.coords.size() + 1];
|
||||||
|
this.coords.toArray(coordinates);
|
||||||
|
coordinates[coordinates.length - 1] = coordinates[0];
|
||||||
|
return gf.createPolygon(gf.createLinearRing(coordinates), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes an intersection {@link Geometry} between sourceEnvelope and
|
||||||
|
* targetEnvelope in targetEnvelope's CRS space. The resulting
|
||||||
|
* {@link Geometry} may contain multiple Geometries within it. But all
|
||||||
|
* geometries will be {@link Polygon}s
|
||||||
|
*
|
||||||
|
* @param sourceEnvelope
|
||||||
|
* @param targetEnvelope
|
||||||
|
* @param maxHorDivisions
|
||||||
|
* @param maxVertDivisions
|
||||||
|
* @return
|
||||||
|
* @throws FactoryException
|
||||||
|
* @throws TransformException
|
||||||
|
*/
|
||||||
|
public static Geometry createEnvelopeIntersection(Envelope sourceEnvelope,
|
||||||
|
Envelope targetEnvelope, int maxHorDivisions, int maxVertDivisions)
|
||||||
|
throws FactoryException, TransformException {
|
||||||
|
return new BruteForceEnvelopeIntersection(sourceEnvelope, targetEnvelope,
|
||||||
|
maxHorDivisions, maxVertDivisions).reproject();
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,8 +55,10 @@ import com.vividsolutions.jts.geom.Polygon;
|
||||||
* Sep 13, 2013 2309 bsteffen Corrected Lines that are extrapolated to
|
* Sep 13, 2013 2309 bsteffen Corrected Lines that are extrapolated to
|
||||||
* intersect the border will use projection
|
* intersect the border will use projection
|
||||||
* factor from all 4 corners instead of 3.
|
* factor from all 4 corners instead of 3.
|
||||||
* Oct 8, 2013 2104 mschenke Added case for where actual border is
|
* Oct 08, 2013 2104 mschenke Added case for where actual border is
|
||||||
* inside out by checking interior point
|
* inside out by checking interior point
|
||||||
|
* Nov 18, 2013 2528 bsteffen Fall back to brute force when corner
|
||||||
|
* points are not found.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -86,11 +88,30 @@ public class EnvelopeIntersection {
|
||||||
int maxVertDivisions) throws TransformException, FactoryException {
|
int maxVertDivisions) throws TransformException, FactoryException {
|
||||||
ReferencedEnvelope sourceREnvelope = reference(sourceEnvelope);
|
ReferencedEnvelope sourceREnvelope = reference(sourceEnvelope);
|
||||||
ReferencedEnvelope targetREnvelope = reference(targetEnvelope);
|
ReferencedEnvelope targetREnvelope = reference(targetEnvelope);
|
||||||
Geometry border = null;
|
|
||||||
WorldWrapCorrector corrector = new WorldWrapCorrector(targetREnvelope);
|
|
||||||
MathTransform sourceCRSToTargetCRS = CRS.findMathTransform(
|
MathTransform sourceCRSToTargetCRS = CRS.findMathTransform(
|
||||||
sourceREnvelope.getCoordinateReferenceSystem(),
|
sourceREnvelope.getCoordinateReferenceSystem(),
|
||||||
targetREnvelope.getCoordinateReferenceSystem());
|
targetREnvelope.getCoordinateReferenceSystem());
|
||||||
|
if (sourceCRSToTargetCRS.isIdentity()) {
|
||||||
|
com.vividsolutions.jts.geom.Envelope intersection = sourceREnvelope
|
||||||
|
.intersection(targetREnvelope);
|
||||||
|
if (intersection == null) {
|
||||||
|
return gf.createGeometryCollection(new Geometry[0]);
|
||||||
|
} else {
|
||||||
|
Coordinate[] border = new Coordinate[5];
|
||||||
|
border[0] = new Coordinate(intersection.getMinX(),
|
||||||
|
intersection.getMinY());
|
||||||
|
border[1] = new Coordinate(intersection.getMinX(),
|
||||||
|
intersection.getMaxY());
|
||||||
|
border[2] = new Coordinate(intersection.getMaxX(),
|
||||||
|
intersection.getMaxY());
|
||||||
|
border[3] = new Coordinate(intersection.getMaxX(),
|
||||||
|
intersection.getMinY());
|
||||||
|
border[4] = border[0];
|
||||||
|
return gf.createPolygon(gf.createLinearRing(border), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Geometry border = null;
|
||||||
|
WorldWrapCorrector corrector = new WorldWrapCorrector(targetREnvelope);
|
||||||
MathTransform targetCRSToSourceCRS = sourceCRSToTargetCRS.inverse();
|
MathTransform targetCRSToSourceCRS = sourceCRSToTargetCRS.inverse();
|
||||||
MathTransform targetCRSToLatLon = MapUtil
|
MathTransform targetCRSToLatLon = MapUtil
|
||||||
.getTransformToLatLon(targetREnvelope
|
.getTransformToLatLon(targetREnvelope
|
||||||
|
@ -136,6 +157,19 @@ public class EnvelopeIntersection {
|
||||||
new double[] { sourceREnvelope.getMinimum(0), midY }, null,
|
new double[] { sourceREnvelope.getMinimum(0), midY }, null,
|
||||||
sourceCRSToTargetCRS, true);
|
sourceCRSToTargetCRS, true);
|
||||||
|
|
||||||
|
if (UL == null || UR == null || LR == null || LL == null) {
|
||||||
|
/*
|
||||||
|
* If entire edges of the tile are invalid in target space then the
|
||||||
|
* algorithms below are not that good. For most cases they produce
|
||||||
|
* overly large polygons but there are cases where they completely
|
||||||
|
* miss intersections. For these cases the BruteForce method is
|
||||||
|
* worth the extra time to get a really accurate envelope.
|
||||||
|
*/
|
||||||
|
return BruteForceEnvelopeIntersection.createEnvelopeIntersection(
|
||||||
|
sourceEnvelope, targetEnvelope, maxHorDivisions,
|
||||||
|
maxVertDivisions);
|
||||||
|
}
|
||||||
|
|
||||||
List<Coordinate> borderPoints = new ArrayList<Coordinate>(
|
List<Coordinate> borderPoints = new ArrayList<Coordinate>(
|
||||||
maxVertDivisions * 2 + maxHorDivisions * 2);
|
maxVertDivisions * 2 + maxHorDivisions * 2);
|
||||||
double[] out = new double[2];
|
double[] out = new double[2];
|
||||||
|
@ -544,7 +578,9 @@ public class EnvelopeIntersection {
|
||||||
try {
|
try {
|
||||||
double[] tmp = new double[maxPoint.length];
|
double[] tmp = new double[maxPoint.length];
|
||||||
mt.transform(maxPoint, 0, tmp, 0, 1);
|
mt.transform(maxPoint, 0, tmp, 0, 1);
|
||||||
return maxPoint;
|
if (!Double.isNaN(tmp[0]) && !Double.isNaN(tmp[1])) {
|
||||||
|
return maxPoint;
|
||||||
|
}
|
||||||
} catch (TransformException e) {
|
} catch (TransformException e) {
|
||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
|
@ -553,13 +589,15 @@ public class EnvelopeIntersection {
|
||||||
try {
|
try {
|
||||||
double[] tmp = new double[point.length];
|
double[] tmp = new double[point.length];
|
||||||
mt.transform(point, 0, tmp, 0, 1);
|
mt.transform(point, 0, tmp, 0, 1);
|
||||||
// point is valid, keep looking
|
if (!Double.isNaN(tmp[0]) && !Double.isNaN(tmp[1])) {
|
||||||
double deltaX = (maxPoint[0] - point[0]) / 2.0;
|
// point is valid, keep looking
|
||||||
double deltaY = (maxPoint[1] - point[1]) / 2.0;
|
double deltaX = (maxPoint[0] - point[0]) / 2.0;
|
||||||
double[] newPoint = new double[] { point[0] + deltaX,
|
double deltaY = (maxPoint[1] - point[1]) / 2.0;
|
||||||
point[1] + deltaY };
|
double[] newPoint = new double[] { point[0] + deltaX,
|
||||||
return findNearestValidPoint(maxPoint, newPoint, point, mt,
|
point[1] + deltaY };
|
||||||
checkMax);
|
return findNearestValidPoint(maxPoint, newPoint, point, mt,
|
||||||
|
checkMax);
|
||||||
|
}
|
||||||
} catch (TransformException e) {
|
} catch (TransformException e) {
|
||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ import javax.measure.unit.Unit;
|
||||||
import org.apache.commons.lang.ArrayUtils;
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
|
|
||||||
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
||||||
|
import com.raytheon.uf.common.colormap.prefs.DataMappingPreferences;
|
||||||
|
import com.raytheon.uf.common.colormap.prefs.DataMappingPreferences.DataMappingEntry;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
@ -42,7 +44,6 @@ import com.raytheon.uf.common.style.level.RangeLevel;
|
||||||
import com.raytheon.uf.common.style.level.SingleLevel;
|
import com.raytheon.uf.common.style.level.SingleLevel;
|
||||||
import com.raytheon.uf.common.util.GridUtil;
|
import com.raytheon.uf.common.util.GridUtil;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ColorMapParameterFactory
|
* ColorMapParameterFactory
|
||||||
*
|
*
|
||||||
|
@ -53,10 +54,11 @@ import com.raytheon.uf.common.util.GridUtil;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Jul 25, 2007 chammack Initial Creation.
|
* Jul 25, 2007 chammack Initial Creation.
|
||||||
* Mar 26, 2009 2086 jsanchez Added a entityList to the match criteria.
|
* 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
|
* 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}
|
* 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
|
* 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
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author chammack
|
* @author chammack
|
||||||
|
@ -129,7 +131,17 @@ public class ColorMapParameterFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a record to convert units exists, use it
|
// If a record to convert units exists, use it
|
||||||
params.setDataUnit(parameterUnits);
|
Unit<?> colorMapUnit = null;
|
||||||
|
try {
|
||||||
|
colorMapUnit = preferences.getColorMapUnitsObject();
|
||||||
|
} catch (StyleException e) {
|
||||||
|
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||||
|
}
|
||||||
|
if (colorMapUnit == null) {
|
||||||
|
params.setColorMapUnit(parameterUnits);
|
||||||
|
} else {
|
||||||
|
params.setColorMapUnit(colorMapUnit);
|
||||||
|
}
|
||||||
params.setDisplayUnit(preferences.getDisplayUnits());
|
params.setDisplayUnit(preferences.getDisplayUnits());
|
||||||
params.setDataMapping(preferences.getDataMapping());
|
params.setDataMapping(preferences.getDataMapping());
|
||||||
|
|
||||||
|
@ -237,9 +249,10 @@ public class ColorMapParameterFactory {
|
||||||
.convert(colormapMax) : colormapMax;
|
.convert(colormapMax) : colormapMax;
|
||||||
|
|
||||||
if (preferences.getColorbarLabeling() != null) {
|
if (preferences.getColorbarLabeling() != null) {
|
||||||
extractLabelValues(sr, displayMax, displayMin, params);
|
extractLabelValues(preferences, displayMax, displayMin, params);
|
||||||
} else if (preferences.getDataMapping() == null) {
|
} else if (preferences.getDataMapping() == null) {
|
||||||
calculateLabelValues(sr, displayMax, displayMin, params);
|
calculateLabelValues(preferences, displayMax, displayMin,
|
||||||
|
params);
|
||||||
if (scale != null) {
|
if (scale != null) {
|
||||||
params.setMirror(scale.isMirror());
|
params.setMirror(scale.isMirror());
|
||||||
}
|
}
|
||||||
|
@ -325,8 +338,8 @@ public class ColorMapParameterFactory {
|
||||||
params.setColorMapMin((float) dataMin);
|
params.setColorMapMin((float) dataMin);
|
||||||
params.setDataMin((float) dataMin);
|
params.setDataMin((float) dataMin);
|
||||||
|
|
||||||
extractLabelValues(sr, (float) displayMax, (float) displayMin,
|
extractLabelValues(preferences, (float) displayMax,
|
||||||
params);
|
(float) displayMin, params);
|
||||||
params.setColorMapName(preferences.getDefaultColormap());
|
params.setColorMapName(preferences.getDefaultColormap());
|
||||||
}
|
}
|
||||||
if (preferences.getDataScale() != null) {
|
if (preferences.getDataScale() != null) {
|
||||||
|
@ -338,6 +351,154 @@ public class ColorMapParameterFactory {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the same thing as {@link #build(ImagePreferences, Unit)} but first
|
||||||
|
* unpacks the ImagePreference from a {@link StyleRule}.
|
||||||
|
*
|
||||||
|
* @param sr
|
||||||
|
* @param defaultColorMapUnit
|
||||||
|
* @return
|
||||||
|
* @throws StyleException
|
||||||
|
*/
|
||||||
|
public static ColorMapParameters build(StyleRule sr,
|
||||||
|
Unit<?> defaultColorMapUnit) throws StyleException {
|
||||||
|
if (sr == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"StyleRule must not be null when building ColorMapParameters");
|
||||||
|
}
|
||||||
|
if (sr.getPreferences() instanceof ImagePreferences == false) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"ImagePreferences are only supported for building ColorMapParameters");
|
||||||
|
}
|
||||||
|
return build((ImagePreferences) sr.getPreferences(),
|
||||||
|
defaultColorMapUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a {@link ColorMapParameters} given {@link ImagePreferences} and a
|
||||||
|
* unit to colormap in. This method provides for the simplest color mapping
|
||||||
|
* case. No data or level information is input so the
|
||||||
|
* {@link ImagePreferences} must specify an exact range or data mapping and
|
||||||
|
* also no lableing is added unless the colorbar labeling is specifically
|
||||||
|
* set in the style rule.
|
||||||
|
*
|
||||||
|
* @param preferences
|
||||||
|
* @param defaultColorMapUnit
|
||||||
|
* @return
|
||||||
|
* @throws StyleException
|
||||||
|
*/
|
||||||
|
public static ColorMapParameters build(ImagePreferences preferences,
|
||||||
|
Unit<?> defaultColorMapUnit) throws StyleException {
|
||||||
|
ColorMapParameters params = new ColorMapParameters();
|
||||||
|
|
||||||
|
Unit<?> colorMapUnit = preferences.getColorMapUnitsObject();
|
||||||
|
if (colorMapUnit == null) {
|
||||||
|
colorMapUnit = defaultColorMapUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Unit<?> displayUnit = preferences.getDisplayUnits();
|
||||||
|
if (displayUnit == null) {
|
||||||
|
displayUnit = colorMapUnit;
|
||||||
|
} else if (colorMapUnit == null) {
|
||||||
|
colorMapUnit = displayUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
params.setColorMapUnit(colorMapUnit);
|
||||||
|
params.setDisplayUnit(displayUnit);
|
||||||
|
params.setDataMapping(preferences.getDataMapping());
|
||||||
|
params.setColorMapName(preferences.getDefaultColormap());
|
||||||
|
|
||||||
|
Float displayMin = null, displayMax = null;
|
||||||
|
DataScale scale = preferences.getDataScale();
|
||||||
|
boolean mirrored = false;
|
||||||
|
Type scaleType = Type.LINEAR;
|
||||||
|
if (scale != null) {
|
||||||
|
if (scale.getMinValue() != null) {
|
||||||
|
displayMin = scale.getMinValue().floatValue();
|
||||||
|
}
|
||||||
|
if (scale.getMaxValue() != null) {
|
||||||
|
displayMax = scale.getMaxValue().floatValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
mirrored = scale.isMirror();
|
||||||
|
scaleType = scale.getScaleType();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayMin == null || displayMax == null) {
|
||||||
|
// Could not find min/max in DataScale, attempt to get from
|
||||||
|
// DataMappingPreferences if set
|
||||||
|
if (params.getDataMapping() != null) {
|
||||||
|
DataMappingPreferences mapping = params.getDataMapping();
|
||||||
|
List<DataMappingEntry> entries = mapping.getEntries();
|
||||||
|
if (entries != null && entries.isEmpty() == false) {
|
||||||
|
if (displayMin == null) {
|
||||||
|
DataMappingEntry min = entries.get(0);
|
||||||
|
if (min.getPixelValue() != null
|
||||||
|
&& min.getDisplayValue() != null) {
|
||||||
|
displayMin = min.getDisplayValue().floatValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (displayMax == null) {
|
||||||
|
DataMappingEntry max = entries.get(entries.size() - 1);
|
||||||
|
if (max.getPixelValue() != null
|
||||||
|
&& max.getDisplayValue() != null) {
|
||||||
|
displayMax = max.getDisplayValue().floatValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (mirrored && (displayMin != null || displayMax != null)) {
|
||||||
|
// Mirror value set
|
||||||
|
if (displayMin == null) {
|
||||||
|
displayMin = -displayMax;
|
||||||
|
} else {
|
||||||
|
displayMax = -displayMin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayMin == null || displayMax == null) {
|
||||||
|
throw new StyleException("Unable to determine colormap min/max.");
|
||||||
|
}
|
||||||
|
|
||||||
|
params.setMirror(mirrored);
|
||||||
|
params.setLogarithmic(scaleType == Type.LOG);
|
||||||
|
|
||||||
|
// Convert to colormap min/max
|
||||||
|
float colorMapMin = displayMin;
|
||||||
|
float colorMapMax = displayMax;
|
||||||
|
|
||||||
|
UnitConverter displayToColorMap = params
|
||||||
|
.getDisplayToColorMapConverter();
|
||||||
|
if (displayToColorMap != null) {
|
||||||
|
colorMapMin = (float) displayToColorMap.convert(displayMin);
|
||||||
|
colorMapMax = (float) displayToColorMap.convert(displayMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
params.setColorMapMin(colorMapMin);
|
||||||
|
params.setColorMapMax(colorMapMax);
|
||||||
|
|
||||||
|
LabelingPreferences labeling = preferences.getColorbarLabeling();
|
||||||
|
if (labeling != null) {
|
||||||
|
if (labeling.getValues() != null) {
|
||||||
|
params.setColorBarIntervals(labeling.getValues());
|
||||||
|
} else if (labeling.getIncrement() != 0) {
|
||||||
|
float increment = labeling.getIncrement();
|
||||||
|
float initialPoint = (float) (Math
|
||||||
|
.ceil(colorMapMin / increment) * increment);
|
||||||
|
float finalPoint = (float) (Math.floor(colorMapMin / increment) * increment);
|
||||||
|
int count = (int) ((finalPoint - initialPoint) / increment) + 1;
|
||||||
|
float[] vals = new float[count];
|
||||||
|
for (int i = 0; i < count; i += 1) {
|
||||||
|
vals[i] = initialPoint + increment * i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
private static Number[] repackData(Object data) {
|
private static Number[] repackData(Object data) {
|
||||||
Number[] numArray = null;
|
Number[] numArray = null;
|
||||||
if (data instanceof byte[]) {
|
if (data instanceof byte[]) {
|
||||||
|
@ -375,33 +536,27 @@ public class ColorMapParameterFactory {
|
||||||
return build(data, parameter, parameterUnits, level, null);
|
return build(data, parameter, parameterUnits, level, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void extractLabelValues(StyleRule sr, float max, float min,
|
private static void extractLabelValues(ImagePreferences preferences,
|
||||||
ColorMapParameters parameters) {
|
float max, float min, ColorMapParameters parameters) {
|
||||||
if (sr != null) {
|
if (preferences.getColorbarLabeling() != null) {
|
||||||
ImagePreferences preferences = (ImagePreferences) sr
|
DataScale dataScale = preferences.getDataScale();
|
||||||
.getPreferences();
|
if (dataScale != null && dataScale.isMirror()
|
||||||
if (preferences.getColorbarLabeling() != null) {
|
&& !dataScale.isAdaptive()
|
||||||
DataScale dataScale = preferences.getDataScale();
|
&& preferences.getColorbarLabeling().getValues() != null) {
|
||||||
if (dataScale != null
|
// if its mirror and not adaptive and the upper half labels
|
||||||
&& dataScale.isMirror()
|
// have been provided.
|
||||||
&& !dataScale.isAdaptive()
|
createMirror(preferences, parameters);
|
||||||
&& preferences.getColorbarLabeling().getValues() != null) {
|
parameters.setMirror(dataScale.isMirror());
|
||||||
// if its mirror and not adaptive and the upper half labels
|
} else if (preferences.getColorbarLabeling().getValues() != null) {
|
||||||
// have been provided.
|
// If a list is provided, use it
|
||||||
createMirror(preferences, parameters);
|
float[] vals = preferences.getColorbarLabeling().getValues();
|
||||||
parameters.setMirror(dataScale.isMirror());
|
|
||||||
} else if (preferences.getColorbarLabeling().getValues() != null) {
|
|
||||||
// If a list is provided, use it
|
|
||||||
float[] vals = preferences.getColorbarLabeling()
|
|
||||||
.getValues();
|
|
||||||
|
|
||||||
parameters.setColorBarIntervals(vals);
|
parameters.setColorBarIntervals(vals);
|
||||||
} else {
|
} else {
|
||||||
// Populate the list using min and max
|
// Populate the list using min and max
|
||||||
calculateLabelValues(sr, max, min, parameters);
|
calculateLabelValues(preferences, max, min, parameters);
|
||||||
if (dataScale != null) {
|
if (dataScale != null) {
|
||||||
parameters.setMirror(dataScale.isMirror());
|
parameters.setMirror(dataScale.isMirror());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -432,29 +587,23 @@ public class ColorMapParameterFactory {
|
||||||
/**
|
/**
|
||||||
* Derived from ImageDepictable.C::adaptGridImageStyle
|
* Derived from ImageDepictable.C::adaptGridImageStyle
|
||||||
*/
|
*/
|
||||||
private static void calculateLabelValues(StyleRule sr, float max,
|
private static void calculateLabelValues(ImagePreferences preferences,
|
||||||
float min, ColorMapParameters parameters) {
|
float max, float min, ColorMapParameters parameters) {
|
||||||
|
|
||||||
boolean haveIncrement = false;
|
boolean haveIncrement = false;
|
||||||
float increment = 0.1f;
|
float increment = 0.1f;
|
||||||
Type dataScaleType = Type.LINEAR;
|
Type dataScaleType = Type.LINEAR;
|
||||||
boolean isMirror = false;
|
boolean isMirror = false;
|
||||||
if (sr != null) {
|
LabelingPreferences prefs = preferences.getColorbarLabeling();
|
||||||
ImagePreferences preferences = (ImagePreferences) sr
|
if (prefs != null) {
|
||||||
.getPreferences();
|
increment = prefs.getIncrement();
|
||||||
if (preferences != null) {
|
haveIncrement = true;
|
||||||
LabelingPreferences prefs = preferences.getColorbarLabeling();
|
}
|
||||||
if (prefs != null) {
|
|
||||||
increment = prefs.getIncrement();
|
|
||||||
haveIncrement = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataScale dataScale = preferences.getDataScale();
|
DataScale dataScale = preferences.getDataScale();
|
||||||
if (dataScale != null) {
|
if (dataScale != null) {
|
||||||
dataScaleType = dataScale.getScaleType();
|
dataScaleType = dataScale.getScaleType();
|
||||||
isMirror = dataScale.isMirror();
|
isMirror = dataScale.isMirror();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (Math.abs(max - min) / increment > 16) {
|
if (Math.abs(max - min) / increment > 16) {
|
||||||
increment *= 2;
|
increment *= 2;
|
||||||
|
|
|
@ -20,6 +20,11 @@
|
||||||
|
|
||||||
package com.raytheon.uf.common.style.image;
|
package com.raytheon.uf.common.style.image;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.ParsePosition;
|
||||||
|
|
||||||
|
import javax.measure.unit.Unit;
|
||||||
|
import javax.measure.unit.UnitFormat;
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
@ -28,6 +33,7 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||||
import com.raytheon.uf.common.colormap.prefs.DataMappingPreferences;
|
import com.raytheon.uf.common.colormap.prefs.DataMappingPreferences;
|
||||||
import com.raytheon.uf.common.style.AbstractStylePreferences;
|
import com.raytheon.uf.common.style.AbstractStylePreferences;
|
||||||
import com.raytheon.uf.common.style.LabelingPreferences;
|
import com.raytheon.uf.common.style.LabelingPreferences;
|
||||||
|
import com.raytheon.uf.common.style.StyleException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -40,6 +46,7 @@ import com.raytheon.uf.common.style.LabelingPreferences;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Jul 27, 2007 chammack Initial Creation.
|
* Jul 27, 2007 chammack Initial Creation.
|
||||||
|
* Nov 25, 2013 2492 bsteffen Add colorMapUnits
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -62,15 +69,18 @@ public class ImagePreferences extends AbstractStylePreferences {
|
||||||
@XmlElement
|
@XmlElement
|
||||||
private SamplePreferences samplePrefs;
|
private SamplePreferences samplePrefs;
|
||||||
|
|
||||||
@XmlElement(name = "dataMapping")
|
@XmlElement
|
||||||
private DataMappingPreferences dataMapping;
|
private DataMappingPreferences dataMapping;
|
||||||
|
|
||||||
@XmlElement(name = "colorbarLabeling")
|
@XmlElement
|
||||||
private LabelingPreferences colorbarLabeling;
|
private LabelingPreferences colorbarLabeling;
|
||||||
|
|
||||||
@XmlElement(name = "interpolate")
|
@XmlElement
|
||||||
private boolean interpolate = true;
|
private boolean interpolate = true;
|
||||||
|
|
||||||
|
@XmlElement
|
||||||
|
private String colorMapUnits;
|
||||||
|
|
||||||
public boolean isInterpolate() {
|
public boolean isInterpolate() {
|
||||||
return interpolate;
|
return interpolate;
|
||||||
}
|
}
|
||||||
|
@ -154,4 +164,37 @@ public class ImagePreferences extends AbstractStylePreferences {
|
||||||
return legend;
|
return legend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return String representation of colorMapUnits for serialization.
|
||||||
|
* @see ImagePreferences#getColorMapUnitsObject()
|
||||||
|
*/
|
||||||
|
public String getColorMapUnits() {
|
||||||
|
return colorMapUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param colorMapUnits
|
||||||
|
* String representation of colorMapUnits for serialization.
|
||||||
|
* @see ImagePreferences#getColorMapUnitsObject()
|
||||||
|
*/
|
||||||
|
public void setColorMapUnits(String colorMapUnits) {
|
||||||
|
this.colorMapUnits = colorMapUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Units that should be used when color mapping. Mostly useful for cases
|
||||||
|
* where the colormap should be applied non linearly.
|
||||||
|
*/
|
||||||
|
public Unit<?> getColorMapUnitsObject() throws StyleException {
|
||||||
|
if (colorMapUnits != null && !colorMapUnits.isEmpty()) {
|
||||||
|
try {
|
||||||
|
return UnitFormat.getUCUMInstance().parseProductUnit(
|
||||||
|
colorMapUnits, new ParsePosition(0));
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new StyleException("Unable to parse colorMap Units.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,7 +266,7 @@ if [ "${1}" = "-full" ]; then
|
||||||
buildRPM "awips2-httpd-pypies"
|
buildRPM "awips2-httpd-pypies"
|
||||||
buildJava
|
buildJava
|
||||||
buildRPM "awips2-groovy"
|
buildRPM "awips2-groovy"
|
||||||
#buildRPM "awips2-ldm"
|
buildRPM "awips2-ldm"
|
||||||
buildRPM "awips2-postgres"
|
buildRPM "awips2-postgres"
|
||||||
buildRPM "awips2-pgadmin3"
|
buildRPM "awips2-pgadmin3"
|
||||||
buildRPM "awips2-tools"
|
buildRPM "awips2-tools"
|
||||||
|
|
|
@ -256,7 +256,7 @@ if [ "${1}" = "-delta" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "${1}" = "-full" ]; then
|
if [ "${1}" = "-full" ]; then
|
||||||
# buildRPM "awips2-common-base"
|
buildRPM "awips2-common-base"
|
||||||
buildCAVE
|
buildCAVE
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -277,7 +277,7 @@ if [ "${1}" = "-full" ]; then
|
||||||
buildRPM "awips2-python-pil"
|
buildRPM "awips2-python-pil"
|
||||||
buildRPM "awips2-python-pmw"
|
buildRPM "awips2-python-pmw"
|
||||||
buildRPM "awips2-python-pupynere"
|
buildRPM "awips2-python-pupynere"
|
||||||
# buildRPM "awips2-python-qpid"
|
buildRPM "awips2-python-qpid"
|
||||||
buildRPM "awips2-python-scientific"
|
buildRPM "awips2-python-scientific"
|
||||||
buildRPM "awips2-python-scipy"
|
buildRPM "awips2-python-scipy"
|
||||||
buildRPM "awips2-python-tables"
|
buildRPM "awips2-python-tables"
|
||||||
|
|
|
@ -19,17 +19,27 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.common.geospatial.util;
|
package com.raytheon.uf.common.geospatial.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.geotools.factory.FactoryIteratorProvider;
|
||||||
|
import org.geotools.factory.GeoTools;
|
||||||
import org.geotools.geometry.jts.JTS;
|
import org.geotools.geometry.jts.JTS;
|
||||||
import org.geotools.geometry.jts.ReferencedEnvelope;
|
import org.geotools.geometry.jts.ReferencedEnvelope;
|
||||||
|
import org.geotools.referencing.crs.DefaultProjectedCRS;
|
||||||
|
import org.geotools.referencing.operation.DefaultMathTransformFactory;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.opengis.geometry.Envelope;
|
import org.opengis.geometry.Envelope;
|
||||||
|
import org.opengis.parameter.ParameterValueGroup;
|
||||||
import org.opengis.referencing.FactoryException;
|
import org.opengis.referencing.FactoryException;
|
||||||
import org.opengis.referencing.crs.ProjectedCRS;
|
import org.opengis.referencing.crs.ProjectedCRS;
|
||||||
import org.opengis.referencing.operation.MathTransform;
|
import org.opengis.referencing.operation.MathTransform;
|
||||||
import org.opengis.referencing.operation.TransformException;
|
import org.opengis.referencing.operation.TransformException;
|
||||||
|
|
||||||
import com.raytheon.uf.common.geospatial.MapUtil;
|
import com.raytheon.uf.common.geospatial.MapUtil;
|
||||||
|
import com.raytheon.uf.common.geospatial.projection.Geostationary;
|
||||||
import com.vividsolutions.jts.geom.Coordinate;
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
import com.vividsolutions.jts.geom.CoordinateSequence;
|
import com.vividsolutions.jts.geom.CoordinateSequence;
|
||||||
import com.vividsolutions.jts.geom.Geometry;
|
import com.vividsolutions.jts.geom.Geometry;
|
||||||
|
@ -49,6 +59,7 @@ import com.vividsolutions.jts.simplify.TopologyPreservingSimplifier;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------- -------- ----------- --------------------------
|
* ------------- -------- ----------- --------------------------
|
||||||
* Sep 13, 2013 2309 bsteffen Initial creation
|
* Sep 13, 2013 2309 bsteffen Initial creation
|
||||||
|
* Nov 18, 2013 2528 bsteffen Add test for geostationary.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -94,6 +105,49 @@ public class EnvelopeIntersectionTest {
|
||||||
1.0324516833231976E7,
|
1.0324516833231976E7,
|
||||||
MapUtil.AWIPS_POLARSTEREO_NORTHAMERICA);
|
MapUtil.AWIPS_POLARSTEREO_NORTHAMERICA);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
GEOSTATIONARY {
|
||||||
|
public Envelope getEnvelope() {
|
||||||
|
try {
|
||||||
|
// Must manually register geostation
|
||||||
|
GeoTools.addFactoryIteratorProvider(new FactoryIteratorProvider() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> Iterator<T> iterator(Class<T> category) {
|
||||||
|
if (category
|
||||||
|
.isAssignableFrom(Geostationary.Provider.class)) {
|
||||||
|
List<T> tmp = new ArrayList<T>(1);
|
||||||
|
tmp.add(category
|
||||||
|
.cast(new Geostationary.Provider()));
|
||||||
|
return tmp.iterator();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ParameterValueGroup parameters = new DefaultMathTransformFactory()
|
||||||
|
.getDefaultParameters(Geostationary.PROJECTION_NAME);
|
||||||
|
|
||||||
|
parameters.parameter("semi_major").setValue(6378137.0);
|
||||||
|
parameters.parameter("semi_minor").setValue(6356732.31414);
|
||||||
|
parameters.parameter("latitude_of_origin").setValue(0.0);
|
||||||
|
parameters.parameter("central_meridian").setValue(-137);
|
||||||
|
parameters.parameter("false_easting").setValue(0);
|
||||||
|
parameters.parameter("false_northing").setValue(0);
|
||||||
|
parameters.parameter(Geostationary.ORBITAL_HEIGHT)
|
||||||
|
.setValue(35785863.0);
|
||||||
|
parameters.parameter(Geostationary.SWEEP_AXIS)
|
||||||
|
.setValue(0.0);
|
||||||
|
DefaultProjectedCRS crs = MapUtil.constructProjection(
|
||||||
|
Geostationary.PROJECTION_NAME, parameters);
|
||||||
|
return new ReferencedEnvelope(-5434870.792806381,
|
||||||
|
-2356713.972039082, -3799599.721331195,
|
||||||
|
-721442.9005638957, crs);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"Unable to create geostationary projection", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public abstract Envelope getEnvelope();
|
public abstract Envelope getEnvelope();
|
||||||
|
@ -107,6 +161,7 @@ public class EnvelopeIntersectionTest {
|
||||||
double threshold, int maxHorDivisions, int maxVertDivisions,
|
double threshold, int maxHorDivisions, int maxVertDivisions,
|
||||||
float[] expectedPolygonCoords) throws TransformException,
|
float[] expectedPolygonCoords) throws TransformException,
|
||||||
FactoryException {
|
FactoryException {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
Geometry testGeom = EnvelopeIntersection.createEnvelopeIntersection(
|
Geometry testGeom = EnvelopeIntersection.createEnvelopeIntersection(
|
||||||
source.getEnvelope(), target.getEnvelope(), threshold,
|
source.getEnvelope(), target.getEnvelope(), threshold,
|
||||||
maxHorDivisions, maxVertDivisions);
|
maxHorDivisions, maxVertDivisions);
|
||||||
|
@ -141,6 +196,10 @@ public class EnvelopeIntersectionTest {
|
||||||
// toKML(target.getEnvelope(), (Polygon) testGeom, expectedPolygon,
|
// toKML(target.getEnvelope(), (Polygon) testGeom, expectedPolygon,
|
||||||
// maxError);
|
// maxError);
|
||||||
|
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
System.out.println(source + " intersected with " + target + " took: "
|
||||||
|
+ (endTime - startTime) + "ms");
|
||||||
|
|
||||||
Assert.assertTrue(source + " intersected with " + target
|
Assert.assertTrue(source + " intersected with " + target
|
||||||
+ " is too large.",
|
+ " is too large.",
|
||||||
expectedPolygon.buffer(maxError).contains(testGeom));
|
expectedPolygon.buffer(maxError).contains(testGeom));
|
||||||
|
@ -237,6 +296,40 @@ public class EnvelopeIntersectionTest {
|
||||||
288, expected);
|
288, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void testGeostationaryToUkmet() throws TransformException,
|
||||||
|
FactoryException {
|
||||||
|
/* This was created using printSimplePolygon. */
|
||||||
|
float[] expected = { -803884, -836926, 5717769, -737647, 5605322,
|
||||||
|
-1820270, 5412823, -2767932, 5122653, -3661810, 4764378,
|
||||||
|
-4405659, 2533964, -4570863, -74925, -4826265, 141761,
|
||||||
|
-4699883, 265720, -4585495, 398396, -4374090, -401980,
|
||||||
|
-4451987, -214394, -4335532, -140376, -4231895, -111147,
|
||||||
|
-4039970, -191289, -3862333, -279094, -3778945, -431268,
|
||||||
|
-3701630, 203526, -3560640, 5468, -3401972, -348043, -3256781,
|
||||||
|
130869, -3136911, -224309, -2994515, -678028, -2942195, -31273,
|
||||||
|
-2816425, -277475, -2750530, 73248, -2647495, -149634,
|
||||||
|
-2580518, -547236, -2523641, -92802, -2417432, -447576,
|
||||||
|
-2357760, -82722, -2259030, -453907, -2199805, -112694,
|
||||||
|
-2104320, -555394, -2047966, -184709, -1952826, 22519,
|
||||||
|
-1866703, -312976, -1804583, -88257, -1718835, -567370,
|
||||||
|
-1661644, -78052, -1491513, -585469, -1433545, -305862,
|
||||||
|
-1348754, -19066, -1190667, -484493, -1128908, -299531,
|
||||||
|
-1049446, -76719, -896167, -803884, -836926, };
|
||||||
|
test(KNOWN_ENVELOPES.GEOSTATIONARY, KNOWN_ENVELOPES.UKMET,
|
||||||
|
19097.596365784917, 64, 49, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public final void testGeostationaryToGeostationary()
|
||||||
|
throws TransformException, FactoryException {
|
||||||
|
/* This was created using printSimplePolygon. */
|
||||||
|
float[] expected = { -5434871, -3799600, -5434871, -721443, -2356714,
|
||||||
|
-721443, -2356714, -3799600, -5434871, -3799600 };
|
||||||
|
test(KNOWN_ENVELOPES.GEOSTATIONARY, KNOWN_ENVELOPES.GEOSTATIONARY,
|
||||||
|
19097.596365784917, 64, 49, expected);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method can be used to assist in generating test cases. It starts
|
* This method can be used to assist in generating test cases. It starts
|
||||||
* with a known good result and minimizes the amount of text to put in the
|
* with a known good result and minimizes the amount of text to put in the
|
||||||
|
|
Loading…
Add table
Reference in a new issue