VLab Issue #4487 - Dim. DR 17313, Additional true color capabilities; fixes #4487

Change-Id: I701f302aa5958e89522208fd7915f5077cf97616

Former-commit-id: 86b34a2f70 [formerly 86b34a2f70 [formerly 1300009502bafd34fee13c8d21d65208b1069bda]]
Former-commit-id: 8f5903920c
Former-commit-id: ac5b372773
This commit is contained in:
Jordan Gerth 2014-09-15 18:48:21 -05:00
parent 0eb194e2bb
commit d9c08b7cac
8 changed files with 303 additions and 93 deletions

View file

@ -28,6 +28,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channel;
/**
@ -41,7 +42,7 @@ import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channe
* ------------- -------- ----------- --------------------------
* Aug 20, 2012 mschenke Initial creation
* Apr 18, 2014 2947 bsteffen Support unitless data.
*
* Sep 9, 2014 DR 17313 jgerth Support for ColorMapParameters
*
* </pre>
*
@ -60,7 +61,9 @@ public class ChannelInfo {
@XmlElement
private double rangeMax = 1.0;
private Unit<?> unit = Unit.ONE;
private Unit<?> unit;
private ColorMapParameters parameters;
/**
* @return the channel
@ -144,6 +147,14 @@ public class ChannelInfo {
: null;
}
public ColorMapParameters getParameters() {
return parameters;
}
public void setParameters(ColorMapParameters parameters) {
this.parameters = parameters;
}
/*
* (non-Javadoc)
*

View file

@ -25,6 +25,7 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import com.raytheon.uf.viz.core.rsc.AbstractResourceData;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channel;
/**
@ -37,18 +38,26 @@ import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channe
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 16, 2012 mschenke Initial creation
* Aug 22, 2014 DR 17313 jgerth Support for load properties
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
/**
* @author awips
*
*/
@XmlAccessorType(XmlAccessType.NONE)
public class ChannelResource {
@XmlElement
protected AbstractResourceData resourceData;
@XmlElement
protected LoadProperties loadProperties;
@XmlElement
protected Channel channel;
@ -100,6 +109,21 @@ public class ChannelResource {
this.channelName = channelName;
}
/**
* @return the loadProperties
*/
public LoadProperties getLoadProperties() {
return loadProperties;
}
/**
* @param loadProperties
* the loadProperties to set
*/
public void setLoadProperties(LoadProperties loadProperties) {
this.loadProperties = loadProperties;
}
/*
* (non-Javadoc)
*

View file

@ -25,11 +25,13 @@ import java.util.IdentityHashMap;
import java.util.Map;
import javax.measure.converter.UnitConverter;
import javax.measure.unit.Unit;
import org.eclipse.swt.graphics.Rectangle;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.viz.core.DrawableImage;
@ -69,6 +71,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* ------------- -------- ----------- --------------------------
* Aug 06, 2012 mschenke Initial creation
* Apr 18, 2014 2947 bsteffen Support unitless data.
* Sep 10, 2014 DR 17313 jgerth Add inspect method
*
* </pre>
*
@ -140,7 +143,7 @@ public class TrueColorResourceGroup extends
* Mapping to keep colormap parameters in sync with ChannelInfo in
* resourceData
*/
private Map<ColorMapParameters, ChannelInfo> channelInfoMap = new IdentityHashMap<ColorMapParameters, ChannelInfo>();
private Map<ColorMapCapability, ChannelInfo> channelInfoMap = new IdentityHashMap<ColorMapCapability, ChannelInfo>();
/**
* @param resourceData
@ -246,9 +249,9 @@ public class TrueColorResourceGroup extends
for (ChannelResource cr : resourceData.getChannelResources()) {
for (ResourcePair rp : resources) {
if (cr.getResourceData() == rp.getResourceData()) {
DisplayedChannelResource displayedResource = new DisplayedChannelResource(
DisplayedChannelResource displayedResource = new DisplayedChannelResource(
cr, rp.getResource());
AbstractVizResource<?, ?> resource = rp.getResource();
AbstractVizResource<?, ?> resource = rp.getResource();
resource.init(target);
// Check resource for required capabilities
@ -256,16 +259,7 @@ public class TrueColorResourceGroup extends
if (resource.hasCapability(ImagingCapability.class)) {
ImagingCapability imaging = resource
.getCapability(ImagingCapability.class);
if (imaging.getProvider() != null) {
if (resource
.hasCapability(ColorMapCapability.class) == false) {
error = "does not have ColorMapCapability";
} else if (resource.getCapability(
ColorMapCapability.class)
.getColorMapParameters() == null) {
error = "does not have ColorMapParameters set";
}
} else {
if (imaging.getProvider() == null) {
error = "does not have image provider set on the ImagingCapability";
}
} else {
@ -279,35 +273,32 @@ public class TrueColorResourceGroup extends
if (error == null) {
// No errors so far, check for ChannelInfo override
ColorMapParameters params = resource.getCapability(
ColorMapCapability.class)
ColorMapCapability cmapCap = resource
.getCapability(ColorMapCapability.class);
ColorMapParameters params = cmapCap
.getColorMapParameters();
ChannelInfo ci = resourceData
.getChannelInfo(displayedResource.getChannel());
if (ci == null
|| ci.getUnit().isCompatible(
params.getDataUnit())) {
if (ci == null) {
ci = new ChannelInfo();
ci.setChannel(displayedResource.getChannel());
resourceData.setChannelInfo(ci);
} else {
params.setDisplayUnit(ci.getUnit());
params.setColorMapMin((float) params
.getDisplayToDataConverter().convert(
ci.getRangeMin()));
params.setColorMapMax((float) params
.getDisplayToDataConverter().convert(
ci.getRangeMax()));
if (ci == null) {
ci = new ChannelInfo();
ci.setChannel(displayedResource.getChannel());
if (params != null) {
ci.setUnit(params.getColorMapUnit());
ci.setRangeMin(params.getColorMapMin());
ci.setRangeMax(params.getColorMapMax());
}
channelInfoMap.put(params, ci);
resourceChanged(
ChangeType.CAPABILITY,
resource.getCapability(ColorMapCapability.class));
} else {
error = "is not compatible with custom ChannelInfo for Channel="
+ displayedResource.getChannel();
resourceData.setChannelInfo(ci);
}
channelInfoMap.put(cmapCap, ci);
if (params != null && params.getColorMapUnit() == null) {
// no colormap units set, default to ChannelInfo
params.setColorMapUnit(ci.getUnit());
}
initializeParameters(ci, params);
}
if (error != null) {
@ -317,7 +308,9 @@ public class TrueColorResourceGroup extends
+ error);
resources.remove(rp);
} else {
resource.getResourceData().addChangeListener(this);
// Listener will handle case where params are changed
// after the fact and we will reinitialize
resource.getResourceData().addChangeListener(this);
displayedResources.put(displayedResource.getChannel(),
displayedResource);
}
@ -430,19 +423,90 @@ public class TrueColorResourceGroup extends
if (toDisplay == null) {
toDisplay = UnitConverter.IDENTITY;
}
ChannelInfo ci = channelInfoMap.get(params);
ChannelInfo ci = channelInfoMap.get(object);
if (ci != null) {
ci.setRangeMin(toDisplay.convert(
params.getColorMapMin()));
ci.setRangeMax(toDisplay.convert(
params.getColorMapMax()));
ci.setUnit(params.getDisplayUnit());
if (ci.getParameters() != params) {
// Reinitialize params from channel info
initializeParameters(ci, params);
} else {
ci.setRangeMin(toDisplay.convert(params
.getColorMapMin()));
ci.setRangeMax(toDisplay.convert(params
.getColorMapMax()));
ci.setUnit(params.getDisplayUnit());
}
}
}
}
issueRefresh();
}
@Override
public String inspect(ReferencedCoordinate coord) throws VizException {
String label = "";
for (Channel c : Channel.values()) {
DisplayedChannelResource dcr = displayedResources.get(c);
if (dcr != null) {
String ri = dcr.resource.inspect(coord);
label += c.name() + ": " + ri;
if (dcr.resource.hasCapability(ColorMapCapability.class) && ri.replaceAll("[^\\d]", "").length() > 0) {
ColorMapParameters cmp = dcr.resource.getCapability(ColorMapCapability.class).getColorMapParameters();
UnitConverter uc = cmp.getColorMapToDisplayConverter();
if (uc == null)
uc = UnitConverter.IDENTITY;
double cmmax = uc.convert(cmp.getColorMapMax());
double cmmin = uc.convert(cmp.getColorMapMin());
String rirall;
if (ri.charAt(0) == ('-'))
rirall = "-" + (ri.substring(1) + "x").replaceAll("[^\\d.]", " ");
else
rirall = (ri + "x").replaceAll("[^\\d.]", " ");
try {
double value = Double.parseDouble(rirall.substring(0,rirall.indexOf(" ")));
double percent = ((value - cmmin) * 100.0 / (cmmax - cmmin));
if (percent < 0)
percent = 0.0;
else if (percent > 100)
percent = 100.0;
label += " (" + Math.round(percent) + "%)\n";
} catch (Exception e) {
label += "\n";
}
} else
label += "\n";
}
}
if (label.length() > 0)
return label;
else
return "NO DATA";
}
private static void initializeParameters(ChannelInfo ci,
ColorMapParameters params) {
if (params != null) {
ci.setParameters(params);
if (ci.getUnit() != null && params.getColorMapUnit() != null
&& ci.getUnit().isCompatible(params.getColorMapUnit())) {
params.setDisplayUnit(ci.getUnit());
UnitConverter displayToCmap = params
.getDisplayToColorMapConverter();
params.setColorMapMin(
(float) displayToCmap.convert(ci.getRangeMin()),
true);
params.setColorMapMax(
(float) displayToCmap.convert(ci.getRangeMax()),
true);
} else {
UnitConverter cmapToDisplay = params
.getColorMapToDisplayConverter();
ci.setRangeMin(cmapToDisplay.convert(params.getColorMapMin()));
ci.setRangeMax(cmapToDisplay.convert(params.getColorMapMax()));
ci.setUnit(params.getDisplayUnit());
}
}
}
public Collection<DisplayedChannelResource> getChannelResources() {
return displayedResources.values();
}

View file

@ -50,6 +50,7 @@ import com.raytheon.uf.viz.truecolor.extension.ITrueColorImagingExtension.Channe
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 6, 2012 mschenke Initial creation
* Aug 22, 2014 DR 17313 jgerth Support for load properties
*
* </pre>
*
@ -94,16 +95,19 @@ public class TrueColorResourceGroupData extends AbstractResourceData implements
}
};
for (ChannelResource resource : channelResources) {
addResource(resource.getResourceData());
addResource(resource.getResourceData(), resource.getLoadProperties());
}
}
return resourceList;
}
private void addResource(AbstractResourceData resourceData) {
private void addResource(AbstractResourceData resourceData, LoadProperties loadProp) {
ResourcePair rp = new ResourcePair();
rp.setResourceData(resourceData);
rp.setLoadProperties(new LoadProperties());
if (loadProp == null)
rp.setLoadProperties(new LoadProperties());
else
rp.setLoadProperties(loadProp);
rp.setProperties(new ResourceProperties());
resourceList.add(rp);
}

View file

@ -63,7 +63,7 @@ import com.raytheon.viz.core.gl.objects.GLTextureObject;
* Oct 16, 2013 2333 mschenke Cleaned up load shader method, used isScaled.
* Added support for colormapping in non-data unit.
* Nov 20, 2013 2492 bsteffen Mosaic in image units.
*
* Aug 21, 2014 DR 17313 jgerth Support for true color
*
* </pre>
*
@ -212,7 +212,8 @@ public class GLColormappedImageExtension extends AbstractGLSLImagingExtension
// datamapping is not set, the data has already been mapped to
// colorMapUnits and we need not do anything
GLDataMapping dataMapping = glImage.getDataMapping();
if (dataMapping == null && colorMapParameters.getDataMapping() == null) {
if (dataMapping == null && colorMapParameters.getDataMapping() == null &&
colorMapParameters.getColorMap() != null) {
Unit<?> dataUnit = glImage.getDataUnit();
int colorMapSize = colorMapParameters.getColorMap().getSize();
float colorMapMin = colorMapParameters.getColorMapMin();

View file

@ -22,6 +22,8 @@ package com.raytheon.viz.grid.rsc.general;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@ -64,12 +66,14 @@ import com.raytheon.uf.common.style.contour.ContourPreferences;
import com.raytheon.uf.common.style.image.ColorMapParameterFactory;
import com.raytheon.uf.common.style.image.ImagePreferences;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.drawables.ColorMapLoader;
import com.raytheon.uf.viz.core.drawables.IRenderable;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.drawables.PaintStatus;
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension.ImageProvider;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.IMapDescriptor;
import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData;
@ -125,7 +129,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* Jan 14, 2014 2594 bsteffen Switch vector mag/dir to use data source
* instead of raw float data.
* Feb 28, 2014 2791 bsteffen Switch all data to use data source.
*
* Aug 21, 2014 DR 17313 jgerth Implements ImageProvider
*
* </pre>
*
@ -134,7 +138,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* @param <T>
*/
public abstract class AbstractGridResource<T extends AbstractResourceData>
extends AbstractVizResource<T, IMapDescriptor> {
extends AbstractVizResource<T, IMapDescriptor> implements ImageProvider {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(AbstractGridResource.class);
@ -345,6 +349,7 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
this.getCapability(ImagingCapability.class)
.setInterpolationState(true);
}
this.getCapability(ImagingCapability.class).setProvider(this);
altDisplayTypes.add(DisplayType.CONTOUR);
break;
case BARB:
@ -438,43 +443,6 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
}
}
@Override
protected void paintInternal(IGraphicsTarget target,
PaintProperties paintProps) throws VizException {
DataTime time = paintProps.getDataTime();
if (time == null) {
time = getTimeForResource();
}
if (time == null) {
return;
}
synchronized (renderableMap) {
if (renderableMap.containsKey(time)) {
for (IRenderable renderable : renderableMap.get(time)) {
renderable.paint(target, paintProps);
}
return;
}
List<GeneralGridData> dataList = requestData(time);
if (dataList == null) {
updatePaintStatus(PaintStatus.INCOMPLETE);
return;
}
List<IRenderable> renderableList = new ArrayList<IRenderable>(
dataList.size());
for (GeneralGridData data : dataList) {
IRenderable renderable = createRenderable(target, data);
if (renderable != null) {
renderableList.add(renderable);
renderable.paint(target, paintProps);
}
}
renderableMap.put(time, renderableList);
}
}
/**
* Create a renderable for this data.
*
@ -993,4 +961,63 @@ public abstract class AbstractGridResource<T extends AbstractResourceData>
return new ArrayList<PluginDataObject>(list);
}
public Collection<DrawableImage> getImages(IGraphicsTarget target, PaintProperties paintProps) throws VizException {
if (getCapability(DisplayTypeCapability.class).getDisplayType() != DisplayType.IMAGE) {
throw new VizException("Grid resource not configured for image rendering");
}
Collection<IRenderable> renderables = getOrCreateRenderables(target, paintProps);
if (renderables.isEmpty()) {
return Collections.emptyList();
}
List<DrawableImage> images = new ArrayList<DrawableImage>();
for (IRenderable renderable : renderables) {
images.addAll(((TileSetRenderable)renderable).getImagesToRender(target, paintProps));
}
return images;
}
protected Collection<IRenderable> getOrCreateRenderables(
IGraphicsTarget target, PaintProperties paintProps)
throws VizException {
DataTime time = paintProps.getDataTime();
if (time == null) {
time = getTimeForResource();
}
if (time == null) {
return Collections.emptyList();
}
List<IRenderable> renderables;
synchronized (renderableMap) {
if (renderableMap.containsKey(time)) {
renderables = renderableMap.get(time);
} else {
List<GeneralGridData> dataList = requestData(time);
if (dataList == null) {
updatePaintStatus(PaintStatus.INCOMPLETE);
return Collections.emptyList();
}
renderables = new ArrayList<IRenderable>(dataList.size());
for (GeneralGridData data : dataList) {
IRenderable renderable = createRenderable(target, data);
if (renderable != null) {
renderables.add(renderable);
}
}
renderableMap.put(time, renderables);
}
}
return renderables;
}
@Override
protected void paintInternal(IGraphicsTarget target,
PaintProperties paintProps) throws VizException {
for (IRenderable renderable : getOrCreateRenderables(target, paintProps)) {
renderable.paint(target, paintProps);
}
}
}

View file

@ -101,6 +101,7 @@ import com.vividsolutions.jts.geom.Coordinate;
* Apr 09, 2014 2947 bsteffen Improve flexibility of sat derived
* parameters, implement ImageProvider
* May 06, 2014 njensen Improve error message
* Aug 21, 2014 DR 17313 jgerth Set no data value if no data mapping
*
* </pre>
*
@ -354,7 +355,8 @@ public class SatResource extends
if (persisted != null) {
colorMapParameters.applyPersistedParameters(persisted);
}
colorMapParameters.setNoDataValue(0);
if (colorMapParameters.getDataMapping() == null)
colorMapParameters.setNoDataValue(0);
getCapability(ColorMapCapability.class).setColorMapParameters(
colorMapParameters);
@ -423,7 +425,7 @@ public class SatResource extends
if (dataMapping != null) {
// if the pixel value matches the data mapping entry use that
// label instead
String label = dataMapping.getLabelValueForDataValue(measuredValue);
String label = dataMapping.getSampleOrLabelValueForDataValue(measuredValue);
if (label != null) {
return label;
}

View file

@ -39,6 +39,7 @@ import com.raytheon.uf.common.units.PiecewisePixel;
* ------------ ---------- ----------- --------------------------
* 6/2013 DR 16070 jgerth Interpolation capability
* Aug 2, 2013 2211 mschenke Backed out 16070 changes
* Aug 21, 2014 DR 17313 jgerth New methods
*
* </pre>
*
@ -249,7 +250,7 @@ public class DataMappingPreferences {
} else if (">".equals(operator)) {
greaterThanEntries.add(entry);
Collections
.sort(greaterThanEntries, Collections.reverseOrder());
.sort(greaterThanEntries, Collections.reverseOrder());
} else if ("<".equals(operator)) {
lessThanEntries.add(entry);
Collections.sort(lessThanEntries);
@ -289,4 +290,80 @@ public class DataMappingPreferences {
return null;
}
/**
* Matches a number against the pixelValue in each entry based on the
* operator until the first match is found.
*
* jjg 7/24/2014
*
* @param dataValue
* the data value to match
* @return The entry sample, if one exists.
*/
public String getSampleValueForDataValue(double dataValue) {
for (DataMappingEntry entry : equalsEntries) {
Double entryValue = entry.getPixelValue();
if (entryValue.equals(dataValue)) {
return entry.getSample();
}
}
for (DataMappingEntry entry : lessThanEntries) {
Double entryValue = entry.getPixelValue();
if (dataValue < entryValue) {
return entry.getSample();
}
}
for (DataMappingEntry entry : greaterThanEntries) {
Double entryValue = entry.getPixelValue();
if (dataValue > entryValue) {
return entry.getSample();
}
}
return null;
}
/**
* Matches a number against the pixelValue in each entry based on the
* operator until the first match is found.
*
* jjg 7/24/2014
*
* @param dataValue
* the data value to match
* @return The entry sample or label, if one exists.
*/
public String getSampleOrLabelValueForDataValue(double dataValue) {
for (DataMappingEntry entry : equalsEntries) {
Double entryValue = entry.getPixelValue();
if (entryValue.equals(dataValue)) {
if (entry.getSample() == null)
return entry.getLabel();
else
return entry.getSample();
}
}
for (DataMappingEntry entry : lessThanEntries) {
Double entryValue = entry.getPixelValue();
if (dataValue < entryValue) {
if (entry.getSample() == null)
return entry.getLabel();
else
return entry.getSample();
}
}
for (DataMappingEntry entry : greaterThanEntries) {
Double entryValue = entry.getPixelValue();
if (dataValue > entryValue) {
if (entry.getSample() == null)
return entry.getLabel();
else
return entry.getSample();
}
}
return null;
}
}