Issue #1553 make data access resources time match.

Change-Id: I4f539aa7fb6638052a1c47a54b591d624b7e4b37

Former-commit-id: e4b5a93bb4 [formerly 04608dd42b] [formerly b0f47fa146] [formerly e4b5a93bb4 [formerly 04608dd42b] [formerly b0f47fa146] [formerly 0fe99c227e [formerly b0f47fa146 [formerly 82808b8e254098f6773d7320fd99564c7f33d012]]]]
Former-commit-id: 0fe99c227e
Former-commit-id: 5da0d5c2a6 [formerly eef3228f72] [formerly 3662e58f187c58937c2aa09b2e2f79708368fd27 [formerly a56fa20253]]
Former-commit-id: 5f5b9ba07fad0aa4aa25bcf431bea50b3709410e [formerly 845f6e26ab]
Former-commit-id: ffad90077a
This commit is contained in:
Ben Steffensmeier 2013-02-07 17:57:08 -06:00
parent 271d5096a0
commit 60943b76f4
4 changed files with 273 additions and 112 deletions

View file

@ -19,8 +19,11 @@
**/
package com.raytheon.viz.dataaccess.rsc;
import java.util.Arrays;
import org.apache.commons.lang.StringUtils;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.MapDescriptor;
@ -49,7 +52,7 @@ public abstract class AbstractDataAccessResource<T extends AbstractDataAccessRes
protected static final String _SPACE_ = " ";
private String legendText;
private String genericLegendText;
/**
* Constructor
@ -64,19 +67,33 @@ public abstract class AbstractDataAccessResource<T extends AbstractDataAccessRes
protected AbstractDataAccessResource(T resourceData,
LoadProperties loadProperties, String genericLegendText) {
super(resourceData, loadProperties);
this.buildLegendText(genericLegendText);
this.genericLegendText = genericLegendText;
if (resourceData.getDataTimes() == null) {
this.dataTimes = TIME_AGNOSTIC;
} else {
this.dataTimes = Arrays.asList(resourceData.getDataTimes());
}
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.rsc.AbstractVizResource#initInternal(com.raytheon
* .uf.viz.core.IGraphicsTarget)
*/
@Override
protected void initInternal(IGraphicsTarget target) throws VizException {
this.prepareData(target);
DataTime[] timesToLoad = descriptor.getFramesInfo().getTimeMap()
.get(this);
if (timesToLoad == null && descriptor.getTimeMatcher() != null) {
timesToLoad = descriptor.getTimeMatcher().initialLoad(
getLoadProperties(), getDataTimes(), descriptor);
}
if (timesToLoad != null) {
for (DataTime time : timesToLoad) {
prepareData(target, time);
}
}
}
@Override
public void remove(DataTime dataTime) {
;// for now never remove anything from dataTimes since there are no
// updates on redoTimeMatching
}
/*
@ -86,7 +103,7 @@ public abstract class AbstractDataAccessResource<T extends AbstractDataAccessRes
*/
@Override
public String getName() {
return this.legendText;
return buildLegendText(genericLegendText);
}
/**
@ -96,7 +113,7 @@ public abstract class AbstractDataAccessResource<T extends AbstractDataAccessRes
* @param target
* @throws VizException
*/
protected abstract void prepareData(IGraphicsTarget target)
protected abstract void prepareData(IGraphicsTarget target, DataTime time)
throws VizException;
/**
@ -112,15 +129,11 @@ public abstract class AbstractDataAccessResource<T extends AbstractDataAccessRes
* @param genericLegendText
* the request-type specific legend text
*/
private final void buildLegendText(String genericLegendText) {
private final String buildLegendText(String genericLegendText) {
StringBuilder stringBuilder = new StringBuilder(genericLegendText);
stringBuilder.append(this.padWithSeparator(this
.buildLegendTextInternal()));
if (this.resourceData.getFirstDataElement().getDataTime() != null) {
stringBuilder.append(this.resourceData.getFirstDataElement()
.getDataTime().getLegendString());
}
this.legendText = stringBuilder.toString();
return stringBuilder.toString();
}
/**

View file

@ -19,6 +19,9 @@
**/
package com.raytheon.viz.dataaccess.rsc;
import java.util.HashMap;
import java.util.Map;
import com.raytheon.uf.common.dataaccess.DataAccessLayer;
import com.raytheon.uf.common.dataaccess.IData;
import com.raytheon.uf.common.dataaccess.IDataRequest;
@ -51,13 +54,15 @@ import com.raytheon.uf.viz.core.rsc.LoadProperties;
public abstract class AbstractDataAccessResourceData<T extends IDataRequest<X>, X extends IData>
extends AbstractResourceData {
private X[] data;
private DataTime[] dataTimes;
private Map<DataTime, X[]> data;
/**
* Constructor
*/
public AbstractDataAccessResourceData() {
this.data = null;
this.data = new HashMap<DataTime, X[]>();
}
/*
@ -71,10 +76,35 @@ public abstract class AbstractDataAccessResourceData<T extends IDataRequest<X>,
@Override
public AbstractVizResource<?, ?> construct(LoadProperties loadProperties,
IDescriptor descriptor) throws VizException {
this.retrieveData(this.getRequest());
this.populateTimes(this.getRequest());
return this.constructResource(loadProperties, descriptor);
}
/**
* Retrieves and stores the dataTimes associated using the specified
* request.
*
* @param request
* the request
*/
protected void populateTimes(T request) throws NoDataAvailableException {
dataTimes = null;
try {
dataTimes = DataAccessLayer.getAvailableTimes(request);
if (dataTimes == null || dataTimes.length <= 0) {
throw new NoDataAvailableException(this.getClass());
}
} catch (TimeAgnosticDataException e1) {
// Make sure that time agnostic has data before continuing.
dataTimes = null;
X[] data = retreiveData(request, null);
if (data == null || data.length == 0) {
throw new NoDataAvailableException(this.getClass());
}
}
}
/**
* Retrieves and stores the data associated using the specified request.
*
@ -84,36 +114,21 @@ public abstract class AbstractDataAccessResourceData<T extends IDataRequest<X>,
* the class that is requesting the data; will always be a
* subclass of AbstractDataAccessResourceData
*/
private void retrieveData(T request) throws NoDataAvailableException {
this.data = null;
boolean timeAgnostic = false;
DataTime[] dataTimes = null;
try {
dataTimes = DataAccessLayer.getAvailableTimes(request);
} catch (TimeAgnosticDataException e1) {
timeAgnostic = true;
}
if (timeAgnostic) {
private X[] retreiveData(T request, DataTime dataTime) {
X[] data = null;
if (dataTime == null && dataTimes == null) {
/*
* If we were a legitimate resource, we would want to cache time
* agnostic data that was retrieved. The cache could be a simple Map
* or even the cache provided by GOOG in the guava library.
*/
this.data = DataAccessLayer.getData(request);
} else {
if (dataTimes == null || dataTimes.length <= 0) {
throw new NoDataAvailableException(this.getClass());
}
data = DataAccessLayer.getData(request);
} else if (dataTime != null) {
/* Just use the latest time since this is a sample / test resource */
this.data = DataAccessLayer.getData(request, dataTimes[0]);
data = DataAccessLayer.getData(request, dataTime);
}
if (this.data == null || this.data.length <= 0) {
throw new NoDataAvailableException(this.getClass());
}
return data;
}
/**
@ -169,8 +184,23 @@ public abstract class AbstractDataAccessResourceData<T extends IDataRequest<X>,
*
* @return all of the data that was retrieved
*/
public X[] getData() {
return data;
public X[] getData(DataTime time) {
if (data.containsKey(time)) {
return data.get(time);
} else {
X[] data = retreiveData(getRequest(), time);
this.data.put(time, data);
return data;
}
}
/**
* get the dataTimes
*
* @return all available times for this data or null if time agnostic.
*/
public DataTime[] getDataTimes() {
return dataTimes;
}
/**
@ -178,7 +208,12 @@ public abstract class AbstractDataAccessResourceData<T extends IDataRequest<X>,
*
* @return the first data element that has been retrieved
*/
public X getFirstDataElement() {
return (this.data == null) ? null : this.data[0];
public X getFirstDataElement(DataTime time) {
X[] data = getData(time);
if (data == null) {
return null;
} else {
return data[0];
}
}
}

View file

@ -20,16 +20,18 @@
package com.raytheon.viz.dataaccess.rsc.geometry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import com.raytheon.uf.common.dataaccess.geom.IGeometryData;
import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.drawables.IWireframeShape;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
@ -41,6 +43,8 @@ import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability;
import com.raytheon.viz.core.rsc.jts.JTSCompiler;
import com.raytheon.viz.core.rsc.jts.JTSCompiler.PointStyle;
import com.raytheon.viz.dataaccess.rsc.AbstractDataAccessResource;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
/**
* Renders various geometric entities based on geometry data that is retrieved
@ -67,11 +71,20 @@ public class GenericGeometryResource extends
private static final String GENERIC_LEGEND_TEXT = "Generic Geometry ";
private boolean geometriesReady;
private static class FrameData {
private List<double[]> pointsToRender;
public final List<double[]> pointsToRender;
private IWireframeShape shape;
public final IWireframeShape shape;
public FrameData(List<double[]> pointsToRender, IWireframeShape shape) {
this.pointsToRender = pointsToRender;
this.shape = shape;
}
}
private Map<DataTime, FrameData> renderableData = new HashMap<DataTime, FrameData>();
/**
* Constructor
@ -82,7 +95,6 @@ public class GenericGeometryResource extends
protected GenericGeometryResource(GenericGeometryResourceData resourceData,
LoadProperties loadProperties) {
super(resourceData, loadProperties, GENERIC_LEGEND_TEXT);
this.geometriesReady = false;
}
/*
@ -108,13 +120,22 @@ public class GenericGeometryResource extends
@Override
protected void paintInternal(IGraphicsTarget target,
PaintProperties paintProps) throws VizException {
if (this.geometriesReady == false) {
this.prepareData(target);
DataTime timeToPaint = null;
if (!isTimeAgnostic()) {
timeToPaint = paintProps.getDataTime();
if (timeToPaint == null) {
return;
}
}
if (!renderableData.containsKey(timeToPaint)) {
this.prepareData(target, timeToPaint);
}
FrameData frameData = renderableData.get(timeToPaint);
// First, draw the points
if (this.pointsToRender.size() > 0) {
target.drawPoints(this.pointsToRender,
if (frameData.pointsToRender.size() > 0) {
target.drawPoints(frameData.pointsToRender,
getCapability(ColorableCapability.class).getColor(),
IGraphicsTarget.PointStyle.CIRCLE,
getCapability(MagnificationCapability.class)
@ -123,8 +144,8 @@ public class GenericGeometryResource extends
OutlineCapability outlineCapability = getCapability(OutlineCapability.class);
// Finally, draw the shape
if (this.shape != null && outlineCapability.isOutlineOn()) {
target.drawWireframeShape(this.shape,
if (frameData.shape != null && outlineCapability.isOutlineOn()) {
target.drawWireframeShape(frameData.shape,
getCapability(ColorableCapability.class).getColor(),
outlineCapability.getOutlineWidth(),
outlineCapability.getLineStyle());
@ -151,19 +172,21 @@ public class GenericGeometryResource extends
* (com.raytheon.uf.viz.core.IGraphicsTarget)
*/
@Override
protected void prepareData(IGraphicsTarget target) throws VizException {
this.initDrawableStorage();
protected void prepareData(IGraphicsTarget target, DataTime time)
throws VizException {
IWireframeShape shape = null;
List<double[]> pointsToRender = new ArrayList<double[]>();
int numberOfPoints = 0;
for (IGeometryData geometryData : this.resourceData.getData()) {
for (IGeometryData geometryData : this.resourceData.getData(time)) {
Geometry geometry = geometryData.getGeometry();
if (geometry instanceof Point) {
double[] pixels = this.descriptor
.worldToPixel(new double[] {
geometry.getCoordinate().x,
geometry.getCoordinate().y });
this.pointsToRender.add(pixels);
pointsToRender.add(pixels);
} else {
// Calculate the number of points.
@ -184,14 +207,13 @@ public class GenericGeometryResource extends
if (numberOfPoints > 0) {
// create the wireframe shape
this.shape = target.createWireframeShape(false, this.descriptor,
0.0f);
shape = target.createWireframeShape(false, this.descriptor, 0.0f);
JTSCompiler jtsCompiler = new JTSCompiler(null, this.shape,
JTSCompiler jtsCompiler = new JTSCompiler(null, shape,
this.descriptor, PointStyle.CROSS);
this.shape.allocate(numberOfPoints);
shape.allocate(numberOfPoints);
// add the geometries
for (IGeometryData geometryData : this.resourceData.getData()) {
for (IGeometryData geometryData : this.resourceData.getData(time)) {
try {
jtsCompiler.handle((Geometry) geometryData.getGeometry()
.clone());
@ -204,9 +226,9 @@ public class GenericGeometryResource extends
}
// compile
this.shape.compile();
shape.compile();
}
this.geometriesReady = true;
renderableData.put(time, new FrameData(pointsToRender, shape));
}
/*
@ -221,24 +243,17 @@ public class GenericGeometryResource extends
return StringUtils.EMPTY;
}
/**
* Initializes the lists that will track the geometric entities that we will
* be drawing.
*/
private void initDrawableStorage() {
this.pointsToRender = new ArrayList<double[]>();
}
/**
* Normally invoked when the resource is disposed; purges all saved
* geometric entities
*/
public void purgeDrawableStorage() {
this.pointsToRender = null;
if (this.shape != null) {
this.shape.dispose();
Collection<FrameData> frames = renderableData.values();
renderableData = new HashMap<DataTime, FrameData>();
for (FrameData frame : frames) {
if (frame.shape != null) {
frame.shape.dispose();
}
}
this.shape = null;
this.geometriesReady = false;
}
}

View file

@ -20,12 +20,20 @@
package com.raytheon.viz.dataaccess.rsc.grid;
import java.nio.Buffer;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import javax.measure.unit.UnitFormat;
import org.apache.commons.lang.StringUtils;
import org.geotools.coverage.grid.GridGeometry2D;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import com.raytheon.uf.common.dataaccess.grid.IGridData;
import com.raytheon.uf.common.geospatial.interpolation.data.ByteBufferWrapper;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.geospatial.interpolation.data.FloatBufferWrapper;
import com.raytheon.uf.common.time.DataTime;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.drawables.ColorMapLoader;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
@ -33,6 +41,7 @@ import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
import com.raytheon.uf.viz.core.style.level.Level.LevelType;
import com.raytheon.uf.viz.core.style.level.SingleLevel;
import com.raytheon.viz.core.drawables.ColorMapParameterFactory;
import com.raytheon.viz.core.rsc.displays.GriddedImageDisplay2;
@ -64,7 +73,7 @@ public class GenericGridResource extends
private static final String GENERIC_LEGEND_TEXT = "Generic Grid ";
private GriddedImageDisplay2 griddedImageDisplay;
private Map<DataTime, GriddedImageDisplay2> displays = new HashMap<DataTime, GriddedImageDisplay2>();
protected GenericGridResource(GenericGridResourceData resourceData,
LoadProperties loadProperties) {
@ -79,33 +88,63 @@ public class GenericGridResource extends
* @throws VizException
*/
@Override
protected void prepareData(IGraphicsTarget target) throws VizException {
IGridData gridData = this.resourceData.getFirstDataElement();
protected void prepareData(IGraphicsTarget target, DataTime time)
throws VizException {
IGridData gridData = this.resourceData.getFirstDataElement(time);
GridGeometry2D gridGeometry = gridData.getGridGeometry();
// Extract the raw data
ByteBufferWrapper byteBufferWrapper = new ByteBufferWrapper(
gridGeometry);
byteBufferWrapper = gridData.populateData(byteBufferWrapper);
Buffer buffer = byteBufferWrapper.getBuffer();
FloatBufferWrapper bufferWrapper = new FloatBufferWrapper(gridGeometry);
bufferWrapper = gridData.populateData(bufferWrapper);
Buffer buffer = bufferWrapper.getBuffer();
// Prepare the Color Map
SingleLevel singleLevel = null;
if (gridData.getLevel() != null) {
// TODO: convert level to single level
initColorMapParameters(gridData, buffer);
GriddedImageDisplay2 griddedImageDisplay = new GriddedImageDisplay2(
buffer, gridGeometry, this);
displays.put(time, griddedImageDisplay);
}
protected void initColorMapParameters(IGridData gridData, Buffer buffer)
throws VizException {
ColorMapCapability capability = getCapability(ColorMapCapability.class);
ColorMapParameters colorMapParameters = capability
.getColorMapParameters();
if (colorMapParameters == null || this.displays.isEmpty()) {
SingleLevel singleLevel = null;
if (gridData.getLevel() != null) {
try {
singleLevel = new SingleLevel(gridData.getLevel()
.getMasterLevel().getName());
} catch (IllegalArgumentException e) {
// level cannot be mapped to a level
singleLevel = new SingleLevel(LevelType.DEFAULT);
}
singleLevel.setValue(gridData.getLevel().getLevelonevalue());
}
ColorMapParameters newCmp = ColorMapParameterFactory
.build(buffer.array(), gridData.getParameter(),
gridData.getUnit(), singleLevel);
if (colorMapParameters != null) {
// This means the capability was serialized so preserve
// serialized fields.
newCmp.applyPersistedParameters(colorMapParameters
.getPersisted());
newCmp.setColorMapName(colorMapParameters.getColorMapName());
}
colorMapParameters = newCmp;
}
ColorMapParameters colorMapParameters = ColorMapParameterFactory.build(
buffer.array(), gridData.getParameter(), gridData.getUnit(),
singleLevel);
colorMapParameters.setColorMapName(GRID_COLORMAP);
colorMapParameters.setColorMap(ColorMapLoader
.loadColorMap(colorMapParameters.getColorMapName()));
getCapability(ColorMapCapability.class).setColorMapParameters(
colorMapParameters);
this.griddedImageDisplay = new GriddedImageDisplay2(buffer,
gridGeometry, this);
if (colorMapParameters.getColorMap() == null) {
String colorMapName = colorMapParameters.getColorMapName();
if (colorMapName == null) {
colorMapName = GRID_COLORMAP;
colorMapParameters.setColorMapName(colorMapName);
}
colorMapParameters.setColorMap(ColorMapLoader
.loadColorMap(colorMapName));
}
capability.setColorMapParameters(colorMapParameters);
}
/*
@ -116,9 +155,21 @@ public class GenericGridResource extends
*/
@Override
protected String buildLegendTextInternal() {
DataTime timeToInspect = null;
if (!isTimeAgnostic()) {
timeToInspect = descriptor.getTimeForResource(this);
if (timeToInspect == null) {
return "";
}
}
IGridData gridData = this.resourceData
.getFirstDataElement(timeToInspect);
if (gridData == null) {
return StringUtils.EMPTY;
}
StringBuilder stringBuilder = new StringBuilder();
IGridData gridData = this.resourceData.getFirstDataElement();
if (gridData.getParameter() != null) {
stringBuilder.append(gridData.getParameter());
stringBuilder.append(_SPACE_);
@ -140,10 +191,11 @@ public class GenericGridResource extends
*/
@Override
protected void disposeInternal() {
if (this.griddedImageDisplay != null) {
this.griddedImageDisplay.dispose();
Collection<GriddedImageDisplay2> displays = this.displays.values();
this.displays = new HashMap<DataTime, GriddedImageDisplay2>();
for (GriddedImageDisplay2 display : displays) {
display.dispose();
}
this.griddedImageDisplay = null;
}
/*
@ -157,7 +209,20 @@ public class GenericGridResource extends
@Override
protected void paintInternal(IGraphicsTarget target,
PaintProperties paintProps) throws VizException {
this.griddedImageDisplay.paint(target, paintProps);
DataTime timeToPaint = null;
if (!isTimeAgnostic()) {
timeToPaint = paintProps.getDataTime();
if (timeToPaint == null) {
return;
}
}
GriddedImageDisplay2 griddedImageDisplay = displays.get(timeToPaint);
if (griddedImageDisplay == null) {
prepareData(target, paintProps.getDataTime());
griddedImageDisplay = displays.get(paintProps.getDataTime());
}
griddedImageDisplay.paint(target, paintProps);
}
/*
@ -169,6 +234,39 @@ public class GenericGridResource extends
*/
@Override
public void project(CoordinateReferenceSystem mapData) throws VizException {
this.griddedImageDisplay.project(this.descriptor.getGridGeometry());
for (GriddedImageDisplay2 display : displays.values()) {
display.project(this.descriptor.getGridGeometry());
}
}
@Override
public String inspect(ReferencedCoordinate coord) throws VizException {
DataTime timeToInspect = null;
if (!isTimeAgnostic()) {
timeToInspect = descriptor.getTimeForResource(this);
if (timeToInspect == null) {
return "";
}
}
GriddedImageDisplay2 display = displays.get(timeToInspect);
if (display == null) {
return null;
}
ColorMapParameters cmp = getCapability(ColorMapCapability.class)
.getColorMapParameters();
double value = Double.NaN;
try {
value = display.interrogate(coord.asLatLon());
} catch (Exception e) {
throw new VizException(e);
}
String unitString = "";
if (cmp.getDisplayUnit() != null) {
unitString = _SPACE_
+ UnitFormat.getUCUMInstance().format(cmp.getDisplayUnit());
value = cmp.getDataToDisplayConverter().convert(value);
}
return value + unitString;
}
}