/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wps.sextante; import java.awt.geom.Rectangle2D; import java.awt.image.DataBuffer; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.io.File; import javax.media.jai.PlanarImage; import javax.media.jai.RasterFactory; import org.geotools.coverage.CoverageFactoryFinder; import org.geotools.coverage.GridSampleDimension; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.grid.GridCoverageFactory; import org.geotools.coverage.grid.io.AbstractGridCoverageWriter; import org.geotools.gce.arcgrid.ArcGridWriter; import org.geotools.gce.geotiff.GeoTiffWriter; import org.geotools.geometry.Envelope2D; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.opengis.geometry.Envelope; import org.opengis.referencing.crs.CoordinateReferenceSystem; import es.unex.sextante.core.AnalysisExtent; import es.unex.sextante.dataObjects.AbstractRasterLayer; import es.unex.sextante.outputs.FileOutputChannel; import es.unex.sextante.outputs.IOutputChannel; public class GTRasterLayer extends AbstractRasterLayer { private CoordinateReferenceSystem m_CRS; private String m_sFilename; private String m_sName = ""; private PlanarImage m_image; private AnalysisExtent m_LayerExtent; private double m_dNoDataValue; private Object m_BaseDataObject; public void create(final String name, final String filename, final AnalysisExtent ge, final int dataType, final int numBands, Object crs, final double defaultNoDataValue) { if (!(crs instanceof CoordinateReferenceSystem) || (crs == null)) { crs = DefaultGeographicCRS.WGS84; } m_CRS = (CoordinateReferenceSystem) crs; final Raster m_Raster = RasterFactory.createBandedRaster(dataType, ge.getNX(), ge.getNY(), numBands, null); double width = ge.getXMax() - ge.getXMin(); double height = ge.getYMax() - ge.getYMin(); final Envelope envelope = new Envelope2D((CoordinateReferenceSystem) crs, ge.getXMin(), ge.getYMin(), width, height); final GridCoverageFactory factory = CoverageFactoryFinder.getGridCoverageFactory(null); final GridCoverage2D gc = factory.create(name, (WritableRaster) m_Raster, envelope, null, null, null, null, null); m_BaseDataObject = gc; m_sName = name; m_sFilename = filename; m_LayerExtent = ge; m_image = (PlanarImage) gc.getRenderedImage(); m_dNoDataValue = defaultNoDataValue; initNoData((GridCoverage2D) m_BaseDataObject); } private void initNoData(final GridCoverage2D gc) { final Object value = gc.getProperty("GC_NODATA"); if ((value != null) && (value instanceof Number)) { m_dNoDataValue = ((Number) value).doubleValue(); return; } else { final GridSampleDimension[] dimList = gc.getSampleDimensions(); double[] noDataList; for (int i = 0; i < dimList.length; i++) { noDataList = dimList[i].getNoDataValues(); if ((noDataList != null) && (noDataList.length > 0)) { m_dNoDataValue = noDataList[0]; return; } } } // ensure we got a sensible result, because some GridCoverage2D are not able to provide no-data values //setNoDataValue(CommandLineData.getDefaultNoData()); } public void create(final Object obj) { if (obj instanceof GridCoverage2D) { m_BaseDataObject = obj; final GridCoverage2D gc = ((GridCoverage2D) obj); m_CRS = gc.getCoordinateReferenceSystem(); final Envelope2D env = gc.getEnvelope2D(); m_LayerExtent = new AnalysisExtent(); m_LayerExtent.setCellSize((env.getMaxX() - env.getMinX()) / gc.getRenderedImage().getWidth()); m_LayerExtent.setXRange(env.getMinX(), env.getMaxX(), true); m_LayerExtent.setYRange(env.getMinY(), env.getMaxY(), true); m_image = (PlanarImage) gc.getRenderedImage(); m_sName = gc.getName().toString(); m_dNoDataValue = -99999; //-> Default value in 'OutputFactory::getDefaultNoDataValue()'. initNoData(gc); } } public int getBandsCount() { if (m_BaseDataObject != null) { final GridCoverage2D gc = (GridCoverage2D) m_BaseDataObject; return gc.getNumSampleDimensions(); } else { return 0; } } public double getCellValueInLayerCoords(final int x, final int y, final int band) { try { if (m_image != null) { return getTile(x, y).getSampleDouble(x, y, band); } else { return getNoDataValue(); } } catch (final Exception e) { return getNoDataValue(); } } public int getDataType() { if (m_image != null) { return m_image.getTile(0, 0).getDataBuffer().getDataType(); } else { return DataBuffer.TYPE_DOUBLE; } } public double getLayerCellSize() { if (m_LayerExtent != null) { return m_LayerExtent.getCellSize(); } else { return 0; } } public AnalysisExtent getLayerGridExtent() { return m_LayerExtent; } public double getNoDataValue() { return m_dNoDataValue; } public void setCellValue(final int x, final int y, final int band, final double value) { if (isInWindow(x, y)) { final Raster raster = getTile(x, y); if (raster instanceof WritableRaster) { ((WritableRaster) raster).setSample(x, y, band, value); } } } public void setNoDataValue(final double noDataValue) { m_dNoDataValue = noDataValue; } public Object getCRS() { return m_CRS; } public Rectangle2D getFullExtent() { if (m_BaseDataObject != null) { final GridCoverage2D gc = (GridCoverage2D) m_BaseDataObject; return new Envelope2D(gc.getEnvelope()); } else { return null; } } public void open() {} public void close() {} public void postProcess() {} public IOutputChannel getOutputChannel() { return new FileOutputChannel(m_sFilename); } public String getName() { return m_sName; } public void setName(final String sName) { m_sName = sName; } private Raster getTile(final int x, final int y) { return m_image.getTile(m_image.XToTileX(x), m_image.YToTileY(y)); } @Override public void free() { ((GridCoverage2D) m_BaseDataObject).dispose(true); m_BaseDataObject = null; } @Override public Object getBaseDataObject() { return m_BaseDataObject; } }