Class MapProjection

All Implemented Interfaces:
Serializable, MathTransform, MathTransform2D
Direct Known Subclasses:
AlbersEqualArea, AzimuthalEquidistant.Abstract, CassiniSoldner, CylindricalEqualArea, EckertIV, EqualArea, EquidistantConic, EquidistantCylindrical, GeneralOblique, GeostationarySatellite, Gnomonic, Homolosine, Krovak, LambertAzimuthalEqualArea, LambertConformal, Mercator, MeteosatSG, Mollweide, NewZealandMapGrid, ObliqueMercator, Orthographic, Polyconic.Abstract, Robinson, RotatedPole, Sinusoidal, Stereographic, TransverseMercator, WinkelTripel, WorldVanDerGrintenI

public abstract class MapProjection extends AbstractMathTransform implements MathTransform2D, Serializable
Base class for transformation services between ellipsoidal and cartographic projections. This base class provides the basic feature needed for all methods (no need to overrides methods). Subclasses must "only" implements the following methods:

NOTE:Serialization of this class is appropriate for short-term storage or RMI use, but will probably not be compatible with future version. For long term storage, WKT (Well Know Text) or XML (not yet implemented) are more appropriate.

Since:
2.0
Author:
André Gosselin, Martin Desruisseaux (PMO, IRD), Rueben Schulz
See Also:
  • Field Details

    • SKIP_SANITY_CHECKS

      public static boolean SKIP_SANITY_CHECKS
      A global variable use to disable the reciprocal distance checks made when assertions are enabled. This allows tests to work in "real world" conditions, where users often ask for points that are way to far from the correct area of usage of projections
    • LOGGER

      protected static final Logger LOGGER
      The projection package logger
    • excentricity

      protected final double excentricity
      Ellipsoid excentricity, equals to sqrt(excentricitySquared). Value 0 means that the ellipsoid is spherical.
      See Also:
    • excentricitySquared

      protected final double excentricitySquared
      The square of excentricity: e² = (a²-b²)/a² where e is the excentricity, a is the semi major axis length and b is the semi minor axis length.
      See Also:
    • isSpherical

      protected final boolean isSpherical
      true if this projection is spherical. Spherical model has identical semi major and semi minor axis length, and an excentricity zero.
      See Also:
    • semiMajor

      protected final double semiMajor
      Length of semi-major axis, in metres. This is named 'a' or 'R' (Radius in spherical cases) in Snyder.
      See Also:
    • semiMinor

      protected final double semiMinor
      Length of semi-minor axis, in metres. This is named 'b' in Snyder.
      See Also:
    • centralMeridian

      protected double centralMeridian
      Central longitude in radians. Default value is 0, the Greenwich meridian. This is called 'lambda0' in Snyder.

      Consider this field as final. It is not final only because some classes need to modify it at construction time.

    • latitudeOfOrigin

      protected double latitudeOfOrigin
      Latitude of origin in radians. Default value is 0, the equator. This is called 'phi0' in Snyder.

      Consider this field as final. It is not final only because some classes need to modify it at construction time.

    • scaleFactor

      protected double scaleFactor
      The scale factor. Default value is 1. Named 'k' in Snyder.

      Consider this field as final. It is not final only because some classes need to modify it at construction time.

    • falseEasting

      protected final double falseEasting
      False easting, in metres. Default value is 0.
    • falseNorthing

      protected final double falseNorthing
      False northing, in metres. Default value is 0.
    • globalScale

      protected double globalScale
      Global scale factor. Default value globalScale is equal to semiMajor×scaleFactor.

      Consider this field as final. It is not final only because some classes need to modify it at construction time.

    • en0

      protected double en0
      Constant needed for the mlfn method. Setup at construction time.
    • en1

      protected double en1
      Constant needed for the mlfn method. Setup at construction time.
    • en2

      protected double en2
      Constant needed for the mlfn method. Setup at construction time.
    • en3

      protected double en3
      Constant needed for the mlfn method. Setup at construction time.
    • en4

      protected double en4
      Constant needed for the mlfn method. Setup at construction time.
    • invertible

      protected boolean invertible
      Marks if the projection is invertible. The vast majority is, subclasses can override.
  • Constructor Details

    • MapProjection

      protected MapProjection(ParameterValueGroup values) throws ParameterNotFoundException
      Constructs a new map projection from the suplied parameters.
      Parameters:
      values - The parameter values in standard units. The following parameter are recognized:
      • "semi_major" (mandatory: no default)
      • "semi_minor" (mandatory: no default)
      • "central_meridian" (default to 0°)
      • "latitude_of_origin" (default to 0°)
      • "scale_factor" (default to 1 )
      • "false_easting" (default to 0 )
      • "false_northing" (default to 0 )
      Throws:
      ParameterNotFoundException - if a mandatory parameter is missing.
  • Method Details

    • getParameterDescriptors

      public abstract ParameterDescriptorGroup getParameterDescriptors()
      Returns the parameter descriptors for this map projection. This is used for a providing a default implementation of getParameterValues(), as well as arguments checking.
      Overrides:
      getParameterDescriptors in class AbstractMathTransform
      Returns:
      The parameter descriptors for this math transform, or null.
      See Also:
    • getParameterValues

      public ParameterValueGroup getParameterValues()
      Returns the parameter values for this map projection.
      Overrides:
      getParameterValues in class AbstractMathTransform
      Returns:
      A copy of the parameter values for this map projection.
      See Also:
    • getSourceDimensions

      public final int getSourceDimensions()
      Returns the dimension of input points.
      Specified by:
      getSourceDimensions in interface MathTransform
      Specified by:
      getSourceDimensions in class AbstractMathTransform
      Returns:
      The dimension of input points.
    • getTargetDimensions

      public final int getTargetDimensions()
      Returns the dimension of output points.
      Specified by:
      getTargetDimensions in interface MathTransform
      Specified by:
      getTargetDimensions in class AbstractMathTransform
      Returns:
      The dimension of output points.
    • orthodromicDistance

      protected double orthodromicDistance(Point2D source, Point2D target)
      Returns the orthodromic distance between the two specified points using a spherical approximation. This is used for assertions only.
    • checkReciprocal

      protected boolean checkReciprocal(Point2D point, Point2D target, boolean inverse) throws ProjectionException
      Check if the transform of point is close enough to target. "Close enough" means that the two points are separated by a distance shorter than getToleranceForAssertions(double, double). This method is used for assertions with J2SE 1.4.
      Parameters:
      point - Point to transform, in decimal degrees if inverse is false.
      target - Point to compare to, in metres if inverse is false.
      inverse - true for an inverse transform instead of a direct one.
      Returns:
      true if the two points are close enough.
      Throws:
      ProjectionException
    • inverseTransformNormalized

      protected abstract Point2D inverseTransformNormalized(double x, double y, Point2D ptDst) throws ProjectionException
      Transforms the specified coordinate and stores the result in ptDst. This method returns longitude as x values in the range [-PI..PI] and latitude as y values in the range [-PI/2..PI/2]. It will be checked by the caller, so this method doesn't need to performs this check.

      Input coordinates have the falseEasting and falseNorthing removed and are divided by globalScale before this method is invoked. After this method is invoked, the centralMeridian is added to the x results in ptDst. This means that projections that implement this method are performed on an ellipse (or sphere) with a semi-major axis of 1.

      In PROJ.4, the same standardization, described above, is handled by pj_inv.c. Therefore when porting projections from PROJ.4, the inverse transform equations can be used directly here with minimal change. In the equations of Snyder, falseEasting, falseNorthing and scaleFactor are usually not given. When implementing these equations here, you will not need to add the centralMeridian to the output longitude or remove the semiMajor (a or R).

      Parameters:
      x - The easting of the coordinate, linear distance on a unit sphere or ellipse.
      y - The northing of the coordinate, linear distance on a unit sphere or ellipse.
      ptDst - the specified coordinate point that stores the result of transforming ptSrc, or null. Ordinates will be in radians.
      Returns:
      the coordinate point after transforming x, y and storing the result in ptDst.
      Throws:
      ProjectionException - if the point can't be transformed.
    • transformNormalized

      protected abstract Point2D transformNormalized(double lambda, double phi, Point2D ptDst) throws ProjectionException
      Transforms the specified coordinate and stores the result in ptDst. This method is usually (but not guaranteed) to be invoked with values of x in the range [-PI..PI] and values of y in the range [-PI/2..PI/2]. Values outside those ranges are accepted (sometime with a warning logged) on the assumption that most implementations use those values only in trigonometric functions like sin and cos.

      Coordinates have the centralMeridian removed from lambda before this method is invoked. After this method is invoked, the results in ptDst are multiplied by globalScale, and the falseEasting and falseNorthing are added. This means that projections that implement this method are performed on an ellipse (or sphere) with a semi-major axis of 1.

      In PROJ.4, the same standardization, described above, is handled by pj_fwd.c. Therefore when porting projections from PROJ.4, the forward transform equations can be used directly here with minimal change. In the equations of Snyder, falseEasting, falseNorthing and scaleFactor are usually not given. When implementing these equations here, you will not need to remove the centralMeridian from lambda or apply the semiMajor (a or R).

      Parameters:
      lambda - The longitude of the coordinate, in radians.
      phi - The latitude of the coordinate, in radians.
      ptDst - the specified coordinate point that stores the result of transforming ptSrc, or null. Ordinates will be in a dimensionless unit, as a linear distance on a unit sphere or ellipse.
      Returns:
      the coordinate point after transforming (lambda, phi) and storing the result in ptDst.
      Throws:
      ProjectionException - if the point can't be transformed.
    • transform

      public final Point2D transform(Point2D ptSrc, Point2D ptDst) throws ProjectionException
      Transforms the specified ptSrc and stores the result in ptDst.

      This method standardizes the source x coordinate by removing the centralMeridian, before invoking transformNormalized(x, y, ptDst). It also multiplies by globalScale and adds the falseEasting and falseNorthing to the point returned by the transformNormalized(...) call.

      Specified by:
      transform in interface MathTransform2D
      Overrides:
      transform in class AbstractMathTransform
      Parameters:
      ptSrc - the specified coordinate point to be transformed. Ordinates must be in decimal degrees.
      ptDst - the specified coordinate point that stores the result of transforming ptSrc, or null. Ordinates will be in metres.
      Returns:
      the coordinate point after transforming ptSrc and storing the result in ptDst.
      Throws:
      ProjectionException - if the point can't be transformed.
      See Also:
    • transform

      public final void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) throws ProjectionException
      Transforms a list of coordinate point ordinal values. Ordinates must be (longitude,latitude) pairs in decimal degrees.
      Specified by:
      transform in interface MathTransform
      Parameters:
      srcPts - the array containing the source point coordinates.
      srcOff - the offset to the first point to be transformed in the source array.
      dstPts - the array into which the transformed point coordinates are returned. May be the same than srcPts.
      dstOff - the offset to the location of the first transformed point that is stored in the destination array.
      numPts - the number of point objects to be transformed.
      Throws:
      ProjectionException - if a point can't be transformed. This method tries to transform every points even if some of them can't be transformed. Non-transformable points will have value Double.NaN. If more than one point can't be transformed, then this exception may be about an arbitrary point.
    • transform

      public final void transform(float[] srcPts, int srcOff, float[] dstPts, int dstOff, int numPts) throws ProjectionException
      Transforms a list of coordinate point ordinal values. Ordinates must be (longitude,latitude) pairs in decimal degrees.
      Specified by:
      transform in interface MathTransform
      Overrides:
      transform in class AbstractMathTransform
      Parameters:
      srcPts - the array containing the source point coordinates.
      srcOff - the offset to the first point to be transformed in the source array.
      dstPts - the array into which the transformed point coordinates are returned. May be the same than srcPts.
      dstOff - the offset to the location of the first transformed point that is stored in the destination array.
      numPts - the number of point objects to be transformed.
      Throws:
      ProjectionException - if a point can't be transformed. This method tries to transform every points even if some of them can't be transformed. Non-transformable points will have value Float.NaN. If more than one point can't be transformed, then this exception may be about an arbitrary point.
    • inverse

      public final MathTransform2D inverse() throws NoninvertibleTransformException
      Returns the inverse of this map projection.
      Specified by:
      inverse in interface MathTransform
      Specified by:
      inverse in interface MathTransform2D
      Overrides:
      inverse in class AbstractMathTransform
      Returns:
      The inverse transform.
      Throws:
      NoninvertibleTransformException - if the transform can't be inversed.
    • getToleranceForAssertions

      protected double getToleranceForAssertions(double longitude, double latitude)
      Maximal error (in metres) tolerated for assertions, if enabled. When assertions are enabled, every direct projection is followed by an inverse projection, and the result is compared to the original coordinate. If a distance greater than the tolerance level is found, then an ProjectionException will be thrown. Subclasses should override this method if they need to relax the tolerance level.
      Parameters:
      longitude - The longitude in decimal degrees.
      latitude - The latitude in decimal degrees.
      Returns:
      The tolerance level for assertions, in meters.
    • resetWarnings

      public static void resetWarnings()
      Resets the warning status of all projections in the current JVM. Every MapProjection instance may log a warning the first time they are given coordinates outside their area of validity. Subsequent coordinates outside the area of validity are silently projected in order to avoid flowing the log with warnings. In case of suspicion, this method may be invoked in order to force all projections to log again their first out-of-bounds coordinates.

      Multi-threading
      Calls to this method have immediate effect in the invoker's thread. The effect in other threads may be delayed by some arbitrary amount of time. This method works only on a "best effort" basis.

      Since:
      2.5
      See Also:
    • hashCode

      public int hashCode()
      Returns a hash value for this map projection.
      Overrides:
      hashCode in class AbstractMathTransform
    • equals

      public boolean equals(Object object)
      Compares the specified object with this map projection for equality.
      Overrides:
      equals in class AbstractMathTransform
      Parameters:
      object - The object to compare with this transform.
      Returns:
      true if the given object is a transform of the same class and if, given identical source position, the transformed position would be the equals.
    • mlfn

      protected final double mlfn(double phi, double sphi, double cphi)
      Calculates the meridian distance. This is the distance along the central meridian from the equator to phi. Accurate to < 1e-5 meters when used in conjuction with typical major axis values.
      Parameters:
      phi - latitude to calculate meridian distance for.
      sphi - sin(phi).
      cphi - cos(phi).
      Returns:
      meridian distance for the given latitude.
    • inv_mlfn

      protected final double inv_mlfn(double arg) throws ProjectionException
      Calculates the latitude (phi) from a meridian distance. Determines phi to TOL (1e-11) radians, about 1e-6 seconds.
      Parameters:
      arg - meridian distance to calulate latitude for.
      Returns:
      the latitude of the meridian distance.
      Throws:
      ProjectionException - if the itteration does not converge.