/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2005-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2009-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.referencing.operation.provider; import javax.media.jai.Warp; import javax.media.jai.WarpCubic; import javax.media.jai.WarpAffine; import javax.media.jai.WarpQuadratic; import javax.media.jai.WarpGeneralPolynomial; import org.opengis.parameter.ParameterValueGroup; import org.opengis.parameter.ParameterDescriptor; import org.opengis.parameter.ParameterDescriptorGroup; import org.opengis.parameter.ParameterNotFoundException; import org.opengis.referencing.operation.Transformation; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.MathTransformFactory; import org.geotoolkit.metadata.Citations; import org.apache.sis.referencing.NamedIdentifier; import org.geotoolkit.referencing.operation.MathTransformProvider; import org.geotoolkit.referencing.operation.transform.WarpTransform2D; import org.apache.sis.parameter.ParameterBuilder; import static org.geotoolkit.parameter.Parameters.*; import static org.geotoolkit.referencing.operation.provider.UniversalParameters.createDescriptorGroup; /** * The provider for {@link WarpTransform2D}. This provider constructs a JAI * {@linkplain javax.media.jai.WarpPolynomial} from a set of polynomial coefficients, * and wraps it in a {@link WarpTransform2D} object. * * <!-- PARAMETERS WarpPolynomial --> * <p>The following table summarizes the parameters recognized by this provider. * For a more detailed parameter list, see the {@link #PARAMETERS} constant.</p> * <blockquote><p><b>Operation name:</b> {@code WarpPolynomial}</p> * <table class="geotk"> * <tr><th>Parameter name</th><th>Default value</th></tr> * <tr><td>{@code degree}</td><td>2</td></tr> * <tr><td>{@code xCoeffs}</td><td></td></tr> * <tr><td>{@code yCoeffs}</td><td></td></tr> * <tr><td>{@code preScaleX}</td><td>1</td></tr> * <tr><td>{@code preScaleY}</td><td>1</td></tr> * <tr><td>{@code postScaleX}</td><td>1</td></tr> * <tr><td>{@code postScaleY}</td><td>1</td></tr> * </table></blockquote> * <!-- END OF PARAMETERS --> * * @author Martin Desruisseaux (IRD, Geomatys) * @version 3.20 * * @see <a href="{@docRoot}/../modules/referencing/operation-parameters.html">Geotk coordinate operations matrix</a> * * @since 2.1 * @module */ public class WarpPolynomial extends MathTransformProvider { /** * Serial number for inter-operability with different versions. */ private static final long serialVersionUID = -7949539694656719923L; /** * The operation parameter descriptor for the * "{@link javax.media.jai.WarpPolynomial#getDegree degree}" parameter value. * * @deprecated Invoke <code>{@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)}</code> instead. */ public static final ParameterDescriptor<Integer> DEGREE; /** * The operation parameter descriptor for the * "{@link javax.media.jai.WarpPolynomial#getXCoeffs xCoeffs}" parameter value. * * @deprecated Invoke <code>{@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)}</code> instead. */ public static final ParameterDescriptor<float[]> X_COEFFS; /** * The operation parameter descriptor for the * "{@link javax.media.jai.WarpPolynomial#getYCoeffs yCoeffs}" parameter value. * * @deprecated Invoke <code>{@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)}</code> instead. */ public static final ParameterDescriptor<float[]> Y_COEFFS; /** * The operation parameter descriptor for the * "{@link javax.media.jai.WarpPolynomial#getPreScaleX preScaleX}" parameter value. * * @deprecated Invoke <code>{@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)}</code> instead. */ public static final ParameterDescriptor<Float> PRE_SCALE_X; /** * The operation parameter descriptor for the * "{@link javax.media.jai.WarpPolynomial#getPreScaleY preScaleY}" parameter value. * * @deprecated Invoke <code>{@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)}</code> instead. */ public static final ParameterDescriptor<Float> PRE_SCALE_Y; /** * The operation parameter descriptor for the * "{@link javax.media.jai.WarpPolynomial#getPostScaleX postScaleX}" parameter value. * * @deprecated Invoke <code>{@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)}</code> instead. */ public static final ParameterDescriptor<Float> POST_SCALE_X; /** * The operation parameter descriptor for the * "{@link javax.media.jai.WarpPolynomial#getPostScaleY postScaleY}" parameter value. * * @deprecated Invoke <code>{@linkplain #PARAMETERS}.{@linkplain ParameterDescriptorGroup#descriptor(String) * descriptor(String)}</code> instead. */ public static final ParameterDescriptor<Float> POST_SCALE_Y; static { final ParameterBuilder builder = new ParameterBuilder().setCodeSpace(Citations.GEOTOOLKIT, null); final Float ONE = 1f; final Class<Float> type = Float.class; PRE_SCALE_X = builder.addName("preScaleX") .create(type, ONE); PRE_SCALE_Y = builder.addName("preScaleY") .create(type, ONE); POST_SCALE_X = builder.addName("postScaleX").create(type, ONE); POST_SCALE_Y = builder.addName("postScaleY").create(type, ONE); builder.setRequired(true); X_COEFFS = builder.addName("xCoeffs").create(float[].class, null); Y_COEFFS = builder.addName("yCoeffs").create(float[].class, null); DEGREE = builder.addName("degree").createBounded(1, WarpTransform2D.MAX_DEGREE, 2); } /** * The group of all parameters expected by this coordinate operation. * The following table lists the operation names and the parameters recognized by Geotk: * <p> * <!-- GENERATED PARAMETERS - inserted by ProjectionParametersJavadoc --> * <table class="geotk" border="1"> * <tr><th colspan="2"> * <table class="compact"> * <tr><td><b>Name:</b></td><td class="onright"><code>Geotk</code>:</td><td class="onleft"><code>WarpPolynomial</code></td></tr> * </table> * </th></tr> * <tr><td> * <table class="compact"> * <tr><td><b>Name:</b></td><td class="onright"><code>Geotk</code>:</td><td class="onleft"><code>degree</code></td></tr> * </table> * </td><td> * <table class="compact"> * <tr><td><b>Type:</b></td><td>{@code Integer}</td></tr> * <tr><td><b>Obligation:</b></td><td>mandatory</td></tr> * <tr><td><b>Value range:</b></td><td>[1…7]</td></tr> * <tr><td><b>Default value:</b></td><td>2</td></tr> * </table> * </td></tr> * <tr><td> * <table class="compact"> * <tr><td><b>Name:</b></td><td class="onright"><code>Geotk</code>:</td><td class="onleft"><code>xCoeffs</code></td></tr> * </table> * </td><td> * <table class="compact"> * <tr><td><b>Type:</b></td><td>{@code float[]}</td></tr> * <tr><td><b>Obligation:</b></td><td>mandatory</td></tr> * </table> * </td></tr> * <tr><td> * <table class="compact"> * <tr><td><b>Name:</b></td><td class="onright"><code>Geotk</code>:</td><td class="onleft"><code>yCoeffs</code></td></tr> * </table> * </td><td> * <table class="compact"> * <tr><td><b>Type:</b></td><td>{@code float[]}</td></tr> * <tr><td><b>Obligation:</b></td><td>mandatory</td></tr> * </table> * </td></tr> * <tr><td> * <table class="compact"> * <tr><td><b>Name:</b></td><td class="onright"><code>Geotk</code>:</td><td class="onleft"><code>preScaleX</code></td></tr> * </table> * </td><td> * <table class="compact"> * <tr><td><b>Type:</b></td><td>{@code Float}</td></tr> * <tr><td><b>Obligation:</b></td><td>optional</td></tr> * <tr><td><b>Value range:</b></td><td>(-∞ … ∞)</td></tr> * <tr><td><b>Default value:</b></td><td>1</td></tr> * </table> * </td></tr> * <tr><td> * <table class="compact"> * <tr><td><b>Name:</b></td><td class="onright"><code>Geotk</code>:</td><td class="onleft"><code>preScaleY</code></td></tr> * </table> * </td><td> * <table class="compact"> * <tr><td><b>Type:</b></td><td>{@code Float}</td></tr> * <tr><td><b>Obligation:</b></td><td>optional</td></tr> * <tr><td><b>Value range:</b></td><td>(-∞ … ∞)</td></tr> * <tr><td><b>Default value:</b></td><td>1</td></tr> * </table> * </td></tr> * <tr><td> * <table class="compact"> * <tr><td><b>Name:</b></td><td class="onright"><code>Geotk</code>:</td><td class="onleft"><code>postScaleX</code></td></tr> * </table> * </td><td> * <table class="compact"> * <tr><td><b>Type:</b></td><td>{@code Float}</td></tr> * <tr><td><b>Obligation:</b></td><td>optional</td></tr> * <tr><td><b>Value range:</b></td><td>(-∞ … ∞)</td></tr> * <tr><td><b>Default value:</b></td><td>1</td></tr> * </table> * </td></tr> * <tr><td> * <table class="compact"> * <tr><td><b>Name:</b></td><td class="onright"><code>Geotk</code>:</td><td class="onleft"><code>postScaleY</code></td></tr> * </table> * </td><td> * <table class="compact"> * <tr><td><b>Type:</b></td><td>{@code Float}</td></tr> * <tr><td><b>Obligation:</b></td><td>optional</td></tr> * <tr><td><b>Value range:</b></td><td>(-∞ … ∞)</td></tr> * <tr><td><b>Default value:</b></td><td>1</td></tr> * </table> * </td></tr> * </table> */ public static final ParameterDescriptorGroup PARAMETERS = createDescriptorGroup(new NamedIdentifier[] { new NamedIdentifier(Citations.GEOTOOLKIT, "WarpPolynomial") }, null, new ParameterDescriptor<?>[] { DEGREE, X_COEFFS, Y_COEFFS, PRE_SCALE_X, PRE_SCALE_Y, POST_SCALE_X, POST_SCALE_Y }, 0); /** * Creates a provider for warp transforms. */ public WarpPolynomial() { super(2, 2, PARAMETERS); } /** * Returns the operation type. */ @Override public Class<Transformation> getOperationType() { return Transformation.class; } /** * Creates a warp transform from the specified group of parameter values. * * @param values The group of parameter values. * @return The created math transform. * @throws ParameterNotFoundException if a required parameter was not found. */ @Override public MathTransform createMathTransform(MathTransformFactory factory, final ParameterValueGroup values) throws ParameterNotFoundException { final int degree = integerValue(DEGREE, values); final float[] xCoeffs = value(X_COEFFS, values); final float[] yCoeffs = value(Y_COEFFS, values); final float preScaleX = scale( PRE_SCALE_X, values); final float preScaleY = scale( PRE_SCALE_Y, values); final float postScaleX = scale(POST_SCALE_X, values); final float postScaleY = scale(POST_SCALE_Y, values); final Warp warp; switch (degree) { case 1: warp = new WarpAffine (xCoeffs, yCoeffs, preScaleX, preScaleY, postScaleX, postScaleY); break; case 2: warp = new WarpQuadratic (xCoeffs, yCoeffs, preScaleX, preScaleY, postScaleX, postScaleY); break; case 3: warp = new WarpCubic (xCoeffs, yCoeffs, preScaleX, preScaleY, postScaleX, postScaleY); break; default: warp = new WarpGeneralPolynomial(xCoeffs, yCoeffs, preScaleX, preScaleY, postScaleX, postScaleY); break; } return WarpTransform2D.create(warp); } /** * Returns the parameter value for the specified operation parameter. * * @param param The parameter to look for. * @param group The parameter value group to search into. * @return The requested parameter value, or {@code 1} if none. */ private static float scale(final ParameterDescriptor<Float> param, final ParameterValueGroup group) throws ParameterNotFoundException { final Object value = value(param, group); return (value != null) ? ((Number) value).floatValue() : 1; } }