/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2014-2015, Open Source Geospatial Foundation (OSGeo) * (C) 2014 TOPP - www.openplans.org. * * 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.geotools.process.raster; import java.util.Collection; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.coverage.processing.CoverageProcessor; import org.geotools.coverage.processing.operation.BandMerge; import org.geotools.process.ProcessException; import org.geotools.process.factory.DescribeParameter; import org.geotools.process.factory.DescribeProcess; import org.geotools.process.factory.DescribeResult; import org.opengis.feature.simple.SimpleFeature; import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.crs.CoordinateReferenceSystem; import com.vividsolutions.jts.geom.Geometry; /** * Process calling the {@link BandMerge} operation. This process requires: * <ul> * <li>a {@link Collection} of {@link GridCoverage2D} objects (Note that they must be in the same CRS).</li> * <li>an optional ROI passed as {@link SimpleFeature}.</li> * <li>an optional String indicating the policy for choosing the Grid To World transformation(from those of all the Coverages) to use for the final * coverage. The available values are: FIRST(default), for selecting the first coverage; LAST, for the last coverage; INDEX, for selecting the * Coverage defined by the Index Parameter.</li> * <li>an optional integer parameter called Index used by the Grid To World transformation policy for choosing the coverage at the "Index" position.</li> * </ul> * * The output of this process is a {@link GridCoverage2D} object which contains all the input Coverages, each one stored as a Band (or multiple bands * if the coverage is multibanded). This process can be used also for merging coverages which are not aligned and with different resolutions. * * @author Nicola Lagomarsini, GeoSolutions S.A.S. * */ @DescribeProcess(title = "Merge Coverages", description = "Returns a raster generated by the merge of the input raster bands. Source rasters must have the same CRS.") public class BandMergeProcess implements RasterProcess { /** Processor to use for executing the {@link BandMerge} operation */ private static final CoverageProcessor PROCESSOR = CoverageProcessor.getInstance(); @DescribeResult(name = "result", description = "Merged Rasters") public GridCoverage2D execute( @DescribeParameter(name = "coverages", description = "Coverage List", min = 1, collectionType = GridCoverage2D.class) Collection<GridCoverage2D> coverages, @DescribeParameter(name = "roi", description = "Geometry to use as ROI", min = 0) Geometry roi, @DescribeParameter(name = "transformChoice", description = "Choice on which Coverage G2W transform to use", min = 0) String transformChoice, @DescribeParameter(name = "index", description = "Index used by the transformChoice parameter", min = 0) Integer index) throws ProcessException { // // // // Initialization: CRS checks // // // BaseCoverageAlgebraProcess.checkCompatibleCoveragesForMerge(coverages); // // // // Doing the Operation // // // final ParameterValueGroup param = PROCESSOR.getOperation("BandMerge").getParameters(); // // // // ROI extraction // // // Geometry geo = null; if (roi != null) { geo = roi; Object crsGeo = geo.getUserData(); if (crsGeo != null && crsGeo instanceof CoordinateReferenceSystem) { CoordinateReferenceSystem geoCRS = (CoordinateReferenceSystem) crsGeo; GridCoverage2D cov = coverages.iterator().next(); // CRS Check BaseCoverageAlgebraProcess.checkCompatibleCRS(geoCRS, cov.getCoordinateReferenceSystem()); // Setting of the ROI if present param.parameter(BandMerge.GEOMETRY).setValue(geo); } else { // Supposing that the Geometry has the same CRS of the Coverage param.parameter(BandMerge.GEOMETRY).setValue(geo); } } // Addition of all the Coverages as source param.parameter("sources").setValue(coverages); // Addition of the Transformation Choice parameter if present if (transformChoice != null && !transformChoice.isEmpty()) { param.parameter(BandMerge.TRANSFORM_CHOICE).setValue(transformChoice); } // Addition of the Index parameter to use by the Transformation Choice if present if (transformChoice != null && !transformChoice.isEmpty()) { param.parameter(BandMerge.COVERAGE_INDEX).setValue(index); } // Call the "BandMerge" operation return (GridCoverage2D) PROCESSOR.doOperation(param); } }