Convert between degrees and the DMS representation. More...
#include <DMS.hpp>
Public Types | |
enum | component { DEGREE, MINUTE, SECOND } |
enum | flag { NONE, LATITUDE, LONGITUDE, AZIMUTH, NUMBER } |
Static Public Member Functions | |
static Math::real | Decode (const std::string &dms, flag &ind) |
static Math::real | Decode (real d, real m=0, real s=0) |
static Math::real | DecodeAngle (const std::string &angstr) |
static Math::real | DecodeAzimuth (const std::string &azistr) |
static void | DecodeLatLon (const std::string &dmsa, const std::string &dmsb, real &lat, real &lon, bool longfirst=false) |
static void | Encode (real ang, real &d, real &m) |
static void | Encode (real ang, real &d, real &m, real &s) |
static std::string | Encode (real angle, component trailing, unsigned prec, flag ind=NONE, char dmssep=char(0)) |
static std::string | Encode (real angle, unsigned prec, flag ind=NONE, char dmssep=char(0)) |
Private Types | |
typedef Math::real | real |
Private Member Functions | |
DMS () | |
Static Private Member Functions | |
static Math::real | InternalDecode (const std::string &dmsa, flag &ind) |
static Math::real | NumMatch (const std::string &s) |
static void | replace (std::string &s, const std::string &pat, char c) |
Static Private Attributes | |
static const char *const | components_ [3] = {"degrees", "minutes", "seconds"} |
static const char *const | digits_ = "0123456789" |
static const char *const | dmsindicators_ = "D'\":" |
static const char *const | hemispheres_ = "SNWE" |
static const char *const | signs_ = "-+" |
Convert between degrees and the DMS representation.
Parse a string representing degree, minutes, and seconds and return the angle in degrees and format an angle in degrees as degree, minutes, and seconds. In addition, handle NANs and infinities on input and output.
Example of use:
|
private |
Indicator for presence of hemisphere indicator (N/S/E/W) on latitudes and longitudes.
|
private |
|
static |
Convert a string in DMS to an angle.
[in] | dms | string input. |
[out] | ind | a DMS::flag value signaling the presence of a hemisphere indicator. |
GeographicErr | if dms is malformed (see below). |
Degrees, minutes, and seconds are indicated by the characters d, ' (single quote), " (double quote), and these components may only be given in this order. Any (but not all) components may be omitted and other symbols (e.g., the ° symbol for degrees and the unicode prime and double prime symbols for minutes and seconds) may be substituted; two single quotes can be used instead of ". The last component indicator may be omitted and is assumed to be the next smallest unit (thus 33d10 is interpreted as 33d10'). The final component may be a decimal fraction but the non-final components must be integers. Instead of using d, ', and " to indicate degrees, minutes, and seconds, : (colon) may be used to separate these components (numbers must appear before and after each colon); thus 50d30'10.3" may be written as 50:30:10.3, 5.5' may be written 0:5.5, and so on. The integer parts of the minutes and seconds components must be less than 60. A single leading sign is permitted. A hemisphere designator (N, E, W, S) may be added to the beginning or end of the string. The result is multiplied by the implied sign of the hemisphere designator (negative for S and W). In addition ind is set to DMS::LATITUDE if N or S is present, to DMS::LONGITUDE if E or W is present, and to DMS::NONE otherwise. Throws an error on a malformed string. No check is performed on the range of the result. Examples of legal and illegal strings are
The decoding operation can also perform addition and subtraction operations. If the string includes internal signs (i.e., not at the beginning nor immediately after an initial hemisphere designator), then the string is split immediately before such signs and each piece is decoded according to the above rules and the results added; thus S3-2.5+4.1N
is parsed as the sum of S3
, -2.5
, +4.1N
. Any piece can include a hemisphere designator; however, if multiple designators are given, they must compatible; e.g., you cannot mix N and E. In addition, the designator can appear at the beginning or end of the first piece, but must be at the end of all subsequent pieces (a hemisphere designator is not allowed after the initial sign). Examples of legal and illegal combinations are
7.0E1
is illegal, while 7.0E+1
is parsed as (7.0E) + (+1)
, yielding the same result as 8.0E
.Here is the list of Unicode symbols supported for degrees, minutes, seconds, and the sign:
The codes with a leading zero byte, e.g., U+00b0, are accepted in their UTF-8 coded form 0xc2 0xb0 and as a single byte 0xb0.
Definition at line 28 of file src/DMS.cpp.
|
inlinestatic |
Convert DMS to an angle.
[in] | d | degrees. |
[in] | m | arc minutes. |
[in] | s | arc seconds. |
This does not propagate the sign on d to the other components, so -3d20' would need to be represented as - DMS::Decode(3.0, 20.0) or DMS::Decode(-3.0, -20.0).
|
static |
Convert a string to an angle in degrees.
[in] | angstr | input string. |
GeographicErr | if angstr is malformed. |
GeographicErr | if angstr includes a hemisphere designator. |
No hemisphere designator is allowed and no check is done on the range of the result.
Definition at line 281 of file src/DMS.cpp.
|
static |
Convert a string to an azimuth in degrees.
[in] | azistr | input string. |
GeographicErr | if azistr is malformed. |
GeographicErr | if azistr includes a N/S designator. |
A hemisphere designator E/W can be used; the result is multiplied by −1 if W is present.
Definition at line 290 of file src/DMS.cpp.
|
static |
Convert a pair of strings to latitude and longitude.
[in] | dmsa | first string. |
[in] | dmsb | second string. |
[out] | lat | latitude (degrees). |
[out] | lon | longitude (degrees). |
[in] | longfirst | if true assume longitude is given before latitude in the absence of hemisphere designators (default false). |
GeographicErr | if dmsa or dmsb is malformed. |
GeographicErr | if dmsa and dmsb are both interpreted as latitudes. |
GeographicErr | if dmsa and dmsb are both interpreted as longitudes. |
GeographicErr | if decoded latitude is not in [−90°, 90°]. |
By default, the lat (resp., lon) is assigned to the results of decoding dmsa (resp., dmsb). However this is overridden if either dmsa or dmsb contain a latitude or longitude hemisphere designator (N, S, E, W). If an exception is thrown, lat and lon are unchanged.
Definition at line 252 of file src/DMS.cpp.
|
static |
Convert angle (in degrees) into a DMS string (using d, ', and ").
[in] | angle | input angle (degrees) |
[in] | trailing | DMS::component value indicating the trailing units of the string (this component is given as a decimal number if necessary). |
[in] | prec | the number of digits after the decimal point for the trailing component. |
[in] | ind | DMS::flag value indicating additional formatting. |
[in] | dmssep | if non-null, use as the DMS separator character (instead of d, ', " delimiters). |
std::bad_alloc | if memory for the string can't be allocated. |
The interpretation of ind is as follows:
The integer parts of the minutes and seconds components are always given with 2 digits.
Definition at line 299 of file src/DMS.cpp.
|
inlinestatic |
Convert angle into a DMS string (using d, ', and ") selecting the trailing component based on the precision.
[in] | angle | input angle (degrees) |
[in] | prec | the precision relative to 1 degree. |
[in] | ind | DMS::flag value indicated additional formatting. |
[in] | dmssep | if non-null, use as the DMS separator character (instead of d, ', " delimiters). |
std::bad_alloc | if memory for the string can't be allocated. |
prec indicates the precision relative to 1 degree, e.g., prec = 3 gives a result accurate to 0.1' and prec = 4 gives a result accurate to 1". ind is interpreted as in DMS::Encode with the additional facility that DMS::NUMBER represents angle as a number in fixed format with precision prec.
|
staticprivate |
Definition at line 81 of file src/DMS.cpp.
|
staticprivate |
|
inlinestaticprivate |
|
staticprivate |
|
staticprivate |
|
staticprivate |
|
staticprivate |
|
staticprivate |