GeographicLib  2.6
OSGB.hpp
Go to the documentation of this file.
1 /**
2  * \file OSGB.hpp
3  * \brief Header for GeographicLib::OSGB class
4  *
5  * Copyright (c) Charles Karney (2010-2024) <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_OSGB_HPP)
11 #define GEOGRAPHICLIB_OSGB_HPP 1
12 
15 
16 namespace GeographicLib {
17 
18  /**
19  * \brief Ordnance Survey grid system for Great Britain
20  *
21  * The class implements the coordinate system used by the Ordnance Survey for
22  * maps of Great Britain and conversions to the grid reference system.
23  *
24  * See
25  * - <a href="https://www.ordnancesurvey.co.uk/documents/resources/guide-coordinate-systems-great-britain.pdf">
26  * A guide to coordinate systems in Great Britain</a>
27  * - <a href="https://www.ordnancesurvey.co.uk/documents/resources/guide-to-nationalgrid.pdf">
28  * Using the National Grid</a>
29  *
30  * \warning the latitudes and longitudes for the Ordnance Survey grid
31  * system do not use the WGS84 datum. Do not use the values returned by this
32  * class in the UTMUPS, MGRS, or Geoid classes without first converting the
33  * datum (and vice versa).
34  *
35  * Example of use:
36  * \include example-OSGB.cpp
37  **********************************************************************/
39  private:
40  typedef Math::real real;
41  static const char* const letters_;
42  static const char* const digits_;
43  static const TransverseMercator& OSGBTM();
44  static constexpr int base_ = 10;
45  static constexpr int tile_ = 100000;
46  static constexpr int tilelevel_ = 5;
47  static constexpr int tilegrid_ = 5;
48  static constexpr int tileoffx_ = 2 * tilegrid_;
49  static constexpr int tileoffy_ = 1 * tilegrid_;
50  static constexpr int minx_ = - tileoffx_ * tile_;
51  static constexpr int miny_ = - tileoffy_ * tile_;
52  static constexpr int maxx_ = (tilegrid_*tilegrid_ - tileoffx_) * tile_;
53  static constexpr int maxy_ = (tilegrid_*tilegrid_ - tileoffy_) * tile_;
54  // Maximum precision is um
55  static constexpr int maxprec_ = 5 + 6;
56  static real computenorthoffset();
57  static void CheckCoords(real x, real y);
58  OSGB() = delete; // Disable constructor
59  public:
60 
61  /**
62  * Forward projection, from geographic to OSGB coordinates.
63  *
64  * @param[in] lat latitude of point (degrees).
65  * @param[in] lon longitude of point (degrees).
66  * @param[out] x easting of point (meters).
67  * @param[out] y northing of point (meters).
68  * @param[out] gamma meridian convergence at point (degrees).
69  * @param[out] k scale of projection at point.
70  *
71  * \e lat should be in the range [&minus;90&deg;, 90&deg;].
72  **********************************************************************/
73  static void Forward(real lat, real lon,
74  real& x, real& y, real& gamma, real& k) {
75  OSGBTM().Forward(OriginLongitude(), lat, lon, x, y, gamma, k);
76  x += FalseEasting();
77  y += computenorthoffset();
78  }
79 
80  /**
81  * Reverse projection, from OSGB coordinates to geographic.
82  *
83  * @param[in] x easting of point (meters).
84  * @param[in] y northing of point (meters).
85  * @param[out] lat latitude of point (degrees).
86  * @param[out] lon longitude of point (degrees).
87  * @param[out] gamma meridian convergence at point (degrees).
88  * @param[out] k scale of projection at point.
89  *
90  * The value of \e lon returned is in the range [&minus;180&deg;,
91  * 180&deg;].
92  **********************************************************************/
93 
94  static void Reverse(real x, real y,
95  real& lat, real& lon, real& gamma, real& k) {
96  x -= FalseEasting();
97  y -= computenorthoffset();
98  OSGBTM().Reverse(OriginLongitude(), x, y, lat, lon, gamma, k);
99  }
100 
101  /**
102  * OSGB::Forward without returning the convergence and scale.
103  **********************************************************************/
104  static void Forward(real lat, real lon, real& x, real& y) {
105  real gamma, k;
106  Forward(lat, lon, x, y, gamma, k);
107  }
108 
109  /**
110  * OSGB::Reverse without returning the convergence and scale.
111  **********************************************************************/
112  static void Reverse(real x, real y, real& lat, real& lon) {
113  real gamma, k;
114  Reverse(x, y, lat, lon, gamma, k);
115  }
116 
117  /**
118  * Convert OSGB coordinates to a grid reference.
119  *
120  * @param[in] x easting of point (meters).
121  * @param[in] y northing of point (meters).
122  * @param[in] prec precision relative to 100 km.
123  * @param[out] gridref National Grid reference.
124  * @exception GeographicErr if \e prec, \e x, or \e y is outside its
125  * allowed range.
126  * @exception std::bad_alloc if the memory for \e gridref can't be
127  * allocatied.
128  *
129  * \e prec specifies the precision of the grid reference string as follows:
130  * - prec = 0 (min), 100km
131  * - prec = 1, 10km
132  * - prec = 2, 1km
133  * - prec = 3, 100m
134  * - prec = 4, 10m
135  * - prec = 5, 1m
136  * - prec = 6, 0.1m
137  * - prec = 11 (max), 1&mu;m
138  *
139  * The easting must be in the range [&minus;1000 km, 1500 km) and the
140  * northing must be in the range [&minus;500 km, 2000 km). These bounds
141  * are consistent with rules for the letter designations for the grid
142  * system.
143  *
144  * If \e x or \e y is NaN, the returned grid reference is "INVALID".
145  **********************************************************************/
146  static void GridReference(real x, real y, int prec, std::string& gridref);
147 
148  /**
149  * Convert OSGB grid reference to coordinates.
150  *
151  * @param[in] gridref National Grid reference.
152  * @param[out] x easting of point (meters).
153  * @param[out] y northing of point (meters).
154  * @param[out] prec precision relative to 100 km.
155  * @param[in] centerp if true (default), return center of the grid square,
156  * else return SW (lower left) corner.
157  * @exception GeographicErr if \e gridref is illegal.
158  *
159  * The grid reference must be of the form: two letters (not including I)
160  * followed by an even number of digits (up to 22).
161  *
162  * If the first 2 characters of \e gridref are "IN", then \e x and \e y are
163  * set to NaN and \e prec is set to &minus;2.
164  **********************************************************************/
165  static void GridReference(const std::string& gridref,
166  real& x, real& y, int& prec,
167  bool centerp = true);
168 
169  /** \name Inspector functions
170  **********************************************************************/
171  ///@{
172  /**
173  * @return \e a the equatorial radius of the Airy 1830 ellipsoid (meters).
174  *
175  * This is 20923713 ft converted to meters using the rule 1 ft =
176  * 10<sup>9.48401603&minus;10</sup> m. The Airy 1830 value is returned
177  * because the OSGB projection is based on this ellipsoid. The conversion
178  * factor from feet to meters is the one used for the 1936 retriangulation
179  * of Britain; see Section A.1 (footnote 10 on p. 44) of <i>A guide to
180  * coordinate systems in Great Britain</i>, v3.6 (2020).
181  **********************************************************************/
183  // result is about 6377563.3960320664406 m
184  using std::pow;
185  return pow(real(10), real(48401603 - 100000000) / 100000000)
186  * real(20923713);
187  }
188 
189  /**
190  * @return \e f the inverse flattening of the Airy 1830 ellipsoid.
191  *
192  * For the Airy 1830 ellipsoid, \e a = 20923713 ft and \e b = 20853810 ft;
193  * thus the flattening = (20923713 &minus; 20853810)/20923713 =
194  * 7767/2324857 = 1/299.32496459... (The Airy 1830 value is returned
195  * because the OSGB projection is based on this ellipsoid.)
196  **********************************************************************/
198  { return real(20923713 - 20853810) / real(20923713); }
199 
200  /**
201  * @return \e k0 central scale for the OSGB projection (0.9996012717...).
202  *
203  * C. J. Mugnier, Grids &amp; Datums, PE&amp;RS, Oct. 2003, states that
204  * this is defined as 10<sup>9.9998268&minus;10</sup>.
205  **********************************************************************/
207  using std::pow;
208  return pow(real(10), real(9998268 - 10000000) / 10000000);
209  }
210 
211  /**
212  * @return latitude of the origin for the OSGB projection (49 degrees).
213  **********************************************************************/
214  static Math::real OriginLatitude() { return real(49); }
215 
216  /**
217  * @return longitude of the origin for the OSGB projection (&minus;2
218  * degrees).
219  **********************************************************************/
220  static Math::real OriginLongitude() { return real(-2); }
221 
222  /**
223  * @return false northing the OSGB projection (&minus;100000 meters).
224  **********************************************************************/
225  static Math::real FalseNorthing() { return real(-100000); }
226 
227  /**
228  * @return false easting the OSGB projection (400000 meters).
229  **********************************************************************/
230  static Math::real FalseEasting() { return real(400000); }
231  ///@}
232 
233  };
234 
235 } // namespace GeographicLib
236 
237 #endif // GEOGRAPHICLIB_OSGB_HPP
static void Forward(real lat, real lon, real &x, real &y, real &gamma, real &k)
Definition: OSGB.hpp:73
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:59
static Math::real Flattening()
Definition: OSGB.hpp:197
static Math::real FalseEasting()
Definition: OSGB.hpp:230
static Math::real OriginLatitude()
Definition: OSGB.hpp:214
Transverse Mercator projection.
Header for GeographicLib::TransverseMercator class.
static Math::real CentralScale()
Definition: OSGB.hpp:206
static Math::real FalseNorthing()
Definition: OSGB.hpp:225
static Math::real OriginLongitude()
Definition: OSGB.hpp:220
void Forward(real lon0, real lat, real lon, real &x, real &y, real &gamma, real &k) const
Namespace for GeographicLib.
Definition: Accumulator.cpp:12
static Math::real EquatorialRadius()
Definition: OSGB.hpp:182
static void Reverse(real x, real y, real &lat, real &lon, real &gamma, real &k)
Definition: OSGB.hpp:94
GeographicLib::Math::real real
Definition: Geod3Solve.cpp:25
Ordnance Survey grid system for Great Britain.
Definition: OSGB.hpp:38
Header for GeographicLib::Constants class.
static void Forward(real lat, real lon, real &x, real &y)
Definition: OSGB.hpp:104
static void Reverse(real x, real y, real &lat, real &lon)
Definition: OSGB.hpp:112
void Reverse(real lon0, real x, real y, real &lat, real &lon, real &gamma, real &k) const