Omaha #3522 geotiff resources uses TileSetRenderable

Change-Id: I6f7bf69edb2f696847d44323511c0de219b96852

Former-commit-id: b6106ae8cd [formerly 9514da9d0aed2e2446412dad9f201642288e6aae]
Former-commit-id: 18b9be2315
This commit is contained in:
Brian Clements 2014-08-14 11:04:46 -05:00
parent a75af54f30
commit 3129f1032b
3 changed files with 195 additions and 25 deletions

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2 Bundle-ManifestVersion: 2
Bundle-Name: Geotiff Plug-in Bundle-Name: Geotiff Plug-in
Bundle-SymbolicName: com.raytheon.viz.geotiff;singleton:=true Bundle-SymbolicName: com.raytheon.viz.geotiff;singleton:=true
Bundle-Version: 1.14.0.qualifier Bundle-Version: 1.14.1.qualifier
Bundle-Activator: com.raytheon.viz.geotiff.Activator Bundle-Activator: com.raytheon.viz.geotiff.Activator
Bundle-Vendor: Raytheon Bundle-Vendor: Raytheon
Require-Bundle: org.eclipse.ui, Require-Bundle: org.eclipse.ui,

View file

@ -20,13 +20,12 @@
package com.raytheon.viz.geotiff.rsc; package com.raytheon.viz.geotiff.rsc;
import java.awt.image.RenderedImage;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import javax.imageio.ImageIO; import org.geotools.coverage.grid.GeneralGridGeometry;
import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.gce.geotiff.GeoTiffFormat; import org.geotools.gce.geotiff.GeoTiffFormat;
import org.geotools.gce.geotiff.GeoTiffReader; import org.geotools.gce.geotiff.GeoTiffReader;
import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.CoordinateReferenceSystem;
@ -37,13 +36,13 @@ import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.MapDescriptor; import com.raytheon.uf.viz.core.map.MapDescriptor;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.LoadProperties; import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.viz.core.rsc.hdf5.PureMemoryBasedTileSet; import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability;
import com.raytheon.uf.viz.core.tile.TileSetRenderable;
import com.raytheon.uf.viz.core.tile.TileSetRenderable.TileImageCreator;
/** /**
* Supports GeoTIFF imagery * Supports GeoTIFF imagery
* *
* NOTE: maximum of 2048 height/width in pixels.
*
* <pre> * <pre>
* *
* SOFTWARE HISTORY * SOFTWARE HISTORY
@ -51,6 +50,7 @@ import com.raytheon.viz.core.rsc.hdf5.PureMemoryBasedTileSet;
* Date Ticket# Engineer Description * Date Ticket# Engineer Description
* ------------ ---------- ----------- -------------------------- * ------------ ---------- ----------- --------------------------
* 8/24/06 chammack Initial Creation. * 8/24/06 chammack Initial Creation.
* Aug 14, 2014 3522 bclement reworked to use TileSetRenderable
* *
* </pre> * </pre>
* *
@ -60,11 +60,17 @@ import com.raytheon.viz.core.rsc.hdf5.PureMemoryBasedTileSet;
public class GeoTiffResource extends public class GeoTiffResource extends
AbstractVizResource<GeoTiffResourceData, MapDescriptor> { AbstractVizResource<GeoTiffResourceData, MapDescriptor> {
/** The tiled image */ private static final int TILE_SIZE = 512;
private PureMemoryBasedTileSet image;
private TileSetRenderable image;
private ImageStreamTileCreator tileCreator;
private String filePath; private String filePath;
/* true since TileSetRenderable needs reproject() called on it before use */
private boolean project = true;
protected GeoTiffResource(GeoTiffResourceData data, LoadProperties props) protected GeoTiffResource(GeoTiffResourceData data, LoadProperties props)
throws VizException, IOException { throws VizException, IOException {
super(data, props); super(data, props);
@ -78,6 +84,14 @@ public class GeoTiffResource extends
*/ */
@Override @Override
protected void disposeInternal() { protected void disposeInternal() {
if (tileCreator != null) {
try {
tileCreator.close();
} catch (IOException e) {
statusHandler.error(
"Unable to close geotiff tile image stream", e);
}
}
if (image != null) { if (image != null) {
image.dispose(); image.dispose();
} }
@ -92,28 +106,31 @@ public class GeoTiffResource extends
*/ */
@Override @Override
protected void initInternal(IGraphicsTarget target) throws VizException { protected void initInternal(IGraphicsTarget target) throws VizException {
File imgFile = new File(filePath);
if (!imgFile.canRead()) {
String msg = "Check file permissions.";
if (!imgFile.exists()) {
msg = "File does not exist.";
}
throw new VizException("Unable to open geotiff image: "
+ imgFile.getAbsolutePath()
+ ". " + msg);
}
try { try {
GeoTiffReader gcr = (GeoTiffReader) new GeoTiffFormat() GeoTiffReader gcr = (GeoTiffReader) new GeoTiffFormat()
.getReader(new File(filePath)); .getReader(imgFile);
// Read in the image itself using ImageIO as it is much more
// reliable
RenderedImage img = ImageIO.read(new File(filePath));
GridCoverage2D gridCoverage = (GridCoverage2D) gcr.read(null); GridCoverage2D gridCoverage = (GridCoverage2D) gcr.read(null);
image = new PureMemoryBasedTileSet(resourceData.getNameGenerator() ImagingCapability imaging = getCapability(ImagingCapability.class);
.getName(this), this, gridCoverage.getGridGeometry(), GridGeometry2D tileSetGeometry = gridCoverage.getGridGeometry();
PureMemoryBasedTileSet.calculateLevels(img), TileImageCreator tileCreator = new ImageStreamTileCreator(imgFile);
target.getViewType());
image.setMapDescriptor(this.descriptor);
image.setImage(img);
image.init(target);
image = new TileSetRenderable(imaging, tileSetGeometry,
tileCreator, 1, TILE_SIZE);
gridCoverage = null; gridCoverage = null;
img = null;
} catch (Exception e) { } catch (Exception e) {
// TODO: Handle exception throw new VizException("Unable to process geotiff image: "
e.printStackTrace(); + imgFile.getAbsolutePath(), e);
} }
} }
@ -129,6 +146,14 @@ public class GeoTiffResource extends
protected void paintInternal(IGraphicsTarget target, protected void paintInternal(IGraphicsTarget target,
PaintProperties paintProps) throws VizException { PaintProperties paintProps) throws VizException {
if (image != null) { if (image != null) {
if (project) {
project = false;
GeneralGridGeometry targetGeometry = descriptor
.getGridGeometry();
if (image.getTargetGeometry() != targetGeometry) {
image.project(targetGeometry);
}
}
image.paint(target, paintProps); image.paint(target, paintProps);
} }
} }
@ -142,6 +167,6 @@ public class GeoTiffResource extends
*/ */
@Override @Override
public void project(CoordinateReferenceSystem crs) throws VizException { public void project(CoordinateReferenceSystem crs) throws VizException {
image.reproject(); project = true;
} }
} }

View file

@ -0,0 +1,145 @@
/**
* 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.geotiff.rsc;
import java.awt.image.RenderedImage;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;
import org.geotools.coverage.grid.GeneralGridGeometry;
import org.geotools.coverage.grid.GridEnvelope2D;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IMesh;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.IMapMeshExtension;
import com.raytheon.uf.viz.core.tile.Tile;
import com.raytheon.uf.viz.core.tile.TileSetRenderable.TileImageCreator;
/**
* Tile image creator that gets tiles from a FileImageInputStream. Must be
* closed after use.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Aug 14, 2014 3522 bclement Initial creation
*
* </pre>
*
* @author bclement
* @version 1.0
*/
public class ImageStreamTileCreator implements TileImageCreator, Closeable {
private final ImageInputStream imgIn;
private final ImageReader imgReader;
/**
* @param in
* @throws IOException
* @see {@link #close()}
*/
public ImageStreamTileCreator(FileImageInputStream in) throws IOException {
this.imgIn = in;
Iterator<ImageReader> readers = ImageIO.getImageReaders(imgIn);
if (readers.hasNext()) {
this.imgReader = readers.next();
imgReader.setInput(imgIn);
} else {
imgIn.close();
throw new IOException("No image readers found for stream");
}
}
/**
* @param imageFile
* @throws FileNotFoundException
* @throws IOException
* @see {@link #close()}
*/
public ImageStreamTileCreator(File imageFile) throws FileNotFoundException,
IOException {
this(new FileImageInputStream(imageFile));
}
/* (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 {
if (tile.tileLevel != 0) {
throw new VizException(getClass().getSimpleName()
+ " only supports single level tiled data");
}
final GridEnvelope2D env = tile.tileGeometry.getGridRange2D();
final ImageReadParam param = imgReader.getDefaultReadParam();
param.setSourceRegion(env);
IImage img = target.initializeRaster(new IRenderedImageCallback() {
@Override
public RenderedImage getImage() throws VizException {
try {
synchronized (imgReader) {
return imgReader.read(0, param);
}
} catch (IOException e) {
throw new VizException(
"Unable to read tile from image stream for bounds: "
+ env, e);
}
}
});
IMesh mesh = target.getExtension(IMapMeshExtension.class)
.constructMesh(tile.tileGeometry, targetGeometry);
return new DrawableImage(img, new PixelCoverage(mesh));
}
/*
* (non-Javadoc)
*
* @see java.io.Closeable#close()
*/
@Override
public void close() throws IOException {
imgIn.close();
imgReader.dispose();
}
}