GeographicLib 2.1.2
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
21namespace 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