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> = <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 }