GeographicLib 2.3

GARS.hpp
Go to the documentation of this file.
1/**
2 * \file GARS.hpp
3 * \brief Header for GeographicLib::GARS 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_GARS_HPP)
11#define GEOGRAPHICLIB_GARS_HPP 1
12
13#include <GeographicLib/Constants.hpp>
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 Global Area Reference System (GARS)
25 *
26 * The Global Area Reference System is described in
27 * - https://en.wikipedia.org/wiki/Global_Area_Reference_System
28 * - https://earth-info.nga.mil/index.php?dir=coordsys&action=coordsys#tab_gars
29 * .
30 * It provides a compact string representation of a geographic area
31 * (expressed as latitude and longitude). The classes Georef and Geohash
32 * implement similar compact representations.
33 *
34 * Example of use:
35 * \include example-GARS.cpp
36 **********************************************************************/
37
38 class GEOGRAPHICLIB_EXPORT GARS {
39 private:
40 typedef Math::real real;
41 static const char* const digits_;
42 static const char* const letters_;
43 enum {
44 lonorig_ = -Math::hd, // Origin for longitude
45 latorig_ = -Math::qd, // Origin for latitude
46 baselon_ = 10, // Base for longitude tiles
47 baselat_ = 24, // Base for latitude tiles
48 lonlen_ = 3,
49 latlen_ = 2,
50 baselen_ = lonlen_ + latlen_,
51 mult1_ = 2, // base precision = 1/2 degree
52 mult2_ = 2, // 6th char gives 2x more precision
53 mult3_ = 3, // 7th char gives 3x more precision
54 m_ = mult1_ * mult2_ * mult3_,
55 maxprec_ = 2,
56 maxlen_ = baselen_ + maxprec_
57 };
58 GARS() = delete; // Disable constructor
59
60 public:
61
62 /**
63 * Convert from geographic coordinates to GARS.
64 *
65 * @param[in] lat latitude of point (degrees).
66 * @param[in] lon longitude of point (degrees).
67 * @param[in] prec the precision of the resulting GARS.
68 * @param[out] gars the GARS string.
69 * @exception GeographicErr if \e lat is not in [&minus;90&deg;,
70 * 90&deg;].
71 * @exception std::bad_alloc if memory for \e gars can't be allocated.
72 *
73 * \e prec specifies the precision of \e gars as follows:
74 * - \e prec = 0 (min), 30' precision, e.g., 006AG;
75 * - \e prec = 1, 15' precision, e.g., 006AG3;
76 * - \e prec = 2 (max), 5' precision, e.g., 006AG39.
77 *
78 * If \e lat or \e lon is NaN, then \e gars is set to "INVALID".
79 **********************************************************************/
80 static void Forward(real lat, real lon, int prec, std::string& gars);
81
82 /**
83 * Convert from GARS to geographic coordinates.
84 *
85 * @param[in] gars the GARS.
86 * @param[out] lat latitude of point (degrees).
87 * @param[out] lon longitude of point (degrees).
88 * @param[out] prec the precision of \e gars.
89 * @param[in] centerp if true (the default) return the center of the
90 * \e gars, otherwise return the south-west corner.
91 * @exception GeographicErr if \e gars is illegal.
92 *
93 * The case of the letters in \e gars is ignored. \e prec is in the range
94 * [0, 2] and gives the precision of \e gars as follows:
95 * - \e prec = 0 (min), 30' precision, e.g., 006AG;
96 * - \e prec = 1, 15' precision, e.g., 006AG3;
97 * - \e prec = 2 (max), 5' precision, e.g., 006AG39.
98 *
99 * If the first 3 characters of \e gars are "INV", then \e lat and \e lon
100 * are set to NaN and \e prec is unchanged.
101 **********************************************************************/
102 static void Reverse(const std::string& gars, real& lat, real& lon,
103 int& prec, bool centerp = true);
104
105 /**
106 * The angular resolution of a GARS.
107 *
108 * @param[in] prec the precision of the GARS.
109 * @return the latitude-longitude resolution (degrees).
110 *
111 * Internally, \e prec is first put in the range [0, 2].
112 **********************************************************************/
113 static Math::real Resolution(int prec) {
114 return 1/real(prec <= 0 ? mult1_ : (prec == 1 ? mult1_ * mult2_ :
115 mult1_ * mult2_ * mult3_));
116 }
117
118 /**
119 * The GARS precision required to meet a given geographic resolution.
120 *
121 * @param[in] res the minimum of resolution in latitude and longitude
122 * (degrees).
123 * @return GARS precision.
124 *
125 * The returned length is in the range [0, 2].
126 **********************************************************************/
127 static int Precision(real res) {
128 using std::fabs; res = fabs(res);
129 for (int prec = 0; prec < maxprec_; ++prec)
130 if (Resolution(prec) <= res)
131 return prec;
132 return maxprec_;
133 }
134
135 };
136
137} // namespace GeographicLib
138
139#if defined(_MSC_VER)
140# pragma warning (pop)
141#endif
142
143#endif // GEOGRAPHICLIB_GARS_HPP
Constants.hpp
Header for GeographicLib::Constants class.
GEOGRAPHICLIB_EXPORT
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:67
real
GeographicLib::Math::real real
Definition: GeodSolve.cpp:29
GeographicLib::GARS
Conversions for the Global Area Reference System (GARS)
Definition: GARS.hpp:38
GeographicLib::GARS::Resolution
static Math::real Resolution(int prec)
Definition: GARS.hpp:113
GeographicLib::GARS::Precision
static int Precision(real res)
Definition: GARS.hpp:127
GeographicLib::Math::real
double real
Definition: Math.hpp:100
GeographicLib::Math::hd
@ hd
degrees per half turn
Definition: Math.hpp:141
GeographicLib::Math::qd
@ qd
degrees per quarter turn
Definition: Math.hpp:138
GeographicLib
Namespace for GeographicLib.
Definition: Accumulator.cpp:12