NETGeographicLib  1.38
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Pages
GeoCoords.h
Go to the documentation of this file.
1 /**
2  * \file NETGeographicLib/GeoCoords.h
3  * \brief Header for NETGeographicLib::GeoCoords class
4  *
5  * NETGeographicLib is copyright (c) Scott Heiman (2013)
6  * GeographicLib is Copyright (c) Charles Karney (2010-2012)
7  * <charles@karney.com> and licensed under the MIT/X11 License.
8  * For more information, see
9  * http://geographiclib.sourceforge.net/
10  **********************************************************************/
11 #pragma once
12 
13 namespace NETGeographicLib
14 {
15  /**
16  * \brief .NET wrapper for GeographicLib::GeoCoords.
17  *
18  * This class allows .NET applications to access GeographicLib::GeoCoords.
19  *
20  * This class stores a geographic position which may be set via the
21  * constructors or Reset via
22  * - latitude and longitude
23  * - UTM or UPS coordinates
24  * - a string representation of these or an MGRS coordinate string
25  *
26  * The state consists of the latitude and longitude and the supplied UTM or
27  * UPS coordinates (possibly derived from the MGRS coordinates). If latitude
28  * and longitude were given then the UTM/UPS coordinates follows the standard
29  * conventions.
30  *
31  * The mutable state consists of the UTM or UPS coordinates for a alternate
32  * zone. A method SetAltZone is provided to set the alternate UPS/UTM zone.
33  *
34  * Methods are provided to return the geographic coordinates, the input UTM
35  * or UPS coordinates (and associated meridian convergence and scale), or
36  * alternate UTM or UPS coordinates (and their associated meridian
37  * convergence and scale).
38  *
39  * Once the input string has been parsed, you can print the result out in any
40  * of the formats, decimal degrees, degrees minutes seconds, MGRS, UTM/UPS.
41  *
42  * C# Example:
43  * \include example-GeoCoords.cs
44  * Managed C++ Example:
45  * \include example-GeoCoords.cpp
46  * Visual Basic Example:
47  * \include example-GeoCoords.vb
48  *
49  * <B>INTERFACE DIFFERENCES:</B><BR>
50  * The following functions are implemented as properties: MajorRadius,
51  * Flattening, Latitude, Longitude, Easting, Northing, Convergence,
52  * Scale, Northp, Hemisphere, Zone, AltZone, AltEasting, AltNorthing,
53  * AltConvergence, and AltScale.
54  **********************************************************************/
55  public ref class GeoCoords
56  {
57  private:
58  // pointer to the unmanaged GeographicLib::GeoCoords
59  GeographicLib::GeoCoords* m_pGeoCoords;
60 
61  // The finalizer frees unmanaged memory when the object is destroyed.
62  !GeoCoords();
63  public:
64  /** \name Initializing the GeoCoords object
65  **********************************************************************/
66  ///@{
67  /**
68  * The default constructor is equivalent to \e latitude = 90&deg;,
69  * \e longitude = 0&deg;.
70  **********************************************************************/
71  GeoCoords();
72 
73  /**
74  * Construct from a string.
75  *
76  * @param[in] s 1-element, 2-element, or 3-element string representation of
77  * the position.
78  * @param[in] centerp governs the interpretation of MGRS coordinates (see
79  * below).
80  * @param[in] swaplatlong governs the interpretation of geographic
81  * coordinates (see below).
82  * @exception GeographicErr if the \e s is malformed (see below).
83  *
84  * Parse as a string and interpret it as a geographic position. The input
85  * string is broken into space (or comma) separated pieces and Basic
86  * decision on which format is based on number of components
87  * -# MGRS
88  * -# "Lat Long" or "Long Lat"
89  * -# "Zone Easting Northing" or "Easting Northing Zone"
90  *
91  * The following inputs are approximately the same (Ar Ramadi Bridge, Iraq)
92  * - Latitude and Longitude
93  * - 33.44 43.27
94  * - N33d26.4' E43d16.2'
95  * - 43d16'12&quot;E 33d26'24&quot;N
96  * - 43:16:12E 33:26:24
97  * - MGRS
98  * - 38SLC30
99  * - 38SLC391014
100  * - 38SLC3918701405
101  * - 37SHT9708
102  * - UTM
103  * - 38N 339188 3701405
104  * - 897039 3708229 37N
105  *
106  * <b>Latitude and Longitude parsing</b>: Latitude precedes longitude,
107  * unless a N, S, E, W hemisphere designator is used on one or both
108  * coordinates. If \e swaplatlong = true (default is false), then
109  * longitude precedes latitude in the absence of a hemisphere designator.
110  * Thus (with \e swaplatlong = false)
111  * - 40 -75
112  * - N40 W75
113  * - -75 N40
114  * - 75W 40N
115  * - E-75 -40S
116  * .
117  * are all the same position. The coordinates may be given in
118  * decimal degrees, degrees and decimal minutes, degrees, minutes,
119  * seconds, etc. Use d, ', and &quot; to mark off the degrees,
120  * minutes and seconds. Various alternative symbols for degrees, minutes,
121  * and seconds are allowed. Alternatively, use : to separate these
122  * components. (See DMS::Decode for details.) Thus
123  * - 40d30'30&quot;
124  * - 40d30'30
125  * - 40&deg;30'30
126  * - 40d30.5'
127  * - 40d30.5
128  * - 40:30:30
129  * - 40:30.5
130  * - 40.508333333
131  * .
132  * all specify the same angle. The leading sign applies to all components
133  * so -1d30 is -(1+30/60) = -1.5. Latitudes must be in the range
134  * [&minus;90&deg;, 90&deg;] and longitudes in the range
135  * [&minus;540&deg;, 540&deg;). Internally longitudes are reduced
136  * to the range [&minus;180&deg;, 180&deg;).
137  *
138  * <b>UTM/UPS parsing</b>: For UTM zones (&minus;80&deg; &le; Lat <
139  * 84&deg;), the zone designator is made up of a zone number (for 1 to 60)
140  * and a hemisphere letter (N or S), e.g., 38N. The latitude zone designer
141  * ([C--M] in the southern hemisphere and [N--X] in the northern) should
142  * NOT be used. (This is part of the MGRS coordinate.) The zone
143  * designator for the poles (where UPS is employed) is a hemisphere letter
144  * by itself, i.e., N or S.
145  *
146  * <b>MGRS parsing</b> interprets the grid references as square area at the
147  * specified precision (1m, 10m, 100m, etc.). If \e centerp = true (the
148  * default), the center of this square is then taken to be the precise
149  * position; thus:
150  * - 38SMB = 38N 450000 3650000
151  * - 38SMB4484 = 38N 444500 3684500
152  * - 38SMB44148470 = 38N 444145 3684705
153  * .
154  * Otherwise, the "south-west" corner of the square is used, i.e.,
155  * - 38SMB = 38N 400000 3600000
156  * - 38SMB4484 = 38N 444000 3684000
157  * - 38SMB44148470 = 38N 444140 3684700
158  **********************************************************************/
159  GeoCoords(System::String^ s, bool centerp, bool swaplatlong );
160 
161  /**
162  * Construct from geographic coordinates.
163  *
164  * @param[in] latitude (degrees).
165  * @param[in] longitude (degrees).
166  * @param[in] zone if specified, force the UTM/UPS representation to use a
167  * specified zone using the rules given in UTMUPS::zonespec.
168  * @exception GeographicErr if \e latitude is not in [&minus;90&deg;,
169  * 90&deg;].
170  * @exception GeographicErr if \e longitude is not in [&minus;540&deg;,
171  * 540&deg;).
172  * @exception GeographicErr if \e zone cannot be used for this location.
173  **********************************************************************/
174  GeoCoords(double latitude, double longitude, int zone );
175 
176  /**
177  * Construct from UTM/UPS coordinates.
178  *
179  * @param[in] zone UTM zone (zero means UPS).
180  * @param[in] northp hemisphere (true means north, false means south).
181  * @param[in] easting (meters).
182  * @param[in] northing (meters).
183  * @exception GeographicErr if \e zone, \e easting, or \e northing is
184  * outside its allowed range.
185  **********************************************************************/
186  GeoCoords(int zone, bool northp, double easting, double northing);
187 
188  /**
189  * The destructor calls the finalizer.
190  **********************************************************************/
191  ~GeoCoords() { this->!GeoCoords(); }
192 
193  /**
194  * Reset the location from a string. See
195  * GeoCoords(const std::string& s, bool centerp, bool swaplatlong).
196  *
197  * @param[in] s 1-element, 2-element, or 3-element string representation of
198  * the position.
199  * @param[in] centerp governs the interpretation of MGRS coordinates.
200  * @param[in] swaplatlong governs the interpretation of geographic
201  * coordinates.
202  * @exception GeographicErr if the \e s is malformed.
203  **********************************************************************/
204  void Reset( System::String^ s, bool centerp, bool swaplatlong);
205 
206  /**
207  * Reset the location in terms of geographic coordinates. See
208  * GeoCoords(double latitude, double longitude, int zone).
209  *
210  * @param[in] latitude (degrees).
211  * @param[in] longitude (degrees).
212  * @param[in] zone if specified, force the UTM/UPS representation to use a
213  * specified zone using the rules given in UTMUPS::zonespec.
214  * @exception GeographicErr if \e latitude is not in [&minus;90&deg;,
215  * 90&deg;].
216  * @exception GeographicErr if \e longitude is not in [&minus;540&deg;,
217  * 540&deg;).
218  * @exception GeographicErr if \e zone cannot be used for this location.
219  **********************************************************************/
220  void Reset(double latitude, double longitude, int zone ) ;
221 
222  /**
223  * Reset the location in terms of UPS/UPS coordinates. See
224  * GeoCoords(int zone, bool northp, double easting, double northing).
225  *
226  * @param[in] zone UTM zone (zero means UPS).
227  * @param[in] northp hemisphere (true means north, false means south).
228  * @param[in] easting (meters).
229  * @param[in] northing (meters).
230  * @exception GeographicErr if \e zone, \e easting, or \e northing is
231  * outside its allowed range.
232  **********************************************************************/
233  void Reset(int zone, bool northp, double easting, double northing);
234  ///@}
235 
236  /** \name Querying the GeoCoords object
237  **********************************************************************/
238  ///@{
239  /**
240  * @return latitude (degrees)
241  **********************************************************************/
242  property double Latitude { double get(); }
243 
244  /**
245  * @return longitude (degrees)
246  **********************************************************************/
247  property double Longitude { double get(); }
248 
249  /**
250  * @return easting (meters)
251  **********************************************************************/
252  property double Easting { double get(); }
253 
254  /**
255  * @return northing (meters)
256  **********************************************************************/
257  property double Northing { double get(); }
258 
259  /**
260  * @return meridian convergence (degrees) for the UTM/UPS projection.
261  **********************************************************************/
262  property double Convergence { double get(); }
263 
264  /**
265  * @return scale for the UTM/UPS projection.
266  **********************************************************************/
267  property double Scale { double get(); }
268 
269  /**
270  * @return hemisphere (false means south, true means north).
271  **********************************************************************/
272  property bool Northp { bool get(); }
273 
274  /**
275  * @return hemisphere letter N or S.
276  **********************************************************************/
277  property char Hemisphere { char get(); }
278 
279  /**
280  * @return the zone corresponding to the input (return 0 for UPS).
281  **********************************************************************/
282  property int Zone { int get(); }
283 
284  /**
285  * Gets/Sets the current alternate zone (0 = UPS).
286  * @exception GeographicErr if \e zone cannot be used for this location.
287  *
288  * See UTMUPS::zonespec for more information on the interpretation of \e
289  * zone. Note that \e zone == UTMUPS::STANDARD (the default) use the
290  * standard UPS or UTM zone, UTMUPS::MATCH does nothing retaining the
291  * existing alternate representation. Before this is called the alternate
292  * zone is the input zone.
293  **********************************************************************/
294  property int AltZone
295  {
296  int get();
297  void set( int zone );
298  }
299  ///@}
300 
301  /**
302  * @return easting (meters) for alternate zone.
303  **********************************************************************/
304  property double AltEasting { double get(); }
305 
306  /**
307  * @return northing (meters) for alternate zone.
308  **********************************************************************/
309  property double AltNorthing { double get(); }
310 
311  /**
312  * @return meridian convergence (degrees) for alternate zone.
313  **********************************************************************/
314  property double AltConvergence { double get(); }
315 
316  /**
317  * @return scale for alternate zone.
318  **********************************************************************/
319  property double AltScale { double get(); }
320  ///@}
321 
322  /** \name String representations of the GeoCoords object
323  **********************************************************************/
324  ///@{
325  /**
326  * String representation with latitude and longitude as signed decimal
327  * degrees.
328  *
329  * @param[in] prec precision (relative to about 1m).
330  * @param[in] swaplatlong if true give longitude first (default = false)
331  * @exception std::bad_alloc if memory for the string can't be allocated.
332  * @return decimal latitude/longitude string representation.
333  *
334  * Precision specifies accuracy of representation as follows:
335  * - prec = &minus;5 (min), 1&deg;
336  * - prec = 0, 10<sup>&minus;5</sup>&deg; (about 1m)
337  * - prec = 3, 10<sup>&minus;8</sup>&deg;
338  * - prec = 9 (max), 10<sup>&minus;14</sup>&deg;
339  **********************************************************************/
340  System::String^ GeoRepresentation(int prec, bool swaplatlong );
341 
342  /**
343  * String representation with latitude and longitude as degrees, minutes,
344  * seconds, and hemisphere.
345  *
346  * @param[in] prec precision (relative to about 1m)
347  * @param[in] swaplatlong if true give longitude first (default = false)
348  * @param[in] dmssep if non-null, use as the DMS separator character
349  * (instead of d, ', &quot; delimiters).
350  * @exception std::bad_alloc if memory for the string can't be allocated.
351  * @return DMS latitude/longitude string representation.
352  *
353  * Precision specifies accuracy of representation as follows:
354  * - prec = &minus;5 (min), 1&deg;
355  * - prec = &minus;4, 0.1&deg;
356  * - prec = &minus;3, 1'
357  * - prec = &minus;2, 0.1'
358  * - prec = &minus;1, 1&quot;
359  * - prec = 0, 0.1&quot; (about 3m)
360  * - prec = 1, 0.01&quot;
361  * - prec = 10 (max), 10<sup>&minus;11</sup>&quot;
362  **********************************************************************/
363  System::String^ DMSRepresentation(int prec, bool swaplatlong,
364  char dmssep );
365 
366  /**
367  * MGRS string.
368  *
369  * @param[in] prec precision (relative to about 1m).
370  * @exception std::bad_alloc if memory for the string can't be allocated.
371  * @return MGRS string.
372  *
373  * This gives the coordinates of the enclosing grid square with size given
374  * by the precision. Thus 38N 444180 3684790 converted to a MGRS
375  * coordinate at precision &minus;2 (100m) is 38SMB441847 and not
376  * 38SMB442848. \e prec specifies the precision of the MGRS string as
377  * follows:
378  * - prec = &minus;5 (min), 100km
379  * - prec = &minus;4, 10km
380  * - prec = &minus;3, 1km
381  * - prec = &minus;2, 100m
382  * - prec = &minus;1, 10m
383  * - prec = 0, 1m
384  * - prec = 1, 0.1m
385  * - prec = 6 (max), 1&mu;m
386  **********************************************************************/
387  System::String^ MGRSRepresentation(int prec);
388 
389  /**
390  * UTM/UPS string.
391  *
392  * @param[in] prec precision (relative to about 1m)
393  * @param[in] abbrev if true (the default) use abbreviated (n/s) notation
394  * for hemisphere; otherwise spell out the hemisphere (north/south)
395  * @exception std::bad_alloc if memory for the string can't be allocated.
396  * @return UTM/UPS string representation: zone designator, easting, and
397  * northing.
398  *
399  * Precision specifies accuracy of representation as follows:
400  * - prec = &minus;5 (min), 100km
401  * - prec = &minus;3, 1km
402  * - prec = 0, 1m
403  * - prec = 3, 1mm
404  * - prec = 6, 1&mu;m
405  * - prec = 9 (max), 1nm
406  **********************************************************************/
407  System::String^ UTMUPSRepresentation(int prec, bool abbrev);
408 
409  /**
410  * UTM/UPS string with hemisphere override.
411  *
412  * @param[in] northp hemisphere override
413  * @param[in] prec precision (relative to about 1m)
414  * @param[in] abbrev if true (the default) use abbreviated (n/s) notation
415  * for hemisphere; otherwise spell out the hemisphere (north/south)
416  * @exception GeographicErr if the hemisphere override attempts to change
417  * UPS N to UPS S or vice versa.
418  * @exception std::bad_alloc if memory for the string can't be allocated.
419  * @return UTM/UPS string representation: zone designator, easting, and
420  * northing.
421  **********************************************************************/
422  System::String^ UTMUPSRepresentation(bool northp, int prec, bool abbrev);
423 
424  /**
425  * MGRS string for the alternate zone. See GeoCoords::MGRSRepresentation.
426  *
427  * @param[in] prec precision (relative to about 1m).
428  * @exception std::bad_alloc if memory for the string can't be allocated.
429  * @return MGRS string.
430  **********************************************************************/
431  System::String^ AltMGRSRepresentation(int prec);
432 
433  /**
434  * UTM/UPS string for the alternate zone. See
435  * GeoCoords::UTMUPSRepresentation.
436  *
437  * @param[in] prec precision (relative to about 1m)
438  * @param[in] abbrev if true (the default) use abbreviated (n/s) notation
439  * for hemisphere; otherwise spell out the hemisphere (north/south)
440  * @exception std::bad_alloc if memory for the string can't be allocated.
441  * @return UTM/UPS string representation: zone designator, easting, and
442  * northing.
443  **********************************************************************/
444  System::String^ AltUTMUPSRepresentation(int prec, bool abbrev);
445 
446  /**
447  * UTM/UPS string for the alternate zone, with hemisphere override.
448  *
449  * @param[in] northp hemisphere override
450  * @param[in] prec precision (relative to about 1m)
451  * @param[in] abbrev if true (the default) use abbreviated (n/s) notation
452  * for hemisphere; otherwise spell out the hemisphere (north/south)
453  * @exception GeographicErr if the hemisphere override attempts to change
454  * UPS n to UPS s or vice verse.
455  * @exception std::bad_alloc if memory for the string can't be allocated.
456  * @return UTM/UPS string representation: zone designator, easting, and
457  * northing.
458  **********************************************************************/
459  System::String^ AltUTMUPSRepresentation(bool northp, int prec, bool abbrev);
460  ///@}
461 
462  /** \name Inspector functions
463  **********************************************************************/
464  ///@{
465  /**
466  * @return \e a the equatorial radius of the WGS84 ellipsoid (meters).
467  *
468  * (The WGS84 value is returned because the UTM and UPS projections are
469  * based on this ellipsoid.)
470  **********************************************************************/
471  property double MajorRadius { double get(); }
472 
473  /**
474  * @return \e f the flattening of the WGS84 ellipsoid.
475  *
476  * (The WGS84 value is returned because the UTM and UPS projections are
477  * based on this ellipsoid.)
478  **********************************************************************/
479  property double Flattening { double get(); }
480  ///@}
481  };
482 } //namespace NETGeographicLib