Issue #1562 Made topo create colormap parameters off existing ones and moved to new tileset API

Change-Id: Iba534200e893a0e4febc2b14ec0161e2d8b0e6d3

Former-commit-id: 51ad0f0a990f1238ba0ba01491e155eb5efb6012
This commit is contained in:
Max Schenkelberg 2013-01-31 14:26:06 -06:00
parent 49a4e1c39d
commit a3efce7917
3 changed files with 208 additions and 179 deletions

View file

@ -20,7 +20,9 @@
package com.raytheon.viz.core.topo;
import java.io.File;
import java.text.DecimalFormat;
import java.util.Map;
import javax.measure.converter.UnitConverter;
import javax.measure.quantity.Length;
@ -29,18 +31,34 @@ import javax.measure.unit.SI;
import javax.measure.unit.Unit;
import javax.measure.unit.UnitFormat;
import org.apache.commons.lang.Validate;
import org.geotools.coverage.grid.GeneralGridEnvelope;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.geospatial.CRSCache;
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
import com.raytheon.uf.common.localization.IPathManager;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.drawables.ColorMapLoader;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters.PersistedParameters;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.IMapDescriptor;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.IResourceDataChanged;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability;
import com.raytheon.uf.viz.core.tile.TileSetRenderable;
import com.raytheon.viz.core.drawables.ColorMapParameterFactory;
/**
@ -60,7 +78,17 @@ import com.raytheon.viz.core.drawables.ColorMapParameterFactory;
public class TopoResource extends
AbstractVizResource<TopoResourceData, IMapDescriptor> {
private TopoTileSet topoTileSet;
private static final File DATA_FILE = new File("topo"
+ IPathManager.SEPARATOR + "srtm30.hdf");
private IResourceDataChanged changeListener = new IResourceDataChanged() {
@Override
public void resourceChanged(ChangeType type, Object object) {
issueRefresh();
}
};
private TileSetRenderable topoTileSet;
protected TopoResource(TopoResourceData topoData,
LoadProperties loadProperties) throws VizException {
@ -76,7 +104,9 @@ public class TopoResource extends
protected void disposeInternal() {
if (topoTileSet != null) {
topoTileSet.dispose();
topoTileSet = null;
}
resourceData.removeChangeListener(changeListener);
}
/*
@ -88,6 +118,8 @@ public class TopoResource extends
*/
@Override
protected void initInternal(IGraphicsTarget target) throws VizException {
resourceData.addChangeListener(changeListener);
Unit<Length> dataUnit = SI.METER;
// TODO: create topo style rules for topo and bathymetric topo
@ -104,7 +136,26 @@ public class TopoResource extends
if (colorMapName == null) {
colorMapName = "topo";
}
parameters.setColorMap(target.buildColorMap(colorMapName));
ColorMapParameters existing = getCapability(ColorMapCapability.class)
.getColorMapParameters();
if (existing != null) {
PersistedParameters params = existing.getPersisted();
if (params != null) {
parameters.setColorMapMin(params.getColorMapMin());
parameters.setColorMapMax(params.getColorMapMax());
}
if (existing.getColorMap() != null) {
parameters.setColorMap(existing.getColorMap());
} else if (existing.getColorMapName() != null) {
colorMapName = existing.getColorMapName();
}
}
if (parameters.getColorMap() == null) {
parameters.setColorMap(ColorMapLoader.loadColorMap(colorMapName));
}
if (parameters.getDisplayUnit() == null) {
parameters.setDisplayUnit(NonSI.FOOT);
@ -114,10 +165,64 @@ public class TopoResource extends
getCapability(ColorMapCapability.class).setColorMapParameters(
parameters);
topoTileSet = new TopoTileSet(this, target.getViewType());
topoTileSet.setMapDescriptor(descriptor);
topoTileSet.init(target);
topoTileSet = new TileSetRenderable(
getCapability(ImagingCapability.class), getTopoGeometry(),
new TopoTileImageCreator(this, DATA_FILE),
getNumberOfTopoLevels(), 512);
topoTileSet.project(descriptor.getGridGeometry());
}
private int getNumberOfTopoLevels() throws VizException {
IDataStore ds = DataStoreFactory.getDataStore(DATA_FILE);
try {
return ds.getDatasets("/interpolated").length + 1;
} catch (Exception e) {
throw new VizException("Error getting interpolation levels", e);
}
}
private GridGeometry2D getTopoGeometry() throws VizException {
IDataStore ds = DataStoreFactory.getDataStore(DATA_FILE);
Request request = Request.buildSlab(new int[] { 0, 0 }, new int[] { 1,
1 });
try {
IDataRecord record = ds.retrieve("/", "full", request);
Map<String, Object> attributes = record.getDataAttributes();
int width = (Integer) attributes.get("Width");
int height = (Integer) attributes.get("Height");
double ulLat = (Double) attributes.get("ulLat");
double ulLon = (Double) attributes.get("ulLon");
double lrLat = (Double) attributes.get("lrLat");
double lrLon = (Double) attributes.get("lrLon");
String crsString = (String) attributes.get("CRS");
// construct the grid geometry that covers the topo grid
CoordinateReferenceSystem crs = CRSCache.getInstance()
.getCoordinateReferenceSystem(crsString);
GeneralEnvelope ge = new GeneralEnvelope(2);
ge.setCoordinateReferenceSystem(crs);
ge.setRange(0, ulLon, lrLon);
ge.setRange(1, lrLat, ulLat);
GeneralGridEnvelope gr = new GeneralGridEnvelope(
new int[] { 1, 1 }, new int[] { width, height }, false);
GridToEnvelopeMapper mapper = new GridToEnvelopeMapper();
mapper.setEnvelope(ge);
mapper.setGridRange(gr);
mapper.setPixelAnchor(PixelInCell.CELL_CENTER);
mapper.setReverseAxis(new boolean[] { false, true });
MathTransform mt = mapper.createTransform();
GridGeometry2D gridGeom = new GridGeometry2D(
PixelInCell.CELL_CORNER, mt, ge, null);
return gridGeom;
} catch (Exception e) {
throw new VizException("Error getting grid geometry", e);
}
}
/*
@ -131,30 +236,11 @@ public class TopoResource extends
@Override
protected void paintInternal(IGraphicsTarget target,
PaintProperties paintProps) throws VizException {
if (topoTileSet != null) {
topoTileSet.paint(target, paintProps);
}
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.uf.viz.core.rsc.AbstractVizResource#setDescriptor(com.raytheon
* .uf.viz.core.drawables.IDescriptor)
*/
@Override
public void setDescriptor(IMapDescriptor descriptor) {
super.setDescriptor(descriptor);
Validate.isTrue(descriptor instanceof IMapDescriptor,
"Resource expects map descriptor");
if (topoTileSet != null) {
topoTileSet.setMapDescriptor(this.descriptor);
}
}
/*
* (non-Javadoc)
*
@ -165,7 +251,7 @@ public class TopoResource extends
@Override
public void project(CoordinateReferenceSystem mapData) throws VizException {
if (topoTileSet != null) {
topoTileSet.reproject();
topoTileSet.project(descriptor.getGridGeometry());
}
}
@ -181,7 +267,7 @@ public class TopoResource extends
double height;
try {
// height = TopoQuery.getInstance().getHeight(coord.asLatLon());
height = topoTileSet.interrogate(coord.asLatLon(), true);
height = topoTileSet.interrogate(coord.asLatLon());
} catch (Exception e) {
throw new VizException("Error transforming", e);
}

View file

@ -0,0 +1,95 @@
/**
* 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.viz.core.topo;
import java.io.File;
import org.geotools.coverage.grid.GeneralGridGeometry;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IGraphicsTarget.RasterMode;
import com.raytheon.uf.viz.core.IMesh;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.data.prep.HDF5DataRetriever;
import com.raytheon.uf.viz.core.drawables.IColormappedImage;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormappedImageExtension;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.IMapMeshExtension;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
import com.raytheon.uf.viz.core.tile.Tile;
import com.raytheon.uf.viz.core.tile.TileSetRenderable.TileImageCreator;
/**
* Image creator for topo tiles, uses hdf5 data file for retrieval
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 31, 2013 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
public class TopoTileImageCreator implements TileImageCreator {
private TopoResource resource;
private File dataFile;
public TopoTileImageCreator(TopoResource resource, File dataFile) {
this.resource = resource;
this.dataFile = dataFile;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.tile.TileSetRenderable.TileImageCreator#
* createTileImage(com.raytheon.uf.viz.core.IGraphicsTarget,
* com.raytheon.uf.viz.core.tile.Tile,
* org.geotools.coverage.grid.GeneralGridGeometry)
*/
@Override
public DrawableImage createTileImage(IGraphicsTarget target, Tile tile,
GeneralGridGeometry targetGeometry) throws VizException {
int level = tile.tileLevel;
String dataset = "/full";
if (level > 0) {
dataset = "/interpolated/" + level;
}
IColormappedImage image = target.getExtension(
IColormappedImageExtension.class).initializeRaster(
new HDF5DataRetriever(dataFile, dataset, tile.getRectangle()),
resource.getCapability(ColorMapCapability.class)
.getColorMapParameters());
IMesh mesh = target.getExtension(IMapMeshExtension.class)
.constructMesh(tile.tileGeometry, targetGeometry);
return new DrawableImage(image, new PixelCoverage(mesh),
RasterMode.ASYNCHRONOUS);
}
}

View file

@ -1,152 +0,0 @@
/**
* This software was developed and / or modified by Raytheon Company,
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
*
* U.S. EXPORT CONTROLLED TECHNICAL DATA
* This software product contains export-restricted data whose
* export/transfer/disclosure is restricted by U.S. law. Dissemination
* to non-U.S. persons whether in the United States or abroad requires
* an export license or other authorization.
*
* Contractor Name: Raytheon Company
* Contractor Address: 6825 Pine Street, Suite 340
* Mail Stop B8
* Omaha, NE 68106
* 402.291.0100
*
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.viz.core.topo;
import java.io.File;
import java.util.Map;
import org.geotools.coverage.grid.GeneralGridEnvelope;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
import com.raytheon.uf.common.datastorage.DataStoreFactory;
import com.raytheon.uf.common.datastorage.IDataStore;
import com.raytheon.uf.common.datastorage.Request;
import com.raytheon.uf.common.datastorage.records.IDataRecord;
import com.raytheon.uf.common.geospatial.CRSCache;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.data.prep.HDF5DataRetriever;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormappedImageExtension;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
import com.raytheon.viz.core.rsc.hdf5.FileBasedTileSet;
/**
* Implements a single tile of the SRTM dataset
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 15, 2007 chammack Initial Creation.
* Jan 14, 2013 1469 bkowal The hdf5 data directory is no longer included in the
* DATA_FILE
*
* </pre>
*
* @author chammack
* @version 1
*/
public class TopoTileSet extends FileBasedTileSet {
private static String DATA_FILE = "/topo/srtm30.hdf";
static {
DATA_FILE = new File(DATA_FILE)
.getAbsolutePath();
}
protected static int getNumLevels() throws VizException {
IDataStore ds = DataStoreFactory.getDataStore(new File(DATA_FILE));
try {
return ds.getDatasets("/interpolated").length + 1;
} catch (Exception e) {
throw new VizException("Error getting interpolation levels", e);
}
}
protected static GridGeometry2D getGridGeometry() throws VizException {
IDataStore ds = DataStoreFactory.getDataStore(new File(DATA_FILE));
Request request = Request.buildSlab(new int[] { 0, 0 }, new int[] { 1,
1 });
try {
IDataRecord record = ds.retrieve("/", "full", request);
Map<String, Object> attributes = record.getDataAttributes();
int width = (Integer) attributes.get("Width");
int height = (Integer) attributes.get("Height");
double ulLat = (Double) attributes.get("ulLat");
double ulLon = (Double) attributes.get("ulLon");
double lrLat = (Double) attributes.get("lrLat");
double lrLon = (Double) attributes.get("lrLon");
String crsString = (String) attributes.get("CRS");
// construct the grid geometry that covers the topo grid
CoordinateReferenceSystem crs = CRSCache.getInstance()
.getCoordinateReferenceSystem(crsString);
GeneralEnvelope ge = new GeneralEnvelope(2);
ge.setCoordinateReferenceSystem(crs);
ge.setRange(0, ulLon, lrLon);
ge.setRange(1, lrLat, ulLat);
GeneralGridEnvelope gr = new GeneralGridEnvelope(
new int[] { 1, 1 }, new int[] { width, height }, false);
GridToEnvelopeMapper mapper = new GridToEnvelopeMapper();
mapper.setEnvelope(ge);
mapper.setGridRange(gr);
mapper.setPixelAnchor(PixelInCell.CELL_CENTER);
mapper.setReverseAxis(new boolean[] { false, true });
MathTransform mt = mapper.createTransform();
GridGeometry2D gridGeom = new GridGeometry2D(
PixelInCell.CELL_CORNER, mt, ge, null);
return gridGeom;
} catch (Exception e) {
throw new VizException("Error getting grid geometry", e);
}
}
public TopoTileSet(AbstractVizResource<?, ?> rsc, String viewType)
throws VizException {
super(DATA_FILE, null, null, getNumLevels(), 256, getGridGeometry(),
rsc, PixelInCell.CELL_CORNER, viewType);
}
@Override
protected IImage createTile(IGraphicsTarget target, int level, int i, int j)
throws VizException {
String dataset;
if (level == 0) {
dataset = "/full";
} else {
dataset = "/interpolated/" + level;
}
return target.getExtension(IColormappedImageExtension.class)
.initializeRaster(
new HDF5DataRetriever(new File(this.hdf5File), dataset,
this.tileSet.getTile(level, i, j)
.getRectangle()),
rsc.getCapability(ColorMapCapability.class)
.getColorMapParameters());
}
}