001/* 002 * GeoAPI - Java interfaces for OGC/ISO standards 003 * Copyright © 2004-2024 Open Geospatial Consortium, Inc. 004 * http://www.geoapi.org 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.opengis.referencing.operation; 019 020import java.util.Map; 021 022import org.opengis.annotation.UML; 023import org.opengis.util.FactoryException; 024import org.opengis.util.NoSuchIdentifierException; 025import org.opengis.referencing.ObjectFactory; 026import org.opengis.referencing.cs.CartesianCS; 027import org.opengis.referencing.cs.CoordinateSystem; 028import org.opengis.referencing.crs.CoordinateReferenceSystem; 029import org.opengis.referencing.crs.GeographicCRS; 030import org.opengis.referencing.crs.CRSFactory; 031import org.opengis.referencing.datum.GeodeticDatum; 032import org.opengis.parameter.ParameterValueGroup; 033import org.opengis.parameter.ParameterDescriptorGroup; 034 035import static org.opengis.annotation.Specification.*; 036 037 038/** 039 * Creates coordinate operations from parameter values, or infers operations from source and target CRS. 040 * This factory provides two groups of methods: 041 * 042 * <ul> 043 * <li>Finding instances provided by the implementation:<ul> 044 * <li>{@link #getOperationMethod(String)}</li> 045 * <li>{@link #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem)}</li> 046 * <li>{@link #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, OperationMethod)}</li> 047 * </ul></li> 048 * <li>Creating new instances from user supplied parameters:<ul> 049 * <li>{@link #createOperationMethod(Map, ParameterDescriptorGroup)}</li> 050 * <li>{@link #createDefiningConversion(Map, OperationMethod, ParameterValueGroup)}</li> 051 * <li>{@link #createConcatenatedOperation(Map, CoordinateOperation[])}</li> 052 * </ul></li> 053 * </ul> 054 * 055 * @author Martin Desruisseaux (IRD, Geomatys) 056 * @version 3.1 057 * @since 1.0 058 */ 059@UML(identifier="CT_CoordinateTransformationFactory", specification=OGC_01009) 060public interface CoordinateOperationFactory extends ObjectFactory { 061 /** 062 * Returns an operation for conversion or transformation between two coordinate reference systems. 063 * 064 * <ul> 065 * <li>If an operation exists, it is returned.</li> 066 * <li>If more than one operation exists, the default is returned.</li> 067 * <li>If no operation exists, then the exception is thrown.</li> 068 * </ul> 069 * 070 * Implementations may try to 071 * {@linkplain CoordinateOperationAuthorityFactory#createFromCoordinateReferenceSystemCodes 072 * query an authority factory} first, and compute the operation next if no operation from 073 * {@code source} to {@code target} code was explicitly defined by the authority. 074 * 075 * @param sourceCRS input coordinate reference system. 076 * @param targetCRS output coordinate reference system. 077 * @return a coordinate operation from {@code sourceCRS} to {@code targetCRS}. 078 * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS} 079 * to {@code targetCRS}. 080 * @throws FactoryException if the operation creation failed for some other reason. 081 */ 082 @UML(identifier="createFromCoordinateSystems", specification=OGC_01009) 083 CoordinateOperation createOperation(CoordinateReferenceSystem sourceCRS, 084 CoordinateReferenceSystem targetCRS) 085 throws FactoryException; 086 087 /** 088 * Returns an operation using a particular method for conversion or transformation 089 * between two coordinate reference systems. 090 * 091 * <ul> 092 * <li>If the operation exists on the implementation, then it is returned.</li> 093 * <li>If the operation does not exist on the implementation, then the implementation 094 * has the option of inferring the operation from the argument objects.</li> 095 * <li>If for whatever reason the specified operation will not be returned, then 096 * the exception is thrown.</li> 097 * </ul> 098 * 099 * <b>Example:</b> A transformation between two {@linkplain GeographicCRS geographic CRS} using 100 * different {@linkplain GeodeticDatum datum} requires a <i>datum shift</i>. 101 * Many methods exist for this purpose, including interpolations in a grid, 102 * a scale/rotation/translation in geocentric coordinates or the Molodenski approximation. 103 * When invoking {@code createOperation(…)} without operation method, 104 * this factory may select by default the transformation specified by the authority. 105 * When invoking {@code createOperation(…)} with an operation method, 106 * user can force usage of Molodenski approximation for instance. 107 * 108 * @param sourceCRS input coordinate reference system. 109 * @param targetCRS output coordinate reference system. 110 * @param method the algorithmic method for conversion or transformation. 111 * @return a coordinate operation from {@code sourceCRS} to {@code targetCRS}. 112 * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS} 113 * to {@code targetCRS}. 114 * @throws FactoryException if the operation creation failed for some other reason. 115 * 116 * @departure extension 117 * This method has been added at user request, in order to specify the desired 118 * transformation path when many are available. 119 */ 120 CoordinateOperation createOperation(CoordinateReferenceSystem sourceCRS, 121 CoordinateReferenceSystem targetCRS, 122 OperationMethod method) 123 throws FactoryException; 124 125 /** 126 * Creates a concatenated operation from a sequence of operations. 127 * The source coordinate reference system of the first step and the target coordinate reference system of the 128 * last step are the source and target coordinate reference system associated with the concatenated operation. 129 * 130 * @param properties name and other properties to give to the new object. 131 * Available properties are {@linkplain ObjectFactory listed there}. 132 * @param operations the sequence of operations. 133 * @return the concatenated operation. 134 * @throws FactoryException if the object creation failed. 135 * 136 * @departure extension 137 * This method has been added because OGC 01-009 does not define a factory 138 * method for creating such object. 139 */ 140 CoordinateOperation createConcatenatedOperation(Map<String, ?> properties, 141 CoordinateOperation... operations) 142 throws FactoryException; 143 144 /** 145 * Creates a defining conversion from a set of properties. Defining conversions have no 146 * {@linkplain Conversion#getSourceCRS() source} and {@linkplain Conversion#getTargetCRS() target CRS}, 147 * and do not need to have a {@linkplain Conversion#getMathTransform() math transform}. 148 * Their sole purpose is to be given as an argument to {@linkplain CRSFactory#createDerivedCRS 149 * derived CRS} and {@linkplain CRSFactory#createProjectedCRS projected CRS} constructors. 150 * 151 * <p>Some available properties are {@linkplain ObjectFactory listed there}.</p> 152 * 153 * @param properties set of properties. Shall contain at least {@code "name"}. 154 * @param method the operation method. A value can be obtained by {@link #getOperationMethod(String)}. 155 * @param parameters the parameter values. A default set of parameters can be obtained by 156 * {@code method.getParameters().createValue()} and modified before to be given to this constructor. 157 * @return the defining conversion. 158 * @throws FactoryException if the object creation failed. 159 * 160 * @see CRSFactory#createProjectedCRS(Map, GeographicCRS, Conversion, CartesianCS) 161 * @see CRSFactory#createDerivedCRS(Map, CoordinateReferenceSystem, Conversion, CoordinateSystem) 162 * 163 * @departure extension 164 * The <i>defining conversion</i> concept appears in ISO 19111 specification without formalization in UML diagrams. 165 * This concept has been formalized in GeoAPI in order to allow the creation of {@code ProjectedCRS} instances. 166 */ 167 Conversion createDefiningConversion(Map<String,?> properties, 168 OperationMethod method, 169 ParameterValueGroup parameters) 170 throws FactoryException; 171 172 /** 173 * Creates an operation method from a set of properties and a descriptor group. 174 * This factory method allows the creation of arbitrary {@code OperationMethod} instances. 175 * Some available properties are {@linkplain ObjectFactory listed there}. 176 * Additionally, the following properties should be accepted by this constructor: 177 * 178 * <table class="ogc"> 179 * <caption>Keys for additional standard properties</caption> 180 * <tr> 181 * <th>Property name</th> 182 * <th>Value type</th> 183 * <th>Returned by</th> 184 * </tr><tr> 185 * <td>{@value org.opengis.referencing.operation.OperationMethod#FORMULA_KEY}</td> 186 * <td>{@link Formula}</td> 187 * <td>{@link OperationMethod#getFormula()}</td> 188 * </tr> 189 * </table> 190 * 191 * Note that implementations may have a build-in list of predefined operation methods. 192 * For obtaining a build-in instance, see {@link #getOperationMethod(String)} instead. 193 * 194 * @param properties set of properties. Shall contain at least {@code "name"}. 195 * @param parameters a description of the parameters for the operation method. 196 * @return the operation method. 197 * @throws FactoryException if the object creation failed. 198 * 199 * @departure extension 200 * This method has been added because OGC 01-009 does not define a factory 201 * method for creating such object. 202 * 203 * @since 3.1 204 */ 205 OperationMethod createOperationMethod(Map<String,?> properties, 206 ParameterDescriptorGroup parameters) throws FactoryException; 207 208 /** 209 * Returns the build-in operation method of the given name. 210 * This is a helper method for usage of the following methods: 211 * 212 * <ul> 213 * <li>{@link #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, OperationMethod)}</li> 214 * <li>{@link #createDefiningConversion(Map, OperationMethod, ParameterValueGroup)}</li> 215 * </ul> 216 * 217 * Examples of typical operation method names are: 218 * 219 * <table class="ogc"> 220 * <caption>Example of operation method names</caption> 221 * <tr> 222 * <th>OGC name</th> 223 * <th>EPSG name</th> 224 * </tr> 225 * <tr><td>Mercator_1SP</td> <td>Mercator (variant A)</td></tr> 226 * <tr><td>Mercator_2SP</td> <td>Mercator (variant B)</td></tr> 227 * <tr><td>Transverse_Mercator</td> <td>Transverse Mercator</td></tr> 228 * <tr><td>Lambert_Conformal_Conic_1SP</td> <td>Lambert Conic Conformal (1SP)</td></tr> 229 * <tr><td>Lambert_Conformal_Conic_2SP</td> <td>Lambert Conic Conformal (2SP)</td></tr> 230 * <tr><td>Lambert_Azimuthal_Equal_Area</td> <td>Lambert Azimuthal Equal Area</td></tr> 231 * <tr><td>Albers_Conic_Equal_Area</td> <td>Albers Equal Area</td></tr> 232 * <tr><td>Cassini_Soldner</td> <td>Cassini-Soldner</td></tr> 233 * <tr><td>Orthographic</td> <td>Orthographic</td></tr> 234 * </table> 235 * 236 * Implementations may delegate to their {@link MathTransformFactory}, or delegate to their 237 * {@link CoordinateOperationAuthorityFactory}, or get the operation method in some other way 238 * at implementer choice. 239 * 240 * @param name the name of the operation method to fetch. 241 * @return the operation method of the given name. 242 * @throws NoSuchIdentifierException if no operation method of the given name is known to this factory. 243 * @throws FactoryException if the method failed for some other reason. 244 * 245 * @departure easeOfUse 246 * This method has been added in order to free the user from choosing whether he should 247 * get the operation method from {@code CoordinateOperationAuthorityFactory}, or from 248 * {@code MathTransformFactory}, or creating it himself. 249 * 250 * @see MathTransformFactory#getAvailableMethods(Class) 251 * @see CoordinateOperationAuthorityFactory#createOperationMethod(String) 252 * 253 * @since 3.1 254 */ 255 OperationMethod getOperationMethod(String name) throws FactoryException; 256}