Convert between geographic coordinates and UTM/UPS. More...
#include <UTMUPS.hpp>
Public Types | |
enum | zonespec { MINPSEUDOZONE = -4, INVALID = -4, MATCH = -3, UTM = -2, STANDARD = -1, MAXPSEUDOZONE = -1, MINZONE = 0, UPS = 0, MINUTMZONE = 1, MAXUTMZONE = 60, MAXZONE = 60 } |
Static Public Member Functions | |
static void | DecodeEPSG (int epsg, int &zone, bool &northp) |
static void | DecodeZone (const std::string &zonestr, int &zone, bool &northp) |
static int | EncodeEPSG (int zone, bool northp) |
static std::string | EncodeZone (int zone, bool northp, bool abbrev=true) |
static void | Forward (real lat, real lon, int &zone, bool &northp, real &x, real &y, real &gamma, real &k, int setzone=STANDARD, bool mgrslimits=false) |
static void | Forward (real lat, real lon, int &zone, bool &northp, real &x, real &y, int setzone=STANDARD, bool mgrslimits=false) |
static void | Reverse (int zone, bool northp, real x, real y, real &lat, real &lon, real &gamma, real &k, bool mgrslimits=false) |
static void | Reverse (int zone, bool northp, real x, real y, real &lat, real &lon, bool mgrslimits=false) |
static int | StandardZone (real lat, real lon, int setzone=STANDARD) |
static void | Transfer (int zonein, bool northpin, real xin, real yin, int zoneout, bool northpout, real &xout, real &yout, int &zone) |
static Math::real | UTMShift () |
Inspector functions | |
static Math::real | MajorRadius () |
static Math::real | Flattening () |
Private Types | |
typedef Math::real | real |
Private Member Functions | |
UTMUPS () | |
Static Private Member Functions | |
static real | CentralMeridian (int zone) |
static bool | CheckCoords (bool utmp, bool northp, real x, real y, bool msgrlimits=false, bool throwp=true) |
Static Private Attributes | |
static const int | epsg01N = 32601 |
static const int | epsg01S = 32701 |
static const int | epsg60N = 32660 |
static const int | epsg60S = 32760 |
static const int | epsgN = 32661 |
static const int | epsgS = 32761 |
static const int | falseeasting_ [4] |
static const int | falsenorthing_ [4] |
static const int | maxeasting_ [4] |
static const int | maxnorthing_ [4] |
static const int | mineasting_ [4] |
static const int | minnorthing_ [4] |
Convert between geographic coordinates and UTM/UPS.
UTM and UPS are defined
Section 2-3 defines UTM and section 3-2.4 defines UPS. This document also includes approximate algorithms for the computation of the underlying transverse Mercator and polar stereographic projections. Here we substitute much more accurate algorithms given by GeographicLib:TransverseMercator and GeographicLib:PolarStereographic. These are the algorithms recommended by the NGA document
In this implementation, the conversions are closed, i.e., output from Forward is legal input for Reverse and vice versa. The error is about 5nm in each direction. However, the conversion from legal UTM/UPS coordinates to geographic coordinates and back might throw an error if the initial point is within 5nm of the edge of the allowed range for the UTM/UPS coordinates.
The simplest way to guarantee the closed property is to define allowed ranges for the eastings and northings for UTM and UPS coordinates. The UTM boundaries are the same for all zones. (The only place the exceptional nature of the zone boundaries is evident is when converting to UTM/UPS coordinates requesting the standard zone.) The MGRS lettering scheme imposes natural limits on UTM/UPS coordinates which may be converted into MGRS coordinates. For the conversion to/from geographic coordinates these ranges have been extended by 100km in order to provide a generous overlap between UTM and UPS and between UTM zones.
The NGA software package geotrans also provides conversions to and from UTM and UPS. Version 2.4.2 (and earlier) suffers from some drawbacks:
The GeographicLib::UTMUPS::EncodeZone encodes the UTM zone and hemisphere to allow UTM/UPS coordinated to be displayed as, for example, "38N 444500 3688500". According to NGA.SIG.0012_2.0.0_UTMUPS the use of "N" to denote "north" in the context is not allowed (since a upper case letter in this context denotes the MGRS latitude band). Consequently, as of version 1.36, EncodeZone uses the lower case letters "n" and "s" to denote the hemisphere. In addition EncodeZone accepts an optional final argument abbrev, which, if false, results in the hemisphere being spelled out as in "38north".
Example of use:
Definition at line 75 of file UTMUPS.hpp.
|
private |
Definition at line 77 of file UTMUPS.hpp.
In this class we bring together the UTM and UPS coordinates systems. The UTM divides the earth between latitudes −80° and 84° into 60 zones numbered 1 thru 60. Zone assign zone number 0 to the UPS regions, covering the two poles. Within UTMUPS, non-negative zone numbers refer to one of the "physical" zones, 0 for UPS and [1, 60] for UTM. Negative "pseudo-zone" numbers are used to select one of the physical zones.
Enumerator | |
---|---|
MINPSEUDOZONE | The smallest pseudo-zone number. |
INVALID | A marker for an undefined or invalid zone. Equivalent to NaN. |
MATCH | If a coordinate already include zone information (e.g., it is an MGRS coordinate), use that, otherwise apply the UTMUPS::STANDARD rules. |
UTM | Apply the standard rules for UTM zone assigment extending the UTM zone to each pole to give a zone number in [1, 60]. For example, use UTM zone 38 for longitude in [42°, 48°). The rules include the Norway and Svalbard exceptions. |
STANDARD | Apply the standard rules for zone assignment to give a zone number in [0, 60]. If the latitude is not in [−80°, 84°), then use UTMUPS::UPS = 0, otherwise apply the rules for UTMUPS::UTM. The tests on latitudes and longitudes are all closed on the lower end open on the upper. Thus for UTM zone 38, latitude is in [−80°, 84°) and longitude is in [42°, 48°). |
MAXPSEUDOZONE | The largest pseudo-zone number. |
MINZONE | The smallest physical zone number. |
UPS | The zone number used for UPS |
MINUTMZONE | The smallest UTM zone number. |
MAXUTMZONE | The largest UTM zone number. |
MAXZONE | The largest physical zone number. |
Definition at line 109 of file UTMUPS.hpp.
|
private |
Definition at line 90 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 143 of file src/UTMUPS.cpp.
Decode EPSG.
[in] | epsg | the EPSG code. |
[out] | zone | the UTM zone (zero means UPS). |
[out] | northp | hemisphere (true means north, false means south). |
EPSG (European Petroleum Survery Group) codes are a way to refer to many different projections. DecodeEPSG decodes those refering to UTM or UPS projections for the WGS84 ellipsoid. If the code does not refer to one of these projections, zone is set to UTMUPS::INVALID. See http://spatialreference.org/ref/epsg/
Definition at line 270 of file src/UTMUPS.cpp.
|
static |
Decode a UTM/UPS zone string.
[in] | zonestr | string representation of zone and hemisphere. |
[out] | zone | the UTM zone (zero means UPS). |
[out] | northp | hemisphere (true means north, false means south). |
GeographicErr | if zonestr is malformed. |
For UTM, zonestr has the form of a zone number in the range [UTMUPS::MINUTMZONE, UTMUPS::MAXUTMZONE] = [1, 60] followed by a hemisphere letter, n or s (or "north" or "south" spelled out). For UPS, it consists just of the hemisphere letter (or the spelled out hemisphere). The returned value of zone is UTMUPS::UPS = 0 for UPS. Note well that "38s" indicates the southern hemisphere of zone 38 and not latitude band S, 32° ≤ lat < 40°. n, 01s, 2n, 38s, south, 3north are legal. 0n, 001s, +3n, 61n, 38P are illegal. INV is a special value for which the returned value of is UTMUPS::INVALID.
Definition at line 208 of file src/UTMUPS.cpp.
Encode zone as EPSG.
[in] | zone | the UTM zone (zero means UPS). |
[in] | northp | hemisphere (true means north, false means south). |
Convert zone and northp to the corresponding EPSG (European Petroleum Survery Group) codes
Definition at line 287 of file src/UTMUPS.cpp.
|
static |
Encode a UTM/UPS zone string.
[in] | zone | the UTM zone (zero means UPS). |
[in] | northp | hemisphere (true means north, false means south). |
[in] | abbrev | if true (the default) use abbreviated (n/s) notation for hemisphere; otherwise spell out the hemisphere (north/south) |
GeographicErr | if zone is out of range (see below). |
std::bad_alloc | if memoy for the string can't be allocated. |
zone must be in the range [UTMUPS::MINZONE, UTMUPS::MAXZONE] = [0, 60] with zone = UTMUPS::UPS, 0, indicating UPS (but the resulting string does not contain "0"). zone may also be UTMUPS::INVALID, in which case the returned string is "inv". This reverses UTMUPS::DecodeZone.
Definition at line 254 of file src/UTMUPS.cpp.
|
inlinestatic |
(The WGS84 value is returned because the UTM and UPS projections are based on this ellipsoid.)
Definition at line 414 of file UTMUPS.hpp.
|
static |
Forward projection, from geographic to UTM/UPS.
[in] | lat | latitude of point (degrees). |
[in] | lon | longitude of point (degrees). |
[out] | zone | the UTM zone (zero means UPS). |
[out] | northp | hemisphere (true means north, false means south). |
[out] | x | easting of point (meters). |
[out] | y | northing of point (meters). |
[out] | gamma | meridian convergence at point (degrees). |
[out] | k | scale of projection at point. |
[in] | setzone | zone override (optional). |
[in] | mgrslimits | if true enforce the stricter MGRS limits on the coordinates (default = false). |
GeographicErr | if lat is not in [−90°, 90°]. |
GeographicErr | if the resulting x or y is out of allowed range (see Reverse); in this case, these arguments are unchanged. |
If setzone is omitted, use the standard rules for picking the zone. If setzone is given then use that zone if it is non-negative, otherwise apply the rules given in UTMUPS::zonespec. The accuracy of the conversion is about 5nm.
The northing y jumps by UTMUPS::UTMShift() when crossing the equator in the southerly direction. Sometimes it is useful to remove this discontinuity in y by extending the "northern" hemisphere using UTMUPS::Transfer:
Definition at line 67 of file src/UTMUPS.cpp.
|
inlinestatic |
UTMUPS::Forward without returning convergence and scale.
Definition at line 269 of file UTMUPS.hpp.
|
inlinestatic |
(The WGS84 value is returned because the UTM and UPS projections are based on this ellipsoid.)
Definition at line 405 of file UTMUPS.hpp.
|
static |
Reverse projection, from UTM/UPS to geographic.
[in] | zone | the UTM zone (zero means UPS). |
[in] | northp | hemisphere (true means north, false means south). |
[in] | x | easting of point (meters). |
[in] | y | northing of point (meters). |
[out] | lat | latitude of point (degrees). |
[out] | lon | longitude of point (degrees). |
[out] | gamma | meridian convergence at point (degrees). |
[out] | k | scale of projection at point. |
[in] | mgrslimits | if true enforce the stricter MGRS limits on the coordinates (default = false). |
GeographicErr | if zone, x, or y is out of allowed range; this this case the arguments are unchanged. |
The accuracy of the conversion is about 5nm.
UTM eastings are allowed to be in the range [0km, 1000km], northings are allowed to be in in [0km, 9600km] for the northern hemisphere and in [900km, 10000km] for the southern hemisphere. However UTM northings can be continued across the equator. So the actual limits on the northings are [-9100km, 9600km] for the "northern" hemisphere and [900km, 19600km] for the "southern" hemisphere.
UPS eastings and northings are allowed to be in the range [1200km, 2800km] in the northern hemisphere and in [700km, 3300km] in the southern hemisphere.
These ranges are 100km larger than allowed for the conversions to MGRS. (100km is the maximum extra padding consistent with eastings remaining non-negative.) This allows generous overlaps between zones and UTM and UPS. If mgrslimits = true, then all the ranges are shrunk by 100km so that they agree with the stricter MGRS ranges. No checks are performed besides these (e.g., to limit the distance outside the standard zone boundaries).
Definition at line 121 of file src/UTMUPS.cpp.
|
inlinestatic |
UTMUPS::Reverse without returning convergence and scale.
Definition at line 279 of file UTMUPS.hpp.
The standard zone.
[in] | lat | latitude (degrees). |
[in] | lon | longitude (degrees). |
[in] | setzone | zone override (optional). If omitted, use the standard rules for picking the zone. If setzone is given then use that zone if it is non-negative, otherwise apply the rules given in UTMUPS::zonespec. |
GeographicErr | if setzone is outside the range [UTMUPS::MINPSEUDOZONE, UTMUPS::MAXZONE] = [−4, 60]. |
This is exact.
Definition at line 43 of file src/UTMUPS.cpp.
|
static |
Transfer UTM/UPS coordinated from one zone to another.
[in] | zonein | the UTM zone for xin and yin (or zero for UPS). |
[in] | northpin | hemisphere for xin and yin (true means north, false means south). |
[in] | xin | easting of point (meters) in zonein. |
[in] | yin | northing of point (meters) in zonein. |
[in] | zoneout | the requested UTM zone for xout and yout (or zero for UPS). |
[in] | northpout | hemisphere for xout output and yout. |
[out] | xout | easting of point (meters) in zoneout. |
[out] | yout | northing of point (meters) in zoneout. |
[out] | zone | the actual UTM zone for xout and yout (or zero for UPS); this equals zoneout if zoneout ≥ 0. |
GeographicErr | if zonein is out of range (see below). |
GeographicErr | if zoneout is out of range (see below). |
GeographicErr | if xin or yin fall outside their allowed ranges (see UTMUPS::Reverse). |
GeographicErr | if xout or yout fall outside their allowed ranges (see UTMUPS::Reverse). |
zonein must be in the range [UTMUPS::MINZONE, UTMUPS::MAXZONE] = [0, 60] with zonein = UTMUPS::UPS, 0, indicating UPS. zonein may also be UTMUPS::INVALID.
zoneout must be in the range [UTMUPS::MINPSEUDOZONE, UTMUPS::MAXZONE] = [-4, 60]. If zoneout < UTMUPS::MINZONE then the rules give in the documentation of UTMUPS::zonespec are applied, and zone is set to the actual zone used for output.
(xout, yout) can overlap with (xin, yin).
Definition at line 174 of file src/UTMUPS.cpp.
|
static |
Definition at line 298 of file src/UTMUPS.cpp.
|
staticprivate |
Definition at line 84 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 87 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 85 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 88 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 86 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 89 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 78 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 79 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 81 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 83 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 80 of file UTMUPS.hpp.
|
staticprivate |
Definition at line 82 of file UTMUPS.hpp.