Georef.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /**
  2. * \file Georef.hpp
  3. * \brief Header for GeographicLib::Georef class
  4. *
  5. * Copyright (c) Charles Karney (2015-2021) <charles@karney.com> and licensed
  6. * under the MIT/X11 License. For more information, see
  7. * https://geographiclib.sourceforge.io/
  8. **********************************************************************/
  9. #if !defined(GEOGRAPHICLIB_GEOREF_HPP)
  10. #define GEOGRAPHICLIB_GEOREF_HPP 1
  11. #include <GeographicLib/Constants.hpp>
  12. #if defined(_MSC_VER)
  13. // Squelch warnings about dll vs string
  14. # pragma warning (push)
  15. # pragma warning (disable: 4251)
  16. #endif
  17. namespace GeographicLib {
  18. /**
  19. * \brief Conversions for the World Geographic Reference System (georef)
  20. *
  21. * The World Geographic Reference System is described in
  22. * - https://en.wikipedia.org/wiki/Georef
  23. * - https://web.archive.org/web/20161214054445/http://earth-info.nga.mil/GandG/coordsys/grids/georef.pdf
  24. * .
  25. * It provides a compact string representation of a geographic area
  26. * (expressed as latitude and longitude). The classes GARS and Geohash
  27. * implement similar compact representations.
  28. *
  29. * Example of use:
  30. * \include example-Georef.cpp
  31. **********************************************************************/
  32. class GEOGRAPHICLIB_EXPORT Georef {
  33. private:
  34. typedef Math::real real;
  35. static const char* const digits_;
  36. static const char* const lontile_;
  37. static const char* const lattile_;
  38. static const char* const degrees_;
  39. enum {
  40. tile_ = 15, // The size of tile in degrees
  41. lonorig_ = -180, // Origin for longitude
  42. latorig_ = -90, // Origin for latitude
  43. base_ = 10, // Base for minutes
  44. baselen_ = 4,
  45. maxprec_ = 11, // approximately equivalent to MGRS class
  46. maxlen_ = baselen_ + 2 * maxprec_,
  47. };
  48. Georef(); // Disable constructor
  49. public:
  50. /**
  51. * Convert from geographic coordinates to georef.
  52. *
  53. * @param[in] lat latitude of point (degrees).
  54. * @param[in] lon longitude of point (degrees).
  55. * @param[in] prec the precision of the resulting georef.
  56. * @param[out] georef the georef string.
  57. * @exception GeographicErr if \e lat is not in [&minus;90&deg;,
  58. * 90&deg;].
  59. * @exception std::bad_alloc if memory for \e georef can't be allocated.
  60. *
  61. * \e prec specifies the precision of \e georef as follows:
  62. * - \e prec = &minus;1 (min), 15&deg;
  63. * - \e prec = 0, 1&deg;
  64. * - \e prec = 1, converted to \e prec = 2
  65. * - \e prec = 2, 1'
  66. * - \e prec = 3, 0.1'
  67. * - \e prec = 4, 0.01'
  68. * - \e prec = 5, 0.001'
  69. * - &hellip;
  70. * - \e prec = 11 (max), 10<sup>&minus;9</sup>'
  71. *
  72. * If \e lat or \e lon is NaN, then \e georef is set to "INVALID".
  73. **********************************************************************/
  74. static void Forward(real lat, real lon, int prec, std::string& georef);
  75. /**
  76. * Convert from Georef to geographic coordinates.
  77. *
  78. * @param[in] georef the Georef.
  79. * @param[out] lat latitude of point (degrees).
  80. * @param[out] lon longitude of point (degrees).
  81. * @param[out] prec the precision of \e georef.
  82. * @param[in] centerp if true (the default) return the center
  83. * \e georef, otherwise return the south-west corner.
  84. * @exception GeographicErr if \e georef is illegal.
  85. *
  86. * The case of the letters in \e georef is ignored. \e prec is in the
  87. * range [&minus;1, 11] and gives the precision of \e georef as follows:
  88. * - \e prec = &minus;1 (min), 15&deg;
  89. * - \e prec = 0, 1&deg;
  90. * - \e prec = 1, not returned
  91. * - \e prec = 2, 1'
  92. * - \e prec = 3, 0.1'
  93. * - \e prec = 4, 0.01'
  94. * - \e prec = 5, 0.001'
  95. * - &hellip;
  96. * - \e prec = 11 (max), 10<sup>&minus;9</sup>'
  97. *
  98. * If the first 3 characters of \e georef are "INV", then \e lat and \e lon
  99. * are set to NaN and \e prec is unchanged.
  100. **********************************************************************/
  101. static void Reverse(const std::string& georef, real& lat, real& lon,
  102. int& prec, bool centerp = true);
  103. /**
  104. * The angular resolution of a Georef.
  105. *
  106. * @param[in] prec the precision of the Georef.
  107. * @return the latitude-longitude resolution (degrees).
  108. *
  109. * Internally, \e prec is first put in the range [&minus;1, 11].
  110. **********************************************************************/
  111. static Math::real Resolution(int prec) {
  112. if (prec < 1)
  113. return real(prec < 0 ? 15 : 1);
  114. else {
  115. using std::pow;
  116. // Treat prec = 1 as 2.
  117. prec = (std::max)(2, (std::min)(int(maxprec_), prec));
  118. // Need extra real because, since C++11, pow(float, int) returns double
  119. return 1/(60 * real(pow(real(base_), prec - 2)));
  120. }
  121. }
  122. /**
  123. * The Georef precision required to meet a given geographic resolution.
  124. *
  125. * @param[in] res the minimum of resolution in latitude and longitude
  126. * (degrees).
  127. * @return Georef precision.
  128. *
  129. * The returned length is in the range [0, 11].
  130. **********************************************************************/
  131. static int Precision(real res) {
  132. using std::abs; res = abs(res);
  133. for (int prec = 0; prec < maxprec_; ++prec) {
  134. if (prec == 1)
  135. continue;
  136. if (Resolution(prec) <= res)
  137. return prec;
  138. }
  139. return maxprec_;
  140. }
  141. };
  142. } // namespace GeographicLib
  143. #if defined(_MSC_VER)
  144. # pragma warning (pop)
  145. #endif
  146. #endif // GEOGRAPHICLIB_GEOREF_HPP