GeographicLib  2.1.2
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-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_GARS_HPP)
11 #define GEOGRAPHICLIB_GARS_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 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 
39  private:
40  typedef Math::real real;
41  static const char* const digits_;
42  static const char* const letters_;
43 #if GEOGRAPHICLIB_PRECISION == 4
44  // Work around an enum lossage introduced in boost 1.76
45  // https://github.com/boostorg/multiprecision/issues/324
46  // and fixed in
47  // https://github.com/boostorg/multiprecision/pull/333
48  static const int
49 #else
50  enum {
51 #endif
52  lonorig_ = -Math::hd, // Origin for longitude
53  latorig_ = -Math::qd, // Origin for latitude
54  baselon_ = 10, // Base for longitude tiles
55  baselat_ = 24, // Base for latitude tiles
56  lonlen_ = 3,
57  latlen_ = 2,
58  baselen_ = lonlen_ + latlen_,
59  mult1_ = 2, // base precision = 1/2 degree
60  mult2_ = 2, // 6th char gives 2x more precision
61  mult3_ = 3, // 7th char gives 3x more precision
62  m_ = mult1_ * mult2_ * mult3_,
63  maxprec_ = 2,
64  maxlen_ = baselen_ + maxprec_
65 #if GEOGRAPHICLIB_PRECISION == 4
66  ;
67 #else
68  };
69 #endif
70  GARS() = delete; // Disable constructor
71 
72  public:
73 
74  /**
75  * Convert from geographic coordinates to GARS.
76  *
77  * @param[in] lat latitude of point (degrees).
78  * @param[in] lon longitude of point (degrees).
79  * @param[in] prec the precision of the resulting GARS.
80  * @param[out] gars the GARS string.
81  * @exception GeographicErr if \e lat is not in [&minus;90&deg;,
82  * 90&deg;].
83  * @exception std::bad_alloc if memory for \e gars can't be allocated.
84  *
85  * \e prec specifies the precision of \e gars as follows:
86  * - \e prec = 0 (min), 30' precision, e.g., 006AG;
87  * - \e prec = 1, 15' precision, e.g., 006AG3;
88  * - \e prec = 2 (max), 5' precision, e.g., 006AG39.
89  *
90  * If \e lat or \e lon is NaN, then \e gars is set to "INVALID".
91  **********************************************************************/
92  static void Forward(real lat, real lon, int prec, std::string& gars);
93 
94  /**
95  * Convert from GARS to geographic coordinates.
96  *
97  * @param[in] gars the GARS.
98  * @param[out] lat latitude of point (degrees).
99  * @param[out] lon longitude of point (degrees).
100  * @param[out] prec the precision of \e gars.
101  * @param[in] centerp if true (the default) return the center of the
102  * \e gars, otherwise return the south-west corner.
103  * @exception GeographicErr if \e gars is illegal.
104  *
105  * The case of the letters in \e gars is ignored. \e prec is in the range
106  * [0, 2] and gives the precision of \e gars as follows:
107  * - \e prec = 0 (min), 30' precision, e.g., 006AG;
108  * - \e prec = 1, 15' precision, e.g., 006AG3;
109  * - \e prec = 2 (max), 5' precision, e.g., 006AG39.
110  *
111  * If the first 3 characters of \e gars are "INV", then \e lat and \e lon
112  * are set to NaN and \e prec is unchanged.
113  **********************************************************************/
114  static void Reverse(const std::string& gars, real& lat, real& lon,
115  int& prec, bool centerp = true);
116 
117  /**
118  * The angular resolution of a GARS.
119  *
120  * @param[in] prec the precision of the GARS.
121  * @return the latitude-longitude resolution (degrees).
122  *
123  * Internally, \e prec is first put in the range [0, 2].
124  **********************************************************************/
125  static Math::real Resolution(int prec) {
126  return 1/real(prec <= 0 ? mult1_ : (prec == 1 ? mult1_ * mult2_ :
127  mult1_ * mult2_ * mult3_));
128  }
129 
130  /**
131  * The GARS precision required to meet a given geographic resolution.
132  *
133  * @param[in] res the minimum of resolution in latitude and longitude
134  * (degrees).
135  * @return GARS precision.
136  *
137  * The returned length is in the range [0, 2].
138  **********************************************************************/
139  static int Precision(real res) {
140  using std::fabs; res = fabs(res);
141  for (int prec = 0; prec < maxprec_; ++prec)
142  if (Resolution(prec) <= res)
143  return prec;
144  return maxprec_;
145  }
146 
147  };
148 
149 } // namespace GeographicLib
150 
151 #if defined(_MSC_VER)
152 # pragma warning (pop)
153 #endif
154 
155 #endif // GEOGRAPHICLIB_GARS_HPP
Header for GeographicLib::Constants class.
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:67
GeographicLib::Math::real real
Definition: GeodSolve.cpp:31
Conversions for the Global Area Reference System (GARS)
Definition: GARS.hpp:38
static Math::real Resolution(int prec)
Definition: GARS.hpp:125
static int Precision(real res)
Definition: GARS.hpp:139
@ 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