GeographicLib  2.1.1
Georef.hpp
Go to the documentation of this file.
1 /**
2  * \file Georef.hpp
3  * \brief Header for GeographicLib::Georef class
4  *
5  * Copyright (c) Charles Karney (2015-2022) <charles@karney.com> and licensed
6  * under the MIT/X11 License. For more information, see
7  * https://geographiclib.sourceforge.io/
8  **********************************************************************/
9 
10 #if !defined(GEOGRAPHICLIB_GEOREF_HPP)
11 #define GEOGRAPHICLIB_GEOREF_HPP 1
12 
14 
15 #if defined(_MSC_VER)
16 // Squelch warnings about dll vs string
17 # pragma warning (push)
18 # pragma warning (disable: 4251)
19 #endif
20 
21 namespace GeographicLib {
22 
23  /**
24  * \brief Conversions for the World Geographic Reference System (georef)
25  *
26  * The World Geographic Reference System is described in
27  * - https://en.wikipedia.org/wiki/Georef
28  * - https://web.archive.org/web/20161214054445/http://earth-info.nga.mil/GandG/coordsys/grids/georef.pdf
29  * .
30  * It provides a compact string representation of a geographic area
31  * (expressed as latitude and longitude). The classes GARS and Geohash
32  * implement similar compact representations.
33  *
34  * Example of use:
35  * \include example-Georef.cpp
36  **********************************************************************/
37 
39  private:
40  typedef Math::real real;
41  static const char* const digits_;
42  static const char* const lontile_;
43  static const char* const lattile_;
44  static const char* const degrees_;
45 #if GEOGRAPHICLIB_PRECISION == 4
46  // Work around an enum lossage introduced in boost 1.76
47  // https://github.com/boostorg/multiprecision/issues/324
48  // and fixed in
49  // https://github.com/boostorg/multiprecision/pull/333
50  static const int
51 #else
52  enum {
53 #endif
54  tile_ = 15, // The size of tile in degrees
55  lonorig_ = -Math::hd, // Origin for longitude
56  latorig_ = -Math::qd, // Origin for latitude
57  base_ = 10, // Base for minutes
58  baselen_ = 4,
59  maxprec_ = 11, // approximately equivalent to MGRS class
60  maxlen_ = baselen_ + 2 * maxprec_
61 #if GEOGRAPHICLIB_PRECISION == 4
62  ;
63 #else
64  };
65 #endif
66  Georef() = delete; // Disable constructor
67 
68  public:
69 
70  /**
71  * Convert from geographic coordinates to georef.
72  *
73  * @param[in] lat latitude of point (degrees).
74  * @param[in] lon longitude of point (degrees).
75  * @param[in] prec the precision of the resulting georef.
76  * @param[out] georef the georef string.
77  * @exception GeographicErr if \e lat is not in [&minus;90&deg;,
78  * 90&deg;].
79  * @exception std::bad_alloc if memory for \e georef can't be allocated.
80  *
81  * \e prec specifies the precision of \e georef as follows:
82  * - \e prec = &minus;1 (min), 15&deg;
83  * - \e prec = 0, 1&deg;
84  * - \e prec = 1, converted to \e prec = 2
85  * - \e prec = 2, 1'
86  * - \e prec = 3, 0.1'
87  * - \e prec = 4, 0.01'
88  * - \e prec = 5, 0.001'
89  * - &hellip;
90  * - \e prec = 11 (max), 10<sup>&minus;9</sup>'
91  *
92  * If \e lat or \e lon is NaN, then \e georef is set to "INVALID".
93  **********************************************************************/
94  static void Forward(real lat, real lon, int prec, std::string& georef);
95 
96  /**
97  * Convert from Georef to geographic coordinates.
98  *
99  * @param[in] georef the Georef.
100  * @param[out] lat latitude of point (degrees).
101  * @param[out] lon longitude of point (degrees).
102  * @param[out] prec the precision of \e georef.
103  * @param[in] centerp if true (the default) return the center
104  * \e georef, otherwise return the south-west corner.
105  * @exception GeographicErr if \e georef is illegal.
106  *
107  * The case of the letters in \e georef is ignored. \e prec is in the
108  * range [&minus;1, 11] and gives the precision of \e georef as follows:
109  * - \e prec = &minus;1 (min), 15&deg;
110  * - \e prec = 0, 1&deg;
111  * - \e prec = 1, not returned
112  * - \e prec = 2, 1'
113  * - \e prec = 3, 0.1'
114  * - \e prec = 4, 0.01'
115  * - \e prec = 5, 0.001'
116  * - &hellip;
117  * - \e prec = 11 (max), 10<sup>&minus;9</sup>'
118  *
119  * If the first 3 characters of \e georef are "INV", then \e lat and \e lon
120  * are set to NaN and \e prec is unchanged.
121  **********************************************************************/
122  static void Reverse(const std::string& georef, real& lat, real& lon,
123  int& prec, bool centerp = true);
124 
125  /**
126  * The angular resolution of a Georef.
127  *
128  * @param[in] prec the precision of the Georef.
129  * @return the latitude-longitude resolution (degrees).
130  *
131  * Internally, \e prec is first put in the range [&minus;1, 11].
132  **********************************************************************/
133  static Math::real Resolution(int prec) {
134  if (prec < 1)
135  return real(prec < 0 ? 15 : 1);
136  else {
137  using std::pow;
138  // Treat prec = 1 as 2.
139  prec = (std::max)(2, (std::min)(int(maxprec_), prec));
140  // Need extra real because, since C++11, pow(float, int) returns double
141  return 1/(60 * real(pow(real(base_), prec - 2)));
142  }
143  }
144 
145  /**
146  * The Georef precision required to meet a given geographic resolution.
147  *
148  * @param[in] res the minimum of resolution in latitude and longitude
149  * (degrees).
150  * @return Georef precision.
151  *
152  * The returned length is in the range [0, 11].
153  **********************************************************************/
154  static int Precision(real res) {
155  using std::fabs; res = fabs(res);
156  for (int prec = 0; prec < maxprec_; ++prec) {
157  if (prec == 1)
158  continue;
159  if (Resolution(prec) <= res)
160  return prec;
161  }
162  return maxprec_;
163  }
164 
165  };
166 
167 } // namespace GeographicLib
168 
169 #if defined(_MSC_VER)
170 # pragma warning (pop)
171 #endif
172 
173 #endif // GEOGRAPHICLIB_GEOREF_HPP
Header for GeographicLib::Constants class.
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:67
GeographicLib::Math::real real
Definition: GeodSolve.cpp:31
Conversions for the World Geographic Reference System (georef)
Definition: Georef.hpp:38
static int Precision(real res)
Definition: Georef.hpp:154
static Math::real Resolution(int prec)
Definition: Georef.hpp:133
@ hd
degrees per half turn
Definition: Math.hpp:144
@ qd
degrees per quarter turn
Definition: Math.hpp:141
Namespace for GeographicLib.
Definition: Accumulator.cpp:12