Class GeodeticCalculator

java.lang.Object
org.apache.sis.referencing.GeodeticCalculator
Direct Known Subclasses:
GeodesicsOnEllipsoid

public class GeodeticCalculator extends Object
Performs geodetic calculations on a sphere or an ellipsoid. This class computes the distance between two points, or conversely the point located at a given distance from another point when navigating in a given direction. The distance depends on the path (or track) on Earth surface connecting the two points. The track can be great circles (shortest path between two points) or rhumb lines (path with constant heading).

This class uses the following information:

  • The start point, which is always considered valid after the first call to setStartPoint(…). Its value can only be changed by another call to setStartPoint(…).
  • One of the followings (the latest specified properties override other properties and determines what will be calculated):

Algorithms

GeodeticCalculator uses two set of formulas, depending if the figure of the Earth is a sphere or an ellipsoid. Publications relevant to this class are:

Accuracy

GeodeticCalculator aims for a positional accuracy of one centimetre. The accuracy is often better (about one millimetre), but not everywhere. Azimuthal accuracy corresponds to an error of one centimetre at a distance of one kilometer, except for nearly antipodal points (less than 1° of longitude and latitude from antipode) and points close to the poles where the azimuthal errors are larger. Karney's GeographicLib should be used if better accuracy is desired. Apache SIS accuracy does not go as far as GeographicLib because the rest of Apache SIS library (map projections, etc.) aims for an one centimetre accuracy anyway.

Limitations

Current implementation cannot compute the geodesics in some cases. In particular, calculation may fail for antipodal points on an ellipsoid. Karney's algorithm should cover those cases, but this GeodeticCalculator implementation may not be sufficiently tuned. See SIS-467 for more information.

Thread safety

This class is not thread-safe. If geodetic calculations are needed in a multi-threads environment, then a distinct instance of GeodeticCalculator needs to be created for each thread.
Since:
1.0
Version:
1.1
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    private final class 
    Builds a circular region around the start point.
    private class 
    Builds a geodesic path as a sequence of Bézier curves.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    (package private) static final int
    Bitmask specifying which information are valid.
    (package private) final org.opengis.referencing.datum.Ellipsoid
    The ellipsoid on which geodetic computations are performed.
    (package private) static final int
    Bitmask specifying which information are valid.
    (package private) static final int
    Bitmask specifying which information are valid.
    (package private) static final int
    Bitmask specifying which information are valid.
    (package private) double
    The shortest distance from the starting point (φ1,λ1) to the end point (φ2,λ2).
    (package private) static final double
    Maximal difference (in radians) between two latitudes for enabling the use of simplified formulas.
    (package private) double
    The azimuth at start point (α₁) and at end point (α₂) as vector components.
    (package private) double
    The azimuth at start point (α₁) and at end point (α₂) as vector components.
    (package private) double
    The azimuth at start point (α₁) and at end point (α₂) as vector components.
    (package private) double
    The azimuth at start point (α₁) and at end point (α₂) as vector components.
    The factory for map projections created by createProjectionAroundStart(), fetched when first needed.
    private Parameters
    Parameters of the projection created by createProjectionAroundStart(), saved for reuse when new projection is requested.
    The provider of "Azimuthal Equidistant (Spherical)" or "Modified Azimuthal Equidistant" projection.
    (package private) static final int
    Bitmask specifying which information are valid.
    (package private) double
    Constant bearing on the rhumb line path, in radians.
    (package private) double
    Length of the rhumb line from the starting point (φ1,λ1) to the end point (φ2,λ2).
    (package private) final double
    Length of the semi-major axis.
    (package private) static final int
    Bitmask specifying which information are valid.
    (package private) static final int
    Bitmask specifying which information are valid.
    private org.opengis.referencing.operation.MathTransform
    Conversion from position CRS to projection base CRS.
    private final PositionTransformer
    The transform from user coordinates to geodetic coordinates used in computation.
    private int
    A bitmask specifying which information are valid.
    (package private) double
    The (latitude, longitude) coordinates of the start point in radians.
    (package private) double
    The (latitude, longitude) coordinates of the end point in radians.
    (package private) double
    The (latitude, longitude) coordinates of the start point in radians.
    (package private) double
    The (latitude, longitude) coordinates of the end point in radians.
  • Constructor Summary

    Constructors
    Constructor
    Description
    GeodeticCalculator(org.opengis.referencing.crs.CoordinateReferenceSystem crs, org.opengis.referencing.datum.Ellipsoid ellipsoid)
    Constructs a new geodetic calculator expecting coordinates in the supplied CRS.
  • Method Summary

    Modifier and Type
    Method
    Description
    (package private) final void
    Ensures that the start point and end point are set.
    (package private) final void
    Ensures that the start point, starting azimuth and geodesic distance are set.
    (package private) void
    Computes the geodesic distance and azimuths from the start point and end point.
    (package private) void
    Computes the end point from the start point, the azimuth and the geodesic distance.
    (package private) void
    Computes the length of rhumb line from start point to end point.
    create(org.opengis.referencing.crs.CoordinateReferenceSystem crs)
    Constructs a new geodetic calculator expecting coordinates in the supplied CRS.
    createGeodesicCircle2D(double tolerance)
    Creates an approximation of the curve at a constant geodesic distance around the start point.
    createGeodesicPath2D(double tolerance)
    Creates an approximation of the geodesic track from start point to end point as a Java2D object.
    org.opengis.referencing.operation.MathTransform
    Creates an Azimuthal Equidistant projection centered on current starting point.
    (package private) double
    dφ_dy(double φ)
    Computes (∂y/∂φ)⁻¹ where (∂y/∂φ) is the partial derivative of Northing values in a Mercator projection at the given latitude on an ellipsoid with semi-major axis length of 1.
    geographic(double φ, double λ)
    Sets userToGeodetic to the given coordinates.
    double
    Computes the angular heading of a rhumb line path.
    javax.measure.Unit<javax.measure.quantity.Length>
    Returns the unit of measurement of all distance measurements.
    double
    Computes the angular heading at the ending point of a geodesic path.
    org.opengis.geometry.DirectPosition
    Returns or computes the destination in the CRS specified at construction time.
    double
    Returns or computes the shortest distance from start point to end point.
    org.opengis.referencing.crs.GeographicCRS
    Returns the coordinate reference system for all methods expecting (φ,λ) as double values.
    org.opengis.referencing.crs.CoordinateReferenceSystem
    Returns the Coordinate Reference System (CRS) in which Positions are represented, unless otherwise specified.
    (package private) String
    The operation method to use for creating a map projection.
    double
    Returns or computes the length of rhumb line (part of constant heading) from start point to end point.
    double
    Returns or computes the angular heading at the starting point of a geodesic path.
    org.opengis.geometry.DirectPosition
    Returns the starting point in the CRS specified at construction time.
    (package private) final boolean
    isInvalid(int mask)
    Returns true if at least one of the properties identified by the given mask is invalid.
    void
    Sets the start point and starting azimuth to the current end point and ending azimuth values.
    void
    setEndGeographicPoint(double latitude, double longitude)
    Sets the destination as geographic (latitude, longitude) coordinates.
    void
    setEndPoint(org.opengis.geometry.coordinate.Position position)
    Sets the destination as coordinates in arbitrary reference system.
    void
    setGeodesicDistance(double distance)
    Sets the geodesic distance from the start point to the end point.
    void
    setStartGeographicPoint(double latitude, double longitude)
    Sets the starting point as geographic (latitude, longitude) coordinates.
    void
    setStartingAzimuth(double azimuth)
    Sets the angular heading at the starting point of a geodesic path.
    void
    setStartPoint(org.opengis.geometry.coordinate.Position point)
    Sets the starting point as coordinates in arbitrary reference system.
    (package private) final void
    setValid(int mask)
    Sets the properties specified by the given bitmask as valid.
    Returns a string representation of start point, end point, azimuths and distance.
    private String
    transformError(boolean toCRS)
    Returns the error message to give to GeodeticException when a TransformException occurred.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

    • LATITUDE_THRESHOLD

      static final double LATITUDE_THRESHOLD
      Maximal difference (in radians) between two latitudes for enabling the use of simplified formulas. This is used in two contexts:
      • Maximal difference between latitude φ₁ and equator for using the equatorial approximation.
      • Maximal difference between |β₁| and |β₂| for enabling the use of Karney's equation 47.
      Those special cases are needed when general formulas produce indeterminations like 0/0. Current angular value corresponds to a distance of 1 millimetre on a planet of the size of Earth, which is about 1.57E-10 radians. This value is chosen empirically by trying to minimize the amount of "No convergence errors" reported by GeodesicsOnEllipsoidTest in the compareAgainstDataset() method.

      Note: this is an angular tolerance threshold, but is also used with sine and cosine values because sin(θ) ≈ θ for small angles.

      See Also:
    • userToGeodetic

      private final PositionTransformer userToGeodetic
      The transform from user coordinates to geodetic coordinates used in computation. This object also holds the following information:
    • ellipsoid

      final org.opengis.referencing.datum.Ellipsoid ellipsoid
      The ellipsoid on which geodetic computations are performed. This ellipsoid is inferred from the coordinate reference system specified at construction time.
    • semiMajorAxis

      final double semiMajorAxis
      Length of the semi-major axis. For a sphere, this is the radius of the sphere.
    • φ1

      double φ1
      The (latitude, longitude) coordinates of the start point in radians. This point is set by setStartGeographicPoint(double, double).
      See Also:
    • λ1

      double λ1
      The (latitude, longitude) coordinates of the start point in radians. This point is set by setStartGeographicPoint(double, double).
      See Also:
    • φ2

      double φ2
      The (latitude, longitude) coordinates of the end point in radians. This point is set by setEndGeographicPoint(double, double).
      See Also:
    • λ2

      double λ2
      The (latitude, longitude) coordinates of the end point in radians. This point is set by setEndGeographicPoint(double, double).
      See Also:
    • msinα1

      double msinα1
      The azimuth at start point (α₁) and at end point (α₂) as vector components. Angles can be obtained as below, with α a geographic (not arithmetic) angle:
      • Geographic angle: atan2(msinα, mcosα) gives the azimuth in radians between -π and +π with 0° pointing toward North and values increasing clockwise.
      • Arithmetic angle: atan2(mcosα, msinα) (radians increasing anticlockwise). Obtained using the tan(π/2 − α) = 1/tan(α) identity.
      Sine and cosine of azimuth can are related to vector components as below:
      • m⋅sin(α) is proportional to a displacement in the λ direction.
      • m⋅cos(α) is proportional to a displacement in the φ direction. The unit of measurement is the unit of any conformal projection. For representing a displacement in degrees, divide by ∂y/∂φ.
      Those vectors may not be normalized to unitary vectors. For example, msinα is sinα multiplied by an unknown constant m. It is often not needed to know m value because most formulas are written in a way that cancel the magnitude. If nevertheless needed, normalization is applied by dividing those fields by m = hypot(msinα, mcosα).
      See Also:
    • mcosα1

      double mcosα1
      The azimuth at start point (α₁) and at end point (α₂) as vector components. Angles can be obtained as below, with α a geographic (not arithmetic) angle:
      • Geographic angle: atan2(msinα, mcosα) gives the azimuth in radians between -π and +π with 0° pointing toward North and values increasing clockwise.
      • Arithmetic angle: atan2(mcosα, msinα) (radians increasing anticlockwise). Obtained using the tan(π/2 − α) = 1/tan(α) identity.
      Sine and cosine of azimuth can are related to vector components as below:
      • m⋅sin(α) is proportional to a displacement in the λ direction.
      • m⋅cos(α) is proportional to a displacement in the φ direction. The unit of measurement is the unit of any conformal projection. For representing a displacement in degrees, divide by ∂y/∂φ.
      Those vectors may not be normalized to unitary vectors. For example, msinα is sinα multiplied by an unknown constant m. It is often not needed to know m value because most formulas are written in a way that cancel the magnitude. If nevertheless needed, normalization is applied by dividing those fields by m = hypot(msinα, mcosα).
      See Also:
    • msinα2

      double msinα2
      The azimuth at start point (α₁) and at end point (α₂) as vector components. Angles can be obtained as below, with α a geographic (not arithmetic) angle:
      • Geographic angle: atan2(msinα, mcosα) gives the azimuth in radians between -π and +π with 0° pointing toward North and values increasing clockwise.
      • Arithmetic angle: atan2(mcosα, msinα) (radians increasing anticlockwise). Obtained using the tan(π/2 − α) = 1/tan(α) identity.
      Sine and cosine of azimuth can are related to vector components as below:
      • m⋅sin(α) is proportional to a displacement in the λ direction.
      • m⋅cos(α) is proportional to a displacement in the φ direction. The unit of measurement is the unit of any conformal projection. For representing a displacement in degrees, divide by ∂y/∂φ.
      Those vectors may not be normalized to unitary vectors. For example, msinα is sinα multiplied by an unknown constant m. It is often not needed to know m value because most formulas are written in a way that cancel the magnitude. If nevertheless needed, normalization is applied by dividing those fields by m = hypot(msinα, mcosα).
      See Also:
    • mcosα2

      double mcosα2
      The azimuth at start point (α₁) and at end point (α₂) as vector components. Angles can be obtained as below, with α a geographic (not arithmetic) angle:
      • Geographic angle: atan2(msinα, mcosα) gives the azimuth in radians between -π and +π with 0° pointing toward North and values increasing clockwise.
      • Arithmetic angle: atan2(mcosα, msinα) (radians increasing anticlockwise). Obtained using the tan(π/2 − α) = 1/tan(α) identity.
      Sine and cosine of azimuth can are related to vector components as below:
      • m⋅sin(α) is proportional to a displacement in the λ direction.
      • m⋅cos(α) is proportional to a displacement in the φ direction. The unit of measurement is the unit of any conformal projection. For representing a displacement in degrees, divide by ∂y/∂φ.
      Those vectors may not be normalized to unitary vectors. For example, msinα is sinα multiplied by an unknown constant m. It is often not needed to know m value because most formulas are written in a way that cancel the magnitude. If nevertheless needed, normalization is applied by dividing those fields by m = hypot(msinα, mcosα).
      See Also:
    • geodesicDistance

      double geodesicDistance
      The shortest distance from the starting point (φ1,λ1) to the end point (φ2,λ2). The distance is in the same units than ellipsoid axes and the azimuth is in radians.
      See Also:
    • rhumblineLength

      double rhumblineLength
      Length of the rhumb line from the starting point (φ1,λ1) to the end point (φ2,λ2). The distance is in the same units than ellipsoid axes.
      See Also:
    • rhumblineAzimuth

      double rhumblineAzimuth
      Constant bearing on the rhumb line path, in radians.
      See Also:
    • validity

      private int validity
      A bitmask specifying which information are valid. For example if the END_POINT bit is not set, then φ2 and λ2 need to be computed, which implies the computation of ∂φ/∂λ as well. If the GEODESIC_DISTANCE bit is not set, then geodesicDistance needs to be computed, which implies recomputation of ∂φ/∂λ as well.
      See Also:
    • START_POINT

      static final int START_POINT
      Bitmask specifying which information are valid.
      See Also:
    • END_POINT

      static final int END_POINT
      Bitmask specifying which information are valid.
      See Also:
    • STARTING_AZIMUTH

      static final int STARTING_AZIMUTH
      Bitmask specifying which information are valid.
      See Also:
    • ENDING_AZIMUTH

      static final int ENDING_AZIMUTH
      Bitmask specifying which information are valid.
      See Also:
    • GEODESIC_DISTANCE

      static final int GEODESIC_DISTANCE
      Bitmask specifying which information are valid.
      See Also:
    • RHUMBLINE_LENGTH

      static final int RHUMBLINE_LENGTH
      Bitmask specifying which information are valid.
      See Also:
    • COEFFICIENTS_FOR_START_POINT

      static final int COEFFICIENTS_FOR_START_POINT
      Bitmask specifying which information are valid.
      See Also:
    • projectionFactory

      private DefaultMathTransformFactory projectionFactory
      The factory for map projections created by createProjectionAroundStart(), fetched when first needed. Caching is disabled on this factory because profiling shows that DefaultMathTransformFactory.unique(MathTransform) consumes a lot of time when projections are created frequently. Since each projection is specific to current start point, they are unlikely to be shared anyway.
      See Also:
    • projectionProvider

      private MapProjection projectionProvider
      The provider of "Azimuthal Equidistant (Spherical)" or "Modified Azimuthal Equidistant" projection. Usually it is not necessary to keep a reference to the provider because projectionFactory finds them automatically. However, by keeping a reference to it, we save the search phase.
      See Also:
    • projectionParameters

      private Parameters projectionParameters
      Parameters of the projection created by createProjectionAroundStart(), saved for reuse when new projection is requested. Only the "Latitude of natural origin" and "Longitude of natural origin" parameter values will change for different projections.
      See Also:
    • toProjectionBase

      private org.opengis.referencing.operation.MathTransform toProjectionBase
      Conversion from position CRS to projection base CRS. Computed when first needed. This transform does not change after creation.
  • Constructor Details

    • GeodeticCalculator

      GeodeticCalculator(org.opengis.referencing.crs.CoordinateReferenceSystem crs, org.opengis.referencing.datum.Ellipsoid ellipsoid)
      Constructs a new geodetic calculator expecting coordinates in the supplied CRS. The geodetic formulas implemented by this GeodeticCalculator base class assume a spherical model. This constructor is for subclasses computing geodesy on an ellipsoid or other figure of the Earth. Users should invoke create(CoordinateReferenceSystem) instead, which will choose a subtype based on the given coordinate reference system.

      This class is currently not designed for sub-classing outside this package. If in a future version we want to relax this restriction, we should revisit the package-private API in order to commit to a safer protected API.

      Parameters:
      crs - the reference system for the Position arguments and return values.
      ellipsoid - ellipsoid associated to the geodetic component of given CRS.
  • Method Details

    • create

      public static GeodeticCalculator create(org.opengis.referencing.crs.CoordinateReferenceSystem crs)
      Constructs a new geodetic calculator expecting coordinates in the supplied CRS. All GeodeticCalculator methods having a Position argument or return value will use that specified CRS. That CRS is the value returned by getPositionCRS().

      Limitations

      Current implementation uses only spherical formulas. Implementation using ellipsoidal formulas will be provided in a future Apache SIS release.
      Parameters:
      crs - the reference system for the Position objects.
      Returns:
      a new geodetic calculator using the specified CRS.
    • isInvalid

      final boolean isInvalid(int mask)
      Returns true if at least one of the properties identified by the given mask is invalid.
    • setValid

      final void setValid(int mask)
      Sets the properties specified by the given bitmask as valid.
    • getPositionCRS

      public org.opengis.referencing.crs.CoordinateReferenceSystem getPositionCRS()
      Returns the Coordinate Reference System (CRS) in which Positions are represented, unless otherwise specified. This is the CRS of all Position instances returned by methods in this class. This is also the default CRS assumed by methods receiving a Position argument when the given position does not specify its CRS. This default CRS is specified at construction time. It is not necessarily geographic; it may be projected or geocentric.
      Returns:
      the default CRS for Position instances.
    • getGeographicCRS

      public org.opengis.referencing.crs.GeographicCRS getGeographicCRS()
      Returns the coordinate reference system for all methods expecting (φ,λ) as double values. This CRS always has (latitude, longitude) axes, in that order and in degrees. The CRS may contain an additional axis for ellipsoidal height.
      Returns:
      the coordinate reference system of (φ,λ) coordinates.
    • geographic

      private PositionTransformer geographic(double φ, double λ)
      Sets userToGeodetic to the given coordinates. All coordinates in dimension 2 and above (typically the ellipsoidal height) are set to zero.
      Parameters:
      φ - the latitude value to set, in radians.
      λ - the longitude value to set, in radians.
      Returns:
      userToGeodetic for convenience.
    • transformError

      private String transformError(boolean toCRS)
      Returns the error message to give to GeodeticException when a TransformException occurred.
      Parameters:
      toCRS - false if converting from the position CRS, true if converting to the position CRS.
    • getStartPoint

      public org.opengis.geometry.DirectPosition getStartPoint()
      Returns the starting point in the CRS specified at construction time. This method returns the last point given to a setStartPoint(…) method, transformed to the position CRS.
      Returns:
      the starting point represented in the CRS specified at construction time.
      Throws:
      IllegalStateException - if the start point has not yet been specified.
      GeodeticException - if the coordinates cannot be transformed to position CRS.
      See Also:
    • setStartPoint

      public void setStartPoint(org.opengis.geometry.coordinate.Position point)
      Sets the starting point as coordinates in arbitrary reference system. This method transforms the given coordinates to geographic coordinates, then delegates to setStartGeographicPoint(double, double). If the given point is not associated to a Coordinate Reference System (CRS), then this method assumes the CRS specified at construction time.
      Parameters:
      point - the starting point in any coordinate reference system.
      Throws:
      IllegalArgumentException - if the given coordinates cannot be transformed.
      See Also:
    • setStartGeographicPoint

      public void setStartGeographicPoint(double latitude, double longitude)
      Sets the starting point as geographic (latitude, longitude) coordinates. The starting and ending azimuths, the end point, the geodesic distance and the rhumb line length are discarded by this method call; some of them will need to be specified again.
      Parameters:
      latitude - the latitude in degrees between -90.0° and 90.0°.
      longitude - the longitude in degrees.
      See Also:
    • getEndPoint

      public org.opengis.geometry.DirectPosition getEndPoint()
      Returns or computes the destination in the CRS specified at construction time. This method returns the point specified in the last call to a setEndPoint(…) method, unless the starting azimuth and geodesic distance have been set more recently. In the latter case, the end point will be computed from the start point and the current azimuth and distance.
      Returns:
      the destination (end point) represented in the CRS specified at construction time.
      Throws:
      IllegalStateException - if the destination point, azimuth or distance have not been set.
      GeodeticException - if the coordinates cannot be computed.
      See Also:
    • setEndPoint

      public void setEndPoint(org.opengis.geometry.coordinate.Position position)
      Sets the destination as coordinates in arbitrary reference system. This method transforms the given coordinates to geographic coordinates, then delegates to setEndGeographicPoint(double, double). If the given point is not associated to a Coordinate Reference System (CRS), then this method assumes the CRS specified at construction time.
      Parameters:
      position - the destination (end point) in any coordinate reference system.
      Throws:
      IllegalArgumentException - if the given coordinates cannot be transformed.
      See Also:
    • setEndGeographicPoint

      public void setEndGeographicPoint(double latitude, double longitude)
      Sets the destination as geographic (latitude, longitude) coordinates. The starting azimuth, ending azimuth geodesic distance and rhumb line length will be updated as an effect of this call.
      Parameters:
      latitude - the latitude in degrees between -90.0° and 90.0°.
      longitude - the longitude in degrees.
      See Also:
    • getStartingAzimuth

      public double getStartingAzimuth()
      Returns or computes the angular heading at the starting point of a geodesic path. Azimuth is relative to geographic North with values increasing clockwise. This method returns the azimuth normalized to [-180 … +180]° range given in last call to setStartingAzimuth(double) method, unless the setEndPoint(…) method has been invoked more recently. In the latter case, the azimuth will be computed from the start point and the current end point.
      Returns:
      the azimuth in degrees from -180° to +180°. 0° is toward North and values are increasing clockwise.
      Throws:
      IllegalStateException - if the end point, azimuth or distance have not been set.
      GeodeticException - if the azimuth cannot be computed.
    • setStartingAzimuth

      public void setStartingAzimuth(double azimuth)
      Sets the angular heading at the starting point of a geodesic path. Azimuth is relative to geographic North with values increasing clockwise. The ending azimuth, end point and rhumb line length will be updated as an effect of this method call.
      Parameters:
      azimuth - the starting azimuth in degrees, with 0° toward north and values increasing clockwise.
      See Also:
    • getEndingAzimuth

      public double getEndingAzimuth()
      Computes the angular heading at the ending point of a geodesic path. Azimuth is relative to geographic North with values increasing clockwise. This method computes the azimuth from the current start point and end point, or from start point and the current starting azimuth and geodesic distance.
      Returns:
      the azimuth in degrees from -180° to +180°. 0° is toward North and values are increasing clockwise.
      Throws:
      IllegalStateException - if the destination point, azimuth or distance have not been set.
      GeodeticException - if the azimuth cannot be computed.
    • getConstantAzimuth

      public double getConstantAzimuth()
      Computes the angular heading of a rhumb line path. Azimuth is relative to geographic North with values increasing clockwise.
      Returns:
      the azimuth in degrees from -180° to +180°. 0° is toward North and values are increasing clockwise.
      Throws:
      IllegalStateException - if the start point or end point has not been set.
      GeodeticException - if the azimuth cannot be computed.
    • getGeodesicDistance

      public double getGeodesicDistance()
      Returns or computes the shortest distance from start point to end point. This is sometimes called "great circle" or "orthodromic" distance. This method returns the value given in last call to setGeodesicDistance(double), unless the setEndPoint(…) method has been invoked more recently. In the latter case, the distance will be computed from the start point and current end point.
      Returns:
      the shortest distance in the unit of measurement given by getDistanceUnit().
      Throws:
      IllegalStateException - if the start point or end point has not been set.
      GeodeticException - if the distance cannot be computed.
      See Also:
    • setGeodesicDistance

      public void setGeodesicDistance(double distance)
      Sets the geodesic distance from the start point to the end point. The end point, ending azimuth and rhumb line length will be updated as an effect of this method call.
      Parameters:
      distance - the geodesic distance in unit of measurement given by getDistanceUnit().
      See Also:
    • getRhumblineLength

      public double getRhumblineLength()
      Returns or computes the length of rhumb line (part of constant heading) from start point to end point. This is sometimes called "loxodrome". This is not the shortest path between two points. The rhumb line distance may be up to 50% longer than the geodesic distance.
      Returns:
      length of rhumb line in the unit of measurement given by getDistanceUnit().
      Throws:
      IllegalStateException - if a point has not been set.
    • getDistanceUnit

      public javax.measure.Unit<javax.measure.quantity.Length> getDistanceUnit()
      Returns the unit of measurement of all distance measurements. This is the ellipsoid axis unit.
      Returns:
      the unit of measurement of all distance measurements.
      See Also:
    • dφ_dy

      double dφ_dy(double φ)
      Computes (∂y/∂φ)⁻¹ where (∂y/∂φ) is the partial derivative of Northing values in a Mercator projection at the given latitude on an ellipsoid with semi-major axis length of 1. There is no method for partial derivative of Easting values since it is 1 everywhere. This derivative is cos(φ) on a sphere and close but slightly different on an ellipsoid.
      Parameters:
      φ - the latitude in radians.
      Returns:
      the northing derivative of a Mercator projection at the given latitude on an ellipsoid with a=1.
      See Also:
    • canComputeDistance

      final void canComputeDistance()
      Ensures that the start point and end point are set. This method should be invoked at the beginning of computeDistance().
      Throws:
      IllegalStateException - if the start point or end point has not been set.
    • computeRhumbLine

      void computeRhumbLine()
      Computes the length of rhumb line from start point to end point.
      See Also:
    • computeDistance

      void computeDistance()
      Computes the geodesic distance and azimuths from the start point and end point. This method should be invoked if the distance or an azimuth is requested while STARTING_AZIMUTH, ENDING_AZIMUTH or GEODESIC_DISTANCE validity flag is not set.

      Note on terminology:

      • Course: the intended path of travel.
      • Track: the actual path traveled over ground.
      Throws:
      IllegalStateException - if the distance or azimuth has not been set.
      GeodeticException - if an azimuth or the distance cannot be computed.
    • canComputeEndPoint

      final void canComputeEndPoint()
      Ensures that the start point, starting azimuth and geodesic distance are set. This method should be invoked at the beginning of computeEndPoint().
      Throws:
      IllegalStateException - if the start point, azimuth or distance has not been set.
    • computeEndPoint

      void computeEndPoint()
      Computes the end point from the start point, the azimuth and the geodesic distance. This method should be invoked if the end point or ending azimuth is requested while END_POINT validity flag is not set.

      The default implementation computes φ2, λ2 and ∂φ/∂λ derivatives using spherical formulas. Subclasses should override if they can provide ellipsoidal formulas.

      Throws:
      IllegalStateException - if the start point, azimuth or distance has not been set.
      GeodeticException - if the end point or ending azimuth cannot be computed.
    • moveToEndPoint

      public void moveToEndPoint()
      Sets the start point and starting azimuth to the current end point and ending azimuth values. The ending azimuths, the geodesic distance and the end point are discarded by this method call; some of them will need to be specified again.
      Throws:
      GeodeticException - if the end point or ending azimuth cannot be computed.
      See Also:
    • createGeodesicPath2D

      public Shape createGeodesicPath2D(double tolerance)
      Creates an approximation of the geodesic track from start point to end point as a Java2D object. The coordinates are expressed in the coordinate reference system specified at creation time. The approximation uses linear, quadratic or cubic Bézier curves. The returned path has the following characteristics:
      1. The first point is getStartPoint().
      2. The beginning of the curve (more specifically, the tangent at starting point) is oriented toward the direction given by getStartingAzimuth(), adjusted for the map projection (if any) deformation at that location.
      3. The point B(½) in the middle of the Bézier curve is a point of the geodesic path.
      4. The end of the curve (more specifically, the tangent at ending point) is oriented toward the direction given by getEndingAzimuth(), adjusted for the map projection (if any) deformation at that location.
      5. The last point is getEndPoint(), potentially with 360° added or subtracted to the longitude.
      This method tries to stay within the given tolerance threshold of the geodesic track. The tolerance parameter should not be too small for avoiding creation of unreasonably long chain of Bézier curves. For example, a value of 1/10 of geodesic length may be sufficient.
      Note: this method depends on the presence of java.desktop module. This constraint may be addressed in a future Apache SIS version (see SIS-453). The "2D" suffix in the method name represents this relationship with Java2D. The createGeodesicPath(…) method name (without suffix) is reserved for a future version using ISO curves instead.
      Parameters:
      tolerance - maximal error between the approximated curve and actual geodesic track in the units of measurement given by getDistanceUnit(). This is approximate; the actual errors may vary around that value.
      Returns:
      an approximation of geodesic track as Bézier curves in a Java2D object.
      Throws:
      IllegalStateException - if some required properties have not been specified.
      GeodeticException - if some coordinates cannot be computed.
    • createGeodesicCircle2D

      public Shape createGeodesicCircle2D(double tolerance)
      Creates an approximation of the curve at a constant geodesic distance around the start point. The returned shape is circlelike with the start point in its center. The coordinates are expressed in the coordinate reference system specified at creation time. The approximation uses cubic Bézier curves.
      Note: some authors define geodesic circle as the curve which enclose the maximum area for a given perimeter. This method adopts a different definition, the locus of points at a fixed geodesic distance from center point.
      This method tries to stay within the given tolerance threshold of the geodesic track. The tolerance parameter should not be too small for avoiding creation of unreasonably long chain of Bézier curves. For example, a value of 1/10 of geodesic length may be sufficient.
      Note: this method depends on the presence of java.desktop module. This constraint may be addressed in a future Apache SIS version (see SIS-453). The "2D" suffix in the method name represents this relationship with Java2D. The createGeodesicCircle(…) method name (without suffix) is reserved for a future version using ISO curves instead.
      Parameters:
      tolerance - maximal error in the units of measurement given by getDistanceUnit(). This is approximate; the actual errors may vary around that value.
      Returns:
      an approximation of circular region as a Java2D object.
      Throws:
      IllegalStateException - if some required properties have not been specified.
      GeodeticException - if some coordinates cannot be computed.
    • getProjectionMethod

      String getProjectionMethod()
      The operation method to use for creating a map projection. In the spherical case this is "Azimuthal Equidistant (Spherical)". In the ellipsoidal case it become "Modified Azimuthal Equidistant".
    • createProjectionAroundStart

      public org.opengis.referencing.operation.MathTransform createProjectionAroundStart()
      Creates an Azimuthal Equidistant projection centered on current starting point. On input, the MathTransform expects coordinates expressed in the position CRS. On output, the MathTransform produces coordinates in a ProjectedCRS having the following characteristics:
      • Coordinate system is a two-dimensional CartesianCS with (Easting, Northing) axis order and directions.
      • Unit of measurement is the same as position CRS if those units are linear, or Units.METRE otherwise.
      • Projection of the start point results in (0,0).
      • Distances relative to (0,0) are approximately exact for distances less than 800 km.
      • Azimuths from (0,0) to other points are approximately exact for points located at less than 800 km.
      Given above characteristics, the following calculations are satisfying approximations when using (x, y) coordinates in the output space for D < 800 km:
      D = √(x² + y²) — distance from projection center.
      θ = atan2(y, x) — arithmetic angle from projection center to (x, y).
      x = D⋅cos θ
      y = D⋅sin θ — end point for a distance and angle from start point.
      The following calculations are not exacts, because distances and azimuths are approximately exacts only when measured from (0,0) coordinates:
      D = √[(x₂x₁)² + (y₂y₁)²] — distances between points other then projection center are not valid.
      θ = atan2(y₂y₁, x₂x₁) — azimuths between points other then projection center are not valid.
      etc.
      This method can be invoked repetitively for doing calculations around different points. All returned MathTransform instances are immutable; changing GeodeticCalculator state does not affect those transforms.
      Returns:
      transform from position CRS to Azimuthal Equidistant projected CRS centered on current start point.
      Throws:
      IllegalStateException - if the start point has not been set.
      GeodeticException - if the projection cannot be computed.
      Since:
      1.1
      See Also:
    • toString

      public String toString()
      Returns a string representation of start point, end point, azimuths and distance. The text representation is implementation-specific and may change in any future version. Current implementation is like below:
      Overrides:
      toString in class Object
      Returns:
      a string representation of this calculator state.