Merge "Issue #2492 Added getDataUnit to IColormappedImage and implementing classes. Deprecated dataUnit methods in ColorMapParameters. Fixed colormap slider to work with data and colormap units differing." into development

Former-commit-id: a349a980d3 [formerly a3fd84d9ef] [formerly 7dda17a660] [formerly a349a980d3 [formerly a3fd84d9ef] [formerly 7dda17a660] [formerly 05ee46c4bc [formerly 7dda17a660 [formerly 904a5e0c81912cb125abc71d1d5d9a5fdf4817ec]]]]
Former-commit-id: 05ee46c4bc
Former-commit-id: bdfe31ca9d [formerly 208cc6a534] [formerly bde810fa0fc654c54b6988c3f5dabe5ab75424e3 [formerly 64df0d8d8f]]
Former-commit-id: f5d0c26157b0203df59e509eceb3715e4f4503f8 [formerly 175cc8dd74]
Former-commit-id: 3ef3e4453d
This commit is contained in:
Nate Jensen 2013-11-11 14:05:11 -06:00 committed by Gerrit Code Review
commit 46fd118602
19 changed files with 610 additions and 427 deletions

View file

@ -19,8 +19,9 @@
**/ **/
package com.raytheon.uf.viz.core.drawables; package com.raytheon.uf.viz.core.drawables;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters; import javax.measure.unit.Unit;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
/** /**
* Describes a Colormapped Image * Describes a Colormapped Image
@ -64,4 +65,12 @@ public interface IColormappedImage extends IImage {
*/ */
public abstract double getValue(int x, int y); public abstract double getValue(int x, int y);
/**
* Get the unit associated with the data in the image. Values returned from
* {@link #getValue(int, int)} will be in this unit
*
* @return
*/
public abstract Unit<?> getDataUnit();
} }

View file

@ -21,6 +21,8 @@ package com.raytheon.uf.viz.core.drawables.ext.colormap;
import java.awt.image.RenderedImage; import java.awt.image.RenderedImage;
import javax.measure.unit.Unit;
import com.raytheon.uf.common.colormap.image.ColorMapData; import com.raytheon.uf.common.colormap.image.ColorMapData;
import com.raytheon.uf.common.colormap.image.Colormapper; import com.raytheon.uf.common.colormap.image.Colormapper;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters; import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
@ -59,6 +61,8 @@ public class ColormappedImage implements IColormappedImage,
private ColorMapParameters parameters; private ColorMapParameters parameters;
private Unit<?> dataUnit;
public ColormappedImage(IGraphicsTarget target, public ColormappedImage(IGraphicsTarget target,
IColorMapDataRetrievalCallback callback, IColorMapDataRetrievalCallback callback,
ColorMapParameters parameters) { ColorMapParameters parameters) {
@ -103,9 +107,7 @@ public class ColormappedImage implements IColormappedImage,
*/ */
@Override @Override
public void dispose() { public void dispose() {
if (image != null) { image.dispose();
image.dispose();
}
} }
/* /*
@ -209,11 +211,15 @@ public class ColormappedImage implements IColormappedImage,
*/ */
@Override @Override
public RenderedImage getImage() throws VizException { public RenderedImage getImage() throws VizException {
if (parameters == null || parameters.getColorMap() == null) { RenderedImage image = null;
return null; if (parameters != null && parameters.getColorMap() != null) {
ColorMapData colorMapData = callback.getColorMapData();
if (colorMapData != null) {
this.dataUnit = colorMapData.getDataUnit();
image = Colormapper.colorMap(colorMapData, parameters);
}
} }
ColorMapData colorMapData = callback.getColorMapData(); return image;
return Colormapper.colorMap(colorMapData, parameters);
} }
/* /*
@ -237,4 +243,15 @@ public class ColormappedImage implements IColormappedImage,
image.stage(); image.stage();
} }
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.IColormappedImage#getDataUnit()
*/
@Override
public Unit<?> getDataUnit() {
return dataUnit == null ? getColorMapParameters().getDataUnit()
: dataUnit;
}
} }

View file

@ -24,6 +24,8 @@ import java.nio.FloatBuffer;
import java.nio.IntBuffer; import java.nio.IntBuffer;
import java.nio.ShortBuffer; import java.nio.ShortBuffer;
import javax.measure.unit.Unit;
import org.geotools.coverage.grid.GridGeometry2D; import org.geotools.coverage.grid.GridGeometry2D;
import com.raytheon.uf.common.colormap.image.ColorMapData; import com.raytheon.uf.common.colormap.image.ColorMapData;
@ -64,6 +66,8 @@ public class KmlColormappedImage extends KmlImage implements IColormappedImage {
private ColorMapParameters colorMapParameters; private ColorMapParameters colorMapParameters;
private Unit<?> dataUnit;
public KmlColormappedImage(IColorMapDataRetrievalCallback dataCallback, public KmlColormappedImage(IColorMapDataRetrievalCallback dataCallback,
ColorMapParameters colorMapParameters) { ColorMapParameters colorMapParameters) {
this.dataCallback = dataCallback; this.dataCallback = dataCallback;
@ -72,6 +76,7 @@ public class KmlColormappedImage extends KmlImage implements IColormappedImage {
public DataSource getData(GridGeometry2D geometry) throws VizException { public DataSource getData(GridGeometry2D geometry) throws VizException {
ColorMapData data = dataCallback.getColorMapData(); ColorMapData data = dataCallback.getColorMapData();
this.dataUnit = data.getDataUnit();
switch (data.getDataType()) { switch (data.getDataType()) {
case FLOAT: case FLOAT:
return new FloatBufferWrapper(((FloatBuffer) data.getBuffer()), return new FloatBufferWrapper(((FloatBuffer) data.getBuffer()),
@ -122,4 +127,15 @@ public class KmlColormappedImage extends KmlImage implements IColormappedImage {
return 0; return 0;
} }
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.IColormappedImage#getDataUnit()
*/
@Override
public Unit<?> getDataUnit() {
return dataUnit == null ? getColorMapParameters().getDataUnit()
: dataUnit;
}
} }

View file

@ -21,6 +21,8 @@ package com.raytheon.uf.viz.kml.export.graphics.ext;
import java.util.Comparator; import java.util.Comparator;
import javax.measure.unit.Unit;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters; import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.viz.core.DrawableImage; import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.IExtent; import com.raytheon.uf.viz.core.IExtent;
@ -146,4 +148,14 @@ class KmlMosaicImage implements IMosaicImage {
this.imageExtent = imageExtent; this.imageExtent = imageExtent;
} }
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.IColormappedImage#getDataUnit()
*/
@Override
public Unit<?> getDataUnit() {
return getColorMapParameters().getColorMapUnit();
}
} }

View file

@ -10,12 +10,12 @@ Eclipse-BuddyPolicy: dependent
Require-Bundle: org.eclipse.ui, Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime, org.eclipse.core.runtime,
com.raytheon.uf.viz.core;bundle-version="1.12.1174", com.raytheon.uf.viz.core;bundle-version="1.12.1174",
org.geotools;bundle-version="2.6.4",
com.raytheon.uf.common.colormap;bundle-version="1.12.1174", com.raytheon.uf.common.colormap;bundle-version="1.12.1174",
com.raytheon.viz.ui;bundle-version="1.12.1174", com.raytheon.viz.ui;bundle-version="1.12.1174",
javax.vecmath;bundle-version="1.3.1",
com.raytheon.uf.common.util;bundle-version="1.12.1174", com.raytheon.uf.common.util;bundle-version="1.12.1174",
com.raytheon.uf.common.geospatial;bundle-version="1.12.1174" com.raytheon.uf.common.geospatial;bundle-version="1.12.1174",
javax.measure;bundle-version="1.0.0",
javax.vecmath;bundle-version="1.3.1"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy Bundle-ActivationPolicy: lazy
Export-Package: com.raytheon.uf.viz.remote.graphics, Export-Package: com.raytheon.uf.viz.remote.graphics,

View file

@ -19,6 +19,8 @@
**/ **/
package com.raytheon.uf.viz.remote.graphics.objects; package com.raytheon.uf.viz.remote.graphics.objects;
import javax.measure.unit.Unit;
import com.raytheon.uf.common.colormap.IColorMap; import com.raytheon.uf.common.colormap.IColorMap;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters; import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.common.colormap.prefs.IColorMapParametersListener; import com.raytheon.uf.common.colormap.prefs.IColorMapParametersListener;
@ -150,4 +152,14 @@ public class DispatchingColormappedImage<T extends IColormappedImage> extends
} }
} }
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.IColormappedImage#getDataUnit()
*/
@Override
public Unit<?> getDataUnit() {
return wrappedObject.getDataUnit();
}
} }

View file

@ -52,7 +52,8 @@ import com.raytheon.viz.core.gl.images.AbstractGLImage;
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Aug 6, 2012 mschenke Initial creation * Aug 6, 2012 mschenke Initial creation
* Nov 4, 2013 2492 mschenke Reworked to use GLSL Data mapping
* *
* </pre> * </pre>
* *

View file

@ -161,69 +161,111 @@ float getLinearIndex(float cmapValue, float cmapMin, float cmapMax) {
return capIndex(index); return capIndex(index);
} }
/**
* Converts a colormap value to a log index
*/
float valueToLogIndex(float value, float rangeMin, float rangeMax) {
// Account for 0 min index
if (rangeMin == 0) {
rangeMin = 0.0000001;
if (rangeMax < 0) {
rangeMin = -rangeMin;
}
}
int reverse = 0;
if ((value < rangeMin && rangeMin > 0)
|| (value > rangeMin && rangeMin < 0)) {
reverse = 1;
}
value = abs(value);
rangeMin = abs(rangeMin);
rangeMax = abs(rangeMax);
// Check uncomputable index value, everything between this range is 0,
// rangeMin->rangeMax 0 -> 1, -rangeMin->-rangeMax 0 -> -1
if (value <= rangeMin && value >= -rangeMin) {
return 0;
}
double index = (log(value) - log(rangeMin))
/ (log(rangeMax) - log(rangeMin));
if (reverse != 0) {
index = -index;
}
return index;
}
/** /**
* This function logarithmically finds the index for the cmapValue into * This function logarithmically finds the index for the cmapValue into
* cmapMin/cmapMax (capped at 0-1). * cmapMin/cmapMax (capped at 0-1).
*/ */
float getLogIndex(float cmapValue, float cmapMin, float cmapMax, int mirror) { float getLogIndex(float cmapValue, float cmapMin, float cmapMax, int mirror) {
int inverted = 0;
float rangeMin = abs(cmapMin);
float rangeMax = abs(cmapMax);
float rangeValue = abs(cmapValue);
if (rangeMin > rangeMax) {
// Inverted colormapping range (cmapMax is closest to 0)
inverted = 1;
float tmp = rangeMin;
rangeMin = rangeMax;
rangeMax = tmp;
}
float index = 0.0; float index = 0.0;
// is this strictly negative, strictly positive or neg to pos scaling? // Flag if min/max values are on opposite sides of zero
if (cmapMin >= 0.0 && cmapMax >= 0.0 && mirror != 1) { int minMaxOpposite = 0;
if (cmapValue < cmapMin) { if ((cmapMin < 0 && cmapMax > 0) || (cmapMin > 0 && cmapMax < 0)) {
index = 0.0; minMaxOpposite = 1;
} else { }
// simple calculation
index = ((log(cmapValue) - log(cmapMin)) if (mirror != 0 || minMaxOpposite != 0) {
/ abs(log(cmapMax) - log(cmapMin))); if (cmapMax < 0) {
// Invert colormapping if negative range was given
cmapValue = -cmapValue;
} }
} else if (cmapMin <= 0.0 && cmapMax <= 0.0 && mirror != 1) { // Log scaling is happening on both sides of zero, need to compute
index = ((log(cmapValue) - log(cmapMax)) // our zero index value
/ abs(log(cmapMin) - log(cmapMax))); float zeroVal = rangeMin;
} else { if (minMaxOpposite == 1) {
// special case, neg to pos: // Min/Max are on opposite sides of zero, compute a zero value
float colorMapMin = cmapMin; zeroVal = max(rangeMin, rangeMax) * 0.0001;
float colorMapMax = cmapMax;
float zeroVal = max(colorMapMax, abs(colorMapMin)) * 0.0001;
if (mirror == 1 && (colorMapMin > 0.0 || colorMapMax < 0.0)) {
if (colorMapMax < 0.0) {
colorMapMax = -cmapMax;
cmapValue = -cmapValue;
zeroVal = -colorMapMin;
} else {
zeroVal = cmapMin;
}
colorMapMin = -cmapMax;
} }
float leftZero = 0.0;
float rightZero = 0.0; float negCmapMax = rangeMin;
float posCmapMax = rangeMax;
if (mirror != 0) {
negCmapMax = posCmapMax = rangeMax;
}
// Compute log zero val and log neg/pos max vals
float absLogZeroVal = abs(log(zeroVal)); float absLogZeroVal = abs(log(zeroVal));
float logNegCmapMax = absLogZeroVal + log(negCmapMax);
rightZero = absLogZeroVal + log(colorMapMax); float logPosCmapMax = absLogZeroVal + log(posCmapMax);
// Calculate index which zeroVal is at based on neg max and pos max
float cmapMax2 = abs(colorMapMin); float zeroValIndex = logNegCmapMax / (logNegCmapMax + logPosCmapMax);
if (cmapValue > 0) {
leftZero = absLogZeroVal + log(cmapMax2); index = valueToLogIndex(rangeValue, zeroVal, posCmapMax);
index = zeroValIndex + (1 - zeroValIndex) * index;
float zeroIndex = leftZero / (leftZero + rightZero);
// figure out index for texture val
float absTextureColor = abs(cmapValue);
if (absTextureColor <= zeroVal) {
index = zeroIndex;
} else if (cmapValue > 0.0) {
// positive texture color value, find index from 0 to
// cmapMax:
float logTexColor = absLogZeroVal + log(cmapValue);
float texIndex = logTexColor / rightZero;
index = (zeroIndex + ((1.0 - zeroIndex) * texIndex));
} else { } else {
// negative texture color value, find index from 0 to index = valueToLogIndex(rangeValue, zeroVal, negCmapMax);
// cmapMax: index = zeroValIndex - zeroValIndex * index;
float logTexColor = absLogZeroVal + log(absTextureColor); }
if (inverted != 0) {
float texIndex = logTexColor / leftZero; index = 1.0 - index;
index = (zeroIndex - (zeroIndex * texIndex)); }
} else {
// Simple case, just use log converter to get index
index = valueToLogIndex(rangeValue, rangeMin, rangeMax);
if (inverted == 1) {
index = 1.0 - index;
}
if (cmapMin > 0 && cmapValue < rangeMin
|| (cmapMin < 0 && cmapValue > -rangeMin)) {
index = -index;
} }
} }
return capIndex(index); return capIndex(index);

View file

@ -256,6 +256,10 @@ public class GLDataMappingFactory {
float currDelta = (float) (currEndValue - dataMapping[0]); float currDelta = (float) (currEndValue - dataMapping[0]);
for (int i = 2; i < dataMapping.length; ++i) { for (int i = 2; i < dataMapping.length; ++i) {
double nextValue = dataMapping[i]; double nextValue = dataMapping[i];
// Deltas are compared in float space because it
// minimizes the precision errors and the mapping will
// occur in floats in GLSL so no need for the extra
// precision
float nextDelta = (float) ((nextValue - currEndValue) / (i - currEndIndex)); float nextDelta = (float) ((nextValue - currEndValue) / (i - currEndIndex));
if (nextDelta == currDelta) { if (nextDelta == currDelta) {
// Remove linear entries // Remove linear entries

View file

@ -27,7 +27,8 @@ import com.raytheon.viz.core.gl.glsl.GLShaderProgram;
import com.raytheon.viz.core.gl.images.AbstractGLImage; import com.raytheon.viz.core.gl.images.AbstractGLImage;
/** /**
* TODO Add Description * Default GL imaging extension. Renders RGB images in GL applying alpha,
* brightness, and contrast settings.
* *
* <pre> * <pre>
* *

View file

@ -23,7 +23,7 @@ import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.viz.core.gl.dataformat.AbstractGLColorMapDataFormat; import com.raytheon.viz.core.gl.dataformat.AbstractGLColorMapDataFormat;
/** /**
* Factory for creating GLSL struct mappings * Factory for creating API defined GLSL structs in a {@link GLShaderProgram}.
* *
* <pre> * <pre>
* *

View file

@ -39,7 +39,8 @@ import com.sun.opengl.util.texture.TextureCoords;
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Oct 16, 2013 2333 mschenke Initial creation * Oct 16, 2013 2333 mschenke Initial creation
* Nov 4, 2013 2492 mschenke Reworked to use GLSL Data mapping
* *
* </pre> * </pre>
* *

View file

@ -19,6 +19,7 @@
**/ **/
package com.raytheon.viz.core.gl.images; package com.raytheon.viz.core.gl.images;
import javax.measure.unit.Unit;
import javax.media.opengl.GL; import javax.media.opengl.GL;
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType; import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
@ -102,4 +103,12 @@ public class GLColormappedImage extends AbstractGLColormappedImage {
super.usaAsFrameBuffer(); super.usaAsFrameBuffer();
} }
@Override
public Unit<?> getDataUnit() {
if (data != null && data.getDataUnit() != null) {
return data.getDataUnit();
}
return getColorMapParameters().getDataUnit();
}
} }

View file

@ -19,6 +19,8 @@
**/ **/
package com.raytheon.viz.core.gl.images; package com.raytheon.viz.core.gl.images;
import javax.measure.unit.Unit;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters; import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension; import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
import com.raytheon.viz.core.gl.dataformat.GLColorMapData; import com.raytheon.viz.core.gl.dataformat.GLColorMapData;
@ -66,4 +68,9 @@ public class GLOffscreenColormappedImage extends AbstractGLColormappedImage {
return Double.NaN; return Double.NaN;
} }
@Override
public Unit<?> getDataUnit() {
return getColorMapParameters().getColorMapUnit();
}
} }

View file

@ -19,6 +19,8 @@
**/ **/
package com.raytheon.viz.core.gl.internal.ext.mosaic; package com.raytheon.viz.core.gl.internal.ext.mosaic;
import javax.measure.unit.Unit;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters; import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.viz.core.DrawableImage; import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.IExtent; import com.raytheon.uf.viz.core.IExtent;
@ -172,4 +174,14 @@ public class GLMosaicImage extends GLDelegateImage<GLOffscreenColormappedImage>
this.image = wrappedImage; this.image = wrappedImage;
} }
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.IColormappedImage#getDataUnit()
*/
@Override
public Unit<?> getDataUnit() {
return image.getDataUnit();
}
} }

View file

@ -21,12 +21,12 @@ package com.raytheon.viz.ui.dialogs;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import javax.measure.converter.ConversionException;
import javax.measure.converter.UnitConverter; import javax.measure.converter.UnitConverter;
import javax.measure.unit.Unit;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridData;
@ -36,11 +36,9 @@ import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Scale; import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Text;
import com.raytheon.uf.common.colormap.image.Colormapper;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters; import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.colormap.prefs.DataMappingPreferences.DataMappingEntry;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.viz.ui.dialogs.colordialog.ColorUtil;
/** /**
* Composite for slider bars for ColorMapParameters * Composite for slider bars for ColorMapParameters
@ -51,7 +49,9 @@ import com.raytheon.viz.ui.dialogs.colordialog.ColorUtil;
* *
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* Jan 3, 2012 mschenke Initial creation * Jan 3, 2012 mschenke Initial creation
* Nov 8, 2013 2492 mschenke Rewritten to work with colormap
* units different from data units
* *
* </pre> * </pre>
* *
@ -61,8 +61,13 @@ import com.raytheon.viz.ui.dialogs.colordialog.ColorUtil;
public class ColorMapSliderComp extends Composite { public class ColorMapSliderComp extends Composite {
private static final transient IUFStatusHandler statusHandler = UFStatus private static final String NaN_STRING = "NO DATA";
.getHandler(ColorMapSliderComp.class);
private static final int SLIDER_MIN = 0;
private static final int SLIDER_MAX = 255;
private static final int SLIDER_INC = 1;
private ColorMapParameters cmap; private ColorMapParameters cmap;
@ -74,25 +79,25 @@ public class ColorMapSliderComp extends Composite {
private Text maxValueText; private Text maxValueText;
private String[] sliderText; private final float cmapAbsoluteMin;
private float cmapMin; private final float cmapAbsoluteMax;
private float cmapMax; private final float origCmapMin;
private float cmapWidth; private final float origCmapMax;
private float cmapIncrement; private float currentCmapMin;
private DecimalFormat format = null; private float currentCmapMax;
private float currentMin; private final DecimalFormat format;
private float currentMax; private final boolean dataInverted;
private float origCmapMin; private UnitConverter displayToColorMap;
private float origCmapMax; private UnitConverter colorMapToDisplay;
/** /**
* @param parent * @param parent
@ -101,8 +106,46 @@ 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.origCmapMin = cmap.getColorMapMin(); this.currentCmapMin = this.origCmapMin = cmap.getColorMapMin();
this.origCmapMax = cmap.getColorMapMax(); this.currentCmapMax = this.origCmapMax = cmap.getColorMapMax();
this.displayToColorMap = cmap.getDisplayToColorMapConverter();
this.colorMapToDisplay = cmap.getColorMapToDisplayConverter();
if (displayToColorMap == null) {
displayToColorMap = Unit.ONE.getConverterTo(Unit.ONE);
}
if (colorMapToDisplay == null) {
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;
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();
initializeComponents(); initializeComponents();
} }
@ -115,16 +158,15 @@ public class ColorMapSliderComp extends Composite {
* *
*/ */
private void initializeComponents() { private void initializeComponents() {
buildColorMapData();
setLayout(new GridLayout(3, false)); setLayout(new GridLayout(3, false));
Label maxLabel = new Label(this, SWT.None); Label maxLabel = new Label(this, SWT.None);
maxLabel.setText("Max:"); maxLabel.setText("Max:");
maxSlider = new Scale(this, SWT.HORIZONTAL); maxSlider = new Scale(this, SWT.HORIZONTAL);
maxSlider.setMaximum(255); maxSlider.setMaximum(SLIDER_MAX);
maxSlider.setMinimum(0); maxSlider.setMinimum(SLIDER_MIN);
maxSlider.setIncrement(1); maxSlider.setIncrement(SLIDER_INC);
maxSlider.setSelection(maxSlider.getMaximum()); maxSlider.setSelection(maxSlider.getMaximum());
GridData layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false); GridData layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
layoutData.minimumWidth = 250; layoutData.minimumWidth = 250;
@ -142,9 +184,9 @@ public class ColorMapSliderComp extends Composite {
minLabel.setText("Min:"); minLabel.setText("Min:");
minSlider = new Scale(this, SWT.HORIZONTAL); minSlider = new Scale(this, SWT.HORIZONTAL);
minSlider.setMaximum(255); minSlider.setMaximum(SLIDER_MAX);
minSlider.setMinimum(0); minSlider.setMinimum(SLIDER_MIN);
minSlider.setIncrement(1); minSlider.setIncrement(SLIDER_INC);
minSlider.setSelection(minSlider.getMinimum()); minSlider.setSelection(minSlider.getMinimum());
layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false); layoutData = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
layoutData.minimumWidth = 250; layoutData.minimumWidth = 250;
@ -156,286 +198,186 @@ public class ColorMapSliderComp extends Composite {
minValueText.setLayoutData(labelLayoutData); minValueText.setLayoutData(labelLayoutData);
maxSlider.addSelectionListener(new SelectionAdapter() { maxSlider.addSelectionListener(new SelectionAdapter() {
@Override @Override
public void widgetSelected(SelectionEvent e) { public void widgetSelected(SelectionEvent e) {
if (maxSlider.getSelection() <= minSlider.getSelection()) { setColorMapMax(selectionToColorMapValue(maxSlider
maxSlider.setSelection(minSlider.getSelection() + 1); .getSelection()));
}
maxValueText.setText(selectionToText(maxSlider.getSelection()));
changeMax(maxSlider.getSelection());
} }
}); });
minSlider.addSelectionListener(new SelectionAdapter() { minSlider.addSelectionListener(new SelectionAdapter() {
@Override @Override
public void widgetSelected(SelectionEvent e) { public void widgetSelected(SelectionEvent e) {
if (minSlider.getSelection() >= maxSlider.getSelection()) { setColorMapMin(selectionToColorMapValue(minSlider
minSlider.setSelection(maxSlider.getSelection() - 1); .getSelection()));
}
minValueText.setText(selectionToText(minSlider.getSelection()));
changeMin(minSlider.getSelection());
} }
}); });
maxValueText.addKeyListener(new KeyListener() { maxValueText.addKeyListener(new KeyAdapter() {
@Override @Override
public void keyPressed(KeyEvent e) { public void keyPressed(KeyEvent e) {
if (e.character == SWT.CR) { if (e.character == SWT.CR) {
maxTextChanged(); setColorMapMax(textToColorMapValue(maxValueText.getText()
.trim()));
} }
} }
@Override
public void keyReleased(KeyEvent e) {
// do nothing
}
}); });
minValueText.addKeyListener(new KeyListener() { minValueText.addKeyListener(new KeyAdapter() {
@Override @Override
public void keyPressed(KeyEvent e) { public void keyPressed(KeyEvent e) {
if (e.character == SWT.CR) { if (e.character == SWT.CR) {
minTextChanged(); setColorMapMin(textToColorMapValue(minValueText.getText()
.trim()));
} }
} }
@Override
public void keyReleased(KeyEvent e) {
// do nothing
}
}); });
// set initial values setColorMapMin(currentCmapMin);
currentMax = cmap.getColorMapMax(); setColorMapMax(currentCmapMax);
currentMin = cmap.getColorMapMin();
maxSlider.setSelection(cmapToSelection(currentMax));
minSlider.setSelection(cmapToSelection(currentMin));
setMaxText();
setMinText();
} }
private void setMaxText() { /**
maxValueText.setText(cmapToText(currentMax)); * Converts a slider selection index to a colormap value
} *
* @param selection
private void setMinText() { * @return
minValueText.setText(cmapToText(currentMin)); */
} private float selectionToColorMapValue(int selection) {
double indexValue = Colormapper.getLinearIndex(selection, SLIDER_MIN,
private void setColorMapMax(float f) { SLIDER_MAX);
if (currentMax != f) { if (dataInverted) {
currentMax = f; indexValue = 1 - indexValue;
cmap.setColorMapMax(f, true);
} }
double colorMapValue = cmapAbsoluteMin
+ (cmapAbsoluteMax - cmapAbsoluteMin) * indexValue;
return (float) colorMapValue;
} }
private void setColorMapMin(float f) { /**
if (currentMin != f) { * Converts a colormap value to a slider selection index
currentMin = f; *
cmap.setColorMapMin(f, true); * @param colorMapValue
* @return
*/
private int colorMapValueToSelection(float colorMapValue) {
double indexValue = Colormapper.getLinearIndex(colorMapValue,
cmapAbsoluteMin, cmapAbsoluteMax);
if (dataInverted) {
indexValue = 1 - indexValue;
} }
return (int) (SLIDER_MIN + (SLIDER_MAX - SLIDER_MIN) * indexValue);
} }
private void minTextChanged() { /**
String text = minValueText.getText().trim().split(" ")[0]; * Converts a text string to a colormap value
try { *
float f = Float.valueOf(text); * @param text
UnitConverter unitConv = cmap.getImageToDisplayConverter(); * @return
if (unitConv != null) { */
f = (float) unitConv.inverse().convert(f); private float textToColorMapValue(String text) {
} if (cmap.getDataMapping() != null && text.isEmpty() == false) {
if (f >= currentMax) { // First check for data mapping entries
setMinText(); for (DataMappingEntry entry : cmap.getDataMapping().getEntries()) {
statusHandler.handle(Priority.ERROR, if (entry.getLabel() != null && text.equals(entry.getLabel())) {
"Minimum of colormap range cannot exceed the maximum."); return entry.getPixelValue().floatValue();
} else if (cmapMin >= f) { }
setColorMapMin(cmapMin);
minSlider.setSelection(0);
setMinText();
} else {
setColorMapMin(f);
minSlider.setSelection(cmapToSelection(f));
}
} catch (NumberFormatException ex) {
statusHandler.handle(Priority.ERROR,
"Minimum of colormap range cannot be parsed: " + text);
setMinText();
} catch (ConversionException ex) {
statusHandler.handle(Priority.ERROR, "Unit converter error.", ex);
setMinText();
}
}
private void maxTextChanged() {
String text = maxValueText.getText().trim().split(" ")[0];
try {
float f = Float.valueOf(text);
UnitConverter unitConv = cmap.getImageToDisplayConverter();
if (unitConv != null) {
f = (float) unitConv.inverse().convert(f);
}
if (currentMin >= f) {
statusHandler
.handle(Priority.ERROR,
"Maximum of colormap range cannot be below the minimum.");
setMaxText();
} else if (f >= cmapMax) {
setColorMapMax(cmapMax);
maxSlider.setSelection(255);
setMaxText();
} else {
setColorMapMax(f);
maxSlider.setSelection(cmapToSelection(f));
}
} catch (NumberFormatException ex) {
statusHandler.handle(Priority.ERROR,
"Maximum of colormap range cannot be parsed: " + text);
setMaxText();
} catch (ConversionException ex) {
statusHandler.handle(Priority.ERROR, "Unit converter error.", ex);
setMaxText();
}
}
private void changeMax(int position) {
// slider min and max is based on the color map, so position is the new
// color map max
currentMax = selectionToCmap(position);
cmap.setColorMapMax(currentMax, true);
}
private void changeMin(int position) {
// slider min and max is based on the color map, so position is the new
// color map min
currentMin = selectionToCmap(position);
cmap.setColorMapMin(currentMin, true);
}
private String cmapToText(double value) {
UnitConverter unitConv = cmap.getImageToDisplayConverter();
String textStr = "";
if (unitConv != null) {
value = unitConv.convert(value);
if (((Double) value).isNaN()) {
textStr = "NO DATA";
} }
} }
if (NaN_STRING.equals(text)) {
String txt; // If special NaN String, try to find first NaN value
if (textStr.length() == 0) { for (int i = SLIDER_MIN; i < SLIDER_MAX; i += SLIDER_INC) {
txt = format.format(value); float colorMapValue = selectionToColorMapValue(i);
if (Double.isNaN(colorMapToDisplay.convert(colorMapValue))) {
return colorMapValue;
}
}
} else { } else {
txt = textStr; // Attempt to parse and convert
} try {
float displayValue = Float.parseFloat(text);
return txt; return (float) displayToColorMap.convert(displayValue);
} } catch (Throwable t) {
// Ignore, NaN will be returned and text will be reverted
private String selectionToText(int selection) {
String rval = "ERR";
if (selection > -1 && selection < sliderText.length) {
// exact match into sliderText array
rval = sliderText[selection];
} else {
statusHandler.handle(Priority.CRITICAL, "index " + selection
+ " out of range, max " + (sliderText.length - 1));
}
return rval;
}
private float selectionToCmap(int selection) {
float percentOffset = selection / 255.0f;
float value = percentOffset * cmapWidth + cmapMin;
return value;
}
private int cmapToSelection(float value) {
int selection = (int) ((value - cmapMin) * 255.0f / cmapWidth);
return selection;
}
// modified from logic in ColorBar.java
private void buildColorMapData() {
sliderText = new String[256];
cmapWidth = cmap.getDataMax() - cmap.getDataMin();
cmapIncrement = cmapWidth / ColorUtil.MAX_VALUE;
cmapMin = cmap.getDataMin();
cmapMax = cmap.getDataMax();
float start = cmap.getDataMin();
String units = "";
UnitConverter unitConv = cmap.getImageToDisplayConverter();
Double lastVal = Double.NaN;
// TODO: Handle piecewise pixel converts to show ranges (for radar)
for (int i = 0; i < sliderText.length; ++i) {
double value = start;
// handle precision errors
if (value > cmapMax) {
// if the difference is .1 the increment between steps assume
// that cmapMax is ok
if ((value - cmapMax) < (.1 * cmapIncrement)) {
value = cmapMax;
}
} }
}
return Float.NaN;
}
String textStr = ""; /**
* Converts a colormap value into a text display string
if (cmap.isLogarithmic()) { *
// TODO: Handle case where min/max go from neg to pos * @param colorMapValue
if (cmap.getColorMapMax() >= 0 && cmap.getColorMapMin() >= 0) { * @return
double index = (i) / ColorUtil.MAX_VALUE; */
value = Math.pow(Math.E, private String colorMapValueToText(float colorMapValue) {
(Math.log(cmap.getColorMapMin()) + (index * (Math String text = null;
.log(cmap.getColorMapMax()) - Math.log(cmap if (cmap.getDataMapping() != null) {
.getColorMapMin()))))); text = cmap.getDataMapping().getLabelValueForDataValue(
} colorMapValue);
if (format == null) { }
format = new DecimalFormat("0.000"); if (text == null || text.trim().isEmpty()) {
} float displayValue = (float) colorMapToDisplay
} .convert(colorMapValue);
if (Float.isNaN(displayValue) == false) {
if (unitConv != null) { text = format.format(displayValue);
value = unitConv.convert(value); } else {
text = NaN_STRING;
/* int selection = colorMapValueToSelection(colorMapValue);
* Check if the last value is non a number. for (int i = selection; i >= SLIDER_MIN; i -= SLIDER_INC) {
*/ displayValue = (float) colorMapToDisplay
if (lastVal.isNaN()) { .convert(selectionToColorMapValue(i));
// If value is not a number then set the text to if (Float.isNaN(displayValue) == false) {
// "NO DATA". text = "> " + format.format(displayValue);
if (((Double) value).isNaN()) { break;
textStr = "NO DATA";
}
lastVal = value;
} else {
// If value is not a number then prepend ">"
// to the value.
if (((Double) value).isNaN()) {
textStr = "> " + lastVal;
} else {
lastVal = value;
} }
} }
} }
}
return text;
}
/**
* Sets the colormap min value, updates the text and slider
*
* @param colorMapMin
*/
private void setColorMapMin(float colorMapMin) {
if (Float.isNaN(colorMapMin) == false) {
currentCmapMin = colorMapMin;
}
minSlider.setSelection(colorMapValueToSelection(currentCmapMin));
minValueText.setText(colorMapValueToText(currentCmapMin));
cmap.setColorMapMin(currentCmapMin, true);
}
/**
* Sets the colormap max value, updates the text and slider
*
* @param colorMapMax
*/
private void setColorMapMax(float colorMapMax) {
if (Float.isNaN(colorMapMax) == false) {
currentCmapMax = colorMapMax;
}
maxSlider.setSelection(colorMapValueToSelection(currentCmapMax));
maxValueText.setText(colorMapValueToText(currentCmapMax));
cmap.setColorMapMax(currentCmapMax, true);
}
private DecimalFormat getTextFormat() {
if (cmap.isLogarithmic() == false) {
for (int i = SLIDER_MIN; i < SLIDER_MAX; ++i) {
double cmapValue = selectionToColorMapValue(i);
double displayValue = colorMapToDisplay.convert(cmapValue);
if (Double.isNaN(displayValue)) {
continue;
}
if (format == null && new Double(value).isNaN() == false) {
int zeros = 0; int zeros = 0;
String val = "" + value; String val = "" + displayValue;
char[] vals = val.substring(val.indexOf(".") + 1).toCharArray(); char[] vals = val.substring(val.indexOf(".") + 1).toCharArray();
for (int j = 0; j < vals.length; ++j) { for (int j = 0; j < vals.length; ++j) {
if (vals[j] == '0') { if (vals[j] == '0') {
@ -451,28 +393,10 @@ public class ColorMapSliderComp extends Composite {
for (int j = 0; j < zeros; ++j) { for (int j = 0; j < zeros; ++j) {
f += "0"; f += "0";
} }
format = new DecimalFormat(f); return new DecimalFormat(f);
} }
String txt;
/*
* If textStr doesn't have any text then set txt to the value in the
* value variable.
*/
if (textStr.length() == 0) {
txt = format.format(value);
} else {
txt = textStr;
}
if (units != null && units.length() != 0) {
txt += " " + units;
}
sliderText[i] = txt;
start += cmapIncrement;
} }
return new DecimalFormat("0.000");
} }
} }

View file

@ -0,0 +1,103 @@
/**
* 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.colormap;
/**
* Converter that can do simple log scaling given a start/end range on either
* side of zero.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Nov 7, 2013 2492 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public class LogConverter {
private static double EFFECTIVE_ZERO = Double.MIN_VALUE;
public static double valueToIndex(double value, double rangeMin,
double rangeMax) {
// Account for 0 min index
if (rangeMin == 0) {
rangeMin = EFFECTIVE_ZERO;
if (rangeMax < 0) {
rangeMin = -rangeMin;
}
}
boolean reverse = false;
if ((value < rangeMin && rangeMin > 0)
|| (value > rangeMin && rangeMin < 0)) {
reverse = true;
}
value = Math.abs(value);
rangeMin = Math.abs(rangeMin);
rangeMax = Math.abs(rangeMax);
// Check uncomputable index value, everything between this range is 0,
// rangeMin->rangeMax 0 -> 1, -rangeMin->-rangeMax 0 -> -1
if (value <= rangeMin && value >= -rangeMin) {
return 0;
}
double index = (Math.log(value) - Math.log(rangeMin))
/ (Math.log(rangeMax) - Math.log(rangeMin));
if (reverse) {
index = -index;
}
return index;
}
public static double indexToValue(double index, double rangeMin,
double rangeMax) {
// Account for 0 min index
if (rangeMin == 0) {
rangeMin = EFFECTIVE_ZERO;
if (rangeMax < 0) {
rangeMin = -rangeMin;
}
}
boolean reverse = index < 0;
index = Math.abs(index);
rangeMin = Math.abs(rangeMin);
rangeMax = Math.abs(rangeMax);
double value = Math.exp(Math.log(rangeMin)
+ (index * (Math.log(rangeMax) - Math.log(rangeMin))));
if (reverse) {
value = -value;
}
return value;
}
}

View file

@ -40,6 +40,7 @@ import javax.measure.unit.Unit;
import com.raytheon.uf.common.colormap.Color; import com.raytheon.uf.common.colormap.Color;
import com.raytheon.uf.common.colormap.IColorMap; import com.raytheon.uf.common.colormap.IColorMap;
import com.raytheon.uf.common.colormap.LogConverter;
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType; import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters; import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
@ -158,27 +159,6 @@ public class Colormapper {
blue, alpha); blue, alpha);
} }
/**
* Sets an index value into the indexArray for use in a Raster with
* IndexColorModel set
*
* @param dataArray
* @param idx
* @param idxValue
*/
public static void setIndexValue(Object dataArray, int idx, int idxValue) {
if (dataArray instanceof byte[]) {
((byte[]) dataArray)[idx] = (byte) idxValue;
} else if (dataArray instanceof short[]) {
((short[]) dataArray)[idx] = (short) idxValue;
} else if (dataArray instanceof int[]) {
((int[]) dataArray)[idx] = idxValue;
} else {
throw new IllegalArgumentException("Unsupported dataArray type: "
+ (dataArray != null ? dataArray.getClass() : null));
}
}
/** /**
* Returns the double representation of the data value for the Buffer at the * Returns the double representation of the data value for the Buffer at the
* given index * given index
@ -250,64 +230,70 @@ public class Colormapper {
*/ */
public static double getLogIndex(double cmapValue, double cmapMin, public static double getLogIndex(double cmapValue, double cmapMin,
double cmapMax, boolean mirror) { double cmapMax, boolean mirror) {
boolean inverted = false;
double rangeMin = Math.abs(cmapMin);
double rangeMax = Math.abs(cmapMax);
double rangeValue = Math.abs(cmapValue);
if (rangeMin > rangeMax) {
// Inverted colormapping range (cmapMax is closest to 0)
inverted = true;
double tmp = rangeMin;
rangeMin = rangeMax;
rangeMax = tmp;
}
double index = 0.0; double index = 0.0;
// is this strictly negative, strictly positive or neg to pos scaling? // Flag if min/max values are on opposite sides of zero
if (cmapMin >= 0.0 && cmapMax >= 0.0 && !mirror) { boolean minMaxOpposite = (cmapMin < 0 && cmapMax > 0)
if (cmapValue < cmapMin) { || (cmapMin > 0 && cmapMax < 0);
index = 0.0;
} else { if (mirror || minMaxOpposite) {
// simple calculation if (cmapMax < 0) {
index = ((Math.log(cmapValue) - Math.log(cmapMin)) / Math // Invert colormapping if negative range was given
.abs(Math.log(cmapMax) - Math.log(cmapMin))); cmapValue = -cmapValue;
} }
} else if (cmapMin <= 0.0 && cmapMax <= 0.0 && !mirror) { // Log scaling is happening on both sides of zero, need to compute
index = ((Math.log(cmapValue) - Math.log(cmapMax)) / Math.abs(Math // our zero index value
.log(cmapMin) - Math.log(cmapMax))); double zeroVal = rangeMin;
} else { if (minMaxOpposite) {
// special case, neg to pos: // Min/Max are on opposite sides of zero, compute a zero value
double colorMapMin = cmapMin; zeroVal = Math.max(rangeMin, rangeMax) * 0.0001;
double colorMapMax = cmapMax;
double zeroVal = Math.max(colorMapMax, Math.abs(colorMapMin)) * 0.0001;
if (mirror && (colorMapMin > 0.0 || colorMapMax < 0.0)) {
if (colorMapMax < 0.0) {
colorMapMax = -cmapMax;
cmapValue = -cmapValue;
zeroVal = -colorMapMin;
} else {
zeroVal = cmapMin;
}
colorMapMin = -cmapMax;
} }
double leftZero = 0.0;
double rightZero = 0.0; double negCmapMax = rangeMin;
double posCmapMax = rangeMax;
if (mirror) {
negCmapMax = posCmapMax = rangeMax;
}
// Compute log zero val and log neg/pos max vals
double absLogZeroVal = Math.abs(Math.log(zeroVal)); double absLogZeroVal = Math.abs(Math.log(zeroVal));
double logNegCmapMax = absLogZeroVal + Math.log(negCmapMax);
rightZero = absLogZeroVal + Math.log(colorMapMax); double logPosCmapMax = absLogZeroVal + Math.log(posCmapMax);
// Calculate index which zeroVal is at based on neg max and pos max
double cmapMax2 = Math.abs(colorMapMin); double zeroValIndex = logNegCmapMax
/ (logNegCmapMax + logPosCmapMax);
leftZero = absLogZeroVal + Math.log(cmapMax2); if (cmapValue > 0) {
index = LogConverter.valueToIndex(rangeValue, zeroVal,
double zeroIndex = leftZero / (leftZero + rightZero); posCmapMax);
index = zeroValIndex + (1 - zeroValIndex) * index;
// figure out index for texture val
double absTextureColor = Math.abs(cmapValue);
if (absTextureColor <= zeroVal) {
index = zeroIndex;
} else if (cmapValue > 0.0) {
// positive texture color value, find index from 0 to
// cmapMax:
double logTexColor = absLogZeroVal + Math.log(cmapValue);
double texIndex = logTexColor / rightZero;
index = (zeroIndex + ((1.0 - zeroIndex) * texIndex));
} else { } else {
// negative texture color value, find index from 0 to index = LogConverter.valueToIndex(rangeValue, zeroVal,
// cmapMax: negCmapMax);
double logTexColor = absLogZeroVal + Math.log(absTextureColor); index = zeroValIndex - zeroValIndex * index;
}
double texIndex = logTexColor / leftZero; if (inverted) {
index = (zeroIndex - (zeroIndex * texIndex)); index = 1.0 - index;
}
} else {
// Simple case, just use log converter to get index
index = LogConverter.valueToIndex(rangeValue, rangeMin, rangeMax);
if (inverted) {
index = 1.0 - index;
}
if (cmapMin > 0 && cmapValue < rangeMin
|| (cmapMin < 0 && cmapValue > -rangeMin)) {
index = -index;
} }
} }
return index; return index;

View file

@ -133,6 +133,7 @@ public class ColorMapParameters {
protected Unit<?> colorMapUnit; protected Unit<?> colorMapUnit;
/** Units of the data values to colormap */ /** Units of the data values to colormap */
@Deprecated
protected Unit<?> dataUnit; protected Unit<?> dataUnit;
/** The maximum value used to apply the colormap */ /** The maximum value used to apply the colormap */
@ -142,9 +143,11 @@ public class ColorMapParameters {
protected float colorMapMin; protected float colorMapMin;
/** The maximum (usually theoretical) value of the data */ /** The maximum (usually theoretical) value of the data */
@Deprecated
protected float dataMax; protected float dataMax;
/** The minimum (usually theoretical) value of the data */ /** The minimum (usually theoretical) value of the data */
@Deprecated
protected float dataMin; protected float dataMin;
/** The intervals upon which to apply labeling to the color bar */ /** The intervals upon which to apply labeling to the color bar */
@ -162,15 +165,19 @@ public class ColorMapParameters {
protected String colorMapName; protected String colorMapName;
/** The converter that converts data values to {@link #displayUnit} * */ /** The converter that converts data values to {@link #displayUnit} * */
@Deprecated
protected UnitConverter dataToDisplayConverter; protected UnitConverter dataToDisplayConverter;
/** The converter that converts display values to {@link #dataUnit} * */ /** The converter that converts display values to {@link #dataUnit} * */
@Deprecated
protected UnitConverter displayToDataConverter; protected UnitConverter displayToDataConverter;
/** The converter that converts data values to {@link #colorMapUnit} */ /** The converter that converts data values to {@link #colorMapUnit} */
@Deprecated
protected UnitConverter dataToColorMapConverter; protected UnitConverter dataToColorMapConverter;
/** The converter that converts color map unit values to {@link #dataUnit} */ /** The converter that converts color map unit values to {@link #dataUnit} */
@Deprecated
protected UnitConverter colorMapToDataConverter; protected UnitConverter colorMapToDataConverter;
/** The converter that converts color map unit values to {@link #displayUnit} */ /** The converter that converts color map unit values to {@link #displayUnit} */
@ -491,32 +498,40 @@ public class ColorMapParameters {
} }
/** /**
* @deprecated data max is not important for general colormapping use
* @return the dataMax * @return the dataMax
*/ */
@Deprecated
public float getDataMax() { public float getDataMax() {
return dataMax; return dataMax;
} }
/** /**
* @deprecated data max is not important for general colormapping use
* @param dataMax * @param dataMax
* the dataMax to set * the dataMax to set
*/ */
@Deprecated
public void setDataMax(float dataMax) { public void setDataMax(float dataMax) {
this.dataMax = dataMax; this.dataMax = dataMax;
notifyListener(); notifyListener();
} }
/** /**
* @deprecated data min is not important for general colormapping use
* @return the dataMin * @return the dataMin
*/ */
@Deprecated
public float getDataMin() { public float getDataMin() {
return dataMin; return dataMin;
} }
/** /**
* @deprecated data min is not important for general colormapping use
* @param dataMin * @param dataMin
* the dataMin to set * the dataMin to set
*/ */
@Deprecated
public void setDataMin(float dataMin) { public void setDataMin(float dataMin) {
this.dataMin = dataMin; this.dataMin = dataMin;
notifyListener(); notifyListener();
@ -563,8 +578,10 @@ public class ColorMapParameters {
/** /**
* Returns the unit data values to be colormapped are in * Returns the unit data values to be colormapped are in
* *
* @deprecated data unit is not important for general colormapping use
* @return the dataUnit * @return the dataUnit
*/ */
@Deprecated
public Unit<?> getDataUnit() { public Unit<?> getDataUnit() {
return dataUnit; return dataUnit;
} }
@ -572,9 +589,11 @@ public class ColorMapParameters {
/** /**
* Sets the unit data values to be colormapped are in * Sets the unit data values to be colormapped are in
* *
* @deprecated data unit is not important for general colormapping use
* @param dataUnit * @param dataUnit
* the dataUnit to set * the dataUnit to set
*/ */
@Deprecated
public void setDataUnit(Unit<?> dataUnit) { public void setDataUnit(Unit<?> dataUnit) {
this.dataUnit = dataUnit; this.dataUnit = dataUnit;
@ -595,8 +614,10 @@ public class ColorMapParameters {
* Returns the {@link UnitConverter} from {@link #dataUnit} to * Returns the {@link UnitConverter} from {@link #dataUnit} to
* {@link #displayUnit} * {@link #displayUnit}
* *
* @deprecated data unit is not important for general colormapping use
* @return the dataToDisplayConverter * @return the dataToDisplayConverter
*/ */
@Deprecated
public UnitConverter getDataToDisplayConverter() { public UnitConverter getDataToDisplayConverter() {
if (dataToDisplayConverter == null) { if (dataToDisplayConverter == null) {
dataToDisplayConverter = constructConverter(dataUnit, displayUnit); dataToDisplayConverter = constructConverter(dataUnit, displayUnit);
@ -611,8 +632,10 @@ public class ColorMapParameters {
* Returns the {@link UnitConverter} from {@link #displayUnit} to * Returns the {@link UnitConverter} from {@link #displayUnit} to
* {@link #dataUnit} * {@link #dataUnit}
* *
* @deprecated data unit is not important for general colormapping use
* @return the displayToDataConverter * @return the displayToDataConverter
*/ */
@Deprecated
public UnitConverter getDisplayToDataConverter() { public UnitConverter getDisplayToDataConverter() {
if (displayToDataConverter == null) { if (displayToDataConverter == null) {
displayToDataConverter = constructConverter(displayUnit, dataUnit); displayToDataConverter = constructConverter(displayUnit, dataUnit);
@ -667,8 +690,10 @@ public class ColorMapParameters {
* Returns a {@link UnitConverter} converting {@link #dataUnit} values to * Returns a {@link UnitConverter} converting {@link #dataUnit} values to
* the {@link #colorMapUnit} if compatible or null otherwise * the {@link #colorMapUnit} if compatible or null otherwise
* *
* @deprecated data unit is not important for general colormapping use
* @return * @return
*/ */
@Deprecated
public UnitConverter getDataToColorMapConverter() { public UnitConverter getDataToColorMapConverter() {
if (dataToColorMapConverter == null) { if (dataToColorMapConverter == null) {
dataToColorMapConverter = constructConverter(dataUnit, colorMapUnit); dataToColorMapConverter = constructConverter(dataUnit, colorMapUnit);
@ -773,8 +798,10 @@ public class ColorMapParameters {
* Returns a {@link UnitConverter} converting {@link #colorMapUnit} values * Returns a {@link UnitConverter} converting {@link #colorMapUnit} values
* to the {@link #dataUnit} if compatible or null otherwise * to the {@link #dataUnit} if compatible or null otherwise
* *
* @deprecated data unit is not important for general colormapping use
* @return * @return
*/ */
@Deprecated
public UnitConverter getColorMapToDataConverter() { public UnitConverter getColorMapToDataConverter() {
if (colorMapToDataConverter == null) { if (colorMapToDataConverter == null) {
colorMapToDataConverter = constructConverter(colorMapUnit, dataUnit); colorMapToDataConverter = constructConverter(colorMapUnit, dataUnit);