GeographicLib::DMS Class Reference

Convert between degrees and the DMS representation. More...

`#include <GeographicLib/DMS.hpp>`

## Public Types

enum | flag { NONE , LATITUDE , LONGITUDE , AZIMUTH , NUMBER }
enum | component { DEGREE , MINUTE , SECOND }

## 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 void | DecodeLatLon (const std::string &dmsa, const std::string &dmsb, real &lat, real &lon, bool longfirst=false)
static Math::real | DecodeAngle (const std::string &angstr)
static Math::real | DecodeAzimuth (const std::string &azistr)
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))
static void | Encode (real ang, real &d, real &m)
static void | Encode (real ang, real &d, real &m, real &s)

## Detailed Description

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:

// Example of using the GeographicLib::DMS class
#include <iostream>
#include <string>
#include <exception>
#include <GeographicLib/DMS.hpp>
using namespace std;
using namespace GeographicLib;
int main() {
try {
{
string dms = "30d14'45.6\"S";
DMS::flag type;
double ang = DMS::Decode(dms, type);
cout << type << " " << ang << "\n";
}
{
double ang = -30.245715;
string dms = DMS::Encode(ang, 6, DMS::LATITUDE);
cout << dms << "\n";
}
}
catch (const exception& e) {
cerr << "Caught exception: " << e.what() << "\n";
return 1;
}
}
main
int main(int argc, const char *const argv[])
Definition: CartConvert.cpp:29
DMS.hpp
Header for GeographicLib::DMS class.
GeographicLib::DMS::flag
flag
Definition: DMS.hpp:41
GeographicLib::DMS::LATITUDE
@ LATITUDE
Definition: DMS.hpp:51
GeographicLib::DMS::Encode
static std::string Encode(real angle, component trailing, unsigned prec, flag ind=NONE, char dmssep=char(0))
Definition: DMS.cpp:416
GeographicLib::DMS::Decode
static Math::real Decode(const std::string &dms, flag &ind)
Definition: DMS.cpp:40
GeographicLib
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
std
Definition: NearestNeighbor.hpp:812

Definition at line 34 of file DMS.hpp.

## Member Enumeration Documentation

## flag

enum GeographicLib::DMS::flag

Indicator for presence of hemisphere indicator (N/S/E/W) on latitudes and longitudes.

Enumerator
NONE | No indicator present.
LATITUDE | Latitude indicator (N/S) present.
LONGITUDE | Longitude indicator (E/W) present.
AZIMUTH | Used in Encode to indicate output of an azimuth in [000, 360) with no letter indicator.
NUMBER | Used in Encode to indicate output of a plain number.

Definition at line 41 of file DMS.hpp.

## component

enum GeographicLib::DMS::component

Indicator for trailing units on an angle.

Enumerator
DEGREE | Trailing unit is degrees.
MINUTE | Trailing unit is arc minutes.
SECOND | Trailing unit is arc seconds.

Definition at line 73 of file DMS.hpp.

## Member Function Documentation

## Decode() [1/2]

Math::real GeographicLib::DMS::Decode | ( | const std::string & | dms,
|  | flag & | ind
| ) |  |

static

Convert a string in DMS to an angle.

Parameters

  [in] | dms | string input.
  [out] | ind | a DMS::flag value signaling the presence of a hemisphere indicator.

Exceptions

  GeographicErr | if dms is malformed (see below).

Returns
  angle (degrees).

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. Leading and trailing whitespace is removed from the string before processing. This routine throws an error on a malformed string. No check is performed on the range of the result. Examples of legal and illegal strings are

- LEGAL (all the entries on each line are equivalent)
  - -20.51125, 20d30'40.5"S, -20°30'40.5, -20d30.675, N-20d30'40.5", -20:30:40.5
  - 4d0'9, 4d9", 4d9'', 4:0:9, 004:00:09, 4.0025, 4.0025d, 4d0.15, 04:.15
  - 4:59.99999999999999, 4:60.0, 4:59:59.9999999999999, 4:59:60.0, 5
- ILLEGAL (the exception thrown explains the problem)
  - 4d5"4', 4::5, 4:5:, :4:5, 4d4.5'4", -N20.5, 1.8e2d, 4:60, 4:59:60

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

- LEGAL (these are all equivalent)
  - -070:00:45, 70:01:15W+0:0.5, 70:01:15W-0:0:30W, W70:01:15+0:0:30E
- ILLEGAL (the exception thrown explains the problem)
  - 70:01:15W+0:0:15N, W70:01:15+W0:0:15

Warning
  The "exponential" notation is not recognized. Thus `7.0E1` is illegal, while `7.0E+1` is parsed as `(7.0E) + (+1)`, yielding the same result as `8.0E`.

Note
  At present, all the string handling in the C++ implementation of GeographicLib is with 8-bit characters. The support for unicode symbols for degrees, minutes, and seconds is therefore via the UTF-8 encoding. (The JavaScript implementation of this class uses unicode natively, of course.)

Here is the list of Unicode symbols supported for degrees, minutes, seconds, and the plus and minus signs; various symbols denoting variants of a space, which may separate the components of a DMS string, are removed:

- degrees:
  - d, D lower and upper case letters
  - U+00b0 degree symbol (°)
  - U+00ba masculine ordinal indicator (º)
  - U+2070 superscript zero (⁰)
  - U+02da ring above (˚)
  - U+2218 compose function (∘)
  - * the GRiD symbol for degrees
- minutes:
  - ' apostrophe
  - ` grave accent
  - U+2032 prime (′)
  - U+2035 back prime (‵)
  - U+00b4 acute accent (´)
  - U+2018 left single quote (‘)
  - U+2019 right single quote (’)
  - U+201b reversed-9 single quote (‛)
  - U+02b9 modifier letter prime (ʹ)
  - U+02ca modifier letter acute accent (ˊ)
  - U+02cb modifier letter grave accent (ˋ)
- seconds:
  - " quotation mark
  - U+2033 double prime (″)
  - U+2036 reversed double prime (‶)
  - U+02dd double acute accent (˝)
  - U+201c left double quote (“)
  - U+201d right double quote (”)
  - U+201f reversed-9 double quote (‟)
  - U+02ba modifier letter double prime (ʺ)
  - ' ' any two consecutive symbols for minutes
- plus sign:
  - + plus
  - U+2795 heavy plus (➕)
  - U+2064 invisible plus (|⁤|)
- minus sign:
  - - hyphen
  - U+2010 dash (‐)
  - U+2011 non-breaking hyphen (‑)
  - U+2013 en dash (–)
  - U+2014 em dash (—)
  - U+2212 minus sign (−)
  - U+2796 heavy minus (➖)
- ignored spaces:
  - U+00a0 non-breaking space
  - U+2007 figure space (| |)
  - U+2009 thin space (| |)
  - U+200a hair space ( | |)
  - U+200b invisible space (|​|)
  - U+202f narrow space ( | |)
  - U+2063 invisible separator (|⁣|)

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 40 of file DMS.cpp.

References GeographicLib::Utility::lookup(), and NONE.

Referenced by DecodeAngle(), DecodeAzimuth(), and DecodeLatLon().

## Decode() [2/2]

static Math::real GeographicLib::DMS::Decode | ( | real | d,
|  | real | m = `0`,
|  | real | s = `0`
| ) |  |

inline static

Convert DMS to an angle.

Parameters

  [in] | d | degrees.
  [in] | m | arc minutes.
  [in] | s | arc seconds.

Returns
  angle (degrees)

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).

Definition at line 250 of file DMS.hpp.

References GeographicLib::Math::dm, and GeographicLib::Math::ms.

## DecodeLatLon()

void GeographicLib::DMS::DecodeLatLon | ( | const std::string & | dmsa,
|  | const std::string & | dmsb,
|  | real & | lat,
|  | real & | lon,
|  | bool | longfirst = `false`
| ) |  |

static

Convert a pair of strings to latitude and longitude.

Parameters

  [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).

Exceptions

  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 368 of file DMS.cpp.

References Decode(), LATITUDE, LONGITUDE, NONE, GeographicLib::Math::qd, and GeographicLib::Utility::str().

Referenced by GeographicLib::GeoCoords::Reset().

## DecodeAngle()

Math::real GeographicLib::DMS::DecodeAngle | ( | const std::string & | angstr | ) |

static

Convert a string to an angle in degrees.

Parameters

  [in] | angstr | input string.

Exceptions

  GeographicErr | if angstr is malformed.
  GeographicErr | if angstr includes a hemisphere designator.

Returns
  angle (degrees)

No hemisphere designator is allowed and no check is done on the range of the result.

Definition at line 398 of file DMS.cpp.

References Decode(), and NONE.

## DecodeAzimuth()

Math::real GeographicLib::DMS::DecodeAzimuth | ( | const std::string & | azistr | ) |

static

Convert a string to an azimuth in degrees.

Parameters

  [in] | azistr | input string.

Exceptions

  GeographicErr | if azistr is malformed.
  GeographicErr | if azistr includes a N/S designator.

Returns
  azimuth (degrees) reduced to the range [−180°, 180°].

A hemisphere designator E/W can be used; the result is multiplied by −1 if W is present.

Definition at line 407 of file DMS.cpp.

References GeographicLib::Math::AngNormalize(), Decode(), and LATITUDE.

## Encode() [1/4]

string GeographicLib::DMS::Encode | ( | real | angle,
|  | component | trailing,
|  | unsigned | prec,
|  | flag | ind = `NONE`,
|  | char | dmssep = `char(0)`
| ) |  |

static

Convert angle (in degrees) into a DMS string (using d, ', and ").

Parameters

  [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).

Exceptions

  std::bad_alloc | if memory for the string can't be allocated.

Returns
  formatted string

The interpretation of ind is as follows:

- ind == DMS::NONE, signed result no leading zeros on degrees except in the units place, e.g., -8d03'.
- ind == DMS::LATITUDE, trailing N or S hemisphere designator, no sign, pad degrees to 2 digits, e.g., 08d03'S.
- ind == DMS::LONGITUDE, trailing E or W hemisphere designator, no sign, pad degrees to 3 digits, e.g., 008d03'W.
- ind == DMS::AZIMUTH, convert to the range [0, 360°), no sign, pad degrees to 3 digits, e.g., 351d57'.

The integer parts of the minutes and seconds components are always given with 2 digits.

Definition at line 416 of file DMS.cpp.

References GeographicLib::Math::AngNormalize(), AZIMUTH, DEGREE, GeographicLib::Math::dm, GeographicLib::Math::ds, GeographicLib::Math::extra_digits(), LATITUDE, MINUTE, GeographicLib::Math::ms, NONE, SECOND, GeographicLib::Utility::str(), and GeographicLib::Math::td.

Referenced by GeographicLib::GeoCoords::DMSRepresentation().

## Encode() [2/4]

static std::string GeographicLib::DMS::Encode | ( | real | angle,
|  | unsigned | prec,
|  | flag | ind = `NONE`,
|  | char | dmssep = `char(0)`
| ) |  |

inline static

Convert angle into a DMS string (using d, ', and ") selecting the trailing component based on the precision.

Parameters

  [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).

Exceptions

  std::bad_alloc | if memory for the string can't be allocated.

Returns
  formatted string

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.

Definition at line 356 of file DMS.hpp.

References GeographicLib::Utility::str().

## Encode() [3/4]

static void GeographicLib::DMS::Encode | ( | real | ang,
|  | real & | d,
|  | real & | m
| ) |  |

inline static

Split angle into degrees and minutes

Parameters

  [in] | ang | angle (degrees)
  [out] | d | degrees (an integer returned as a real)
  [out] | m | arc minutes.

Definition at line 372 of file DMS.hpp.

References GeographicLib::Math::dm.

## Encode() [4/4]

static void GeographicLib::DMS::Encode | ( | real | ang,
|  | real & | d,
|  | real & | m,
|  | real & | s
| ) |  |

inline static

Split angle into degrees and minutes and seconds.

Parameters

  [in] | ang | angle (degrees)
  [out] | d | degrees (an integer returned as a real)
  [out] | m | arc minutes (an integer returned as a real)
  [out] | s | arc seconds.

Definition at line 384 of file DMS.hpp.

References GeographicLib::Math::dm, and GeographicLib::Math::ms.

The documentation for this class was generated from the following files:

- DMS.hpp
- DMS.cpp