NETGeographicLib 1.52
Loading...
Searching...
No Matches
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 * https://geographiclib.sourceforge.io/
11 **********************************************************************/
12
13namespace 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="https://web.archive.org/web/20161214054445/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="https://earth-info.nga.mil/index.php?dir=wgs84&action=wgs84#tab_geotrans">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 EquatorialRadius();
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
.NET wrapper for GeographicLib::MGRS.
Definition: MGRS.h:61
static void Forward(int zone, bool northp, double x, double y, int prec, [System::Runtime::InteropServices::Out] System::String^% mgrs)
static double Flattening()
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 void Forward(int zone, bool northp, double x, double y, double lat, int prec, [System::Runtime::InteropServices::Out] System::String^% mgrs)
static double EquatorialRadius()