Retrun to document top page

Nemo Library, section 6


Sphere to plane mapping and "un-mapping"
   There is a large number of different projections used to depict the
   spheroidal planetary surface on the flat paper map. Most of those were
   developed at the time when cartographic projections were used for two
   purposes: to provide a visual presentation of geographic objects, and,
   in addition, to enable computations using planar instead of spheroidal
   coordinates. For this, the inconvenience of limited spatial extent and
   breakdown of topological equivalence between limitless planar coordinate
   domain and finite spheroidal coordinate domain was offset by much simpler
   planar computational geometry.
   ·
   When coordinate computations are carried out by digital computer with
   a basic algebraic operation with the numerical resolution provided by
   the 64-bit floating hardware, the motivation for computing using planar
   (instead of a combination of spherical and ellipsoidal coordinates)
   quickly evaporates. This leaves the cartographic projections with only
   one purpose: data visualization.
   ·
   On the other hand, the requirement for computational efficiency of
   spheroid-to-plane coordinate transformations becomes much more important
   when the map, possibly consisting of millions of individual points, is
   created on the computer screen, than when the map is created as a
   hard-copy physical object.
   ·
   Traditional cartographic projections invariably assume that spherical or
   ellipsoidal coordinates used as a source for mapping transformations are
   given by angular φ and λ. If the spheroidal coordinates are given in
   direction cosine form instead, most or many projection calculations can
   avoid expensive trigonometry functions, thus significantly increasing the
   speed of cartographic computations.
   ·
   Taking into account the above, most systems that process geographic data
   on digital computers need only a handful of cartographic projections:
   ·
   1) Gnomonic
   Fastest in computation, with shapes on the map reasonably similar to the
   shapes in nature when the spatial extent is an order of magnitude smaller
   than the planetary radius.
   ·
   2) Stereographic
   Similar to Gnomonic, but preserving the similarity at a much greater
   spatial extent, at the cost of somewhat slower computations.
   ·
   3) Orthographic
   The projection shows a complete hemisphere inside a circle, and is
   useful when in addition to the objects on planetary surface the
   visualization includes objects above the surface, such as trajectories
   and positions of orbiting satellites.
   ·
   4) Conical
   The projection may be of use for regions with significant longitude
   extent in mid-latitudes.
   ·
   5) Stylindrical
   The projection is used to depict the whole planetary surface on a cylinder
   with the axis coincident with the "z" coordinate axis, "cut" along the
   meridian antipodal to planar coordinate origin. The shapes resemble those
   on the well-known Mercator map, but since projection centre is the point
   antipodal to the intersection of central meridian and the Equator the
   North/South dimension of the cylinder does not extend to infinity.
   ·
   Projection geometry that relates the latitude (φ) to the planar North/South
   is the same as that of the Stereographic plane, except that it occurs in
   the meridian plane of the projected point instead of the plane defined by
   the projection centre, tangency point and the point to be projected; while
   East/West planar coordinate is equal to the longitude (λ) in angular
   measure.
   ·
   Since the projection is a computational combination of Stereographic and
   "vertical" "cylindrical projections, and since it is not explicitly
   described or named in either of the two references given below, this
   document uses for it the name that is a combination of names of its two
   "component projections".


Five essential spherical cartographic projections

Description:
   In all of the above:
   ·
      S: Point on the sphere to be mapped into plane.
      P: Spherical point projected ("mapped") into planar east, north
         coordinate system.
      C: Projection centre. (For Ortographic projection, the "center" is in
         the infinity distance above the plane coordinate system origin).
      T: Planar projection mapping coordinate system origin (plane/sphere
         tangency point).
      L: Conical projection, intersection of the parallel of latitude
         at which the cone touches the sphere and the meridian plane of
         the spherical point to be projected.
      E: Stylindrical projection, intersection of the Equator and the
         meridian plane of the point to be projected.
   ·
   For Gnomonic, Stereographic and Orthographic projections, the geometry
   is depicted in the plane defined by three points: projection centre, map
   plane origin (i.e., the tangency) point and the the point to be projected.
   For the other two, the geometry is depicted in the meridian plane of the
   spherical point.
   ·
   Worth noting is the relative speed of sphere to plane (i.e., direct)
   mapping transformation of five projections. On a AMD Ryzen 7 4700U CPU
   the speed measured as millions of random spherical points projected
   into the map plane per second (i.e., more is better) is as follows:
   ·
      Gnomonic:      102.4
      Stereographic:  30.6
      Orthographic:   75.5
      Conical:        14.3
      Stylindrical:   26.3
   ·
   The speed of the inverse (i.e. projecting the point from plane back to
   sphere) will generally be 30-50 % slower (i.e., it will take a little bit
   more time to "un-map" the point than it took to map it). This is rarely
   a concern: while a system would usually be required to create a transient
   grephical display consisting of millions of data points in sub-second
   interaction time, the inverse would be required for only a single set of
   display coordinates - usually the cartographic plane equivalent of the
   screen position of a user-operated pointer device.
   ·
   Following the assumption that most high volume data objects manipulated
   by the system will be represented by 8-byte nemoPtU64 concise spherical
   coordinates, both direct and inverse transformations will accept (or
   return) the spherical coordinates in that format. The mechanism is simple:
   when the nemoPtNcs * pointer is NULL, the function assumes the spherical
   coordinates are given by the following nemoPtU64 item in the calling
   sequence, or are expected to be returned in variable pointed to by a
   nemoPtU64 * pointer that follows the NULL nemoPtNcs * in the function
   calling sequence. This is only a programming convenience: the coordinates
   are  internally transformed into full direction cosine form before (or
   after) the required cartographic computations.
   ·
   For additional discussion of cartographic projections, see:
   ·
   Yang, Snyder, Tobler: Map Projection Transformation, Principles
      and Applications, Taylor & Francis, 2000
   Snyder: Map Projections Used by the U.S. Geological Survey
      Geological survey bulletin 1532, Second edition, 1984

nemo_GnomonicInit()   Initialize Gnomonic projection
nemo_GnomonicDirect()   NCS to Gnomonic map plane
nemo_GnomonicInverse()   Gnomonic map plane to NCS
nemo_StereographicInit()   Initialize Stereographic projection
nemo_StereographicDirect()   NCS to Stereographic map plane
nemo_StereographicInverse()   Stereographic map plane to NCS
nemo_OrthographicInit()   Initialize ortographic projection
nemo_OrthographicDirect()   NCS to Ortographic map plane
nemo_OrthographicInverse()   Ortographic map plane to NCS
nemo_ConicalInit()   Initialize conical projection
nemo_ConicalDirect()   NCS to Conical map plane
nemo_ConicalInverse()   Conical map plane to NCS
nemo_StylindricalInit()   Initialize Stylindrical projection
nemo_StylindricalDirect()   NCS to Stylindrical map plane
nemo_StylindricalInverse()   Stylindrical map plane to NCS

nemo_GnomonicInit()
Synopsis:
   #include <nemo.h>
   int nemo_GnomonicInit(const nemoPtNcs *pPtNcsT, nemoPtU64 ptU64,
                         double projParms[NEMO_GNOMONIC_PCNT]);


Hydrography of central Europe in Gnomonic and Stereographic projections

Description:
   Given the coordinates of Gnomonic projection sphere/plane tangency
   point, calculate and return (in an invoker-supplied array of
   NEMO_GNOMONIC_PCNT doubles) the parameters used in subsequent
   direct and inverse coordinate transformations. With spherical coordinates
   in the direction cosine form, Gnomonic projection has by far the quickest
   direct transformation. Another useful property is that great circles
   on the sphere are projected as straight lines in plane, thus many spherical
   geometry propositions of local geometry (for instance, finding a point of
   intersection of two great circle segments) can be readily solved using
   planar coordinate geometry, thus avoiding spherical trigonometry.
   The disadvantage of Gnomonic projection is the loss of similarity of shapes
   as the extent of map coverage increases. What level of distortion is
   acceptable depends on the application contexts. In the illustration above,
   the hydrography linework was rendered in Stereographic projection in red,
   before being "drawn over" in blue - in Gnomonic projection, (the same
   as the rest of the map). The red "ghost" linework in the map periphery
   illustrates how the visual difference between two projections depends on
   the planet size, map scale and display pixel size.
Arguments:
   pPtNcsT:
      pointer to nemoPtNcs structure, given projection tangency point
      spherical coordinates, or NULL.
   ptU64:
      integer of nemoPtU64 type. Ignored if pPtNcsT is non-NULL,
      otherwise tangency point coordinates.
   projParms:
      Array of NEMO_GNOMONIC_PCNT doubles, returned projection parameters.
      The first three array elements are the coordinates of the spherical
      tangency point, which the invoker may read but (like the rest of the
      array) must not modify while the array is used by the two transformation
      functions.
Return Value:
   Integer, 1 for ill-defined tangency pont, 0 otherwise.
See Also:
   nemo_OrthographicInit()
   nemo_StereographicInit()
   nemo_ConicalInit()
   nemo_StylindricalInit()
   nemo_GnomonicDirect()
   nemo_GnomonicInverse()

nemo_GnomonicDirect()
Synopsis:
   #include <nemo.h>
   int nemo_GnomonicDirect(const double projParms[NEMO_GNOMONIC_PCNT],
                           const nemoPtNcs *pPtNcs, nemoPtU64 ptU64,
                           nemoPtPln *pPtPln);
Description:
   Given the coordinates of a point on the sphere and an array of Gnomonic
   projection parameters, return the planar coordinates of the point.
Arguments:
   projParms:
      Array of NEMO_GNOMONIC_PCNT doubles, given projection parameters,
      previously populated by nemo_StereographicInit() function.
   pPtNcs:
      pointer to nemoPtNcs structure, given spherical point coordinates.
   ptU64:
      integer of nemoPtU64 type. Ignored if pPtNcs is non-NULL,
      otherwise the given spherical point coordinates in nemoPtU64 form.
   pPtPln:
      Pointer to nemoPtPln structure, returned planar (projected)
      point coordinates.
Return Value:
   Integer, always 0.
See Also:
   nemo_GnomonicInit()
   nemo_GnomonicInverse()

nemo_GnomonicInverse()
Synopsis:
   #include <nemo.h>
   int nemo_GnomonicInverse(const double projParms[NEMO_GNOMONIC_PCNT],
                            const nemoPtPln *pPtPln,
                            nemoPtNcs *pPtNcs, nemoPtU64 *pPtU64);
Description:
   Given the planar coordinates of a point and an array of Gnomonic projection
   parameters, return the spherical coordinats of the point.
Arguments:
   projParms:
      Array of NEMO_GNOMONIC_PCNT doubles, given projection parameters,
      previously populated by nemo_StereographicInit() function.
   pPtPln:
      Pointer to nemoPtPln type/structure, given planar point coordinates.
   pPtNcs:
      pointer to nemoPtNcs structure, returned spherical point coordinates.
      Ignored if NULL.
   pPtU64:
      Pointer to an integer of nemoPtU64 type. Ignored if NULL, otherwise
      returned spherical point coordinates in nemoPtU64 form.
Return Value:
   Integer, always 0.
See Also:
   nemo_GnomonicInit()
   nemo_GnomonicDirect()

nemo_StereographicInit()
Synopsis:
   #include <nemo.h>
   int nemo_StereographicInit(const nemoPtNcs *pPtNcsT, nemoPtU64 ptU64,
                              double projParms[NEMO_STEREOGRAPHIC_PCNT]);


North Atlantic in Stereographic projection

Description:
   Given the coordinates of Stereographic projection sphere/plane tangency
   point, calculate and return (in an invoker-supplied array of
   NEMO_STEREOGRAPHIC_PCNT doubles) the parameters used in subsequent
   direct and inverse coordinate transformations.
Arguments:
   pPtNcsT:
      pointer to nemoPtNcs structure, given projection tangency point
      spherical coordinates, or NULL.
   ptU64:
      integer of nemoPtU64 type. Ignored if pPtNcsT is non-NULL,
      otherwise tangency point coordinates.
   projParms:
      Array of NEMO_STEREOGRAPHIC_PCNT doubles, returned projection
      parameters. The first three array elements are the coordinates of the
      spherical tangency point, which the invoker may read but (like the rest
      of the array) must not modify while the array is used by the two
      transformation functions.
Return Value:
   Integer, error indicator, non-0 in case of invalid given tangency point.
See Also:
   nemo_GnomonicInit()
   nemo_OrthographicInit()
   nemo_ConicalInit()
   nemo_StylindricalInit()
   nemo_StereographicDirect()
   nemo_StereographicInverse()

nemo_StereographicDirect()
Synopsis:
   #include <nemo.h>
   int nemo_StereographicDirect(const double projParms[NEMO_STEREOGRAPHIC_PCNT],
                                const nemoPtNcs *, nemoPtU64 ptU64,
                                nemoPtPln *pPtPln);
Description:
   Given the coordinates of a point on the sphere and an array of Stereographic
   projection parameters, return the planar coordinates of the point.
Arguments:
   projParms:
      Array of NEMO_STEREOGRAPHIC_PCNT doubles, given projection parameters,
      previously populated by nemo_StereographicInit() function.
   pPtNcs:
      pointer to nemoPtNcs structure, given spherical point coordinates.
   ptU64:
      integer of nemoPtU64 type. Ignored if pPtNcs is non-NULL,
      otherwise the given spherical point coordinates in nemoPtU64 form.
   pPtPln:
      Pointer to nemoPtPln structure, returned planar (projected)
      point coordinates.
Return Value:
   Integer, error indicator, non-0 in case of invalid given point.
See Also:
   nemo_StereographicInit()
   nemo_StereographicInverse()

nemo_StereographicInverse()
Synopsis:
   #include <nemo.h>
   int nemo_StereographicInverse(const double projParms[NEMO_STEREOGRAPHIC_PCNT],
                                 const nemoPtPln *, nemoPtNcs *pPtNcs,
                                 nemoPtU64 *pPtU64);
Description:
   Given the planar coordinates of a point and an array of Stereographic
   projection parameters, return the spherical coordinates of the point.
Arguments:
   projParms:
      Array of NEMO_STEREOGRAPHIC_PCNT doubles, given projection parameters,
      previously populated by nemo_StereographicInit() function.
   pPtPln:
      Pointer to nemoPtPln type/structure, given planar point coordinates.
   pPtNcs:
      pointer to nemoPtNcs structure, returned spherical point coordinates.
      Ignored if NULL.
   pPtU64:
      Pointer to an integer of nemoPtU64 type. Ignored if NULL, otherwise
      returned spherical point coordinates in nemoPtU64 form.
Return Value:
   Integer, error indicator, non-0 in case of invalid return specifications.
See Also:
   nemo_StereographicInit()
   nemo_StereographicDirect()

nemo_OrthographicInit()
Synopsis:
   #include <nemo.h>
   int nemo_OrthographicInit(const nemoPtNcs *pPtNcsPc, nemoPtU64 pPtU64Pc,
                             const nemoPtNcs *pPtNcsUp, nemoPtU64 pPtU64Up,
                             double ppft,
                             double projParms[NEMO_ORTHOGRAPHIC_PCNT]);


A pseudo-regular hierarchical spherical grid in Orthographic projection

Description:
   Given the coordinates of Orthograpgic projection sphere point that
   corresponds to the origin of the planar east, north coordinate system,
   calculate and return (in an invoker-supplied array of
   NEMO_ORTHOGRAPHIC_PCNT doubles) the parameters used in subsequent
   direct and inverse coordinate transformations.
Arguments:
   pPtNcsT:
      pointer to nemoPtNcs structure, given spherical point corresponding
      to the origin of the planar coordinate system. The argument can be NULL,
      in which case the coordinates are assumed to be given in nemoPtU64
      form, in the argument that follows.
   ptU64:
      integer of nemoPtU64 type. Ignored if pPtNcsT is non-NULL,
      otherwise spherical point coordinates as defined above.
   projParms:
      Array of NEMO_ORTHOGRAPHIC_PCNT doubles, returned projection
      parameters. The first three array elements are the coordinates of the
      spherical center-point (see above), which the invoker may read but
      (like the rest of the array) must not modify while the array is used
      by the two transformation functions.
Return Value:
   Integer, 1 for ill-defined center point, 0 otherwise.
See Also:
   nemo_GnomonicInit()
   nemo_StereographicInit()
   nemo_ConicalInit()
   nemo_StylindricalInit()
   nemo_OrthographicDirect()
   nemo_OrthographicInverse()

nemo_OrthographicDirect()
Synopsis:
   #include <nemo.h>
   int nemo_OrthographicDirect(const double projParms[NEMO_ORTHOGRAPHIC_PCNT],
                               const nemoPtNcs *pPtNcs, nemoPtU64 ptU64,
                               nemoPtPln *pPtPln);
Description:
   Given the coordinates of a point on the sphere and an array of Orthographic
   projection parameters, return the planar coordinates of the point.
Arguments:
   projParms:
      Array of NEMO_ORTHOGRAPHIC_PCNT doubles, given projection parameters,
      previously populated by nemo_OrthographicInit() function.
   pPtNcs:
      pointer to nemoPtNcs structure, given spherical point coordinates.
   ptU64:
      integer of nemoPtU64 type. Ignored if pPtNcs is non-NULL,
      otherwise the given spherical point coordinates in nemoPtU64 form.
   pPtPln:
      Pointer to nemoPtPln structure, returned planar (projected)
      point coordinates.
Return Value:
   Integer, always 0;
See Also:
   nemo_OrthographicInit()
   nemo_OrthographicInverse()

nemo_OrthographicInverse()
Synopsis:
   #include <nemo.h>
   int nemo_OrthographicInverse(const double projParms[NEMO_ORTHOGRAPHIC_PCNT],
                                const nemoPtPln *pPtPln,
                                nemoPtNcs *pPtNcsT, nemoPtU64 *pPtU64);
Description:
   Given the planar coordinates of a point and an array of Orthographic
   projection parameters, return the spherical coordinates of the point.
Arguments:
   projParms:
      Array of NEMO_ORTHOGRAPHIC_PCNT doubles, given projection parameters,
      previously populated by nemo_OrthographicInit() function.
   pPtPln:
      Pointer to nemoPtPln type/structure, given planar point coordinates.
   pPtNcs:
      pointer to nemoPtNcs structure, returned spherical point coordinates.
      Ignored if NULL.
   pPtU64:
      Pointer to an integer of nemoPtU64 type. Ignored if NULL, otherwise
      returned spherical point coordinates in nemoPtU64 form.
Return Value:
   Integer, error indicator, non-0 in case of invalid return specifications.
See Also:
   nemo_OrthographicInit()
   nemo_OrthographicDirect()

nemo_ConicalInit()
Synopsis:
   #include <nemo.h>
   int nemo_ConicalInit(const nemoPtNcs *pPtNcs, nemoPtU64 ptU64,
                        double projParms[NEMO_CONICAL_PCNT]);


North-West Passage, Roald Amundsen on Gjøa, in 1906. Conical projection

See Also:
   nemo_GnomonicInit()
   nemo_OrthographicInit()
   nemo_StereographicInit()
   nemo_StylindricalInit()
   nemo_ConicalDirect()
   nemo_ConicalInverse()

nemo_ConicalDirect()
Synopsis:
   #include <nemo.h>
   int nemo_ConicalDirect(const double projParms[NEMO_CONICAL_PCNT],
                          const nemoPtNcs *pPtNcsT, nemoPtU64 ptU64,
                          nemoPtPln *pPtPln);
See Also:
   nemo_ConicalInit()
   nemo_ConicalInverse()

nemo_ConicalInverse()
Synopsis:
   #include <nemo.h>
   int nemo_ConicalInverse(const double projParms[NEMO_CONICAL_PCNT],
                           const nemoPtPln *pPtPln,
                           nemoPtNcs *pPtNcsT, nemoPtU64 *pPtU64);
See Also:
   nemo_ConicalInit()
   nemo_ConicalDirect()

nemo_StylindricalInit()
Synopsis:
   #include <nemo.h>
   int nemo_StylindricalInit(const nemoPtNcs *pPtNcsCm, nemoPtU64 ptU64,
            double projParms[NEMO_STYLINDRICAL_PCNT]);


World-wide seismic events in Stylindrical projection

Description:
   Given the coordinates of a point on "stylindrical" projection central
   meridian, calculate and return (in an invoker-supplied array of
   STYLINDRICAL_PCNT doubles) the parameters used in subsequent direct
   and inverse coordinate transformations.
Arguments:
   pPtNcsT:
      pointer to nemoPtNcs structure, given point that defines the central
      half-meridian of the projection. Any point on the half-meridian can be
      given, as long as it if not in very high latitudes, where the spherical
      vector form of coordinated might not define it's longitude with
      sufficient resolution. (it will commonly be a point on the Equator).
      The other half of the selected meridian will be the half-meridian
      along which the cylinder is "cut" when unfurled into the plane.
   ptU64:
      integer of nemoPtU64 type. Ignored if pPtNcsT is non-NULL,
      otherwise tangency point coordinates.
   projParms:
      Array of NEMO_STYLINDRICAL_PCNT doubles, returned projection
      parameters. The first three array elements are the the spherical
      coordinates of central meridian equatorial point, which the invoker
      may read but (like the rest of the array) not modify while the
      array is used by the two transformation functions.
Return Value:
   Integer, error indicator, non-0 in case of invalid given central
   meridian definition point.
Example:
   ...
   /* The longitude 11° 30' East (for instance, Munich, Bavaria) will be used
      as the central half-meridian. In addition to (unavoidable) "Antarctica
      incision", the only landmass its antipodal half-meridian will cut in
      two pieces is the remote Aleutian island of Nikolski (population 39).
      (There is no "Antarctica-incision-only" half-meridian on planet Earth).
    */
   double projParms[NEMO_STYLINDRICAL_PCNT];         /* projection parameters */
   nemoPtEll cmeEll = {0, NEMO_DEG2RAD * 11.5};        /* central meridian... */
   nemoPtNcs cmeNcs;            /* ...equatorial point, on ellipsoid and NCS. */
   int iRtcd;
   ...
   nemo_EllToNcs(nemo_ElrWgs84(), &cmeEll, &cmeNcs);
   iRtcs = nemo_StylindricalInit(&cmeNcs, NEMO_U64_UNDEF, projParms);
   ...
See Also:
   nemo_GnomonicInit()
   nemo_OrthographicInit()
   nemo_StereographicInit()
   nemo_ConicalInit()
   nemo_StylindricalDirect()
   nemo_StylindricalInverse()

nemo_StylindricalDirect()
Synopsis:
   #include <nemo.h>
   int nemo_StylindricalDirect(const double projParms[NEMO_STYLINDRICAL_PCNT],
                               const nemoPtNcs *pPtNcs, nemoPtU64 ptU64,
                               nemoPtPln *pPtPln);
Description:
   Given the coordinates of a point on the sphere and an array of Stylindrical
   projection parameters, return the planar coordinats of the point.
Arguments:
   projParms:
      Array of NEMO_STYLINDRICAL_PCNT doubles, given projection parameters,
      previously populated by nemo_StylindricalInit() function.
   pPtNcs:
      pointer to nemoPtNcs structure, given spherical point coordinates.
   ptU64:
      integer of nemoPtU64 type. Ignored if pPtNcs is non-NULL,
      otherwise the given spherical point coordinates in nemoPtU64 form.
   pPtPln:
      Pointer to nemoPtPln type/structure, returned planar (projected)
      point coordinates.
Return Value:
   Integer, error indicator, non-0 in case of invalid given point.
See Also:
   nemo_StylindricalInit()
   nemo_StylindricalInverse()

nemo_StylindricalInverse()
Synopsis:
   #include <nemo.h>
   int nemo_StylindricalInverse(const double projParms[NEMO_STYLINDRICAL_PCNT],
                                const nemoPtPln *pPtPln,
                                nemoPtNcs *pPtNcs, nemoPtU64 *pPtU64);
Description:
   Given the planar coordinates of a point and an array of Stylindrical
   projection parameters, return the spherical coordinats of the point.
Arguments:
   pPtPln:
      Pointer to nemoPtPln type/structure, given planar point coordinates.
   projParms:
      Array of NEMO_STYLINDRICAL_PCNT doubles, given projection parameters,
      previously populated by nemo_StylindricalInit() function.
   pPtNcs:
      pointer to nemoPtNcs structure, returned spherical point coordinates.
      Ignored if NULL.
   pPtU64:
      Pointer to an integer of nemoPtU64 type. Ignored if NULL, otherwise
      returned spherical point coordinates in nemoPtU64 form.
Return Value:
   Integer, error indicator, non-0 in case of invalid return coordinates
   specifications.
See Also:
   nemo_StylindricalInit()
   nemo_StylindricalDirect()