/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2012-2015, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.storage.coverage; import java.awt.Point; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.collection.TableColumn; import org.apache.sis.util.logging.Logging; import org.geotoolkit.coverage.io.CoverageReader; import org.geotoolkit.coverage.io.CoverageStoreException; import org.geotoolkit.coverage.io.GridCoverageWriter; import org.opengis.util.GenericName; import org.geotoolkit.storage.DefaultDataNode; import javax.xml.bind.annotation.XmlTransient; import org.apache.sis.metadata.iso.content.DefaultAttributeGroup; import org.apache.sis.metadata.iso.content.DefaultCoverageDescription; import org.geotoolkit.coverage.grid.GeneralGridGeometry; import org.geotoolkit.coverage.grid.GridCoverage2D; import org.geotoolkit.coverage.io.GridCoverageReadParam; import org.geotoolkit.coverage.io.GridCoverageReader; import org.geotoolkit.metadata.ImageStatistics; import org.geotoolkit.utility.parameter.ParametersExt; import org.geotoolkit.process.Process; import org.geotoolkit.process.ProcessDescriptor; import org.geotoolkit.process.ProcessException; import org.geotoolkit.process.ProcessFinder; import org.opengis.coverage.grid.GridCoverage; import org.opengis.coverage.grid.GridEnvelope; import org.opengis.geometry.Envelope; import org.opengis.metadata.content.CoverageDescription; import org.opengis.parameter.ParameterValueGroup; import org.opengis.util.NoSuchIdentifierException; /** * * @author Johann Sorel (Geomatys) */ @XmlTransient public abstract class AbstractCoverageReference extends DefaultDataNode implements CoverageReference { protected final CoverageStore store; protected final GenericName name; private DefaultCoverageDescription desc = null; /** * * @param store can be null * @param name never null */ public AbstractCoverageReference(CoverageStore store, GenericName name) { ArgumentChecks.ensureNonNull("name",name); setValue(TableColumn.NAME, name.tip().toString()); this.store = store; this.name = name; } @Override public GenericName getName() { return name; } @Override public CoverageStore getStore() { return store; } @Override public synchronized CoverageDescription getMetadata() { if(desc!=null) return desc; //calculate image statistics try { final GridCoverageReader reader = acquireReader(); final GeneralGridGeometry gridGeom = reader.getGridGeometry(getImageIndex()); final Envelope env = gridGeom.getEnvelope(); final GridEnvelope ext = gridGeom.getExtent(); final double[] res = new double[ext.getDimension()]; double max = 0; for(int i=0;i<res.length;i++){ res[i] = (env.getSpan(i) / 1000); max = Math.max(max,res[i]); } Arrays.fill(res, max); final GridCoverageReadParam param = new GridCoverageReadParam(); param.setEnvelope(env); param.setResolution(res); final GridCoverage coverage = reader.read(getImageIndex(), param); if(!(coverage instanceof GridCoverage2D)) return null; final ProcessDescriptor processDesc = ProcessFinder.getProcessDescriptor("coverage", "statistic"); final ParameterValueGroup processParam = processDesc.getInputDescriptor().createValue(); ParametersExt.getOrCreateValue(processParam, "inCoverage").setValue(coverage); ParametersExt.getOrCreateValue(processParam, "inExcludeNoData").setValue(true); final Process process = processDesc.createProcess(processParam); final ParameterValueGroup result = process.call(); final ImageStatistics stats = (ImageStatistics) ParametersExt.getOrCreateValue(result, "outStatistic").getValue(); desc = new CoverageDescriptionAdapter(stats); } catch (CoverageStoreException | NoSuchIdentifierException | ProcessException ex) { Logging.getLogger("org.geotoolkit.storage.coverage").log(Level.WARNING, ex.getMessage(), ex); } if (desc == null) { desc = new DefaultCoverageDescription(); final DefaultAttributeGroup attg = new DefaultAttributeGroup(); desc.getAttributeGroups().add(attg); } return desc; } /** * Default recycle implementation. * Dispose the reader. * * @param reader */ @Override public void recycle(CoverageReader reader) { dispose(reader); } /** * Default recycle implementation. * Dispose the writer. * * @param writer */ @Override public void recycle(GridCoverageWriter writer) { try { writer.dispose(); } catch (CoverageStoreException ex) { Logging.getLogger("org.geotoolkit.storage.coverage").log(Level.WARNING, ex.getMessage(), ex); } } protected CoverageStoreManagementEvent firePyramidAdded(final String pyramidId){ final CoverageStoreManagementEvent event = CoverageStoreManagementEvent.createPyramidAddEvent(this, getName(), pyramidId); sendStructureEvent(event); return event; } protected CoverageStoreManagementEvent firePyramidUpdated(final String pyramidId){ final CoverageStoreManagementEvent event = CoverageStoreManagementEvent.createPyramidUpdateEvent(this, getName(), pyramidId); sendStructureEvent(event); return event; } protected CoverageStoreManagementEvent firePyramidDeleted(final String pyramidId){ final CoverageStoreManagementEvent event = CoverageStoreManagementEvent.createPyramidDeleteEvent(this, getName(), pyramidId); sendStructureEvent(event); return event; } protected CoverageStoreManagementEvent fireMosaicAdded(final String pyramidId, final String mosaicId){ final CoverageStoreManagementEvent event = CoverageStoreManagementEvent.createMosaicAddEvent(this, getName(), pyramidId, mosaicId); sendStructureEvent(event); return event; } protected CoverageStoreManagementEvent fireMosaicUpdated(final String pyramidId, final String mosaicId){ final CoverageStoreManagementEvent event = CoverageStoreManagementEvent.createMosaicUpdateEvent(this, getName(), pyramidId, mosaicId); sendStructureEvent(event); return event; } protected CoverageStoreManagementEvent fireMosaicDeleted(final String pyramidId, final String mosaicId){ final CoverageStoreManagementEvent event = CoverageStoreManagementEvent.createMosaicDeleteEvent(this, getName(), pyramidId, mosaicId); sendStructureEvent(event); return event; } protected CoverageStoreContentEvent fireDataUpdated(){ final CoverageStoreContentEvent event = CoverageStoreContentEvent.createDataUpdateEvent(this, getName()); sendContentEvent(event); return event; } protected CoverageStoreContentEvent fireTileAdded(final String pyramidId, final String mosaicId, final List<Point> tiles){ final CoverageStoreContentEvent event = CoverageStoreContentEvent.createTileAddEvent(this, getName(), pyramidId, mosaicId, tiles); sendContentEvent(event); return event; } protected CoverageStoreContentEvent fireTileUpdated(final String pyramidId, final String mosaicId, final List<Point> tiles){ final CoverageStoreContentEvent event = CoverageStoreContentEvent.createTileUpdateEvent(this, getName(), pyramidId, mosaicId, tiles); sendContentEvent(event); return event; } protected CoverageStoreContentEvent fireTileDeleted(final String pyramidId, final String mosaicId, final List<Point> tiles){ final CoverageStoreContentEvent event = CoverageStoreContentEvent.createTileDeleteEvent(this, getName(), pyramidId, mosaicId, tiles); sendContentEvent(event); return event; } /** * Dispose a reader, trying to properly release sub resources. * Best effort. * * @param reader */ protected void dispose(CoverageReader reader) { try { // //try to close sub stream // Object input = reader.getInput(); // if(input instanceof ImageReader){ // final ImageReader ireader = (ImageReader)input; // ImageIOUtilities.releaseReader(ireader); // }else if(input instanceof InputStream){ // final InputStream stream = (InputStream) input; // stream.close(); // }else if(input instanceof ImageInputStream){ // final ImageInputStream stream = (ImageInputStream) input; // stream.close(); // } reader.dispose(); } catch (CoverageStoreException ex) { Logging.getLogger("org.geotoolkit.storage.coverage").log(Level.WARNING, ex.getMessage(), ex); } } }