001/*
002 *    GeoAPI - Java interfaces for OGC/ISO standards
003 *    Copyright © 2003-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 java.util.Map;
021import javax.measure.Unit;
022import org.opengis.referencing.IdentifiedObject;
023import org.opengis.annotation.UML;
024
025import static org.opengis.annotation.Obligation.*;
026import static org.opengis.annotation.Specification.*;
027
028
029/**
030 * Definition of a coordinate system axis.
031 * Each axis is characterized by a unique combination of name, abbreviation, direction and unit.
032 *
033 * <h2>Axis name</h2>
034 * Usage of coordinate system axis names is constrained by geodetic custom in a number of cases,
035 * depending mainly on the coordinate reference system type. These constraints are shown in the table below.
036 * This constraint works in two directions; for example the names <q>geodetic latitude</q> and <q>geodetic longitude</q>
037 * shall be used to designate the coordinate axis names associated with a geographic coordinate reference system.
038 * Conversely, these names shall not be used in any other context.
039 *
040 * <table class="ogc">
041 * <caption>Context of coordinate system axis names usage</caption>
042 * <tr><th><abbr>CS</abbr></th>
043 *     <th><abbr>CRS</abbr></th>
044 *     <th>Permitted coordinate system axis names</th></tr>
045 * <tr><td>Cartesian</td><td>Geodetic</td>
046 *     <td>“geocentric <var>X</var>”,
047 *         “geocentric <var>Y</var>”,
048 *         “geocentric <var>Z</var>”</td></tr>
049 * <tr><td>Cartesian</td><td>Projected</td>
050 *     <td>“easting” or “westing”,
051 *         “northing” or “southing”,
052 *         “ellipsoidal height” (if 3D)</td></tr>
053 * <tr><td>Ellipsoidal</td><td>Geographic</td>
054 *     <td>“geodetic latitude”,
055 *         “geodetic longitude”,
056 *         “ellipsoidal height” (if 3D)</td></tr>
057 * <tr><td>Spherical</td><td>Geodetic</td>
058 *     <td>“spherical latitude”,
059 *         “spherical longitude”,
060 *         “geocentric radius” (if 3D)</td></tr>
061 * <tr><td>″</td><td>″</td>
062 *     <td>“geocentric latitude”,
063 *         “geodetic longitude”,
064 *         “geocentric radius” (if 3D)</td></tr>
065 * <tr><td>″</td><td>″</td>
066 *     <td>“geocentric co-latitude”,
067 *         “geodetic longitude”,
068 *         “geocentric radius” (if 3D)</td></tr>
069 * <tr><td>Vertical</td><td>Vertical</td>
070 *     <td>“depth” or “gravity-related height”</td></tr>
071 * </table>
072 *
073 * Parametric, temporal and engineering coordinate reference systems may make use of names specific
074 * to the local context or custom and are therefore not included as constraints in the above list.
075 *
076 * <h2>Axis direction</h2>
077 * The {@linkplain #getDirection() direction} of the coordinate axes is often only approximate.
078 * Two geographic coordinate reference systems will make use of the same ellipsoidal coordinate system.
079 * These coordinate systems are associated with the planet through two different geodetic reference frames,
080 * which may lead to the two systems being slightly rotated with respect to each other.
081 *
082 * @author  OGC Topic 2 (for abstract model and documentation)
083 * @author  Martin Desruisseaux (IRD, Geomatys)
084 * @version 3.1
085 * @since   1.0
086 *
087 * @see CoordinateSystem
088 * @see CSAuthorityFactory#createCoordinateSystemAxis(String)
089 * @see CSFactory#createCoordinateSystemAxis(Map, String, AxisDirection, Unit)
090 */
091@UML(identifier="CoordinateSystemAxis", specification=ISO_19111)
092public interface CoordinateSystemAxis extends IdentifiedObject {
093    /**
094     * Returns the abbreviation used for this coordinate system axes.
095     * This abbreviation is also used to identify the coordinates in coordinate tuple.
096     * Examples are “<var>X</var>” and “<var>Y</var>”.
097     *
098     * @return the coordinate system axis abbreviation.
099     */
100    @UML(identifier="axisAbbrev", obligation=MANDATORY, specification=ISO_19111)
101    String getAbbreviation();
102
103    /**
104     * Returns the direction of this coordinate system axis. In the case of Cartesian projected
105     * coordinates, this is the direction of this coordinate system axis locally.
106     * Examples:
107     * {@linkplain AxisDirection#NORTH north} or {@linkplain AxisDirection#SOUTH south},
108     * {@linkplain AxisDirection#EAST  east}  or {@linkplain AxisDirection#WEST  west},
109     * {@linkplain AxisDirection#UP    up}    or {@linkplain AxisDirection#DOWN  down}.
110     *
111     * <p>Within any set of coordinate system axes, only one of each pair of terms can be used.
112     * For planet-fixed coordinate reference systems, this direction is often approximate
113     * and intended to provide a human interpretable meaning to the axis.
114     * When a geodetic reference frame is used, the precise directions of the axes may therefore
115     * vary slightly from this approximate direction.</p>
116     *
117     * <p>Note that an {@link org.opengis.referencing.crs.EngineeringCRS} often requires
118     * specific descriptions of the directions of its coordinate system axes.</p>
119     *
120     * @return the coordinate system axis direction.
121     */
122    @UML(identifier="axisDirection", obligation=MANDATORY, specification=ISO_19111)
123    AxisDirection getDirection();
124
125    /**
126     * Returns the unit of measure used for this coordinate system axis.
127     * The value of a coordinate in a coordinate tuple shall be recorded using this unit of measure,
128     * whenever those coordinates use a coordinate reference system that uses a coordinate system
129     * that uses this axis.
130     *
131     * <h4>Obligation</h4>
132     * This element may be {@code null} if this axis is part of an ordinal <abbr>CS</abbr>
133     * (a coordinate system in which axes use {@linkplain CoordinateDataType#INTEGER integer values})
134     * and in the case of a {@link TimeCS} using {@linkplain CoordinateDataType#DATE_TIME date-time}.
135     * This property is mandatory for all other cases.
136     *
137     * @return the coordinate system axis unit.
138     */
139    @UML(identifier="axisUnitID", obligation=CONDITIONAL, specification=ISO_19111)
140    Unit<?> getUnit();
141
142    /**
143     * Returns the minimum value normally allowed for this axis.
144     * The value shall be in the {@linkplain #getUnit() unit of measure for the axis}.
145     * If there is no minimum value, then this method returns
146     * {@linkplain Double#NEGATIVE_INFINITY negative infinity}.
147     *
148     * @return the minimum value, or {@link Double#NEGATIVE_INFINITY} if none.
149     */
150    @UML(identifier="minimumValue", obligation=OPTIONAL, specification=ISO_19111)
151    default double getMinimumValue() {
152        return Double.NEGATIVE_INFINITY;
153    }
154
155    /**
156     * Returns the maximum value normally allowed for this axis.
157     * The value shall be in the {@linkplain #getUnit() unit of measure for the axis}.
158     * If there is no maximum value, then this method returns
159     * {@linkplain Double#POSITIVE_INFINITY positive infinity}.
160     *
161     * @return the maximum value, or {@link Double#POSITIVE_INFINITY} if none.
162     */
163    @UML(identifier="maximumValue", obligation=OPTIONAL, specification=ISO_19111)
164    default double getMaximumValue() {
165        return Double.POSITIVE_INFINITY;
166    }
167
168    /**
169     * Returns the meaning of axis value range specified by the minimum and maximum values.
170     * This element shall be omitted when both minimum and maximum values are omitted.
171     * It may be included when minimum and/or maximum values are included.
172     * If this element is omitted when minimum or maximum values are included, the meaning is unspecified.
173     *
174     * @return the range meaning, or {@code null} in none.
175     *
176     * @see RangeMeaning#EXACT
177     * @see RangeMeaning#WRAPAROUND
178     */
179    @UML(identifier="rangeMeaning", obligation=CONDITIONAL, specification=ISO_19111)
180    default RangeMeaning getRangeMeaning() {
181        return null;
182    }
183}