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.cs;
019
020import javax.measure.Unit;
021import org.opengis.referencing.AuthorityFactory;
022import org.opengis.referencing.NoSuchAuthorityCodeException;
023import org.opengis.util.UnimplementedServiceException;
024import org.opengis.util.FactoryException;
025import org.opengis.annotation.UML;
026
027import static org.opengis.annotation.Specification.*;
028import static org.opengis.geoapi.internal.Errors.unexpectedType;
029
030
031/**
032 * Creates {@linkplain CoordinateSystem coordinate systems} using authority codes.
033 * External authorities are used to manage definitions of objects used in this interface.
034 * The definitions of these objects are referenced using code strings.
035 * A commonly used authority is the <a href="https://epsg.org">EPSG geodetic registry</a>.
036 *
037 * <h2>Default methods</h2>
038 * All {@code create(…)} methods in this interface are optional.
039 * If a method is not overridden by the implementer, the default is:
040 * <ul>
041 *   <li>For methods creating a sub-type of {@link CoordinateSystem}, delegate to
042 *       {@link #createCoordinateSystem(String)} then check the returned object type.</li>
043 *   <li>For all other methods, throw an {@link UnimplementedServiceException} with a message
044 *       saying that the type or service is not supported.</li>
045 * </ul>
046 *
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.crs.CRSAuthorityFactory
053 * @see org.opengis.referencing.datum.DatumAuthorityFactory
054 */
055public interface CSAuthorityFactory extends AuthorityFactory {
056    /**
057     * Returns an unit of measurement from a code.
058     *
059     * @param  code  value allocated by authority.
060     * @return the unit for the given code.
061     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
062     * @throws FactoryException if the object creation failed for some other reason.
063     */
064    @UML(identifier="CS_CoordinateSystemAuthorityFactory.createLinearUnit, createAngularUnit", specification=OGC_01009)
065    default Unit<?> createUnit(String code) throws FactoryException {
066        throw new UnimplementedServiceException(this, Unit.class);
067    }
068
069    /**
070     * Returns a coordinate system axis from a code.
071     *
072     * @param  code  value allocated by authority.
073     * @return the axis for the given code.
074     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
075     * @throws FactoryException if the object creation failed for some other reason.
076     */
077    default CoordinateSystemAxis createCoordinateSystemAxis(String code) throws FactoryException {
078        throw new UnimplementedServiceException(this, CoordinateSystemAxis.class);
079    }
080
081    /**
082     * Returns an arbitrary coordinate system from a code.
083     *
084     * <p>If the coordinate system type is known at compile time, then it is recommended
085     * to invoke the most precise method instead of this one. For example, it is usually better
086     * to invoke <code>{@linkplain #createCartesianCS createCartesianCS}(code)</code> instead
087     * of {@code createCoordinateSystem(code)} if the requested object is known to be a
088     * {@code CartesianCS} instance.</p>
089     *
090     * @param  code  value allocated by authority.
091     * @return the coordinate system for the given code.
092     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
093     * @throws FactoryException if the object creation failed for some other reason.
094     */
095    default CoordinateSystem createCoordinateSystem(String code) throws FactoryException {
096        throw new UnimplementedServiceException(this, CoordinateSystem.class);
097    }
098
099    /**
100     * Returns a Cartesian coordinate system from a code.
101     *
102     * @param  code  value allocated by authority.
103     * @return the coordinate system for the given code.
104     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
105     * @throws FactoryException if the object creation failed for some other reason.
106     */
107    default CartesianCS createCartesianCS(final String code) throws FactoryException {
108        final CoordinateSystem cs = createCoordinateSystem(code);
109        try {
110            return (CartesianCS) cs;
111        } catch (ClassCastException e) {
112            throw unexpectedType(this, code, cs, e);
113        }
114    }
115
116    /**
117     * Returns a polar coordinate system from a code.
118     *
119     * @param  code  value allocated by authority.
120     * @return the coordinate system for the given code.
121     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
122     * @throws FactoryException if the object creation failed for some other reason.
123     */
124    default PolarCS createPolarCS(final String code) throws FactoryException {
125        final CoordinateSystem cs = createCoordinateSystem(code);
126        try {
127            return (PolarCS) cs;
128        } catch (ClassCastException e) {
129            throw unexpectedType(this, code, cs, e);
130        }
131    }
132
133    /**
134     * Returns a cylindrical coordinate system from a code.
135     *
136     * @param  code  value allocated by authority.
137     * @return the coordinate system for the given code.
138     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
139     * @throws FactoryException if the object creation failed for some other reason.
140     */
141    default CylindricalCS createCylindricalCS(final String code) throws FactoryException {
142        final CoordinateSystem cs = createCoordinateSystem(code);
143        try {
144            return (CylindricalCS) cs;
145        } catch (ClassCastException e) {
146            throw unexpectedType(this, code, cs, e);
147        }
148    }
149
150    /**
151     * Returns a spherical coordinate system from a code.
152     *
153     * @param  code  value allocated by authority.
154     * @return the coordinate system for the given code.
155     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
156     * @throws FactoryException if the object creation failed for some other reason.
157     */
158    default SphericalCS createSphericalCS(final String code) throws FactoryException {
159        final CoordinateSystem cs = createCoordinateSystem(code);
160        try {
161            return (SphericalCS) cs;
162        } catch (ClassCastException e) {
163            throw unexpectedType(this, code, cs, e);
164        }
165    }
166
167    /**
168     * Returns an ellipsoidal coordinate system from a code.
169     *
170     * @param  code  value allocated by authority.
171     * @return the coordinate 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    default EllipsoidalCS createEllipsoidalCS(final String code) throws FactoryException {
176        final CoordinateSystem cs = createCoordinateSystem(code);
177        try {
178            return (EllipsoidalCS) cs;
179        } catch (ClassCastException e) {
180            throw unexpectedType(this, code, cs, e);
181        }
182    }
183
184    /**
185     * Returns a vertical coordinate system from a code.
186     *
187     * @param  code  value allocated by authority.
188     * @return the coordinate system for the given code.
189     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
190     * @throws FactoryException if the object creation failed for some other reason.
191     */
192    default VerticalCS createVerticalCS(final String code) throws FactoryException {
193        final CoordinateSystem cs = createCoordinateSystem(code);
194        try {
195            return (VerticalCS) cs;
196        } catch (ClassCastException e) {
197            throw unexpectedType(this, code, cs, e);
198        }
199    }
200
201    /**
202     * Returns a temporal coordinate system from a code.
203     *
204     * @param  code  value allocated by authority.
205     * @return the coordinate system for the given code.
206     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
207     * @throws FactoryException if the object creation failed for some other reason.
208     */
209    default TimeCS createTimeCS(final String code) throws FactoryException {
210        final CoordinateSystem cs = createCoordinateSystem(code);
211        try {
212            return (TimeCS) cs;
213        } catch (ClassCastException e) {
214            throw unexpectedType(this, code, cs, e);
215        }
216    }
217
218    /**
219     * Returns a parametric coordinate system from a code.
220     *
221     * @param  code  value allocated by authority.
222     * @return the coordinate system for the given code.
223     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
224     * @throws FactoryException if the object creation failed for some other reason.
225     */
226    default ParametricCS createParametricCS(final String code) throws FactoryException {
227        final CoordinateSystem cs = createCoordinateSystem(code);
228        try {
229            return (ParametricCS) cs;
230        } catch (ClassCastException e) {
231            throw unexpectedType(this, code, cs, e);
232        }
233    }
234
235    /**
236     * Returns an arbitrary object from a code.
237     *
238     * @param  code  value allocated by authority.
239     * @return the object for the given code.
240     * @throws NoSuchAuthorityCodeException if the specified {@code code} was not found.
241     * @throws FactoryException if the object creation failed for some other reason.
242     *
243     * @deprecated This method is ambiguous. Use {@link #createCoordinateSystem(String)} instead.
244     */
245    @Override
246    @SuppressWarnings("removal")
247    @Deprecated(since="3.1", forRemoval=true)
248    default org.opengis.referencing.IdentifiedObject createObject(String code) throws FactoryException {
249        return createCoordinateSystem(code);
250    }
251}