- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# Y:/msp/devkits/temp_geotrans/master/geotrans3.1/CCS/src/dtcc/CoordinateSystems/neys/Neys.cpp

Go to the documentation of this file.

    00001 // CLASSIFICATION: UNCLASSIFIED
    00002
    00003 /***************************************************************************/
    00004 /* RSC IDENTIFIER: NEYS
    00005  *
    00006  * ABSTRACT
    00007  *
    00008  *    This component provides conversions between Geodetic coordinates
    00009  *    (latitude and longitude in radians) and Ney's (Modified Lambert
    00010  *    Conformal Conic) projection coordinates (easting and northing in meters).
    00011  *
    00012  * ERROR HANDLING
    00013  *
    00014  *    This component checks parameters for valid values.  If an invalid value
    00015  *    is found the error code is combined with the current error code using
    00016  *    the bitwise or.  This combining allows multiple error codes to be
    00017  *    returned. The possible error codes are:
    00018  *
    00019  *       NEYS_NO_ERROR           : No errors occurred in function
    00020  *       NEYS_LAT_ERROR          : Latitude outside of valid range
    00021  *                                     (-90 to 90 degrees)
    00022  *       NEYS_LON_ERROR          : Longitude outside of valid range
    00023  *                                     (-180 to 360 degrees)
    00024  *       NEYS_EASTING_ERROR      : Easting outside of valid range
    00025  *                                     (depends on ellipsoid and projection
    00026  *                                     parameters)
    00027  *       NEYS_NORTHING_ERROR     : Northing outside of valid range
    00028  *                                     (depends on ellipsoid and projection
    00029  *                                     parameters)
    00030  *       NEYS_FIRST_STDP_ERROR   : First standard parallel outside of valid
    00031  *                                     range (71 or 74 degrees)
    00032  *       NEYS_ORIGIN_LAT_ERROR   : Origin latitude outside of valid range
    00033  *                                     (-89 59 59.0 to 89 59 59.0 degrees)
    00034  *       NEYS_CENT_MER_ERROR     : Central meridian outside of valid range
    00035  *                                     (-180 to 360 degrees)
    00036  *       NEYS_A_ERROR            : Semi-major axis less than or equal to zero
    00037  *       NEYS_INV_F_ERROR        : Inverse flattening outside of valid range
    00038  *                                     (250 to 350)
    00039  *
    00040  *
    00041  * REUSE NOTES
    00042  *
    00043  *    NEYS is intended for reuse by any application that performs a Ney's (Modified
    00044  *    Lambert Conformal Conic) projection or its inverse.
    00045  *
    00046  * REFERENCES
    00047  *
    00048  *    Further information on NEYS can be found in the Reuse Manual.
    00049  *
    00050  *    NEYS originated from:
    00051  *                      U.S. Army Topographic Engineering Center
    00052  *                      Geospatial Information Division
    00053  *                      7701 Telegraph Road
    00054  *                      Alexandria, VA  22310-3864
    00055  *
    00056  * LICENSES
    00057  *
    00058  *    None apply to this component.
    00059  *
    00060  * RESTRICTIONS
    00061  *
    00062  *    NEYS has no restrictions.
    00063  *
    00064  * ENVIRONMENT
    00065  *
    00066  *    NEYS was tested and certified in the following environments:
    00067  *
    00068  *    1. Solaris 2.5 with GCC, version 2.8.1
    00069  *    2. Windows 95 with MS Visual C++, version 6
    00070  *
    00071  * MODIFICATIONS
    00072  *
    00073  *    Date              Description
    00074  *    ----              -----------
    00075  *    8-4-00            Original Code
    00076  *    3-2-07            Original C++ Code
    00077  *
    00078  *
    00079  *
    00080  */
    00081
    00082
    00083 /***************************************************************************/
    00084 /*
    00085  *                               INCLUDES
    00086  */
    00087
    00088 #include <math.h>
    00089 #include "LambertConformalConic.h"
    00090 #include "Neys.h"
    00091 #include "NeysParameters.h"
    00092 #include "MapProjectionCoordinates.h"
    00093 #include "GeodeticCoordinates.h"
    00094 #include "CoordinateConversionException.h"
    00095 #include "ErrorMessages.h"
    00096
    00097 /*
    00098  *    math.h     - Standard C math library
    00099  *    LambertConformalConic2.h  - Is used to convert lambert conformal conic coordinates
    00100  *    Neys.h     - Is for prototype error checking
    00101  *    MapProjectionCoordinates.h   - defines map projection coordinates
    00102  *    GeodeticCoordinates.h   - defines geodetic coordinates
    00103  *    CoordinateConversionException.h - Exception handler
    00104  *    ErrorMessages.h  - Contains exception messages
    00105  */
    00106
    00107
    00108 using namespace MSP::CCS;
    00109
    00110
    00111 /***************************************************************************/
    00112 /*                               DEFINES
    00113  *
    00114  */
    00115
    00116 const double PI = 3.14159265358979323e0;                 /* PI     */
    00117 const double PI_OVER_2 = (PI / 2.0);
    00118 const double PI_OVER_180 = (PI / 180.0);
    00119 const double TWO_PI = (2.0 * PI);
    00120 const double SEVENTY_ONE = (71.0 * PI_OVER_180);          /* 71 degrees     */
    00121 const double SEVENTY_FOUR = (74.0 * PI_OVER_180);         /* 74 degrees     */
    00123 const double MAX_LAT = (89.999444444444444 * PI_OVER_180); /* 89 59 58.0 degrees     */
    00124
    00125
    00126 /************************************************************************/
    00127 /*                              FUNCTIONS
    00128  *
    00129  */
    00130
    00131 Neys::Neys( double ellipsoidSemiMajorAxis, double ellipsoidFlattening, double centralMeridian, double originLatitude, double standardParallel, double falseEasting, double falseNorthing ) :
    00132   CoordinateSystem(),
    00133   lambertConformalConic2( 0 ),
    00134   Neys_Std_Parallel_1( SEVENTY_ONE ),
    00135   Neys_Std_Parallel_2( MAX_LAT ),
    00136   Neys_Origin_Long( 0.0 ),
    00137   Neys_Origin_Lat( 80.0 * PI_OVER_180 ),
    00138   Neys_False_Easting( 0.0 ),
    00139   Neys_False_Northing( 0.0 ),
    00140   Neys_Delta_Easting( 400000000.0 ),
    00141   Neys_Delta_Northing( 400000000.0 )
    00142 {
    00143 /*
    00144  * The constructor receives the ellipsoid parameters and
    00145  * Ney's (Modified Lambert Conformal Conic) projection parameters as inputs, and sets the
    00146  * corresponding state variables.  If any errors occur, an exception is thrown
    00147  * with a description of the error.
    00148  *
    00149  *   ellipsoidSemiMajorAxis  : Semi-major axis of ellipsoid, in meters   (input)
    00150  *   ellipsoidFlattening     : Flattening of ellipsoid                   (input)
    00151  *   centralMeridian         : Longitude of origin, in radians           (input)
    00152  *   originLatitude          : Latitude of origin, in radians            (input)
    00153  *   standardParallel        : First standard parallel, in radians       (input)
    00154  *   falseEasting            : False easting, in meters                  (input)
    00155  *   falseNorthing           : False northing, in meters                 (input)
    00156  */
    00157
    00158   double epsilon = 1.0e-10;
    00159   double inv_f = 1 / ellipsoidFlattening;
    00160   char errorStatus[500] = "";
    00161
    00162   if (ellipsoidSemiMajorAxis <= 0.0)
    00163   { /* Semi-major axis must be greater than zero */
    00164     strcat( errorStatus, ErrorMessages::semiMajorAxis );
    00165   }
    00166   if ((inv_f < 250) || (inv_f > 350))
    00167   { /* Inverse flattening must be between 250 and 350 */
    00168     strcat( errorStatus, ErrorMessages::ellipsoidFlattening );
    00169   }
    00170   if ((originLatitude < -MAX_LAT) || (originLatitude > MAX_LAT))
    00171   { /* Origin Latitude out of range */
    00172     strcat( errorStatus, ErrorMessages::originLatitude );
    00173   }
    00174   if ((fabs(standardParallel - SEVENTY_ONE) > epsilon) && (fabs(standardParallel - SEVENTY_FOUR) > epsilon))
    00175   { /* First Standard Parallel invalid */
    00176     strcat( errorStatus, ErrorMessages::standardParallel1 );
    00177   }
    00178   if ((centralMeridian < -PI) || (centralMeridian > TWO_PI))
    00179   { /* Origin Longitude out of range */
    00180     strcat( errorStatus, ErrorMessages::centralMeridian );
    00181   }
    00182
    00183   if( strlen( errorStatus ) > 0)
    00184     throw CoordinateConversionException( errorStatus );
    00185
    00186   semiMajorAxis = ellipsoidSemiMajorAxis;
    00187   flattening = ellipsoidFlattening;
    00188
    00189   Neys_Origin_Lat = originLatitude;
    00190   if (Neys_Origin_Lat >= 0)
    00191   {
    00192     Neys_Std_Parallel_1 = standardParallel;
    00193     Neys_Std_Parallel_2 = MAX_LAT;
    00194   }
    00195   else
    00196   {
    00197     Neys_Std_Parallel_1 = -standardParallel;
    00198     Neys_Std_Parallel_2 = -MAX_LAT;
    00199   }
    00200
    00201   if (centralMeridian > PI)
    00202     centralMeridian -= TWO_PI;
    00203   Neys_Origin_Long = centralMeridian;
    00204   Neys_False_Easting = falseEasting;
    00205   Neys_False_Northing = falseNorthing;
    00206
    00207   lambertConformalConic2 = new LambertConformalConic( semiMajorAxis, flattening, Neys_Origin_Long, Neys_Origin_Lat,
    00208                                                       Neys_Std_Parallel_1, Neys_Std_Parallel_2,
    00209                                                       Neys_False_Easting, Neys_False_Northing );
    00210 }
    00211
    00212
    00213 Neys::Neys( const Neys &n )
    00214 {
    00215   lambertConformalConic2 = new LambertConformalConic( *( n.lambertConformalConic2 ) );
    00216   semiMajorAxis = n.semiMajorAxis;
    00217   flattening = n.flattening;
    00218   Neys_Std_Parallel_1 = n.Neys_Std_Parallel_1;
    00219   Neys_Std_Parallel_2 = n.Neys_Std_Parallel_2;
    00220   Neys_Origin_Long = n.Neys_Origin_Long;
    00221   Neys_Origin_Lat = n.Neys_Origin_Lat;
    00222   Neys_False_Easting = n.Neys_False_Easting;
    00223   Neys_False_Northing = n.Neys_False_Northing;
    00224   Neys_Delta_Easting = n.Neys_Delta_Easting;
    00225   Neys_Delta_Northing = n.Neys_Delta_Northing;
    00226 }
    00227
    00228
    00229 Neys::~Neys()
    00230 {
    00231   delete lambertConformalConic2;
    00232   lambertConformalConic2 = 0;
    00233 }
    00234
    00235
    00236 Neys& Neys::operator=( const Neys &n )
    00237 {
    00238   if( this != &n )
    00239   {
    00240     lambertConformalConic2->operator=( *n.lambertConformalConic2 );
    00241     semiMajorAxis = n.semiMajorAxis;
    00242     flattening = n.flattening;
    00243     Neys_Std_Parallel_1 = n.Neys_Std_Parallel_1;
    00244     Neys_Std_Parallel_2 = n.Neys_Std_Parallel_2;
    00245     Neys_Origin_Long = n.Neys_Origin_Long;
    00246     Neys_Origin_Lat = n.Neys_Origin_Lat;
    00247     Neys_False_Easting = n.Neys_False_Easting;
    00248     Neys_False_Northing = n.Neys_False_Northing;
    00249     Neys_Delta_Easting = n.Neys_Delta_Easting;
    00250     Neys_Delta_Northing = n.Neys_Delta_Northing;
    00251   }
    00252
    00253   return *this;
    00254 }
    00255
    00256
    00257 NeysParameters* Neys::getParameters() const
    00258 {
    00259 /*
    00260  * The function getParameters returns the current ellipsoid
    00261  * parameters and Ney's (Modified Lambert Conformal Conic) projection parameters.
    00262  *
    00263  *   ellipsoidSemiMajorAxis  : Semi-major axis of ellipsoid, in meters   (output)
    00264  *   ellipsoidFlattening     : Flattening of ellipsoid                   (output)
    00265  *   centralMeridian         : Longitude of origin, in radians           (output)
    00266  *   originLatitude          : Latitude of origin, in radians            (output)
    00267  *   standardParallel        : First standard parallel, in radians       (output)
    00268  *   falseEasting            : False easting, in meters                  (output)
    00269  *   falseNorthing           : False northing, in meters                 (output)
    00270  */
    00271
    00272   return new NeysParameters( CoordinateType::neys, Neys_Origin_Long, Neys_Origin_Lat, Neys_Std_Parallel_1, Neys_False_Easting, Neys_False_Northing );
    00273 }
    00274
    00275
    00276 MSP::CCS::MapProjectionCoordinates* Neys::convertFromGeodetic( MSP::CCS::GeodeticCoordinates* geodeticCoordinates )
    00277 {
    00278 /*
    00279  * The function convertFromGeodetic converts Geodetic (latitude and
    00280  * longitude) coordinates to Ney's (Modified Lambert Conformal Conic) projection
    00281  * (easting and northing) coordinates, according to the current ellipsoid and
    00282  * Ney's (Modified Lambert Conformal Conic) projection parameters.  If any errors
    00283  * occur, an exception is thrown with a description of the error.
    00284  *
    00285  *    longitude        : Longitude, in radians                        (input)
    00286  *    latitude         : Latitude, in radians                         (input)
    00287  *    easting          : Easting (X), in meters                       (output)
    00288  *    northing         : Northing (Y), in meters                      (output)
    00289  */
    00290
    00291   char errorStatus[50] = "";
    00292
    00293   double longitude = geodeticCoordinates->longitude();
    00294   double latitude = geodeticCoordinates->latitude();
    00295
    00296   if ((latitude < -PI_OVER_2) || (latitude > PI_OVER_2))
    00297   {  /* Latitude out of range */
    00298     strcat( errorStatus, ErrorMessages::latitude );
    00299   }
    00300   if ((longitude < -PI) || (longitude > TWO_PI))
    00301   {  /* Longitude out of range */
    00302     strcat( errorStatus, ErrorMessages::longitude );
    00303   }
    00304
    00305   if( strlen( errorStatus ) > 0)
    00306     throw CoordinateConversionException( errorStatus );
    00307
    00308   MapProjectionCoordinates* mapProjectionCoordinates = lambertConformalConic2->convertFromGeodetic( geodeticCoordinates );
    00309   double easting = mapProjectionCoordinates->easting();
    00310   double northing = mapProjectionCoordinates->northing();
    00311   delete mapProjectionCoordinates;
    00312
    00313   return new MapProjectionCoordinates( CoordinateType::neys, easting, northing );
    00314 }
    00315
    00316
    00317 MSP::CCS::GeodeticCoordinates* Neys::convertToGeodetic( MSP::CCS::MapProjectionCoordinates* mapProjectionCoordinates )
    00318 {
    00319 /*
    00320  * The function convertToGeodetic converts Ney's (Modified Lambert Conformal
    00321  * Conic) projection (easting and northing) coordinates to Geodetic (latitude)
    00322  * and longitude) coordinates, according to the current ellipsoid and Ney's
    00323  * (Modified Lambert Conformal Conic) projection parameters.  If any errors
    00324  * occur, an exception is thrown with a description of the error.
    00325  *
    00326  *    easting          : Easting (X), in meters                       (input)
    00327  *    northing         : Northing (Y), in meters                      (input)
    00328  *    longitude        : Longitude, in radians                        (output)
    00329  *    latitude         : Latitude, in radians                         (output)
    00330  */
    00331
    00332   char errorStatus[50] = "";
    00333
    00334   double easting = mapProjectionCoordinates->easting();
    00335   double northing = mapProjectionCoordinates->northing();
    00336
    00337   if ((easting < (Neys_False_Easting - Neys_Delta_Easting))
    00338       ||(easting > (Neys_False_Easting + Neys_Delta_Easting)))
    00339   { /* Easting out of range  */
    00340     strcat( errorStatus, ErrorMessages::easting );
    00341   }
    00342   if ((northing < (Neys_False_Northing - Neys_Delta_Northing))
    00343       || (northing > (Neys_False_Northing + Neys_Delta_Northing)))
    00344   { /* Northing out of range */
    00345     strcat( errorStatus, ErrorMessages::northing );
    00346   }
    00347
    00348   if( strlen( errorStatus ) > 0)
    00349     throw CoordinateConversionException( errorStatus );
    00350
    00351   GeodeticCoordinates* geodeticCoordinates = lambertConformalConic2->convertToGeodetic( mapProjectionCoordinates );
    00352   double longitude = geodeticCoordinates->longitude();
    00353   double latitude = geodeticCoordinates->latitude();
    00354   delete geodeticCoordinates;
    00355
    00356   return new GeodeticCoordinates( CoordinateType::geodetic, longitude, latitude );
    00357 }
    00358
    00359
    00360
    00361 // CLASSIFICATION: UNCLASSIFIED