001 /*
002 * GeoAPI - Java interfaces for OGC/ISO standards
003 * http://www.geoapi.org
004 *
005 * Copyright (C) 2004-2013 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.awt.geom.AffineTransform;
035
036 import org.opengis.geometry.DirectPosition;
037 import org.opengis.geometry.MismatchedDimensionException;
038 import org.opengis.annotation.UML;
039
040 import static org.opengis.annotation.Specification.*;
041
042
043 /**
044 * Transforms multi-dimensional coordinate points. This interface transforms coordinate
045 * value for a point given in the {@linkplain CoordinateOperation#getSourceCRS() source
046 * coordinate reference system} to coordinate value for the same point in the
047 * {@linkplain CoordinateOperation#getTargetCRS() target coordinate reference system}.
048 *
049 * <ul>
050 * <li>In a {@linkplain Conversion conversion}, the transformation is accurate to within the
051 * limitations of the computer making the calculations.</li>
052 * <li>In a {@linkplain Transformation transformation}, where some of the operational parameters
053 * are derived from observations, the transformation is accurate to within the limitations of
054 * those observations.</li>
055 * </ul>
056 *
057 * If a client application wishes to query the source and target
058 * {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem coordinate reference systems}
059 * of an operation, then it should keep hold of the {@link CoordinateOperation} interface,
060 * and use the contained math transform object whenever it wishes to perform a transform.
061 *
062 * @author Martin Desruisseaux (IRD)
063 * @version 3.0
064 * @since 1.0
065 *
066 * @see AffineTransform
067 * @see javax.media.jai.PerspectiveTransform
068 * @see javax.media.j3d.Transform3D
069 * @see MathTransformFactory
070 * @see CoordinateOperation#getMathTransform()
071 */
072 @UML(identifier="CT_MathTransform", specification=OGC_01009)
073 public interface MathTransform {
074 /**
075 * Gets the dimension of input points.
076 *
077 * @return The dimension of input points.
078 */
079 @UML(identifier="getDimSource", specification=OGC_01009)
080 int getSourceDimensions();
081
082 /**
083 * Gets the dimension of output points.
084 *
085 * @return The dimension of output points.
086 */
087 @UML(identifier="getDimTarget", specification=OGC_01009)
088 int getTargetDimensions();
089
090 /**
091 * Transforms the specified {@code ptSrc} and stores the result in
092 * {@code ptDst}. If {@code ptDst} is {@code null}, a new
093 * {@link DirectPosition} object is allocated and then the result of the
094 * transformation is stored in this object. In either case, {@code ptDst},
095 * which contains the transformed point, is returned for convenience.
096 * If {@code ptSrc} and {@code ptDst} are the same object,
097 * the input point is correctly overwritten with the transformed point.
098 *
099 * @param ptSrc the specified coordinate point to be transformed.
100 * @param ptDst the specified coordinate point that stores the result of transforming
101 * {@code ptSrc}, or {@code null}.
102 * @return the coordinate point after transforming {@code ptSrc} and storing the result
103 * in {@code ptDst}, or a newly created point if {@code ptDst} was null.
104 * @throws MismatchedDimensionException if {@code ptSrc} or
105 * {@code ptDst} doesn't have the expected dimension.
106 * @throws TransformException if the point can't be transformed.
107 */
108 @UML(identifier="transform", specification=OGC_01009)
109 DirectPosition transform(DirectPosition ptSrc, DirectPosition ptDst)
110 throws MismatchedDimensionException, TransformException;
111
112 /**
113 * Transforms a list of coordinate point ordinal values.
114 * This method is provided for efficiently transforming many points.
115 * The supplied array of ordinal values will contain packed ordinal
116 * values. For example, if the source dimension is 3, then the ordinals
117 * will be packed in this order:
118 *
119 * (<var>x<sub>0</sub></var>,<var>y<sub>0</sub></var>,<var>z<sub>0</sub></var>,
120 * <var>x<sub>1</sub></var>,<var>y<sub>1</sub></var>,<var>z<sub>1</sub></var> …).
121 *
122 * @param srcPts the array containing the source point coordinates.
123 * @param srcOff the offset to the first point to be transformed in the source array.
124 * @param dstPts the array into which the transformed point coordinates are returned.
125 * May be the same than {@code srcPts}.
126 * @param dstOff the offset to the location of the first transformed point that is
127 * stored in the destination array.
128 * @param numPts the number of point objects to be transformed.
129 * @throws TransformException if a point can't be transformed. Some implementations will stop
130 * at the first failure, wile some other implementations will fill the untransformable
131 * points with {@linkplain Double#NaN NaN} values, continue and throw the exception
132 * only at end. Implementations that fall in the later case should set the {@linkplain
133 * TransformException#getLastCompletedTransform last completed transform} to {@code this}.
134 *
135 * @see AffineTransform#transform(double[], int, double[], int, int)
136 */
137 @UML(identifier="transformList", specification=OGC_01009)
138 void transform(double[] srcPts, int srcOff,
139 double[] dstPts, int dstOff, int numPts) throws TransformException;
140
141 /**
142 * Transforms a list of coordinate point ordinal values.
143 * This method is provided for efficiently transforming many points.
144 * The supplied array of ordinal values will contain packed ordinal
145 * values. For example, if the source dimension is 3, then the ordinals
146 * will be packed in this order:
147 *
148 * (<var>x<sub>0</sub></var>,<var>y<sub>0</sub></var>,<var>z<sub>0</sub></var>,
149 * <var>x<sub>1</sub></var>,<var>y<sub>1</sub></var>,<var>z<sub>1</sub></var> …).
150 *
151 * @param srcPts the array containing the source point coordinates.
152 * @param srcOff the offset to the first point to be transformed in the source array.
153 * @param dstPts the array into which the transformed point coordinates are returned.
154 * May be the same than {@code srcPts}.
155 * @param dstOff the offset to the location of the first transformed point that is
156 * stored in the destination array.
157 * @param numPts the number of point objects to be transformed.
158 * @throws TransformException if a point can't be transformed. Some implementations will stop
159 * at the first failure, wile some other implementations will fill the untransformable
160 * points with {@linkplain Double#NaN NaN} values, continue and throw the exception
161 * only at end. Implementations that fall in the later case should set the {@linkplain
162 * TransformException#getLastCompletedTransform last completed transform} to {@code this}.
163 *
164 * @see AffineTransform#transform(float[], int, float[], int, int)
165 */
166 void transform(float[] srcPts, int srcOff,
167 float[] dstPts, int dstOff, int numPts) throws TransformException;
168
169 /**
170 * Transforms a list of coordinate point ordinal values.
171 * This method is provided for efficiently transforming many points.
172 * The supplied array of ordinal values will contain packed ordinal
173 * values. For example, if the source dimension is 3, then the ordinals
174 * will be packed in this order:
175 *
176 * (<var>x<sub>0</sub></var>,<var>y<sub>0</sub></var>,<var>z<sub>0</sub></var>,
177 * <var>x<sub>1</sub></var>,<var>y<sub>1</sub></var>,<var>z<sub>1</sub></var> …).
178 *
179 * @param srcPts the array containing the source point coordinates.
180 * @param srcOff the offset to the first point to be transformed in the source array.
181 * @param dstPts the array into which the transformed point coordinates are returned.
182 * @param dstOff the offset to the location of the first transformed point that is
183 * stored in the destination array.
184 * @param numPts the number of point objects to be transformed.
185 * @throws TransformException if a point can't be transformed. Some implementations will stop
186 * at the first failure, wile some other implementations will fill the untransformable
187 * points with {@linkplain Double#NaN NaN} values, continue and throw the exception
188 * only at end. Implementations that fall in the later case should set the {@linkplain
189 * TransformException#getLastCompletedTransform last completed transform} to {@code this}.
190 *
191 * @see AffineTransform#transform(float[], int, double[], int, int)
192 *
193 * @since 2.2
194 */
195 void transform(float [] srcPts, int srcOff,
196 double[] dstPts, int dstOff, int numPts) throws TransformException;
197
198 /**
199 * Transforms a list of coordinate point ordinal values.
200 * This method is provided for efficiently transforming many points.
201 * The supplied array of ordinal values will contain packed ordinal
202 * values. For example, if the source dimension is 3, then the ordinals
203 * will be packed in this order:
204 *
205 * (<var>x<sub>0</sub></var>,<var>y<sub>0</sub></var>,<var>z<sub>0</sub></var>,
206 * <var>x<sub>1</sub></var>,<var>y<sub>1</sub></var>,<var>z<sub>1</sub></var> …).
207 *
208 * @param srcPts the array containing the source point coordinates.
209 * @param srcOff the offset to the first point to be transformed in the source array.
210 * @param dstPts the array into which the transformed point coordinates are returned.
211 * @param dstOff the offset to the location of the first transformed point that is
212 * stored in the destination array.
213 * @param numPts the number of point objects to be transformed.
214 * @throws TransformException if a point can't be transformed. Some implementations will stop
215 * at the first failure, wile some other implementations will fill the untransformable
216 * points with {@linkplain Double#NaN NaN} values, continue and throw the exception
217 * only at end. Implementations that fall in the later case should set the {@linkplain
218 * TransformException#getLastCompletedTransform last completed transform} to {@code this}.
219 *
220 * @see AffineTransform#transform(double[], int, float[], int, int)
221 *
222 * @since 2.2
223 */
224 void transform(double[] srcPts, int srcOff,
225 float [] dstPts, int dstOff, int numPts) throws TransformException;
226
227 /**
228 * Gets the derivative of this transform at a point. The derivative is the
229 * matrix of the non-translating portion of the approximate affine map at
230 * the point. The matrix will have dimensions corresponding to the source
231 * and target coordinate systems. If the input dimension is <var>M</var>,
232 * and the output dimension is <var>N</var>, then the matrix will have size
233 * <code>N×M</code>. The elements of the matrix
234 *
235 * <code>{e<sub>n,m</sub> : n=0..(N-1)}</code>
236 *
237 * form a vector in the output space which is parallel to the displacement
238 * caused by a small change in the <var>m</var>'th ordinate in the input space.
239 *
240 * <p>For example, if the input dimension is 4 and the
241 * output dimension is 3, then a small displacement</p>
242 *
243 * <code>(x₀, x₁, x₂, x₃)</code>
244 *
245 * in the input space will result in a displacement
246 *
247 * <code>(y₀, y₁, y₂)</code>
248 *
249 * in the output space computed as below (<code>e<sub>n,m</sub></code>
250 * are the matrix elements):
251 *
252 * <pre>
253 *┌ ┐ ┌ ┐ ┌ ┐
254 *│ y₀ │ │ e₀₀ e₀₁ e₀₂ e₀₃ │ │ x₀ │
255 *│ y₁ │ = │ e₁₀ e₁₁ e₁₂ e₁₃ │ │ x₁ │
256 *│ y₂ │ │ e₂₀ e₂₁ e₂₂ e₂₃ │ │ x₂ │
257 *└ ┘ └ ┘ │ x₃ │
258 * └ ┘</pre>
259 *
260 * @param point The coordinate point where to evaluate the derivative. Null
261 * value is accepted only if the derivative is the same everywhere.
262 * For example affine transform accept null value since they produces
263 * identical derivative no matter the coordinate value. But most map
264 * projection will requires a non-null value.
265 * @return The derivative at the specified point (never {@code null}).
266 * This method never returns an internal object: changing the matrix
267 * will not change the state of this math transform.
268 * @throws NullPointerException if the derivative dependents on coordinate
269 * and {@code point} is {@code null}.
270 * @throws MismatchedDimensionException if {@code point} doesn't have
271 * the expected dimension.
272 * @throws TransformException if the derivative can't be evaluated at the
273 * specified point.
274 */
275 @UML(identifier="derivative", specification=OGC_01009)
276 Matrix derivative(final DirectPosition point)
277 throws MismatchedDimensionException, TransformException;
278
279 /**
280 * Creates the inverse transform of this object. The target of the inverse transform
281 * is the source of the original. The source of the inverse transform is the target
282 * of the original. Using the original transform followed by the inverse's transform
283 * will result in an identity map on the source coordinate space, when allowances for
284 * error are made. This method may fail if the transform is not one to one. However,
285 * all cartographic projections should succeed.
286 *
287 * @return The inverse transform.
288 * @throws NoninvertibleTransformException if the transform can't be inverted.
289 *
290 * @see AffineTransform#createInverse()
291 */
292 @UML(identifier="inverse", specification=OGC_01009)
293 MathTransform inverse() throws NoninvertibleTransformException;
294
295 /**
296 * Tests whether this transform does not move any points.
297 *
298 * @return {@code true} if this {@code MathTransform} is
299 * an identity transform; {@code false} otherwise.
300 *
301 * @see AffineTransform#isIdentity()
302 */
303 @UML(identifier="isIdentity", specification=OGC_01009)
304 boolean isIdentity();
305
306 /**
307 * Returns a <cite>Well Known Text</cite> (WKT) for this object. Well know text are
308 * <a href="../doc-files/WKT.html">defined in extended Backus Naur form</a>.
309 * This operation may fails if an object is too complex for the WKT format capability.
310 *
311 * @return The <cite>Well Known Text</cite> (WKT) for this object.
312 * @throws UnsupportedOperationException If this object can't be formatted as WKT.
313 *
314 * @see MathTransformFactory#createFromWKT(String)
315 */
316 @UML(identifier="getWKT", specification=OGC_01009)
317 String toWKT() throws UnsupportedOperationException;
318 }