001 /*
002 * GeoAPI - Java interfaces for OGC/ISO standards
003 * http://www.geoapi.org
004 *
005 * Copyright (C) 2004-2012 Open Geospatial Consortium, Inc.
006 * All Rights Reserved. http://www.opengeospatial.org/ogc/legal
007 *
008 * Permission to use, copy, and modify this software and its documentation, with
009 * or without modification, for any purpose and without fee or royalty is hereby
010 * granted, provided that you include the following on ALL copies of the software
011 * and documentation or portions thereof, including modifications, that you make:
012 *
013 * 1. The full text of this NOTICE in a location viewable to users of the
014 * redistributed or derivative work.
015 * 2. Notice of any changes or modifications to the OGC files, including the
016 * date changes were made.
017 *
018 * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE
019 * NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
020 * TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT
021 * THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY
022 * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
023 *
024 * COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
025 * CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
026 *
027 * The name and trademarks of copyright holders may NOT be used in advertising or
028 * publicity pertaining to the software without specific, written prior permission.
029 * Title to copyright in this software and any associated documentation will at all
030 * times remain with copyright holders.
031 */
032 package org.opengis.referencing.operation;
033
034 import java.util.Set;
035 import org.opengis.util.Factory;
036 import org.opengis.util.FactoryException;
037 import org.opengis.util.NoSuchIdentifierException;
038 import org.opengis.referencing.cs.CoordinateSystem;
039 import org.opengis.referencing.datum.Ellipsoid;
040 import org.opengis.referencing.crs.*; // Contains some import for javadoc.
041 import org.opengis.parameter.*; // Contains some import for javadoc.
042 import org.opengis.annotation.UML;
043
044 import static org.opengis.annotation.Obligation.*;
045 import static org.opengis.annotation.Specification.*;
046
047
048 /**
049 * Low level factory for creating {@linkplain MathTransform math transforms}.
050 * Many high level GIS applications will never need to use this factory directly;
051 * they can use a {@linkplain CoordinateOperationFactory coordinate operation factory}
052 * instead. However, the {@code MathTransformFactory} interface can be used directly
053 * by applications that wish to transform other types of coordinates (e.g. color coordinates,
054 * or image pixel coordinates).
055 * <p>
056 * A {@linkplain MathTransform math transform} is an object that actually does
057 * the work of applying formulae to coordinate values. The math transform does
058 * not know or care how the coordinates relate to positions in the real world.
059 * This lack of semantics makes implementing {@code MathTransformFactory}
060 * significantly easier than it would be otherwise.
061 * <p>
062 * For example the affine transform applies a matrix to the coordinates
063 * without knowing how what it is doing relates to the real world. So if
064 * the matrix scales <var>Z</var> values by a factor of 1000, then it could
065 * be converting meters into millimeters, or it could be converting kilometers
066 * into meters.
067 * <p>
068 * Because {@linkplain MathTransform math transforms} have low semantic value
069 * (but high mathematical value), programmers who do not have much knowledge
070 * of how GIS applications use coordinate systems, or how those coordinate
071 * systems relate to the real world can implement {@code MathTransformFactory}.
072 * The low semantic content of {@linkplain MathTransform math transforms} also
073 * means that they will be useful in applications that have nothing to do with
074 * GIS coordinates. For example, a math transform could be used to map color
075 * coordinates between different color spaces, such as converting (red, green, blue)
076 * colors into (hue, light, saturation) colors.
077 * <p>
078 * Since a {@linkplain MathTransform math transform} does not know what its source
079 * and target coordinate systems mean, it is not necessary or desirable for a math
080 * transform object to keep information on its source and target coordinate systems.
081 *
082 * @author Martin Desruisseaux (IRD)
083 * @version 3.0
084 * @since 1.0
085 *
086 * @see <A HREF="http://www.remotesensing.org/geotiff/proj_list/">Projection transform list on RemoteSensing.org</A>
087 */
088 @UML(identifier="CT_MathTransformFactory", specification=OGC_01009)
089 public interface MathTransformFactory extends Factory {
090 /**
091 * Returns a set of available methods for {@linkplain MathTransform math transforms}. For
092 * each element in this set, the {@linkplain OperationMethod#getName() operation method name}
093 * must be known to the {@link #getDefaultParameters(String)} method in this factory.
094 * The set of available methods is implementation dependent.
095 *
096 * @param type <code>{@linkplain SingleOperation}.class</code> for fetching all operation methods,
097 * or <code>{@linkplain Projection}.class</code> for fetching only map projection methods.
098 * @return All {@linkplain MathTransform math transform} methods available in this factory.
099 *
100 * @departure extension
101 * This method is not part of the OGC specification. It has been added as a way to publish
102 * the capabilities of a factory.
103 *
104 * @see #getDefaultParameters(String)
105 * @see #createParameterizedTransform(ParameterValueGroup)
106 * @see CoordinateOperationFactory#getOperationMethod(String)
107 */
108 Set<OperationMethod> getAvailableMethods(Class<? extends SingleOperation> type);
109
110 /**
111 * Returns the operation method used for the latest call to
112 * {@link #createParameterizedTransform createParameterizedTransform},
113 * or {@code null} if not applicable.
114 * <p>
115 * Implementors should document how their implementation behave in a multi-threads environment.
116 * For example some implementations use {@linkplain java.lang.ThreadLocal thread local variables},
117 * while other can choose to returns {@code null} in all cases since this method is optional.
118 * <p>
119 * Note that this method may apply as well to convenience methods that delegate their work to
120 * {@code createParameterizedTransform}, like {@link #createBaseToDerived createBaseToDerived}.
121 *
122 * @return The last method used, or {@code null} if unknown of unsupported.
123 *
124 * @departure extension
125 * This method is not part of the OGC specification. It has been added because this information
126 * appears to be needed in practice. A more object-oriented approach would have been to
127 * return a {<code>MathTransform</code>, <code>OperationMethod</code>} tuple in the
128 * <code>createParameterizedTransform(&hellip)</code> method, but we wanted to keep the
129 * later unchanged for historical reasons (it is inherited from OGC 01-009) and because
130 * only a minority of use cases need the operation method.
131 * <p>
132 * Note that the existence of this method does not break thread-safety if the implementor
133 * stores this information in a <code>ThreadLocal</code> variable.
134 *
135 * @since 2.1
136 */
137 OperationMethod getLastMethodUsed();
138
139 /**
140 * Returns the default parameter values for a math transform using the given method.
141 * The {@code method} argument is the name of any operation method returned by
142 * <code>{@link #getAvailableMethods(Class) getAvailableMethods}({@linkplain CoordinateOperation}.class)</code>.
143 * A typical example is
144 * <code>"<A HREF="http://www.remotesensing.org/geotiff/proj_list/transverse_mercator.html">Transverse_Mercator</A>"</code>).
145 * <P>
146 * The {@linkplain ParameterDescriptorGroup#getName() parameter group name} shall be the
147 * method name, or an alias to be understood by <code>{@linkplain #createParameterizedTransform
148 * createParameterizedTransform}(parameters)</code>. This method creates new parameter instances
149 * at every call. Parameters are intended to be modified by the user before to be given to the
150 * above-cited {@code createParameterizedTransform} method.
151 *
152 * @param method The case insensitive name of the method to search for.
153 * @return The default parameter values.
154 * @throws NoSuchIdentifierException if there is no transform registered for the specified method.
155 *
156 * @departure extension
157 * This method is part of the GeoAPI mechanism for defining the math transform parameters
158 * or deriving other transforms.
159 *
160 * @see #getAvailableMethods(Class)
161 * @see #createParameterizedTransform(ParameterValueGroup)
162 */
163 ParameterValueGroup getDefaultParameters(String method) throws NoSuchIdentifierException;
164
165 /**
166 * Creates a {@linkplain #createParameterizedTransform parameterized transform} from a base CRS
167 * to a derived CS. This convenience method {@linkplain #createConcatenatedTransform concatenates}
168 * the parameterized transform with any other transform required for performing units changes and
169 * ordinates swapping, as described in the {@linkplain #createParameterizedTransform note on
170 * cartographic projections}.
171 * <p>
172 * In addition, implementations are encouraged to infer the {@code "semi_major"} and
173 * {@code "semi_minor"} parameter values from the {@linkplain Ellipsoid ellipsoid}, if
174 * they are not explicitly given.
175 *
176 * @param baseCRS The source coordinate reference system.
177 * @param parameters The parameter values for the transform.
178 * @param derivedCS The target coordinate system.
179 * @return The parameterized transform.
180 * @throws NoSuchIdentifierException if there is no transform registered for the method.
181 * @throws FactoryException if the object creation failed. This exception is thrown
182 * if some required parameter has not been supplied, or has illegal value.
183 *
184 * @departure extension
185 * This method is part of the GeoAPI mechanism for defining the math transform parameters
186 * or deriving other transforms.
187 *
188 * @since 2.1
189 */
190 MathTransform createBaseToDerived(CoordinateReferenceSystem baseCRS,
191 ParameterValueGroup parameters,
192 CoordinateSystem derivedCS)
193 throws NoSuchIdentifierException, FactoryException;
194
195 /**
196 * Creates a transform from a group of parameters. The method name is inferred from
197 * the {@linkplain ParameterDescriptorGroup#getName() parameter group name}. Example:
198 *
199 * <blockquote><pre>
200 * ParameterValueGroup p = factory.getDefaultParameters("Transverse_Mercator");
201 * p.parameter("semi_major").setValue(6378137.000);
202 * p.parameter("semi_minor").setValue(6356752.314);
203 * MathTransform mt = factory.createParameterizedTransform(p);
204 * </pre></blockquote>
205 *
206 * <b>Note on cartographic projections:</b>
207 * <P>Cartographic projection transforms are used by {@linkplain ProjectedCRS projected coordinate reference systems}
208 * to map geographic coordinates (e.g. <var>longitude</var> and <var>latitude</var>) into (<var>x</var>,<var>y</var>)
209 * coordinates. These (<var>x</var>,<var>y</var>) coordinates can be imagined to lie on a plane, such as a paper map
210 * or a screen. All cartographic projection transforms created through this method will have the following properties:</P>
211 * <UL>
212 * <LI>Converts from (<var>longitude</var>,<var>latitude</var>) coordinates to (<var>x</var>,<var>y</var>).</LI>
213 * <LI>All angles are assumed to be degrees, and all distances are assumed to be meters.</LI>
214 * <LI>The domain shall be a subset of {[-180,180)×(-90,90)}.</LI>
215 * </UL>
216 * <P>Although all cartographic projection transforms must have the properties listed above, many projected coordinate
217 * reference systems have different properties. For example, in Europe some projected CRSs use grads instead of degrees,
218 * and often the {@linkplain ProjectedCRS#getBaseCRS() base geographic CRS} is (<var>latitude</var>, <var>longitude</var>)
219 * instead of (<var>longitude</var>, <var>latitude</var>). This means that the cartographic projected transform is often
220 * used as a single step in a series of transforms, where the other steps change units and swap ordinates.</P>
221 *
222 * @param parameters The parameter values.
223 * @return The parameterized transform.
224 * @throws NoSuchIdentifierException if there is no transform registered for the method.
225 * @throws FactoryException if the object creation failed. This exception is thrown
226 * if some required parameter has not been supplied, or has illegal value.
227 *
228 * @see #getDefaultParameters(String)
229 * @see #getAvailableMethods(Class)
230 */
231 @UML(identifier="createParameterizedTransform", obligation=MANDATORY, specification=OGC_01009)
232 MathTransform createParameterizedTransform(ParameterValueGroup parameters)
233 throws NoSuchIdentifierException, FactoryException;
234
235 /**
236 * Creates an affine transform from a matrix.
237 * If the transform's input dimension is {@code M}, and output dimension
238 * is {@code N}, then the matrix will have size {@code [N+1][M+1]}.
239 * The +1 in the matrix dimensions allows the matrix to do a shift, as well as
240 * a rotation. The {@code [M][j]} element of the matrix will be the <var>j</var>'th
241 * ordinate of the moved origin. The {@code [i][N]} element of the matrix
242 * will be 0 for <var>i</var> less than {@code M}, and 1 for <var>i</var>
243 * equals {@code M}.
244 *
245 * @param matrix The matrix used to define the affine transform.
246 * @return The affine transform.
247 * @throws FactoryException if the object creation failed.
248 */
249 @UML(identifier="createAffineTransform", obligation=MANDATORY, specification=OGC_01009)
250 MathTransform createAffineTransform(Matrix matrix) throws FactoryException;
251
252 /**
253 * Creates a transform by concatenating two existing transforms.
254 * A concatenated transform acts in the same way as applying two
255 * transforms, one after the other.
256 *
257 * The dimension of the output space of the first transform must match
258 * the dimension of the input space in the second transform.
259 * If you wish to concatenate more than two transforms, then you can
260 * repeatedly use this method.
261 *
262 * @param transform1 The first transform to apply to points.
263 * @param transform2 The second transform to apply to points.
264 * @return The concatenated transform.
265 * @throws FactoryException if the object creation failed.
266 */
267 @UML(identifier="createConcatenatedTransform", obligation=MANDATORY, specification=OGC_01009)
268 MathTransform createConcatenatedTransform(MathTransform transform1,
269 MathTransform transform2) throws FactoryException;
270
271 /**
272 * Creates a transform which passes through a subset of ordinates to another transform.
273 * This allows transforms to operate on a subset of ordinates. For example giving
274 * (<var>latitude</var>, <var>longitude</var>, <var>height</var>) coordinates, a pass
275 * through transform can convert the height values from meters to feet without affecting
276 * the (<var>latitude</var>, <var>longitude</var>) values.
277 *
278 * @param firstAffectedOrdinate The lowest index of the affected ordinates.
279 * @param subTransform Transform to use for affected ordinates.
280 * @param numTrailingOrdinates Number of trailing ordinates to pass through.
281 * Affected ordinates will range from {@code firstAffectedOrdinate}
282 * inclusive to {@code dimTarget-numTrailingOrdinates} exclusive.
283 * @return A pass through transform with the following dimensions:<br>
284 * <pre>
285 * Source: firstAffectedOrdinate + subTransform.getDimSource() + numTrailingOrdinates
286 * Target: firstAffectedOrdinate + subTransform.getDimTarget() + numTrailingOrdinates</pre>
287 * @throws FactoryException if the object creation failed.
288 */
289 @UML(identifier="createPassThroughTransform", obligation=MANDATORY, specification=OGC_01009)
290 MathTransform createPassThroughTransform(int firstAffectedOrdinate,
291 MathTransform subTransform,
292 int numTrailingOrdinates) throws FactoryException;
293
294 /**
295 * Creates a math transform object from a XML string.
296 *
297 * @param xml Math transform encoded in XML format.
298 * @return The math transform (never {@code null}).
299 * @throws FactoryException if the object creation failed.
300 */
301 @UML(identifier="createFromXML", obligation=MANDATORY, specification=OGC_01009)
302 MathTransform createFromXML(String xml) throws FactoryException;
303
304 /**
305 * Creates a math transform object from a string.
306 * The <A HREF="../doc-files/WKT.html">definition for WKT</A> is
307 * shown using Extended Backus Naur Form (EBNF).
308 *
309 * @param wkt Math transform encoded in Well-Known Text format.
310 * @return The math transform (never {@code null}).
311 * @throws FactoryException if the Well-Known Text can't be parsed,
312 * or if the math transform creation failed from some other reason.
313 *
314 * @see MathTransform#toWKT()
315 */
316 @UML(identifier="createFromWKT", obligation=MANDATORY, specification=OGC_01009)
317 MathTransform createFromWKT(String wkt) throws FactoryException;
318 }