00001 #pragma once 00002 /** 00003 * \file NETGeographicLib/MGRS.h 00004 * \brief Header for NETGeographicLib::MGRS class 00005 * 00006 * NETGeographicLib is copyright (c) Scott Heiman (2013) 00007 * GeographicLib is Copyright (c) Charles Karney (2010-2012) 00008 * <charles@karney.com> and licensed under the MIT/X11 License. 00009 * For more information, see 00010 * http://geographiclib.sourceforge.net/ 00011 **********************************************************************/ 00012 00013 namespace NETGeographicLib 00014 { 00015 /** 00016 * \brief .NET wrapper for GeographicLib::MGRS. 00017 * 00018 * This class allows .NET applications to access GeographicLib::MGRS. 00019 * 00020 * MGRS is defined in Chapter 3 of 00021 * - J. W. Hager, L. L. Fry, S. S. Jacks, D. R. Hill, 00022 * <a href="http://earth-info.nga.mil/GandG/publications/tm8358.1/pdf/TM8358_1.pdf"> 00023 00024 * Datums, Ellipsoids, Grids, and Grid Reference Systems</a>, 00025 * Defense Mapping Agency, Technical Manual TM8358.1 (1990). 00026 * 00027 * This implementation has the following properties: 00028 * - The conversions are closed, i.e., output from Forward is legal input for 00029 * Reverse and vice versa. Conversion in both directions preserve the 00030 * UTM/UPS selection and the UTM zone. 00031 * - Forward followed by Reverse and vice versa is approximately the 00032 * identity. (This is affected in predictable ways by errors in 00033 * determining the latitude band and by loss of precision in the MGRS 00034 * coordinates.) 00035 * - All MGRS coordinates truncate to legal 100 km blocks. All MGRS 00036 * coordinates with a legal 100 km block prefix are legal (even though the 00037 * latitude band letter may now belong to a neighboring band). 00038 * - The range of UTM/UPS coordinates allowed for conversion to MGRS 00039 * coordinates is the maximum consistent with staying within the letter 00040 * ranges of the MGRS scheme. 00041 * - All the transformations are implemented as static methods in the MGRS 00042 * class. 00043 * 00044 * The <a href="http://www.nga.mil">NGA</a> software package 00045 * <a href="http://earth-info.nga.mil/GandG/geotrans/index.html">geotrans</a> 00046 * also provides conversions to and from MGRS. Version 3.0 (and earlier) 00047 * suffers from some drawbacks: 00048 * - Inconsistent rules are used to determine the whether a particular MGRS 00049 * coordinate is legal. A more systematic approach is taken here. 00050 * - The underlying projections are not very accurately implemented. 00051 * 00052 * C# Example: 00053 * \include example-MGRS.cs 00054 * Managed C++ Example: 00055 * \include example-MGRS.cpp 00056 * Visual Basic Example: 00057 * \include example-MGRS.vb 00058 * 00059 **********************************************************************/ 00060 public ref class MGRS 00061 { 00062 private: 00063 // Hide the constructor since all members are static. 00064 MGRS(void) {} 00065 public: 00066 00067 /** 00068 * Convert UTM or UPS coordinate to an MGRS coordinate. 00069 * 00070 * @param[in] zone UTM zone (zero means UPS). 00071 * @param[in] northp hemisphere (true means north, false means south). 00072 * @param[in] x easting of point (meters). 00073 * @param[in] y northing of point (meters). 00074 * @param[in] prec precision relative to 100 km. 00075 * @param[out] mgrs MGRS string. 00076 * @exception GeographicErr if \e zone, \e x, or \e y is outside its 00077 * allowed range. 00078 * @exception GeographicErr if the memory for the MGRS string can't be 00079 * allocated. 00080 * 00081 * \e prec specifies the precision of the MGRS string as follows: 00082 * - prec = −1 (min), only the grid zone is returned 00083 * - prec = 0 (min), 100 km 00084 * - prec = 1, 10 km 00085 * - prec = 2, 1 km 00086 * - prec = 3, 100 m 00087 * - prec = 4, 10 m 00088 * - prec = 5, 1 m 00089 * - prec = 6, 0.1 m 00090 * - prec = 11 (max), 1 μm 00091 * 00092 * UTM eastings are allowed to be in the range [100 km, 900 km], northings 00093 * are allowed to be in in [0 km, 9500 km] for the northern hemisphere and 00094 * in [1000 km, 10000 km] for the southern hemisphere. (However UTM 00095 * northings can be continued across the equator. So the actual limits on 00096 * the northings are [−9000 km, 9500 km] for the "northern" 00097 * hemisphere and [1000 km, 19500 km] for the "southern" hemisphere.) 00098 * 00099 * UPS eastings/northings are allowed to be in the range [1300 km, 2700 km] 00100 * in the northern hemisphere and in [800 km, 3200 km] in the southern 00101 * hemisphere. 00102 * 00103 * The ranges are 100 km more restrictive that for the conversion between 00104 * geographic coordinates and UTM and UPS given by UTMUPS. These 00105 * restrictions are dictated by the allowed letters in MGRS coordinates. 00106 * The choice of 9500 km for the maximum northing for northern hemisphere 00107 * and of 1000 km as the minimum northing for southern hemisphere provide 00108 * at least 0.5 degree extension into standard UPS zones. The upper ends 00109 * of the ranges for the UPS coordinates is dictated by requiring symmetry 00110 * about the meridians 0E and 90E. 00111 * 00112 * All allowed UTM and UPS coordinates may now be converted to legal MGRS 00113 * coordinates with the proviso that eastings and northings on the upper 00114 * boundaries are silently reduced by about 4 nm (4 nanometers) to place 00115 * them \e within the allowed range. (This includes reducing a southern 00116 * hemisphere northing of 10000 km by 4 nm so that it is placed in latitude 00117 * band M.) The UTM or UPS coordinates are truncated to requested 00118 * precision to determine the MGRS coordinate. Thus in UTM zone 38n, the 00119 * square area with easting in [444 km, 445 km) and northing in [3688 km, 00120 * 3689 km) maps to MGRS coordinate 38SMB4488 (at \e prec = 2, 1 km), 00121 * Khulani Sq., Baghdad. 00122 * 00123 * The UTM/UPS selection and the UTM zone is preserved in the conversion to 00124 * MGRS coordinate. Thus for \e zone > 0, the MGRS coordinate begins with 00125 * the zone number followed by one of [C--M] for the southern 00126 * hemisphere and [N--X] for the northern hemisphere. For \e zone = 00127 * 0, the MGRS coordinates begins with one of [AB] for the southern 00128 * hemisphere and [XY] for the northern hemisphere. 00129 * 00130 * The conversion to the MGRS is exact for prec in [0, 5] except that a 00131 * neighboring latitude band letter may be given if the point is within 5nm 00132 * of a band boundary. For prec in [6, 11], the conversion is accurate to 00133 * roundoff. 00134 * 00135 * If \e prec = -1, then the "grid zone designation", e.g., 18T, is 00136 * returned. This consists of the UTM zone number (absent for UPS) and the 00137 * first letter of the MGRS string which labels the latitude band for UTM 00138 * and the hemisphere for UPS. 00139 * 00140 * If \e x or \e y is NaN or if \e zone is UTMUPS::INVALID, the returned 00141 * MGRS string is "INVALID". 00142 * 00143 * Return the result via a reference argument to avoid the overhead of 00144 * allocating a potentially large number of small strings. If an error is 00145 * thrown, then \e mgrs is unchanged. 00146 **********************************************************************/ 00147 static void Forward(int zone, bool northp, double x, double y, 00148 int prec, 00149 [System::Runtime::InteropServices::Out] System::String^% mgrs); 00150 00151 /** 00152 * Convert UTM or UPS coordinate to an MGRS coordinate when the latitude is 00153 * known. 00154 * 00155 * @param[in] zone UTM zone (zero means UPS). 00156 * @param[in] northp hemisphere (true means north, false means south). 00157 * @param[in] x easting of point (meters). 00158 * @param[in] y northing of point (meters). 00159 * @param[in] lat latitude (degrees). 00160 * @param[in] prec precision relative to 100 km. 00161 * @param[out] mgrs MGRS string. 00162 * @exception GeographicErr if \e zone, \e x, or \e y is outside its 00163 * allowed range. 00164 * @exception GeographicErr if \e lat is inconsistent with the given UTM 00165 * coordinates. 00166 * @exception std::bad_alloc if the memory for \e mgrs can't be allocated. 00167 * 00168 * The latitude is ignored for \e zone = 0 (UPS); otherwise the latitude is 00169 * used to determine the latitude band and this is checked for consistency 00170 * using the same tests as Reverse. 00171 **********************************************************************/ 00172 static void Forward(int zone, bool northp, double x, double y, double lat, 00173 int prec, 00174 [System::Runtime::InteropServices::Out] System::String^% mgrs); 00175 00176 /** 00177 * Convert a MGRS coordinate to UTM or UPS coordinates. 00178 * 00179 * @param[in] mgrs MGRS string. 00180 * @param[out] zone UTM zone (zero means UPS). 00181 * @param[out] northp hemisphere (true means north, false means south). 00182 * @param[out] x easting of point (meters). 00183 * @param[out] y northing of point (meters). 00184 * @param[out] prec precision relative to 100 km. 00185 * @param[in] centerp if true (default), return center of the MGRS square, 00186 * else return SW (lower left) corner. 00187 * @exception GeographicErr if \e mgrs is illegal. 00188 * 00189 * All conversions from MGRS to UTM/UPS are permitted provided the MGRS 00190 * coordinate is a possible result of a conversion in the other direction. 00191 * (The leading 0 may be dropped from an input MGRS coordinate for UTM 00192 * zones 1--9.) In addition, MGRS coordinates with a neighboring 00193 * latitude band letter are permitted provided that some portion of the 00194 * 100 km block is within the given latitude band. Thus 00195 * - 38VLS and 38WLS are allowed (latitude 64N intersects the square 00196 * 38[VW]LS); but 38VMS is not permitted (all of 38VMS is north of 64N) 00197 * - 38MPE and 38NPF are permitted (they straddle the equator); but 38NPE 00198 * and 38MPF are not permitted (the equator does not intersect either 00199 * block). 00200 * - Similarly ZAB and YZB are permitted (they straddle the prime 00201 * meridian); but YAB and ZZB are not (the prime meridian does not 00202 * intersect either block). 00203 * 00204 * The UTM/UPS selection and the UTM zone is preserved in the conversion 00205 * from MGRS coordinate. The conversion is exact for prec in [0, 5]. With 00206 * centerp = true the conversion from MGRS to geographic and back is 00207 * stable. This is not assured if \e centerp = false. 00208 * 00209 * If a "grid zone designation" (for example, 18T or A) is given, then some 00210 * suitable (but essentially arbitrary) point within that grid zone is 00211 * returned. The main utility of the conversion is to allow \e zone and \e 00212 * northp to be determined. In this case, the \e centerp parameter is 00213 * ignored. 00214 * 00215 * If the first 3 characters of \e mgrs are "INV", then \e x and \e y are 00216 * set to NaN and \e zone is set to UTMUPS::INVALID. 00217 * 00218 * If an exception is thrown, then the arguments are unchanged. 00219 **********************************************************************/ 00220 static void Reverse(System::String^ mgrs, 00221 [System::Runtime::InteropServices::Out] int% zone, 00222 [System::Runtime::InteropServices::Out] bool% northp, 00223 [System::Runtime::InteropServices::Out] double% x, 00224 [System::Runtime::InteropServices::Out] double% y, 00225 [System::Runtime::InteropServices::Out] int% prec, 00226 bool centerp ); 00227 00228 /** \name Inspector functions 00229 **********************************************************************/ 00230 ///@{ 00231 /** 00232 * @return \e a the equatorial radius of the WGS84 ellipsoid (meters). 00233 * 00234 * (The WGS84 value is returned because the UTM and UPS projections are 00235 * based on this ellipsoid.) 00236 **********************************************************************/ 00237 static double MajorRadius(); 00238 00239 /** 00240 * @return \e f the flattening of the WGS84 ellipsoid. 00241 * 00242 * (The WGS84 value is returned because the UTM and UPS projections are 00243 * based on this ellipsoid.) 00244 **********************************************************************/ 00245 static double Flattening(); 00246 ///@} 00247 }; 00248 } // namespace NETGeographicLib