00001 /** 00002 * \file NETGeographicLib/GeoCoords.h 00003 * \brief Header for NETGeographicLib::GeoCoords class 00004 * 00005 * NETGeographicLib is copyright (c) Scott Heiman (2013) 00006 * GeographicLib is Copyright (c) Charles Karney (2010-2012) 00007 * <charles@karney.com> and licensed under the MIT/X11 License. 00008 * For more information, see 00009 * http://geographiclib.sourceforge.net/ 00010 **********************************************************************/ 00011 #pragma once 00012 00013 namespace NETGeographicLib 00014 { 00015 /** 00016 * \brief .NET wrapper for GeographicLib::GeoCoords. 00017 * 00018 * This class allows .NET applications to access GeographicLib::GeoCoords. 00019 * 00020 * This class stores a geographic position which may be set via the 00021 * constructors or Reset via 00022 * - latitude and longitude 00023 * - UTM or UPS coordinates 00024 * - a string representation of these or an MGRS coordinate string 00025 * 00026 * The state consists of the latitude and longitude and the supplied UTM or 00027 * UPS coordinates (possibly derived from the MGRS coordinates). If latitude 00028 * and longitude were given then the UTM/UPS coordinates follows the standard 00029 * conventions. 00030 * 00031 * The mutable state consists of the UTM or UPS coordinates for a alternate 00032 * zone. A method SetAltZone is provided to set the alternate UPS/UTM zone. 00033 * 00034 * Methods are provided to return the geographic coordinates, the input UTM 00035 * or UPS coordinates (and associated meridian convergence and scale), or 00036 * alternate UTM or UPS coordinates (and their associated meridian 00037 * convergence and scale). 00038 * 00039 * Once the input string has been parsed, you can print the result out in any 00040 * of the formats, decimal degrees, degrees minutes seconds, MGRS, UTM/UPS. 00041 * 00042 * C# Example: 00043 * \include example-GeoCoords.cs 00044 * Managed C++ Example: 00045 * \include example-GeoCoords.cpp 00046 * Visual Basic Example: 00047 * \include example-GeoCoords.vb 00048 * 00049 * <B>INTERFACE DIFFERENCES:</B><BR> 00050 * The following functions are implemented as properties: MajorRadius, 00051 * Flattening, Latitude, Longitude, Easting, Northing, Convergence, 00052 * Scale, Northp, Hemisphere, Zone, AltZone, AltEasting, AltNorthing, 00053 * AltConvergence, and AltScale. 00054 **********************************************************************/ 00055 public ref class GeoCoords 00056 { 00057 private: 00058 // pointer to the unmanaged GeographicLib::GeoCoords 00059 GeographicLib::GeoCoords* m_pGeoCoords; 00060 00061 // The finalizer frees unmanaged memory when the object is destroyed. 00062 !GeoCoords(); 00063 public: 00064 /** \name Initializing the GeoCoords object 00065 **********************************************************************/ 00066 ///@{ 00067 /** 00068 * The default constructor is equivalent to \e latitude = 90°, 00069 * \e longitude = 0°. 00070 **********************************************************************/ 00071 GeoCoords(); 00072 00073 /** 00074 * Construct from a string. 00075 * 00076 * @param[in] s 1-element, 2-element, or 3-element string representation of 00077 * the position. 00078 * @param[in] centerp governs the interpretation of MGRS coordinates (see 00079 * below). 00080 * @param[in] swaplatlong governs the interpretation of geographic 00081 * coordinates (see below). 00082 * @exception GeographicErr if the \e s is malformed (see below). 00083 * 00084 * Parse as a string and interpret it as a geographic position. The input 00085 * string is broken into space (or comma) separated pieces and Basic 00086 * decision on which format is based on number of components 00087 * -# MGRS 00088 * -# "Lat Long" or "Long Lat" 00089 * -# "Zone Easting Northing" or "Easting Northing Zone" 00090 * 00091 * The following inputs are approximately the same (Ar Ramadi Bridge, Iraq) 00092 * - Latitude and Longitude 00093 * - 33.44 43.27 00094 * - N33d26.4' E43d16.2' 00095 * - 43d16'12"E 33d26'24"N 00096 * - 43:16:12E 33:26:24 00097 * - MGRS 00098 * - 38SLC30 00099 * - 38SLC391014 00100 * - 38SLC3918701405 00101 * - 37SHT9708 00102 * - UTM 00103 * - 38N 339188 3701405 00104 * - 897039 3708229 37N 00105 * 00106 * <b>Latitude and Longitude parsing</b>: Latitude precedes longitude, 00107 * unless a N, S, E, W hemisphere designator is used on one or both 00108 * coordinates. If \e swaplatlong = true (default is false), then 00109 * longitude precedes latitude in the absence of a hemisphere designator. 00110 * Thus (with \e swaplatlong = false) 00111 * - 40 -75 00112 * - N40 W75 00113 * - -75 N40 00114 * - 75W 40N 00115 * - E-75 -40S 00116 * . 00117 * are all the same position. The coordinates may be given in 00118 * decimal degrees, degrees and decimal minutes, degrees, minutes, 00119 * seconds, etc. Use d, ', and " to mark off the degrees, 00120 * minutes and seconds. Various alternative symbols for degrees, minutes, 00121 * and seconds are allowed. Alternatively, use : to separate these 00122 * components. (See DMS::Decode for details.) Thus 00123 * - 40d30'30" 00124 * - 40d30'30 00125 * - 40°30'30 00126 * - 40d30.5' 00127 * - 40d30.5 00128 * - 40:30:30 00129 * - 40:30.5 00130 * - 40.508333333 00131 * . 00132 * all specify the same angle. The leading sign applies to all components 00133 * so -1d30 is -(1+30/60) = -1.5. Latitudes must be in the range 00134 * [−90°, 90°] and longitudes in the range 00135 * [−540°, 540°). Internally longitudes are reduced 00136 * to the range [−180°, 180°). 00137 * 00138 * <b>UTM/UPS parsing</b>: For UTM zones (−80° ≤ Lat < 00139 * 84°), the zone designator is made up of a zone number (for 1 to 60) 00140 * and a hemisphere letter (N or S), e.g., 38N. The latitude zone designer 00141 * ([C--M] in the southern hemisphere and [N--X] in the northern) should 00142 * NOT be used. (This is part of the MGRS coordinate.) The zone 00143 * designator for the poles (where UPS is employed) is a hemisphere letter 00144 * by itself, i.e., N or S. 00145 * 00146 * <b>MGRS parsing</b> interprets the grid references as square area at the 00147 * specified precision (1m, 10m, 100m, etc.). If \e centerp = true (the 00148 * default), the center of this square is then taken to be the precise 00149 * position; thus: 00150 * - 38SMB = 38N 450000 3650000 00151 * - 38SMB4484 = 38N 444500 3684500 00152 * - 38SMB44148470 = 38N 444145 3684705 00153 * . 00154 * Otherwise, the "south-west" corner of the square is used, i.e., 00155 * - 38SMB = 38N 400000 3600000 00156 * - 38SMB4484 = 38N 444000 3684000 00157 * - 38SMB44148470 = 38N 444140 3684700 00158 **********************************************************************/ 00159 GeoCoords(System::String^ s, bool centerp, bool swaplatlong ); 00160 00161 /** 00162 * Construct from geographic coordinates. 00163 * 00164 * @param[in] latitude (degrees). 00165 * @param[in] longitude (degrees). 00166 * @param[in] zone if specified, force the UTM/UPS representation to use a 00167 * specified zone using the rules given in UTMUPS::zonespec. 00168 * @exception GeographicErr if \e latitude is not in [−90°, 00169 * 90°]. 00170 * @exception GeographicErr if \e longitude is not in [−540°, 00171 * 540°). 00172 * @exception GeographicErr if \e zone cannot be used for this location. 00173 **********************************************************************/ 00174 GeoCoords(double latitude, double longitude, int zone ); 00175 00176 /** 00177 * Construct from UTM/UPS coordinates. 00178 * 00179 * @param[in] zone UTM zone (zero means UPS). 00180 * @param[in] northp hemisphere (true means north, false means south). 00181 * @param[in] easting (meters). 00182 * @param[in] northing (meters). 00183 * @exception GeographicErr if \e zone, \e easting, or \e northing is 00184 * outside its allowed range. 00185 **********************************************************************/ 00186 GeoCoords(int zone, bool northp, double easting, double northing); 00187 00188 /** 00189 * The destructor calls the finalizer. 00190 **********************************************************************/ 00191 ~GeoCoords() { this->!GeoCoords(); } 00192 00193 /** 00194 * Reset the location from a string. See 00195 * GeoCoords(const std::string& s, bool centerp, bool swaplatlong). 00196 * 00197 * @param[in] s 1-element, 2-element, or 3-element string representation of 00198 * the position. 00199 * @param[in] centerp governs the interpretation of MGRS coordinates. 00200 * @param[in] swaplatlong governs the interpretation of geographic 00201 * coordinates. 00202 * @exception GeographicErr if the \e s is malformed. 00203 **********************************************************************/ 00204 void Reset( System::String^ s, bool centerp, bool swaplatlong); 00205 00206 /** 00207 * Reset the location in terms of geographic coordinates. See 00208 * GeoCoords(double latitude, double longitude, int zone). 00209 * 00210 * @param[in] latitude (degrees). 00211 * @param[in] longitude (degrees). 00212 * @param[in] zone if specified, force the UTM/UPS representation to use a 00213 * specified zone using the rules given in UTMUPS::zonespec. 00214 * @exception GeographicErr if \e latitude is not in [−90°, 00215 * 90°]. 00216 * @exception GeographicErr if \e longitude is not in [−540°, 00217 * 540°). 00218 * @exception GeographicErr if \e zone cannot be used for this location. 00219 **********************************************************************/ 00220 void Reset(double latitude, double longitude, int zone ) ; 00221 00222 /** 00223 * Reset the location in terms of UPS/UPS coordinates. See 00224 * GeoCoords(int zone, bool northp, double easting, double northing). 00225 * 00226 * @param[in] zone UTM zone (zero means UPS). 00227 * @param[in] northp hemisphere (true means north, false means south). 00228 * @param[in] easting (meters). 00229 * @param[in] northing (meters). 00230 * @exception GeographicErr if \e zone, \e easting, or \e northing is 00231 * outside its allowed range. 00232 **********************************************************************/ 00233 void Reset(int zone, bool northp, double easting, double northing); 00234 ///@} 00235 00236 /** \name Querying the GeoCoords object 00237 **********************************************************************/ 00238 ///@{ 00239 /** 00240 * @return latitude (degrees) 00241 **********************************************************************/ 00242 property double Latitude { double get(); } 00243 00244 /** 00245 * @return longitude (degrees) 00246 **********************************************************************/ 00247 property double Longitude { double get(); } 00248 00249 /** 00250 * @return easting (meters) 00251 **********************************************************************/ 00252 property double Easting { double get(); } 00253 00254 /** 00255 * @return northing (meters) 00256 **********************************************************************/ 00257 property double Northing { double get(); } 00258 00259 /** 00260 * @return meridian convergence (degrees) for the UTM/UPS projection. 00261 **********************************************************************/ 00262 property double Convergence { double get(); } 00263 00264 /** 00265 * @return scale for the UTM/UPS projection. 00266 **********************************************************************/ 00267 property double Scale { double get(); } 00268 00269 /** 00270 * @return hemisphere (false means south, true means north). 00271 **********************************************************************/ 00272 property bool Northp { bool get(); } 00273 00274 /** 00275 * @return hemisphere letter N or S. 00276 **********************************************************************/ 00277 property char Hemisphere { char get(); } 00278 00279 /** 00280 * @return the zone corresponding to the input (return 0 for UPS). 00281 **********************************************************************/ 00282 property int Zone { int get(); } 00283 00284 /** 00285 * Gets/Sets the current alternate zone (0 = UPS). 00286 * @exception GeographicErr if \e zone cannot be used for this location. 00287 * 00288 * See UTMUPS::zonespec for more information on the interpretation of \e 00289 * zone. Note that \e zone == UTMUPS::STANDARD (the default) use the 00290 * standard UPS or UTM zone, UTMUPS::MATCH does nothing retaining the 00291 * existing alternate representation. Before this is called the alternate 00292 * zone is the input zone. 00293 **********************************************************************/ 00294 property int AltZone 00295 { 00296 int get(); 00297 void set( int zone ); 00298 } 00299 ///@} 00300 00301 /** 00302 * @return easting (meters) for alternate zone. 00303 **********************************************************************/ 00304 property double AltEasting { double get(); } 00305 00306 /** 00307 * @return northing (meters) for alternate zone. 00308 **********************************************************************/ 00309 property double AltNorthing { double get(); } 00310 00311 /** 00312 * @return meridian convergence (degrees) for alternate zone. 00313 **********************************************************************/ 00314 property double AltConvergence { double get(); } 00315 00316 /** 00317 * @return scale for alternate zone. 00318 **********************************************************************/ 00319 property double AltScale { double get(); } 00320 ///@} 00321 00322 /** \name String representations of the GeoCoords object 00323 **********************************************************************/ 00324 ///@{ 00325 /** 00326 * String representation with latitude and longitude as signed decimal 00327 * degrees. 00328 * 00329 * @param[in] prec precision (relative to about 1m). 00330 * @param[in] swaplatlong if true give longitude first (default = false) 00331 * @exception std::bad_alloc if memory for the string can't be allocated. 00332 * @return decimal latitude/longitude string representation. 00333 * 00334 * Precision specifies accuracy of representation as follows: 00335 * - prec = −5 (min), 1° 00336 * - prec = 0, 10<sup>−5</sup>° (about 1m) 00337 * - prec = 3, 10<sup>−8</sup>° 00338 * - prec = 9 (max), 10<sup>−14</sup>° 00339 **********************************************************************/ 00340 System::String^ GeoRepresentation(int prec, bool swaplatlong ); 00341 00342 /** 00343 * String representation with latitude and longitude as degrees, minutes, 00344 * seconds, and hemisphere. 00345 * 00346 * @param[in] prec precision (relative to about 1m) 00347 * @param[in] swaplatlong if true give longitude first (default = false) 00348 * @param[in] dmssep if non-null, use as the DMS separator character 00349 * (instead of d, ', " delimiters). 00350 * @exception std::bad_alloc if memory for the string can't be allocated. 00351 * @return DMS latitude/longitude string representation. 00352 * 00353 * Precision specifies accuracy of representation as follows: 00354 * - prec = −5 (min), 1° 00355 * - prec = −4, 0.1° 00356 * - prec = −3, 1' 00357 * - prec = −2, 0.1' 00358 * - prec = −1, 1" 00359 * - prec = 0, 0.1" (about 3m) 00360 * - prec = 1, 0.01" 00361 * - prec = 10 (max), 10<sup>−11</sup>" 00362 **********************************************************************/ 00363 System::String^ DMSRepresentation(int prec, bool swaplatlong, 00364 char dmssep ); 00365 00366 /** 00367 * MGRS string. 00368 * 00369 * @param[in] prec precision (relative to about 1m). 00370 * @exception std::bad_alloc if memory for the string can't be allocated. 00371 * @return MGRS string. 00372 * 00373 * This gives the coordinates of the enclosing grid square with size given 00374 * by the precision. Thus 38N 444180 3684790 converted to a MGRS 00375 * coordinate at precision −2 (100m) is 38SMB441847 and not 00376 * 38SMB442848. \e prec specifies the precision of the MGRS string as 00377 * follows: 00378 * - prec = −5 (min), 100km 00379 * - prec = −4, 10km 00380 * - prec = −3, 1km 00381 * - prec = −2, 100m 00382 * - prec = −1, 10m 00383 * - prec = 0, 1m 00384 * - prec = 1, 0.1m 00385 * - prec = 6 (max), 1μm 00386 **********************************************************************/ 00387 System::String^ MGRSRepresentation(int prec); 00388 00389 /** 00390 * UTM/UPS string. 00391 * 00392 * @param[in] prec precision (relative to about 1m) 00393 * @param[in] abbrev if true (the default) use abbreviated (n/s) notation 00394 * for hemisphere; otherwise spell out the hemisphere (north/south) 00395 * @exception std::bad_alloc if memory for the string can't be allocated. 00396 * @return UTM/UPS string representation: zone designator, easting, and 00397 * northing. 00398 * 00399 * Precision specifies accuracy of representation as follows: 00400 * - prec = −5 (min), 100km 00401 * - prec = −3, 1km 00402 * - prec = 0, 1m 00403 * - prec = 3, 1mm 00404 * - prec = 6, 1μm 00405 * - prec = 9 (max), 1nm 00406 **********************************************************************/ 00407 System::String^ UTMUPSRepresentation(int prec, bool abbrev); 00408 00409 /** 00410 * UTM/UPS string with hemisphere override. 00411 * 00412 * @param[in] northp hemisphere override 00413 * @param[in] prec precision (relative to about 1m) 00414 * @param[in] abbrev if true (the default) use abbreviated (n/s) notation 00415 * for hemisphere; otherwise spell out the hemisphere (north/south) 00416 * @exception GeographicErr if the hemisphere override attempts to change 00417 * UPS N to UPS S or vice versa. 00418 * @exception std::bad_alloc if memory for the string can't be allocated. 00419 * @return UTM/UPS string representation: zone designator, easting, and 00420 * northing. 00421 **********************************************************************/ 00422 System::String^ UTMUPSRepresentation(bool northp, int prec, bool abbrev); 00423 00424 /** 00425 * MGRS string for the alternate zone. See GeoCoords::MGRSRepresentation. 00426 * 00427 * @param[in] prec precision (relative to about 1m). 00428 * @exception std::bad_alloc if memory for the string can't be allocated. 00429 * @return MGRS string. 00430 **********************************************************************/ 00431 System::String^ AltMGRSRepresentation(int prec); 00432 00433 /** 00434 * UTM/UPS string for the alternate zone. See 00435 * GeoCoords::UTMUPSRepresentation. 00436 * 00437 * @param[in] prec precision (relative to about 1m) 00438 * @param[in] abbrev if true (the default) use abbreviated (n/s) notation 00439 * for hemisphere; otherwise spell out the hemisphere (north/south) 00440 * @exception std::bad_alloc if memory for the string can't be allocated. 00441 * @return UTM/UPS string representation: zone designator, easting, and 00442 * northing. 00443 **********************************************************************/ 00444 System::String^ AltUTMUPSRepresentation(int prec, bool abbrev); 00445 00446 /** 00447 * UTM/UPS string for the alternate zone, with hemisphere override. 00448 * 00449 * @param[in] northp hemisphere override 00450 * @param[in] prec precision (relative to about 1m) 00451 * @param[in] abbrev if true (the default) use abbreviated (n/s) notation 00452 * for hemisphere; otherwise spell out the hemisphere (north/south) 00453 * @exception GeographicErr if the hemisphere override attempts to change 00454 * UPS n to UPS s or vice verse. 00455 * @exception std::bad_alloc if memory for the string can't be allocated. 00456 * @return UTM/UPS string representation: zone designator, easting, and 00457 * northing. 00458 **********************************************************************/ 00459 System::String^ AltUTMUPSRepresentation(bool northp, int prec, bool abbrev); 00460 ///@} 00461 00462 /** \name Inspector functions 00463 **********************************************************************/ 00464 ///@{ 00465 /** 00466 * @return \e a the equatorial radius of the WGS84 ellipsoid (meters). 00467 * 00468 * (The WGS84 value is returned because the UTM and UPS projections are 00469 * based on this ellipsoid.) 00470 **********************************************************************/ 00471 property double MajorRadius { double get(); } 00472 00473 /** 00474 * @return \e f the flattening of the WGS84 ellipsoid. 00475 * 00476 * (The WGS84 value is returned because the UTM and UPS projections are 00477 * based on this ellipsoid.) 00478 **********************************************************************/ 00479 property double Flattening { double get(); } 00480 ///@} 00481 }; 00482 } //namespace NETGeographicLib