GeographicLib
1.21
|
00001 /** 00002 * \file OSGB.hpp 00003 * \brief Header for GeographicLib::OSGB class 00004 * 00005 * Copyright (c) Charles Karney (2010, 2011) <charles@karney.com> and licensed 00006 * under the MIT/X11 License. For more information, see 00007 * http://geographiclib.sourceforge.net/ 00008 **********************************************************************/ 00009 00010 #if !defined(GEOGRAPHICLIB_OSGB_HPP) 00011 #define GEOGRAPHICLIB_OSGB_HPP "$Id: e91367e693ad63bb500c953e9c21445bef017464 $" 00012 00013 #include <string> 00014 #include <sstream> 00015 #include <GeographicLib/Constants.hpp> 00016 #include <GeographicLib/TransverseMercator.hpp> 00017 00018 #if defined(_MSC_VER) 00019 // Squelch warnings about dll vs string 00020 #pragma warning (push) 00021 #pragma warning (disable: 4251) 00022 #endif 00023 00024 namespace GeographicLib { 00025 00026 /** 00027 * \brief Ordnance Survey grid system for Great Britain 00028 * 00029 * The class implements the coordinate system used by the Ordnance Survey for 00030 * maps of Great Britain and conversions to the grid reference system. 00031 * 00032 * See 00033 * - <a href="http://www.ordnancesurvey.co.uk/oswebsite/gps/docs/A_Guide_to_Coordinate_Systems_in_Great_Britain.pdf"> 00034 * A guide to coordinate systems in Great Britain</a> 00035 * - <a href="http://www.ordnancesurvey.co.uk/oswebsite/gps/information/coordinatesystemsinfo/guidetonationalgrid/page1.html"> 00036 * Guide to National Grid</a> 00037 * 00038 * \b WARNING: the latitudes and longitudes for the Ordnance Survey grid 00039 * system do not use the WGS84 datum. Do not use the values returned by this 00040 * class in the UTMUPS, MGRS, or Geoid classes without first converting the 00041 * datum (and vice versa). 00042 * 00043 * Example of use: 00044 * \include example-OSGB.cpp 00045 **********************************************************************/ 00046 class GEOGRAPHIC_EXPORT OSGB { 00047 private: 00048 typedef Math::real real; 00049 static const std::string letters_; 00050 static const std::string digits_; 00051 static const TransverseMercator OSGBTM_; 00052 static const real northoffset_; 00053 enum { 00054 base_ = 10, 00055 tile_ = 100000, 00056 tilelevel_ = 5, 00057 tilegrid_ = 5, 00058 tileoffx_ = 2 * tilegrid_, 00059 tileoffy_ = 1 * tilegrid_, 00060 minx_ = - tileoffx_ * tile_, 00061 miny_ = - tileoffy_ * tile_, 00062 maxx_ = (tilegrid_*tilegrid_ - tileoffx_) * tile_, 00063 maxy_ = (tilegrid_*tilegrid_ - tileoffy_) * tile_, 00064 // Maximum precision is um 00065 maxprec_ = 5 + 6, 00066 }; 00067 static real computenorthoffset() throw(); 00068 static void CheckCoords(real x, real y); 00069 OSGB(); // Disable constructor 00070 00071 public: 00072 00073 /** 00074 * Forward projection, from geographic to OSGB coordinates. 00075 * 00076 * @param[in] lat latitude of point (degrees). 00077 * @param[in] lon longitude of point (degrees). 00078 * @param[out] x easting of point (meters). 00079 * @param[out] y northing of point (meters). 00080 * @param[out] gamma meridian convergence at point (degrees). 00081 * @param[out] k scale of projection at point. 00082 * 00083 * \e lat should be in the range [-90, 90]; \e lon and \e lon0 should be in 00084 * the range [-180, 360]. 00085 **********************************************************************/ 00086 static void Forward(real lat, real lon, 00087 real& x, real& y, real& gamma, real& k) throw() { 00088 OSGBTM_.Forward(OriginLongitude(), lat, lon, x, y, gamma, k); 00089 x += FalseEasting(); 00090 y += northoffset_; 00091 } 00092 00093 /** 00094 * Reverse projection, from OSGB coordinates to geographic. 00095 * 00096 * @param[in] x easting of point (meters). 00097 * @param[in] y northing of point (meters). 00098 * @param[out] lat latitude of point (degrees). 00099 * @param[out] lon longitude of point (degrees). 00100 * @param[out] gamma meridian convergence at point (degrees). 00101 * @param[out] k scale of projection at point. 00102 * 00103 * The value of \e lon returned is in the range [-180, 180). 00104 **********************************************************************/ 00105 00106 static void Reverse(real x, real y, 00107 real& lat, real& lon, real& gamma, real& k) throw() { 00108 x -= FalseEasting(); 00109 y -= northoffset_; 00110 OSGBTM_.Reverse(OriginLongitude(), x, y, lat, lon, gamma, k); 00111 } 00112 00113 /** 00114 * OSGB::Forward without returning the convergence and scale. 00115 **********************************************************************/ 00116 static void Forward(real lat, real lon, real& x, real& y) throw() { 00117 real gamma, k; 00118 Forward(lat, lon, x, y, gamma, k); 00119 } 00120 00121 /** 00122 * OSGB::Reverse without returning the convergence and scale. 00123 **********************************************************************/ 00124 static void Reverse(real x, real y, real& lat, real& lon) throw() { 00125 real gamma, k; 00126 Reverse(x, y, lat, lon, gamma, k); 00127 } 00128 00129 /** 00130 * Convert OSGB coordinates to a grid reference. 00131 * 00132 * @param[in] x easting of point (meters). 00133 * @param[in] y northing of point (meters). 00134 * @param[in] prec precision relative to 100 km. 00135 * @param[out] gridref National Grid reference. 00136 * 00137 * \e prec specifies the precision of the grid reference string as follows: 00138 * - prec = 0 (min), 100km 00139 * - prec = 1, 10km 00140 * - prec = 2, 1km 00141 * - prec = 3, 100m 00142 * - prec = 4, 10m 00143 * - prec = 5, 1m 00144 * - prec = 6, 0.1m 00145 * - prec = 11 (max), 1um 00146 * 00147 * The easting must be in the range [-1000 km, 1500 km) and the northing 00148 * must be in the range [-500 km, 2000 km). An exception is thrown if 00149 * either the easting and northing is outside these bounds. These bounds 00150 * are consistent with rules for the letter designations for the grid 00151 * system. 00152 **********************************************************************/ 00153 static void GridReference(real x, real y, int prec, std::string& gridref); 00154 00155 /** 00156 * Convert OSGB coordinates to a grid reference. 00157 * 00158 * @param[in] gridref National Grid reference. 00159 * @param[out] x easting of point (meters). 00160 * @param[out] y northing of point (meters). 00161 * @param[out] prec precision relative to 100 km. 00162 * @param[in] centerp if true (default), return center of the grid square, 00163 * else return SW (lower left) corner. 00164 * 00165 * The grid reference must be of the form: two letters (not including I) 00166 * followed by an even number of digits (up to 22). 00167 **********************************************************************/ 00168 static void GridReference(const std::string& gridref, 00169 real& x, real& y, int& prec, 00170 bool centerp = true); 00171 00172 /** \name Inspector functions 00173 **********************************************************************/ 00174 ///@{ 00175 /** 00176 * @return \e a the equatorial radius of the Airy 1830 ellipsoid (meters). 00177 * 00178 * This is 20923713 ft converted to meters using the rule 1 ft = 00179 * 10^(9.48401603-10) m. (The Airy 1830 value is returned because the OSGB 00180 * projection is based on this ellipsoid.) 00181 **********************************************************************/ 00182 static Math::real MajorRadius() throw() 00183 // result is about 6377563.3960320664406 m 00184 { return real(20923713) * std::pow(real(10), real(0.48401603L) - 1); } 00185 00186 /** 00187 * @return \e f the inverse flattening of the Airy 1830 ellipsoid. 00188 * 00189 * For the Airy 1830 ellipsoid, \e a = 20923713 ft and \e b = 20853810 ft; 00190 * thus the flattening = (20923713 - 20853810)/20923713 = 7767/2324857 = 00191 * 1/299.32496459... (The Airy 1830 value is returned because the OSGB 00192 * projection is based on this ellipsoid.) 00193 **********************************************************************/ 00194 static Math::real Flattening() throw() 00195 { return real(20923713 - 20853810) / real(20923713); } 00196 00197 /// \cond SKIP 00198 /** 00199 * <b>DEPRECATED</b> 00200 * @return \e r the inverse flattening of the Airy 1830 ellipsoid. 00201 **********************************************************************/ 00202 static Math::real InverseFlattening() throw() { return 1/Flattening(); } 00203 /// \endcond 00204 00205 /** 00206 * @return \e k0 central scale for the OSGB projection (0.9996012717). 00207 **********************************************************************/ 00208 static Math::real CentralScale() throw() 00209 { return real(0.9996012717L); } 00210 00211 /** 00212 * @return latitude of the origin for the OSGB projection (49 degrees). 00213 **********************************************************************/ 00214 static Math::real OriginLatitude() throw() { return real(49); } 00215 00216 /** 00217 * @return longitude of the origin for the OSGB projection (-2 degrees). 00218 **********************************************************************/ 00219 static Math::real OriginLongitude() throw() { return real(-2); } 00220 00221 /** 00222 * @return false northing the OSGB projection (-100000 meters). 00223 **********************************************************************/ 00224 static Math::real FalseNorthing() throw() { return real(-100000); } 00225 00226 /** 00227 * @return false easting the OSGB projection (400000 meters). 00228 **********************************************************************/ 00229 static Math::real FalseEasting() throw() { return real(400000); } 00230 ///@} 00231 00232 }; 00233 00234 } // namespace GeographicLib 00235 00236 #if defined(_MSC_VER) 00237 #pragma warning (pop) 00238 #endif 00239 00240 #endif