GeographicLib 2.3
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-2023) <karney@alum.mit.edu> 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 enum {
46 tile_ = 15, // The size of tile in degrees
47 lonorig_ = -Math::hd, // Origin for longitude
48 latorig_ = -Math::qd, // Origin for latitude
49 base_ = 10, // Base for minutes
50 baselen_ = 4,
51 maxprec_ = 11, // approximately equivalent to MGRS class
52 maxlen_ = baselen_ + 2 * maxprec_
53 };
54 Georef() = delete; // Disable constructor
55
56 public:
57
58 /**
59 * Convert from geographic coordinates to georef.
60 *
61 * @param[in] lat latitude of point (degrees).
62 * @param[in] lon longitude of point (degrees).
63 * @param[in] prec the precision of the resulting georef.
64 * @param[out] georef the georef string.
65 * @exception GeographicErr if \e lat is not in [&minus;90&deg;,
66 * 90&deg;].
67 * @exception std::bad_alloc if memory for \e georef can't be allocated.
68 *
69 * \e prec specifies the precision of \e georef as follows:
70 * - \e prec = &minus;1 (min), 15&deg;
71 * - \e prec = 0, 1&deg;
72 * - \e prec = 1, converted to \e prec = 2
73 * - \e prec = 2, 1'
74 * - \e prec = 3, 0.1'
75 * - \e prec = 4, 0.01'
76 * - \e prec = 5, 0.001'
77 * - &hellip;
78 * - \e prec = 11 (max), 10<sup>&minus;9</sup>'
79 *
80 * If \e lat or \e lon is NaN, then \e georef is set to "INVALID".
81 **********************************************************************/
82 static void Forward(real lat, real lon, int prec, std::string& georef);
83
84 /**
85 * Convert from Georef to geographic coordinates.
86 *
87 * @param[in] georef the Georef.
88 * @param[out] lat latitude of point (degrees).
89 * @param[out] lon longitude of point (degrees).
90 * @param[out] prec the precision of \e georef.
91 * @param[in] centerp if true (the default) return the center
92 * \e georef, otherwise return the south-west corner.
93 * @exception GeographicErr if \e georef is illegal.
94 *
95 * The case of the letters in \e georef is ignored. \e prec is in the
96 * range [&minus;1, 11] and gives the precision of \e georef as follows:
97 * - \e prec = &minus;1 (min), 15&deg;
98 * - \e prec = 0, 1&deg;
99 * - \e prec = 1, not returned
100 * - \e prec = 2, 1'
101 * - \e prec = 3, 0.1'
102 * - \e prec = 4, 0.01'
103 * - \e prec = 5, 0.001'
104 * - &hellip;
105 * - \e prec = 11 (max), 10<sup>&minus;9</sup>'
106 *
107 * If the first 3 characters of \e georef are "INV", then \e lat and \e lon
108 * are set to NaN and \e prec is unchanged.
109 **********************************************************************/
110 static void Reverse(const std::string& georef, real& lat, real& lon,
111 int& prec, bool centerp = true);
112
113 /**
114 * The angular resolution of a Georef.
115 *
116 * @param[in] prec the precision of the Georef.
117 * @return the latitude-longitude resolution (degrees).
118 *
119 * Internally, \e prec is first put in the range [&minus;1, 11].
120 **********************************************************************/
121 static Math::real Resolution(int prec) {
122 if (prec < 1)
123 return real(prec < 0 ? 15 : 1);
124 else {
125 using std::pow;
126 // Treat prec = 1 as 2.
127 prec = (std::max)(2, (std::min)(int(maxprec_), prec));
128 // Need extra real because, since C++11, pow(float, int) returns double
129 return 1/(60 * real(pow(real(base_), prec - 2)));
130 }
131 }
132
133 /**
134 * The Georef precision required to meet a given geographic resolution.
135 *
136 * @param[in] res the minimum of resolution in latitude and longitude
137 * (degrees).
138 * @return Georef precision.
139 *
140 * The returned length is in the range [0, 11].
141 **********************************************************************/
142 static int Precision(real res) {
143 using std::fabs; res = fabs(res);
144 for (int prec = 0; prec < maxprec_; ++prec) {
145 if (prec == 1)
146 continue;
147 if (Resolution(prec) <= res)
148 return prec;
149 }
150 return maxprec_;
151 }
152
153 };
154
155} // namespace GeographicLib
156
157#if defined(_MSC_VER)
158# pragma warning (pop)
159#endif
160
161#endif // GEOGRAPHICLIB_GEOREF_HPP
Header for GeographicLib::Constants class.
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:67
GeographicLib::Math::real real
Definition: GeodSolve.cpp:29
Conversions for the World Geographic Reference System (georef)
Definition: Georef.hpp:38
static int Precision(real res)
Definition: Georef.hpp:142
static Math::real Resolution(int prec)
Definition: Georef.hpp:121
@ hd
degrees per half turn
Definition: Math.hpp:141
@ qd
degrees per quarter turn
Definition: Math.hpp:138
Namespace for GeographicLib.
Definition: Accumulator.cpp:12