/* * Geotools 2 - OpenSource mapping toolkit * (C) 2003, Geotools Project Managment Committee (PMC) * (C) 2001, Institut de Recherche pour le Développement * * 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; either * version 2.1 of the License, or (at your option) any later version. * * 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. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * This package contains documentation from OpenGIS specifications. * OpenGIS consortium's work is fully acknowledged here. */ package org.geotools.ct; // Geotools dependencies import java.util.Locale; import javax.media.jai.ParameterList; import javax.media.jai.ParameterListDescriptor; import javax.media.jai.ParameterListDescriptorImpl; import javax.media.jai.ParameterListImpl; import javax.media.jai.util.Range; import org.geotools.cs.Projection; import org.geotools.measure.Latitude; import org.geotools.measure.Longitude; import org.geotools.resources.Utilities; import org.geotools.resources.XArray; import org.geotools.resources.i18n.Vocabulary; import org.opengis.referencing.FactoryException; /** * Base class for {@link MathTransform} providers. Instance of this class * allow the creation of transform objects from a classification name. *

* Note: this class is not part of OpenGIS specification and * may change in a future version. Do not rely strongly on it. * * @source $URL$ * @version $Id$ * @author Martin Desruisseaux * * @deprecated Replaced by {@link org.geotools.referencing.operation.MathTransformProvider} * in the org.geotools.referencing.operation package. */ public abstract class MathTransformProvider { /** * The value zero as a {@link Double}. */ static final Double ZERO = new Double(0); /** * The value one as a {@link Double}. */ static final Double ONE = new Double(1); /** * Range of positives values. Range goes * from 0 exclusive to positive infinity. */ protected static final Range POSITIVE_RANGE = new Range(Double.class, ZERO, false, null, false); /** * Range of longitude values. Range goes * from -180° to +180° inclusives. */ protected static final Range LONGITUDE_RANGE = new Range(Double.class, new Double(Longitude.MIN_VALUE), true, new Double(Longitude.MAX_VALUE), true); /** * Range of latitude values. Range goes * from -90° to +90° inclusives. */ protected static final Range LATITUDE_RANGE = new Range(Double.class, new Double(Latitude.MIN_VALUE), true, new Double(Latitude.MAX_VALUE), true); /** * Number of colunms in table {@link #properties} below. */ private static final int RECORD_LENGTH = 4; /** * A default parameter list descriptor for * map projections. This descriptor declare * "semi_major", * "semi_minor", * "central_meridian", * "latitude_of_origin", * "scale_factor", * "false_easting" and * "false_northing" parameters. */ public static final ParameterListDescriptor DEFAULT_PROJECTION_DESCRIPTOR = getDescriptor(new Object[] { "semi_major", Double.class, ParameterListDescriptor.NO_PARAMETER_DEFAULT, POSITIVE_RANGE, "semi_minor", Double.class, ParameterListDescriptor.NO_PARAMETER_DEFAULT, POSITIVE_RANGE, "central_meridian", Double.class, ZERO, LONGITUDE_RANGE, "latitude_of_origin", Double.class, ZERO, LATITUDE_RANGE, "scale_factor", Double.class, ONE, POSITIVE_RANGE, "false_easting", Double.class, ZERO, null, "false_northing", Double.class, ZERO, null }); /** * The set parameters to use for {@link ParameterListDescriptor} construction, * or null if the descriptor is already constructed. */ private Object[] properties; /** * The parameter list descriptor. This object will * be constructed only the first time it is needed. */ private ParameterListDescriptor descriptor; /** * The classification name. This name do * not contains leading or trailing blanks. */ private final String classification; /** * Resources key for a human readable name. This * is used for {@link #getName} implementation. */ private final int nameKey; /** * Construct a new provider. * * @param classification The classification name. * @param inherit The parameter list descriptor to inherit from, or null * if there is none. All parameter descriptions from inherit will * be copied into this newly created MathTransformProvider. For * map projections, this argument may be {@link #DEFAULT_PROJECTION_DESCRIPTOR}. * Subclasses may add or change parameters in their constructor by invoking * {@link #put}. */ protected MathTransformProvider(final String classification, final ParameterListDescriptor inherit) { this(classification, -1, inherit); } /** * Construct a new provider. * * @param classification The classification name. * @param nameKey Resources key for a human readable name. * This is used for {@link #getName} implementation. * @param inherit The parameter list descriptor to inherit from, or null * if there is none. All parameter descriptions from inherit will * be copied into this newly created MathTransformProvider. For * map projections, this argument may be {@link #DEFAULT_PROJECTION_DESCRIPTOR}. * Subclasses may add or change parameters in their constructor by invoking * {@link #put}. */ MathTransformProvider(final String classification, final int nameKey, final ParameterListDescriptor inherit) { this.classification = classification.trim(); this.nameKey = nameKey; if (inherit!=null) { final String[] names = inherit.getParamNames(); final Class [] classes = inherit.getParamClasses(); final Object[] defaults = inherit.getParamDefaults(); properties = new Object[names.length*RECORD_LENGTH]; for (int i=0; iMathTransformProvider has been constructed with {@link * #DEFAULT_PROJECTION_DESCRIPTOR} as argument, then default values are * already provided for "semi_major", "semi_minor", "central_meridian", * "latitude_of_origin", "scale_factor", "false_easting" and "false_northing". * Subclasses may call this method in their constructor for adding or * changing parameters. * * @param parameter The parameter name. * @param defaultValue The default value for this parameter, or * {@link Double#NaN} if there is none. * @param range The range of legal values. May be one of the predefined * constants ({@link #POSITIVE_RANGE}, {@link #LONGITUDE_RANGE}, * {@link #LATITUDE_RANGE}) or any other {@link Range} object. * May be null if all values are valid for this * parameter. * @throws IllegalStateException If {@link #getParameterList} has already * been invoked prior to this call. */ protected final void put(final String parameter, final double defaultValue, final Range range) throws IllegalStateException { put(parameter, Double.class, wrap(defaultValue), range); } /** * Adds or changes an integer parameter to this math transform provider. * Support of integer values help to make the API clearer, but the true * OpenGIS's parameter class support only double values. * This is why this method is not yet public. Current Geotools version use * integer parameters only for matrix dimension and for a custom parameter * in geocentric transform. We hope the user will barely notice it... * * @param parameter The parameter name. * @param defaultValue The default value for this parameter. * @param range The range of legal values. This is up to the caller to * build is own range with integer values (predefined ranges * like {@link #POSITIVE_RANGE} will not work). * * @throws IllegalStateException If {@link #getParameterList} * has already been invoked prior to this call. */ final void putInt(final String parameter, final int defaultValue, final Range range) throws IllegalStateException { put(parameter, Integer.class, new Integer(defaultValue), range); } /** * Add of changes an object parameter to this math transform provider. The parameter will * have no default value. This method is used for the construction of some math transforms * that are not part of OpenGIS specification (e.g. "Power" and "Logarithm"). The OpenGIS * specification allows only double parameter values, which is why this method * is not yet public. * * @param parameter The parameter name. * @param type The parameter type. */ final void putObject(final String parameter, final Class type) throws IllegalStateException { put(parameter, type, ParameterListDescriptor.NO_PARAMETER_DEFAULT, null); } /** * Adds or changes a parameter to this math transform provider. * * @param parameter The parameter name. * @param type The parameter type. * @param defaultValue The default value for this parameter, or * {@link ParameterListDescriptor#NO_PARAMETER_DEFAULT} if none. * @param range The range of legal values, or null if none. * * @throws IllegalStateException If {@link #getParameterList} * has already been invoked prior to this call. */ private void put(String parameter, final Class type, Object defaultValue, final Range range) throws IllegalStateException { if (properties==null) { // Construction is finished. throw new IllegalStateException(); } if (defaultValue!=null && range!=null) { // Slight optimization for reducing the amount of objects in the heap. Object check; if (defaultValue.equals(check=range.getMinValue())) defaultValue=check; if (defaultValue.equals(check=range.getMaxValue())) defaultValue=check; } parameter = parameter.trim(); final int end = properties.length; for (int i=0; i=0) ? Vocabulary.getResources(locale).getString(nameKey) : getClassName(); } /** * Returns the parameter list descriptor. The default implementation build the * descriptor from the parameters specified by the constructor with {@link #put}. */ public synchronized ParameterListDescriptor getParameterListDescriptor() { if (descriptor==null) { descriptor = getDescriptor(properties); properties = null; // No longer needed. } return descriptor; } /** * Returns a newly created parameter list. The set of parameter * depend of the transform this provider is for. Parameters may * have default values and a range of validity. */ public ParameterList getParameterList() { return new ParameterListImpl(getParameterListDescriptor()); } /** * Returns a transform for the specified parameters. * * @param parameters The parameter values in standard units. * @return A {@link MathTransform} object of this classification. * @throws MissingParameterException if a mandatory parameter is missing. * @throws FactoryException if the transform can't be created. */ public abstract MathTransform create(final ParameterList parameters) throws MissingParameterException, FactoryException; /** * Returns a transform for the specified projection. The default implementation * invokes {@link #create(ParameterList)} with the projection's parameters. * * @param projection The projection. * @return A {@link MathTransform} object of this classification. * @throws MissingParameterException if a mandatory parameter is missing. * @throws FactoryException if the transform can't be created for some other reason. */ protected MathTransform create(final Projection projection) throws MissingParameterException, FactoryException { return create(projection.getParameters()); } /** * Returns a string representation for this provider. */ public String toString() { return Utilities.getShortClassName(this)+'['+getName(null)+']'; } }