001    /*
002     *    GeoAPI - Java interfaces for OGC/ISO standards
003     *    http://www.geoapi.org
004     *
005     *    Copyright (C) 2004-2013 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.datum;
033    
034    import java.util.Map;
035    import javax.measure.unit.Unit;
036    import javax.measure.quantity.Length;
037    import org.opengis.referencing.IdentifiedObject;
038    import org.opengis.annotation.UML;
039    
040    import static org.opengis.annotation.Obligation.*;
041    import static org.opengis.annotation.Specification.*;
042    
043    
044    /**
045     * Geometric figure that can be used to describe the approximate shape of the earth.
046     * In mathematical terms, it is a surface formed by the rotation of an ellipse about
047     * its minor axis. An ellipsoid requires two defining parameters:
048     *
049     * <ul>
050     *   <li>{@linkplain #getSemiMajorAxis() semi-major axis} and
051     *       {@linkplain #getInverseFlattening() inverse flattening}, or</li>
052     *   <li>{@linkplain #getSemiMajorAxis() semi-major axis} and
053     *       {@linkplain #getSemiMinorAxis() semi-minor axis}.</li>
054     * </ul>
055     *
056     * There is not just one ellipsoid. An ellipsoid is a matter of choice, and therefore many
057     * choices are possible. The size and shape of an ellipsoid was traditionally chosen such
058     * that the surface of the geoid is matched as closely as possible locally, e.g. in a country.
059     * A number of global best-fit ellipsoids are now available. An association of an ellipsoid with
060     * the earth is made through the definition of the size and shape of the ellipsoid and the position
061     * and orientation of this ellipsoid with respect to the earth. Collectively this choice is captured
062     * by the concept of "{@linkplain GeodeticDatum geodetic datum}". A change of size, shape, position
063     * or orientation of an ellipsoid will result in a change of geographic coordinates of a point and
064     * be described as a different geodetic datum. Conversely geographic coordinates are unambiguous
065     * only when associated with a geodetic datum.
066     *
067     * @departure constraint
068     *   ISO 19111 defines the union named <code>secondDefiningParameter</code> as being either
069     *   <code>semiMinorAxis</code> or <code>inverseFlattening</code>. The <code>union</code>
070     *   construct (defined in some languages like C/C++) does not exist in Java. GeoAPI changed the
071     *   interface to require both ellipsoidal parameters (in addition to the <code>semiMajorAxis</code>
072     *   parameter which is mandatory in any case), as was done in OGC 01-009. However, implementors
073     *   could readily permit users to only provide one of the two parameters by creating a class which
074     *   calculates the second parameter from the first. For precision, GeoAPI imports the
075     *   <code>isIvfDefinitive</code> attribute from OGC 01-009 to enable the user to establish which of
076     *   the two parameters was used to define the instance.
077     *
078     * @author  Martin Desruisseaux (IRD)
079     * @version 3.0
080     * @since   1.0
081     *
082     * @navassoc 1 - - Unit
083     *
084     * @see DatumAuthorityFactory#createEllipsoid(String)
085     * @see DatumFactory#createEllipsoid(Map, double, double, Unit)
086     * @see DatumFactory#createFlattenedSphere(Map, double, double, Unit)
087     */
088    @UML(identifier="CD_Ellipsoid", specification=ISO_19111)
089    public interface Ellipsoid extends IdentifiedObject {
090        /**
091         * Returns the linear unit of the {@linkplain #getSemiMajorAxis() semi-major}
092         * and {@linkplain #getSemiMinorAxis() semi-minor} axis values.
093         *
094         * @return The axis linear unit.
095         */
096        @UML(identifier="getAxisUnit", specification=OGC_01009)
097        Unit<Length> getAxisUnit();
098    
099        /**
100         * Length of the semi-major axis of the ellipsoid. This is the
101         * equatorial radius in {@linkplain #getAxisUnit() axis linear unit}.
102         *
103         * @return Length of semi-major axis.
104         * @unitof Length
105         */
106        @UML(identifier="semiMajorAxis", obligation=MANDATORY, specification=ISO_19111)
107        double getSemiMajorAxis();
108    
109        /**
110         * Length of the semi-minor axis of the ellipsoid. This is the
111         * polar radius in {@linkplain #getAxisUnit() axis linear unit}.
112         *
113         * @return Length of semi-minor axis.
114         * @unitof Length
115         */
116        @UML(identifier="secondDefiningParameter.semiMinorAxis", obligation=CONDITIONAL, specification=ISO_19111)
117        double getSemiMinorAxis();
118    
119        /**
120         * Returns the value of the inverse of the flattening constant. The inverse
121         * flattening is related to the equatorial/polar radius by the formula
122         *
123         * <var>ivf</var>&nbsp;=&nbsp;<var>r</var><sub>e</sub>/(<var>r</var><sub>e</sub>-<var>r</var><sub>p</sub>).
124         *
125         * For perfect spheres (i.e. if {@link #isSphere()} returns {@code true}),
126         * the {@link Double#POSITIVE_INFINITY POSITIVE_INFINITY} value is used.
127         *
128         * @return The inverse flattening value.
129         * @unitof Scale
130         */
131        @UML(identifier="secondDefiningParameter.inverseFlattening", obligation=CONDITIONAL, specification=ISO_19111)
132        double getInverseFlattening();
133    
134        /**
135         * Indicates if the {@linkplain #getInverseFlattening() inverse flattening} is definitive for
136         * this ellipsoid. Some ellipsoids use the IVF as the defining value, and calculate the polar
137         * radius whenever asked. Other ellipsoids use the polar radius to calculate the IVF whenever
138         * asked. This distinction can be important to avoid floating-point rounding errors.
139         *
140         * @return {@code true} if the {@linkplain #getInverseFlattening() inverse flattening} is
141         *         definitive, or {@code false} if the {@linkplain #getSemiMinorAxis() polar radius}
142         *         is definitive.
143         */
144        @UML(identifier="CS_Ellipsoid.isIvfDefinitive", obligation=CONDITIONAL, specification=OGC_01009)
145        boolean isIvfDefinitive();
146    
147        /**
148         * {@code true} if the ellipsoid is degenerate and is actually a sphere. The sphere is
149         * completely defined by the {@linkplain #getSemiMajorAxis() semi-major axis}, which is
150         * the radius of the sphere.
151         *
152         * @return {@code true} if the ellipsoid is degenerate and is actually a sphere.
153         */
154        @UML(identifier="secondDefiningParameter.isSphere", obligation=CONDITIONAL, specification=ISO_19111)
155        boolean isSphere();
156    }