GeographicLib  1.51
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-2017) <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  * - http://earth-info.nga.mil/GandG/coordsys/grids/gars.html
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  enum {
44  lonorig_ = -180, // Origin for longitude
45  latorig_ = -90, // 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(); // 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::abs; res = abs(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
Header for GeographicLib::Constants class.
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:66
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:113
static int Precision(real res)
Definition: GARS.hpp:127
Namespace for GeographicLib.
Definition: Accumulator.cpp:12