NETGeographicLib  1.43
MGRS.h
Go to the documentation of this file.
1 #pragma once
2 /**
3  * \file NETGeographicLib/MGRS.h
4  * \brief Header for NETGeographicLib::MGRS class
5  *
6  * NETGeographicLib is copyright (c) Scott Heiman (2013)
7  * GeographicLib is Copyright (c) Charles Karney (2010-2012)
8  * <charles@karney.com> and licensed under the MIT/X11 License.
9  * For more information, see
10  * http://geographiclib.sourceforge.net/
11  **********************************************************************/
12 
13 namespace NETGeographicLib
14 {
15  /**
16  * \brief .NET wrapper for GeographicLib::MGRS.
17  *
18  * This class allows .NET applications to access GeographicLib::MGRS.
19  *
20  * MGRS is defined in Chapter 3 of
21  * - J. W. Hager, L. L. Fry, S. S. Jacks, D. R. Hill,
22  * <a href="http://earth-info.nga.mil/GandG/publications/tm8358.1/pdf/TM8358_1.pdf">
23 
24  * Datums, Ellipsoids, Grids, and Grid Reference Systems</a>,
25  * Defense Mapping Agency, Technical Manual TM8358.1 (1990).
26  *
27  * This implementation has the following properties:
28  * - The conversions are closed, i.e., output from Forward is legal input for
29  * Reverse and vice versa. Conversion in both directions preserve the
30  * UTM/UPS selection and the UTM zone.
31  * - Forward followed by Reverse and vice versa is approximately the
32  * identity. (This is affected in predictable ways by errors in
33  * determining the latitude band and by loss of precision in the MGRS
34  * coordinates.)
35  * - All MGRS coordinates truncate to legal 100 km blocks. All MGRS
36  * coordinates with a legal 100 km block prefix are legal (even though the
37  * latitude band letter may now belong to a neighboring band).
38  * - The range of UTM/UPS coordinates allowed for conversion to MGRS
39  * coordinates is the maximum consistent with staying within the letter
40  * ranges of the MGRS scheme.
41  * - All the transformations are implemented as static methods in the MGRS
42  * class.
43  *
44  * The <a href="http://www.nga.mil">NGA</a> software package
45  * <a href="http://earth-info.nga.mil/GandG/geotrans/index.html">geotrans</a>
46  * also provides conversions to and from MGRS. Version 3.0 (and earlier)
47  * suffers from some drawbacks:
48  * - Inconsistent rules are used to determine the whether a particular MGRS
49  * coordinate is legal. A more systematic approach is taken here.
50  * - The underlying projections are not very accurately implemented.
51  *
52  * C# Example:
53  * \include example-MGRS.cs
54  * Managed C++ Example:
55  * \include example-MGRS.cpp
56  * Visual Basic Example:
57  * \include example-MGRS.vb
58  *
59  **********************************************************************/
60  public ref class MGRS
61  {
62  private:
63  // Hide the constructor since all members are static.
64  MGRS(void) {}
65  public:
66 
67  /**
68  * Convert UTM or UPS coordinate to an MGRS coordinate.
69  *
70  * @param[in] zone UTM zone (zero means UPS).
71  * @param[in] northp hemisphere (true means north, false means south).
72  * @param[in] x easting of point (meters).
73  * @param[in] y northing of point (meters).
74  * @param[in] prec precision relative to 100 km.
75  * @param[out] mgrs MGRS string.
76  * @exception GeographicErr if \e zone, \e x, or \e y is outside its
77  * allowed range.
78  * @exception GeographicErr if the memory for the MGRS string can't be
79  * allocated.
80  *
81  * \e prec specifies the precision of the MGRS string as follows:
82  * - prec = &minus;1 (min), only the grid zone is returned
83  * - prec = 0 (min), 100 km
84  * - prec = 1, 10 km
85  * - prec = 2, 1 km
86  * - prec = 3, 100 m
87  * - prec = 4, 10 m
88  * - prec = 5, 1 m
89  * - prec = 6, 0.1 m
90  * - prec = 11 (max), 1 &mu;m
91  *
92  * UTM eastings are allowed to be in the range [100 km, 900 km], northings
93  * are allowed to be in in [0 km, 9500 km] for the northern hemisphere and
94  * in [1000 km, 10000 km] for the southern hemisphere. (However UTM
95  * northings can be continued across the equator. So the actual limits on
96  * the northings are [&minus;9000 km, 9500 km] for the "northern"
97  * hemisphere and [1000 km, 19500 km] for the "southern" hemisphere.)
98  *
99  * UPS eastings/northings are allowed to be in the range [1300 km, 2700 km]
100  * in the northern hemisphere and in [800 km, 3200 km] in the southern
101  * hemisphere.
102  *
103  * The ranges are 100 km more restrictive that for the conversion between
104  * geographic coordinates and UTM and UPS given by UTMUPS. These
105  * restrictions are dictated by the allowed letters in MGRS coordinates.
106  * The choice of 9500 km for the maximum northing for northern hemisphere
107  * and of 1000 km as the minimum northing for southern hemisphere provide
108  * at least 0.5 degree extension into standard UPS zones. The upper ends
109  * of the ranges for the UPS coordinates is dictated by requiring symmetry
110  * about the meridians 0E and 90E.
111  *
112  * All allowed UTM and UPS coordinates may now be converted to legal MGRS
113  * coordinates with the proviso that eastings and northings on the upper
114  * boundaries are silently reduced by about 4 nm (4 nanometers) to place
115  * them \e within the allowed range. (This includes reducing a southern
116  * hemisphere northing of 10000 km by 4 nm so that it is placed in latitude
117  * band M.) The UTM or UPS coordinates are truncated to requested
118  * precision to determine the MGRS coordinate. Thus in UTM zone 38n, the
119  * square area with easting in [444 km, 445 km) and northing in [3688 km,
120  * 3689 km) maps to MGRS coordinate 38SMB4488 (at \e prec = 2, 1 km),
121  * Khulani Sq., Baghdad.
122  *
123  * The UTM/UPS selection and the UTM zone is preserved in the conversion to
124  * MGRS coordinate. Thus for \e zone > 0, the MGRS coordinate begins with
125  * the zone number followed by one of [C--M] for the southern
126  * hemisphere and [N--X] for the northern hemisphere. For \e zone =
127  * 0, the MGRS coordinates begins with one of [AB] for the southern
128  * hemisphere and [XY] for the northern hemisphere.
129  *
130  * The conversion to the MGRS is exact for prec in [0, 5] except that a
131  * neighboring latitude band letter may be given if the point is within 5nm
132  * of a band boundary. For prec in [6, 11], the conversion is accurate to
133  * roundoff.
134  *
135  * If \e prec = &minus;1, then the "grid zone designation", e.g., 18T, is
136  * returned. This consists of the UTM zone number (absent for UPS) and the
137  * first letter of the MGRS string which labels the latitude band for UTM
138  * and the hemisphere for UPS.
139  *
140  * If \e x or \e y is NaN or if \e zone is UTMUPS::INVALID, the returned
141  * MGRS string is "INVALID".
142  *
143  * Return the result via a reference argument to avoid the overhead of
144  * allocating a potentially large number of small strings. If an error is
145  * thrown, then \e mgrs is unchanged.
146  **********************************************************************/
147  static void Forward(int zone, bool northp, double x, double y,
148  int prec,
149  [System::Runtime::InteropServices::Out] System::String^% mgrs);
150 
151  /**
152  * Convert UTM or UPS coordinate to an MGRS coordinate when the latitude is
153  * known.
154  *
155  * @param[in] zone UTM zone (zero means UPS).
156  * @param[in] northp hemisphere (true means north, false means south).
157  * @param[in] x easting of point (meters).
158  * @param[in] y northing of point (meters).
159  * @param[in] lat latitude (degrees).
160  * @param[in] prec precision relative to 100 km.
161  * @param[out] mgrs MGRS string.
162  * @exception GeographicErr if \e zone, \e x, or \e y is outside its
163  * allowed range.
164  * @exception GeographicErr if \e lat is inconsistent with the given UTM
165  * coordinates.
166  * @exception std::bad_alloc if the memory for \e mgrs can't be allocated.
167  *
168  * The latitude is ignored for \e zone = 0 (UPS); otherwise the latitude is
169  * used to determine the latitude band and this is checked for consistency
170  * using the same tests as Reverse.
171  **********************************************************************/
172  static void Forward(int zone, bool northp, double x, double y, double lat,
173  int prec,
174  [System::Runtime::InteropServices::Out] System::String^% mgrs);
175 
176  /**
177  * Convert a MGRS coordinate to UTM or UPS coordinates.
178  *
179  * @param[in] mgrs MGRS string.
180  * @param[out] zone UTM zone (zero means UPS).
181  * @param[out] northp hemisphere (true means north, false means south).
182  * @param[out] x easting of point (meters).
183  * @param[out] y northing of point (meters).
184  * @param[out] prec precision relative to 100 km.
185  * @param[in] centerp if true (default), return center of the MGRS square,
186  * else return SW (lower left) corner.
187  * @exception GeographicErr if \e mgrs is illegal.
188  *
189  * All conversions from MGRS to UTM/UPS are permitted provided the MGRS
190  * coordinate is a possible result of a conversion in the other direction.
191  * (The leading 0 may be dropped from an input MGRS coordinate for UTM
192  * zones 1--9.) In addition, MGRS coordinates with a neighboring
193  * latitude band letter are permitted provided that some portion of the
194  * 100 km block is within the given latitude band. Thus
195  * - 38VLS and 38WLS are allowed (latitude 64N intersects the square
196  * 38[VW]LS); but 38VMS is not permitted (all of 38VMS is north of 64N)
197  * - 38MPE and 38NPF are permitted (they straddle the equator); but 38NPE
198  * and 38MPF are not permitted (the equator does not intersect either
199  * block).
200  * - Similarly ZAB and YZB are permitted (they straddle the prime
201  * meridian); but YAB and ZZB are not (the prime meridian does not
202  * intersect either block).
203  *
204  * The UTM/UPS selection and the UTM zone is preserved in the conversion
205  * from MGRS coordinate. The conversion is exact for prec in [0, 5]. With
206  * centerp = true the conversion from MGRS to geographic and back is
207  * stable. This is not assured if \e centerp = false.
208  *
209  * If a "grid zone designation" (for example, 18T or A) is given, then some
210  * suitable (but essentially arbitrary) point within that grid zone is
211  * returned. The main utility of the conversion is to allow \e zone and \e
212  * northp to be determined. In this case, the \e centerp parameter is
213  * ignored and \e prec is set to &minus;1.
214  *
215  * If the first 3 characters of \e mgrs are "INV", then \e x and \e y are
216  * set to NaN, \e zone is set to UTMUPS::INVALID, and \e prec is set to
217  * &minus;2.
218  *
219  * If an exception is thrown, then the arguments are unchanged.
220  **********************************************************************/
221  static void Reverse(System::String^ mgrs,
222  [System::Runtime::InteropServices::Out] int% zone,
223  [System::Runtime::InteropServices::Out] bool% northp,
224  [System::Runtime::InteropServices::Out] double% x,
225  [System::Runtime::InteropServices::Out] double% y,
226  [System::Runtime::InteropServices::Out] int% prec,
227  bool centerp );
228 
229  /** \name Inspector functions
230  **********************************************************************/
231  ///@{
232  /**
233  * @return \e a the equatorial radius of the WGS84 ellipsoid (meters).
234  *
235  * (The WGS84 value is returned because the UTM and UPS projections are
236  * based on this ellipsoid.)
237  **********************************************************************/
238  static double MajorRadius();
239 
240  /**
241  * @return \e f the flattening of the WGS84 ellipsoid.
242  *
243  * (The WGS84 value is returned because the UTM and UPS projections are
244  * based on this ellipsoid.)
245  **********************************************************************/
246  static double Flattening();
247  ///@}
248  };
249 } // namespace NETGeographicLib
static void Reverse(System::String^ mgrs, [System::Runtime::InteropServices::Out] int% zone, [System::Runtime::InteropServices::Out] bool% northp, [System::Runtime::InteropServices::Out] double% x, [System::Runtime::InteropServices::Out] double% y, [System::Runtime::InteropServices::Out] int% prec, bool centerp)
static double Flattening()
static double MajorRadius()
static void Forward(int zone, bool northp, double x, double y, int prec, [System::Runtime::InteropServices::Out] System::String^% mgrs)
.NET wrapper for GeographicLib::MGRS.
Definition: MGRS.h:60