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.Map;
035    
036    import org.opengis.annotation.UML;
037    import org.opengis.util.FactoryException;
038    import org.opengis.util.NoSuchIdentifierException;
039    import org.opengis.referencing.ObjectFactory;
040    import org.opengis.referencing.cs.CartesianCS;
041    import org.opengis.referencing.cs.CoordinateSystem;
042    import org.opengis.referencing.crs.CoordinateReferenceSystem;
043    import org.opengis.referencing.crs.GeographicCRS;
044    import org.opengis.referencing.crs.CRSFactory;
045    import org.opengis.referencing.datum.GeodeticDatum;
046    import org.opengis.parameter.ParameterValueGroup;
047    import org.opengis.parameter.ParameterDescriptorGroup;
048    
049    import static org.opengis.annotation.Specification.*;
050    
051    
052    /**
053     * Creates {@linkplain CoordinateOperation coordinate operations}.
054     * This factory is capable to find coordinate {@linkplain Transformation transformations}
055     * or {@linkplain Conversion conversions} between two
056     * {@linkplain CoordinateReferenceSystem coordinate reference systems}.
057     *
058     * @author  Martin Desruisseaux (IRD, Geomatys)
059     * @version 3.1
060     * @since   1.0
061     */
062    @UML(identifier="CT_CoordinateTransformationFactory", specification=OGC_01009)
063    public interface CoordinateOperationFactory extends ObjectFactory {
064        /**
065         * Returns an operation for conversion or transformation between two coordinate reference systems.
066         * <p>
067         * <ul>
068         *   <li>If an operation exists, it is returned.</li>
069         *   <li>If more than one operation exists, the default is returned.</li>
070         *   <li>If no operation exists, then the exception is thrown.</li>
071         * </ul>
072         * <p>
073         * Implementations may try to
074         * {@linkplain CoordinateOperationAuthorityFactory#createFromCoordinateReferenceSystemCodes
075         * query an authority factory} first, and compute the operation next if no operation from
076         * {@code source} to {@code target} code was explicitly defined by the authority.
077         *
078         * @param  sourceCRS Input coordinate reference system.
079         * @param  targetCRS Output coordinate reference system.
080         * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
081         * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS}
082         *         to {@code targetCRS}.
083         * @throws FactoryException if the operation creation failed for some other reason.
084         */
085        @UML(identifier="createFromCoordinateSystems", specification=OGC_01009)
086        CoordinateOperation createOperation(CoordinateReferenceSystem sourceCRS,
087                                            CoordinateReferenceSystem targetCRS)
088                throws OperationNotFoundException, FactoryException;
089    
090        /**
091         * Returns an operation using a particular method for conversion or transformation
092         * between two coordinate reference systems.
093         * <p>
094         * <ul>
095         *   <li>If the operation exists on the implementation, then it is returned.</li>
096         *   <li>If the operation does not exist on the implementation, then the implementation
097         *       has the option of inferring the operation from the argument objects.</li>
098         *   <li>If for whatever reason the specified operation will not be returned, then
099         *       the exception is thrown.</li>
100         * </ul>
101         * <p>
102         * <b>Example:</b> A transformation between two {@linkplain GeographicCRS geographic CRS} using
103         * different {@linkplain GeodeticDatum datum}
104         * requires a <cite>datum shift</cite>. Many methods exist for this purpose, including interpolations
105         * in a grid, a scale/rotation/translation in geocentric coordinates or the Molodenski approximation.
106         * When invoking {@code createOperation} without operation method, this factory may select by
107         * default the most accurate transformation (typically interpolation in a grid). When invoking
108         * {@code createOperation} with an operation method, user can force usage of Molodenski
109         * approximation for instance.
110         *
111         * @param  sourceCRS Input coordinate reference system.
112         * @param  targetCRS Output coordinate reference system.
113         * @param  method The algorithmic method for conversion or transformation.
114         * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
115         * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS}
116         *         to {@code targetCRS}.
117         * @throws FactoryException if the operation creation failed for some other reason.
118         *
119         * @departure extension
120         *   This method has been added at user request, in order to specify the desired
121         *   transformation path when many are available.
122         */
123        CoordinateOperation createOperation(CoordinateReferenceSystem sourceCRS,
124                                            CoordinateReferenceSystem targetCRS,
125                                            OperationMethod           method)
126                throws OperationNotFoundException, FactoryException;
127    
128        /**
129         * Creates a concatenated operation from a sequence of operations.
130         *
131         * @param  properties Name and other properties to give to the new object.
132         *         Available properties are {@linkplain ObjectFactory listed there}.
133         * @param  operations The sequence of operations.
134         * @return The concatenated operation.
135         * @throws FactoryException if the object creation failed.
136         *
137         * @departure extension
138         *   This method has been added because OGC 01-009 does not define a factory
139         *   method for creating such object.
140         */
141        CoordinateOperation createConcatenatedOperation(Map<String, ?> properties,
142                                                        CoordinateOperation... operations)
143                throws FactoryException;
144    
145        /**
146         * Creates a defining conversion from a set of properties. Defining conversions have no
147         * {@linkplain Conversion#getSourceCRS source} and {@linkplain Conversion#getTargetCRS target
148         * CRS}, and do not need to have a {@linkplain Conversion#getMathTransform math transform}.
149         * Their sole purpose is to be given as an argument to {@linkplain CRSFactory#createDerivedCRS
150         * derived CRS} and {@linkplain CRSFactory#createProjectedCRS projected CRS} constructors.
151         * <p>
152         * Some available properties are {@linkplain ObjectFactory listed there}.
153         * Additionally, the following properties are understood by this constructor:
154         * <p>
155         * <table border="1" cellspacing="0" cellpadding="2">
156         *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
157         *     <th nowrap>Property name</th>
158         *     <th nowrap>Value type</th>
159         *     <th nowrap>Value given to</th>
160         *   </tr>
161         *   <tr>
162         *     <td nowrap>&nbsp;{@value org.opengis.referencing.operation.CoordinateOperation#OPERATION_VERSION_KEY}&nbsp;</td>
163         *     <td nowrap>&nbsp;{@link String}&nbsp;</td>
164         *     <td nowrap>&nbsp;{@link CoordinateOperation#getOperationVersion()}</td>
165         *   </tr>
166         *   <tr>
167         *     <td nowrap>&nbsp;{@value org.opengis.referencing.operation.CoordinateOperation#COORDINATE_OPERATION_ACCURACY_KEY}&nbsp;</td>
168         *     <td nowrap>&nbsp;<code>{@linkplain org.opengis.metadata.quality.PositionalAccuracy}[]</code>&nbsp;</td>
169         *     <td nowrap>&nbsp;{@link CoordinateOperation#getCoordinateOperationAccuracy()}</td>
170         *   </tr>
171         *   <tr>
172         *     <td nowrap>&nbsp;{@value org.opengis.referencing.operation.CoordinateOperation#DOMAIN_OF_VALIDITY_KEY}&nbsp;</td>
173         *     <td nowrap>&nbsp;{@link org.opengis.metadata.extent.Extent}&nbsp;</td>
174         *     <td nowrap>&nbsp;{@link CoordinateOperation#getDomainOfValidity()}</td>
175         *   </tr>
176         *   <tr>
177         *     <td nowrap>&nbsp;{@value org.opengis.referencing.operation.CoordinateOperation#SCOPE_KEY}&nbsp;</td>
178         *     <td nowrap>&nbsp;{@link String} or {@link org.opengis.util.InternationalString}&nbsp;</td>
179         *     <td nowrap>&nbsp;{@link CoordinateOperation#getScope()}</td>
180         *   </tr>
181         * </table>
182         *
183         * @param  properties Set of properties. Shall contains at least {@code "name"}.
184         * @param  method The operation method. A value can be obtained by {@link #getOperationMethod(String)}.
185         * @param  parameters The parameter values. A default set of parameters can be obtained by
186         *         {@code method.getParameters().createValue()} and modified before to be given to
187         *         this constructor.
188         * @return The defining conversion.
189         * @throws FactoryException if the object creation failed.
190         *
191         * @see CRSFactory#createProjectedCRS(Map, GeographicCRS, Conversion, CartesianCS)
192         * @see CRSFactory#createDerivedCRS(Map, CoordinateReferenceSystem, Conversion, CoordinateSystem)
193         *
194         * @departure extension
195         *   <cite>Defining conversions</cite> is a concept that appears in ISO 19111 textual
196         *   specification without formalization in UML diagrams. This concept has been formalized
197         *   in GeoAPI in order to allow the creation of <code>ProjectedCRS</code> instances.
198         *
199         * @since 2.1
200         */
201        Conversion createDefiningConversion(Map<String,?>       properties,
202                                            OperationMethod     method,
203                                            ParameterValueGroup parameters)
204                throws FactoryException;
205    
206        /**
207         * Creates an operation method from a set of properties and a descriptor group.
208         * This factory method allows the creation of arbitrary {@code OperationMethod}
209         * instances. However some implementations may have a collection of build-in
210         * operation methods. For obtaining such build-in instance, see
211         * {@link #getOperationMethod(String)} instead.
212         * <p>
213         * Some available properties are {@linkplain ObjectFactory listed there}.
214         * Additionally, the following properties are understood by this constructor:
215         * <p>
216         * <table border="1" cellspacing="0" cellpadding="2">
217         *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
218         *     <th nowrap>Property name</th>
219         *     <th nowrap>Value type</th>
220         *     <th nowrap>Value given to</th>
221         *   </tr>
222         *   <tr>
223         *     <td nowrap>&nbsp;{@value org.opengis.referencing.operation.OperationMethod#FORMULA_KEY}&nbsp;</td>
224         *     <td nowrap>&nbsp;{@link Formula}&nbsp;</td>
225         *     <td nowrap>&nbsp;{@link OperationMethod#getFormula()}</td>
226         *   </tr>
227         * </table>
228         *
229         * @param  properties Set of properties. Shall contains at least {@code "name"}.
230         * @param  sourceDimension Number of dimensions in the source CRS of the operation method, or {@code null}.
231         * @param  targetDimension Number of dimensions in the target CRS of the operation method, or {@code null}.
232         * @param  parameters A description of the parameters for the operation method.
233         * @return The operation method.
234         * @throws FactoryException if the object creation failed.
235         *
236         * @departure extension
237         *   This method has been added because OGC 01-009 does not define a factory
238         *   method for creating such object.
239         *
240         * @since 3.1
241         */
242        OperationMethod createOperationMethod(Map<String,?> properties,
243                                              Integer  sourceDimension,
244                                              Integer  targetDimension,
245                                              ParameterDescriptorGroup parameters) throws FactoryException;
246    
247        /**
248         * Returns the build-in operation method of the given name.
249         * This is a helper method for usage of the following methods:
250         * <p>
251         * <ul>
252         *   <li>{@link #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, OperationMethod)}</li>
253         *   <li>{@link #createDefiningConversion(Map, OperationMethod, ParameterValueGroup)}</li>
254         * </ul>
255         * <p>
256         * Examples of typical operation method names are:
257         * <p>
258         * <table border="1" cellspacing="0" cellpadding="2">
259         *   <tr bgcolor="#CCCCFF" class="TableHeadingColor">
260         *     <th nowrap>OGC name</th>
261         *     <th nowrap>EPSG name</th>
262         *   </tr>
263         *   <tr><td>Mercator_1SP</td>                  <td>Mercator (variant A)</td></tr>
264         *   <tr><td>Mercator_2SP</td>                  <td>Mercator (variant B)</td></tr>
265         *   <tr><td>Transverse_Mercator</td>           <td>Transverse Mercator</td></tr>
266         *   <tr><td>Lambert_Conformal_Conic_1SP</td>   <td>Lambert Conic Conformal (1SP)</td></tr>
267         *   <tr><td>Lambert_Conformal_Conic_2SP</td>   <td>Lambert Conic Conformal (2SP)</td></tr>
268         *   <tr><td>Lambert_Azimuthal_Equal_Area</td>  <td>Lambert Azimuthal Equal Area</td></tr>
269         *   <tr><td>Albers_Conic_Equal_Area</td>       <td>Albers Equal Area</td></tr>
270         *   <tr><td>Cassini_Soldner</td>               <td>Cassini-Soldner</td></tr>
271         *   <tr><td>Orthographic</td>                  <td>Orthographic</td></tr>
272         * </table>
273         * <p>
274         * Implementations may delegate to their {@link MathTransformFactory}, or delegate to their
275         * {@link CoordinateOperationAuthorityFactory}, or get the operation method in some other way
276         * at implementor choice.
277         *
278         * @param  name The name of the operation method to fetch.
279         * @return The operation method of the given name.
280         * @throws NoSuchIdentifierException if no operation method of the given name is known to this factory.
281         * @throws FactoryException if the method failed for some other reason.
282         *
283         * @departure easeOfUse
284         *   This method has been added in order to free the user from choosing whatever he should
285         *   get the operation method from <code>CoordinateOperationAuthorityFactory</code>, or from
286         *   <code>MathTransformFactory</code>, or creating it himself.
287         *
288         * @see MathTransformFactory#getAvailableMethods(Class)
289         * @see CoordinateOperationAuthorityFactory#createOperationMethod(String)
290         *
291         * @since 3.1
292         */
293        OperationMethod getOperationMethod(String name) throws NoSuchIdentifierException, FactoryException;
294    }