001/*
002 *    GeoAPI - Java interfaces for OGC/ISO standards
003 *    Copyright © 2004-2023 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.crs;
019
020import org.opengis.referencing.AuthorityFactory;
021import org.opengis.referencing.NoSuchAuthorityCodeException;
022import org.opengis.util.UnimplementedServiceException;
023import org.opengis.util.FactoryException;
024import org.opengis.annotation.UML;
025
026import static org.opengis.annotation.Specification.*;
027import static org.opengis.geoapi.internal.Errors.unexpectedType;
028
029
030/**
031 * Creates coordinate reference systems using authority codes.
032 * External authorities are used to manage definitions of objects used in this interface.
033 * The definitions of these objects are referenced using code strings.
034 * A commonly used authority is the <a href="https://epsg.org">EPSG geodetic registry</a>.
035 *
036 * <h2>Default methods</h2>
037 * All {@code create(…)} methods in this interface are optional.
038 * If a method is not overridden by the implementer, the default is:
039 * <ul>
040 *   <li>For methods creating a sub-type of {@link CoordinateReferenceSystem}, delegate to
041 *       {@link #createCoordinateReferenceSystem(String)} then check the returned object type.</li>
042 *   <li>For all other methods, throw an {@link UnimplementedServiceException} with a message
043 *       saying that the type or service is not supported.</li>
044 * </ul>
045 *
046 * @author  OGC 01-009 (for abstract model and documentation)
047 * @author  Martin Desruisseaux (IRD, Geomatys)
048 * @author  Johann Sorel (Geomatys)
049 * @version 3.1
050 * @since   1.0
051 *
052 * @see org.opengis.referencing.cs.CSAuthorityFactory
053 * @see org.opengis.referencing.datum.DatumAuthorityFactory
054 */
055@UML(identifier="CS_CoordinateSystemAuthorityFactory", specification=OGC_01009)
056public interface CRSAuthorityFactory extends AuthorityFactory {
057    /**
058     * Returns an arbitrary coordinate reference system from a code.
059     *
060     * <p>If the coordinate reference system type is known at compile time, then it is recommended
061     * to invoke the most precise method instead of this one. For example, it is usually better to
062     * invoke <code>{@linkplain #createGeographicCRS createGeographicCRS}(code)</code> instead of
063     * {@code createCoordinateReferenceSystem(code)} if the requested object is known to be a
064     * {@code GeographicCRS} instance.</p>
065     *
066     * @param  code  value allocated by authority.
067     * @return the coordinate reference system for the given code.
068     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
069     * @throws FactoryException if the object creation failed for some other reason.
070     *
071     * @see #createGeographicCRS(String)
072     * @see #createProjectedCRS(String)
073     * @see #createVerticalCRS(String)
074     * @see #createTemporalCRS(String)
075     * @see #createCompoundCRS(String)
076     */
077    @UML(identifier="createHorizontalCoordinateSystem", specification=OGC_01009)
078    default CoordinateReferenceSystem createCoordinateReferenceSystem(String code) throws FactoryException {
079        throw new UnimplementedServiceException(this, CoordinateReferenceSystem.class);
080    }
081
082    /**
083     * Returns a geographic coordinate reference system from a code.
084     *
085     * @param  code  value allocated by authority.
086     * @return the coordinate reference system for the given code.
087     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
088     * @throws FactoryException if the object creation failed for some other reason.
089     *
090     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createGeodeticDatum(String)
091     */
092    @UML(identifier="createGeographicCoordinateSystem", specification=OGC_01009)
093    default GeographicCRS createGeographicCRS(final String code) throws FactoryException {
094        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
095        try {
096            return (GeographicCRS) crs;
097        } catch (ClassCastException e) {
098            throw unexpectedType(this, code, crs, e);
099        }
100    }
101
102    /**
103     * Returns a geocentric coordinate reference system from a code.
104     *
105     * @param  code  value allocated by authority.
106     * @return the coordinate reference system for the given code.
107     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
108     * @throws FactoryException if the object creation failed.
109     *
110     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createGeodeticDatum(String)
111     *
112     * @deprecated The {@code GeocentricCRS} type has been removed since ISO 19111:2007.
113     * Use {@link #createGeodeticCRS(String)} instead.
114     */
115    @Deprecated(since = "3.1")
116    default GeocentricCRS createGeocentricCRS(final String code) throws FactoryException {
117        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
118        try {
119            return (GeocentricCRS) crs;
120        } catch (ClassCastException e) {
121            throw unexpectedType(this, code, crs, e);
122        }
123    }
124
125    /**
126     * Returns a geodetic coordinate reference system from a code.
127     * A geodetic CRS can be {@linkplain #createGeographicCRS(String) geographic} or geocentric.
128     *
129     * @param  code  value allocated by authority.
130     * @return the coordinate reference system for the given code.
131     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
132     * @throws FactoryException if the object creation failed.
133     *
134     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createGeodeticDatum(String)
135     *
136     * @since 3.1
137     */
138    default GeodeticCRS createGeodeticCRS(final String code) throws FactoryException {
139        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
140        try {
141            return (GeodeticCRS) crs;
142        } catch (ClassCastException e) {
143            throw unexpectedType(this, code, crs, e);
144        }
145    }
146
147    /**
148     * Returns a vertical coordinate reference system from a code.
149     *
150     * @param  code  value allocated by authority.
151     * @return the coordinate reference system for the given code.
152     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
153     * @throws FactoryException if the object creation failed for some other reason.
154     *
155     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createVerticalDatum(String)
156     */
157    @UML(identifier="createVerticalCoordinateSystem", specification=OGC_01009)
158    default VerticalCRS createVerticalCRS(final String code) throws FactoryException {
159        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
160        try {
161            return (VerticalCRS) crs;
162        } catch (ClassCastException e) {
163            throw unexpectedType(this, code, crs, e);
164        }
165    }
166
167    /**
168     * Returns a temporal coordinate reference system from a code.
169     *
170     * @param  code  value allocated by authority.
171     * @return the coordinate reference system for the given code.
172     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
173     * @throws FactoryException if the object creation failed for some other reason.
174     *
175     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createTemporalDatum(String)
176     */
177    default TemporalCRS createTemporalCRS(final String code) throws FactoryException {
178        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
179        try {
180            return (TemporalCRS) crs;
181        } catch (ClassCastException e) {
182            throw unexpectedType(this, code, crs, e);
183        }
184    }
185
186    /**
187     * Returns a parametric coordinate reference system from a code.
188     *
189     * @param  code  value allocated by authority.
190     * @return the coordinate reference system for the given code.
191     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
192     * @throws FactoryException if the object creation failed for some other reason.
193     *
194     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createParametricDatum(String)
195     *
196     * @since 3.1
197     */
198    default ParametricCRS createParametricCRS(final String code) throws FactoryException {
199        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
200        try {
201            return (ParametricCRS) crs;
202        } catch (ClassCastException e) {
203            throw unexpectedType(this, code, crs, e);
204        }
205    }
206
207    /**
208     * Returns a 3D coordinate reference system from a code.
209     *
210     * @param  code  value allocated by authority.
211     * @return the coordinate reference system for the given code.
212     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
213     * @throws FactoryException if the object creation failed for some other reason.
214     */
215    @UML(identifier="createCompoundCoordinateSystem", specification=OGC_01009)
216    default CompoundCRS createCompoundCRS(final String code) throws FactoryException {
217        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
218        try {
219            return (CompoundCRS) crs;
220        } catch (ClassCastException e) {
221            throw unexpectedType(this, code, crs, e);
222        }
223    }
224
225    /**
226     * Returns a engineering coordinate reference system from a code.
227     *
228     * @param  code  value allocated by authority.
229     * @return the coordinate reference system for the given code.
230     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
231     * @throws FactoryException if the object creation failed for some other reason.
232     */
233    default EngineeringCRS createEngineeringCRS(final String code) throws FactoryException {
234        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
235        try {
236            return (EngineeringCRS) crs;
237        } catch (ClassCastException e) {
238            throw unexpectedType(this, code, crs, e);
239        }
240    }
241
242    /**
243     * Returns a image coordinate reference system from a code.
244     *
245     * @param  code  value allocated by authority.
246     * @return the coordinate reference system for the given code.
247     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
248     * @throws FactoryException if the object creation failed for some other reason.
249     *
250     * @deprecated {@code ImageCRS} is replaced by {@link EngineeringCRS} as of ISO 19111:2019.
251     */
252    @Deprecated(since="3.1")
253    default ImageCRS createImageCRS(final String code) throws FactoryException {
254        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
255        try {
256            return (ImageCRS) crs;
257        } catch (ClassCastException e) {
258            throw unexpectedType(this, code, crs, e);
259        }
260    }
261
262    /**
263     * Returns a derived coordinate reference system from a code.
264     *
265     * @param  code  value allocated by authority.
266     * @return the coordinate reference system for the given code.
267     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
268     * @throws FactoryException if the object creation failed for some other reason.
269     */
270    default DerivedCRS createDerivedCRS(final String code) throws FactoryException {
271        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
272        try {
273            return (DerivedCRS) crs;
274        } catch (ClassCastException e) {
275            throw unexpectedType(this, code, crs, e);
276        }
277    }
278
279    /**
280     * Returns a projected coordinate reference system from a code.
281     *
282     * @param  code  value allocated by authority.
283     * @return the coordinate reference system for the given code.
284     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
285     * @throws FactoryException if the object creation failed for some other reason.
286     *
287     * @see org.opengis.referencing.datum.DatumAuthorityFactory#createGeodeticDatum(String)
288     */
289    @UML(identifier="createProjectedCoordinateSystem", specification=OGC_01009)
290    default ProjectedCRS createProjectedCRS(final String code) throws FactoryException {
291        final CoordinateReferenceSystem crs = createCoordinateReferenceSystem(code);
292        try {
293            return (ProjectedCRS) crs;
294        } catch (ClassCastException e) {
295            throw unexpectedType(this, code, crs, e);
296        }
297    }
298
299    /**
300     * Returns an arbitrary object from a code.
301     *
302     * @param  code  value allocated by authority.
303     * @return the object for the given code.
304     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
305     * @throws FactoryException if the object creation failed for some other reason.
306     *
307     * @deprecated This method is ambiguous. Use {@link #createCoordinateReferenceSystem(String)} instead.
308     */
309    @Override
310    @SuppressWarnings("removal")
311    @Deprecated(since="3.1", forRemoval=true)
312    default org.opengis.referencing.IdentifiedObject createObject(String code) throws FactoryException {
313        return createCoordinateReferenceSystem(code);
314    }
315}