/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2012, 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.processing.coverage.resample; import java.util.HashMap; import java.util.Map; import org.apache.sis.parameter.ParameterBuilder; import org.apache.sis.util.iso.SimpleInternationalString; import org.geotoolkit.coverage.grid.GridCoverage2D; import org.geotoolkit.image.interpolation.InterpolationCase; import org.geotoolkit.metadata.Citations; import org.geotoolkit.parameter.DefaultParameterDescriptor; import org.geotoolkit.processing.AbstractProcessDescriptor; import org.geotoolkit.process.Process; import org.geotoolkit.process.ProcessDescriptor; import org.geotoolkit.processing.coverage.CoverageProcessingRegistry; import org.apache.sis.referencing.NamedIdentifier; import org.geotoolkit.image.interpolation.ResampleBorderComportement; import org.geotoolkit.processing.ProcessBundle; import org.opengis.coverage.Coverage; import org.opengis.coverage.grid.GridGeometry; import org.opengis.parameter.ParameterDescriptor; import org.opengis.parameter.ParameterDescriptorGroup; import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.IdentifiedObject; import org.opengis.referencing.crs.CoordinateReferenceSystem; /** * Resample a grid coverage using a different grid geometry. This operation provides the following * functionality: * <p> * <UL> * <LI><b>Resampling</b><br> * The grid coverage can be resampled at a different cell resolution. Some implementations * may be able to do resampling efficiently at any resolution. Also a non-rectilinear grid * coverage can be accessed as rectilinear grid coverage with this operation.</LI> * <LI><b>Reprojecting</b><br> * The new grid geometry can have a different coordinate reference system than the underlying * grid geometry. For example, a grid coverage can be reprojected from a geodetic coordinate * reference system to Universal Transverse Mercator CRS.</LI> * <LI><b>Subsetting</b><br> * A subset of a grid can be viewed as a separate coverage by using this operation with a * grid geometry which as the same geoferencing and a region. Grid envelope in the grid * geometry defines the region to subset in the grid coverage.</LI> * </UL> * * <P><b>Name:</b> {@code "Resample"}<BR> * <b>Parameters:</b></P> * <table border='3' cellpadding='6' bgcolor='F4F8FF'> * <tr bgcolor='#B9DCFF'> * <th>Name</th> * <th>Class</th> * <th>Default value</th> * <th>Minimum value</th> * <th>Maximum value</th> * </tr> * <tr> * <td>{@code "Source"}</td> * <td>{@link org.geotoolkit.coverage.grid.GridCoverage2D}</td> * <td align="center">N/A</td> * <td align="center">N/A</td> * <td align="center">N/A</td> * </tr> * <tr> * <td>{@code "InterpolationType"}</td> * <td>{@link java.lang.CharSequence}</td> * <td>"NearestNieghbor"</td> * <td align="center">N/A</td> * <td align="center">N/A</td> * </tr> * <tr> * <td>{@code "CoordinateReferenceSystem"}</td> * <td>{@link org.opengis.referencing.crs.CoordinateReferenceSystem}</td> * <td>Same as source grid coverage</td> * <td align="center">N/A</td> * <td align="center">N/A</td> * </tr> * <tr> * <td>{@code "GridGeometry"}</td> * <td>{@link org.opengis.coverage.grid.GridGeometry}</td> * <td>(automatic)</td> * <td align="center">N/A</td> * <td align="center">N/A</td> * </tr> * <tr> * <td>{@code "Background"}</td> * <td>{@code double[]}</td> * <td>(automatic)</td> * <td align="center">N/A</td> * <td align="center">N/A</td> * </tr> * </table> * * {@section Geotoolkit.org extension} * The {@code "Resample"} operation use the default * {@link org.opengis.referencing.operation.CoordinateOperationFactory} for creating a * transformation from the source to the destination coordinate reference systems. * If a custom factory is desired, it may be supplied as a rendering hint with the * {@link org.geotoolkit.factory.Hints#COORDINATE_OPERATION_FACTORY} key. Rendering * hints can be supplied to {@link org.geotoolkit.coverage.processing.DefaultCoverageProcessor} * at construction time. * <p> * Geotk adds a background parameter which is not part of OGC specification. This parameter * specifies the color to use for pixels in the destination image that don't map to a pixel * in the source image. If this parameter is not specified, then it is inferred from the * "no data" category in the source coverage. * * @author Martin Desruisseaux (IRD, Geomatys) * @author Johann Sorel (Geomatys) * * @version 4.x * @since 2.2 * * @module */ public class ResampleDescriptor extends AbstractProcessDescriptor { public static final String NAME = "Resample"; /** * Convenience constant for the first source {@link GridCoverage2D}. The parameter name * is {@code "Source"} (as specified in OGC implementation specification) and the alias * is {@code "source0"} (for compatibility with <cite>Java Advanced Imaging</cite>). */ public static final ParameterDescriptor<GridCoverage2D> IN_COVERAGE; /** * The parameter descriptor for the interpolation type. */ public static final ParameterDescriptor<InterpolationCase> IN_INTERPOLATION_TYPE; /** * The parameter descriptor for the interpolation type. */ public static final ParameterDescriptor<ResampleBorderComportement> IN_BORDER_COMPORTEMENT_TYPE; /** * The parameter descriptor for the coordinate reference system. */ public static final ParameterDescriptor<CoordinateReferenceSystem> IN_COORDINATE_REFERENCE_SYSTEM; /** * The parameter descriptor for the grid geometry. */ public static final ParameterDescriptor<GridGeometry> IN_GRID_GEOMETRY; /** * The parameter descriptor for the background values. * * @since 3.16 */ public static final ParameterDescriptor<double[]> IN_BACKGROUND; static { final ParameterBuilder builder = new ParameterBuilder().setCodeSpace(Citations.OGC, null); IN_INTERPOLATION_TYPE = builder.addName("InterpolationType") .create(InterpolationCase.class, InterpolationCase.NEIGHBOR); IN_BORDER_COMPORTEMENT_TYPE = builder.addName("BorderComportementType") .create(ResampleBorderComportement.class, ResampleBorderComportement.EXTRAPOLATION); // TODO - not an OGC parameter. IN_COORDINATE_REFERENCE_SYSTEM = builder.addName("CoordinateReferenceSystem").create(CoordinateReferenceSystem.class, null); IN_GRID_GEOMETRY = builder.addName("GridGeometry") .create(GridGeometry.class, null); IN_BACKGROUND = builder.setCodeSpace(Citations.GEOTOOLKIT, null).addName("Background").create(double[].class, null); } /** * Input parameters descriptor of this process. */ public static final ParameterDescriptorGroup INPUT_DESC; /** * Output coverage result of the process execution. */ public static final ParameterDescriptor<Coverage> OUT_COVERAGE; /** * Output parameters descriptor of this process. */ public static final ParameterDescriptorGroup OUTPUT_DESC; static { final Map<String,Object> properties = new HashMap<>(4); properties.put(IdentifiedObject.NAME_KEY, new NamedIdentifier(Citations.OGC, "Source")); properties.put(IdentifiedObject.ALIAS_KEY, new NamedIdentifier(Citations.JAI, "source0")); IN_COVERAGE = new DefaultParameterDescriptor<>(properties, GridCoverage2D.class, null, null, null, null, null, true); INPUT_DESC = new ParameterBuilder().addName(NAME + "InputParameters").createGroup( IN_COVERAGE, IN_INTERPOLATION_TYPE, IN_BORDER_COMPORTEMENT_TYPE, IN_COORDINATE_REFERENCE_SYSTEM, IN_GRID_GEOMETRY, IN_BACKGROUND); final Map<String, Object> propertiesOut = new HashMap<>(); propertiesOut.put(IdentifiedObject.NAME_KEY, "result"); propertiesOut.put(IdentifiedObject.ALIAS_KEY, ProcessBundle.formatInternational(ProcessBundle.Keys.coverage_resample_outCoverage)); propertiesOut.put(IdentifiedObject.REMARKS_KEY, ProcessBundle.formatInternational(ProcessBundle.Keys.coverage_resample_outCoverageDesc)); OUT_COVERAGE = new DefaultParameterDescriptor<>( propertiesOut, Coverage.class, null, null, null, null, null, true); OUTPUT_DESC = new ParameterBuilder().addName(NAME + "OutputParameters").createGroup(OUT_COVERAGE); } /** * Unique instance of this descriptor. */ public static final ProcessDescriptor INSTANCE = new ResampleDescriptor(); private ResampleDescriptor() { super(NAME, CoverageProcessingRegistry.IDENTIFICATION, new SimpleInternationalString("Resample a coverage."), INPUT_DESC, OUTPUT_DESC); } @Override public Process createProcess(ParameterValueGroup input) { return new ResampleProcess(input); } }