110 using namespace MSP::CCS;
 
  118 const double PI = 3.14159265358979323e0;   
 
  122 const double MAX_LAT = (( 
PI *  89.99972222222222) / 180.0);  
 
  136   es( 0.08181919084262188000 ),
 
  137   es_OVER_2( .040909595421311 ),
 
  138   Lambert_1_n( 0.70710678118655 ),
 
  139   Lambert_1_rho0( 6388838.2901212 ),
 
  140   Lambert_1_rho_olat( 6388838.2901211 ),
 
  141   Lambert_1_t0( 0.41618115138974 ),
 
  142   Lambert_Origin_Long( 0.0 ),
 
  143   Lambert_Origin_Latitude( (45.0 * 
PI / 180.0) ),
 
  144   Lambert_False_Easting( 0.0 ),
 
  145   Lambert_False_Northing( 0.0 ),
 
  146   Lambert_Scale_Factor( 1.0 ),
 
  147   Lambert_2_Origin_Lat( (45 * 
PI / 180) ),
 
  148   Lambert_2_Std_Parallel_1( (40 * 
PI / 180) ),
 
  149   Lambert_2_Std_Parallel_2( (50 * 
PI / 180) ),
 
  150   Lambert_Delta_Easting( 400000000.0 ),
 
  151   Lambert_Delta_Northing( 400000000.0 )
 
  170   double inv_f = 1 / ellipsoidFlattening;
 
  172   if (ellipsoidSemiMajorAxis <= 0.0)
 
  176   if ((inv_f < 250) || (inv_f > 350))
 
  180   if ((centralMeridian < -
PI) || (centralMeridian > 
TWO_PI))
 
  188   if (centralMeridian > 
PI)
 
  189     centralMeridian -= 
TWO_PI;
 
  190   Lambert_Origin_Long = centralMeridian;
 
  191   Lambert_False_Easting = falseEasting;
 
  195   es_OVER_2 = es / 2.0;
 
  197   CommonParameters* parameters = setCommonLambert1StandardParallelParameters(
 
  198      originLatitude, falseNorthing, scaleFactor);    
 
  200   Lambert_1_n = parameters->_lambertN;                         
 
  201   Lambert_1_rho0 = parameters->_lambertRho0;                       
 
  202   Lambert_1_rho_olat = parameters->_lambertRhoOlat;
 
  203   Lambert_1_t0 = parameters->_lambertT0;
 
  204   Lambert_Origin_Latitude = parameters->_lambertOriginLatitude; 
 
  205   Lambert_False_Northing = parameters->_lambertFalseNorthing;             
 
  206   Lambert_Scale_Factor = parameters->_lambertScaleFactor;  
 
  208   Lambert_2_Origin_Lat = parameters->_lambertOriginLatitude; 
 
  210   double sinOlat = sin(Lambert_Origin_Latitude);
 
  211   double esSinOlat = es * sinOlat;
 
  212   double w0 = sqrt(1 - es2 * sinOlat * sinOlat);
 
  213   double f0 = cos(Lambert_Origin_Latitude) / (w0 * pow(Lambert_1_t0, Lambert_1_n));
 
  214   double c = Lambert_Scale_Factor * f0;
 
  217   double tempPhi = 1.0;
 
  218   Lambert_2_Std_Parallel_1 = calculateLambert2StandardParallel(es2, phi, tempPhi, c);
 
  222   Lambert_2_Std_Parallel_2 = calculateLambert2StandardParallel(es2, phi, tempPhi, c);
 
  229 LambertConformalConic::LambertConformalConic( 
double ellipsoidSemiMajorAxis, 
double ellipsoidFlattening, 
double centralMeridian, 
double originLatitude, 
double standardParallel1, 
double standardParallel2, 
double falseEasting, 
double falseNorthing ) :
 
  231   coordinateType( 
CoordinateType::lambertConformalConic2Parallels ),
 
  232   es( 0.081819190842621 ),
 
  233   es_OVER_2( 0.040909595421311 ),
 
  234   Lambert_1_n( 0.70710678118655 ),
 
  235   Lambert_1_rho0( 6388838.2901212 ),
 
  236   Lambert_1_rho_olat( 6388838.2901211 ),
 
  237   Lambert_1_t0( 0.41618115138974 ),
 
  238   Lambert_Origin_Long( 0.0 ),
 
  239   Lambert_Origin_Latitude( (45 * 
PI / 180) ),
 
  240   Lambert_False_Easting( 0.0 ),
 
  241   Lambert_False_Northing( 0.0 ),
 
  242   Lambert_Scale_Factor( 1.0 ),
 
  243   Lambert_2_Origin_Lat( (45 * 
PI / 180) ),
 
  244   Lambert_2_Std_Parallel_1( (40 * 
PI / 180) ),
 
  245   Lambert_2_Std_Parallel_2( (50 * 
PI / 180) ),
 
  246   Lambert_Delta_Easting( 400000000.0 ),
 
  247   Lambert_Delta_Northing( 400000000.0 )
 
  283   double Lambert_false_northing;
 
  284   double inv_f = 1 / ellipsoidFlattening;
 
  286   if (ellipsoidSemiMajorAxis <= 0.0)
 
  290   if ((inv_f < 250) || (inv_f > 350))
 
  298   if ((standardParallel1 < -
MAX_LAT) || (standardParallel1 > 
MAX_LAT))
 
  302   if ((standardParallel2 < -
MAX_LAT) || (standardParallel2 > 
MAX_LAT))
 
  306   if ((standardParallel1 == 0) && (standardParallel2 == 0))
 
  310   if (standardParallel1 == -standardParallel2)
 
  315   if ((centralMeridian < -
PI) || (centralMeridian > 
TWO_PI))
 
  323   Lambert_2_Origin_Lat = originLatitude;
 
  324   Lambert_2_Std_Parallel_1 = standardParallel1;
 
  325   Lambert_2_Std_Parallel_2 = standardParallel2;
 
  327   if (centralMeridian > 
PI)
 
  328     centralMeridian -= 
TWO_PI;
 
  329   Lambert_Origin_Long = centralMeridian;
 
  330   Lambert_False_Easting = falseEasting;
 
  334     es_OVER_2 = es / 2.0;
 
  336   if (fabs(Lambert_2_Std_Parallel_1 - Lambert_2_Std_Parallel_2) > 1.0e-10)
 
  338     es_sin = esSin(sin(originLatitude));
 
  339     m_olat = lambertM(cos(originLatitude), es_sin);
 
  340     t_olat = lambertT(originLatitude, es_sin);
 
  342     es_sin = esSin(sin(Lambert_2_Std_Parallel_1));
 
  343     m1 = lambertM(cos(Lambert_2_Std_Parallel_1), es_sin);
 
  344     t1 = lambertT(Lambert_2_Std_Parallel_1, es_sin);
 
  346     es_sin = esSin(sin(Lambert_2_Std_Parallel_2));
 
  347     m2 = lambertM(cos(Lambert_2_Std_Parallel_2), es_sin);
 
  348     t2 = lambertT(Lambert_2_Std_Parallel_2, es_sin);
 
  350     n = log(m1 / m2) / log(t1 / t2);
 
  352     Lambert_lat0 = asin(n);
 
  354     es_sin = esSin(sin(Lambert_lat0));
 
  355     m0 = lambertM(cos(Lambert_lat0), es_sin);
 
  356     t0 = lambertT(Lambert_lat0, es_sin);
 
  358     Lambert_k0 = (m1 / m0) * (pow(t0 / t1, n));
 
  362     Lambert_false_northing =
 
  363        (const_value * pow(t_olat, n)) - (const_value * pow(t0, n))
 
  368     Lambert_lat0 = Lambert_2_Std_Parallel_1;
 
  370     Lambert_false_northing = falseNorthing;
 
  373   CommonParameters* parameters = setCommonLambert1StandardParallelParameters(
 
  374      Lambert_lat0, Lambert_false_northing, Lambert_k0);
 
  376   Lambert_1_n             = parameters->_lambertN;                         
 
  377   Lambert_1_rho0          = parameters->_lambertRho0;                       
 
  378   Lambert_1_rho_olat      = parameters->_lambertRhoOlat;
 
  379   Lambert_1_t0            = parameters->_lambertT0;
 
  380   Lambert_Origin_Latitude = parameters->_lambertOriginLatitude; 
 
  381   Lambert_False_Northing  = parameters->_lambertFalseNorthing;             
 
  382   Lambert_Scale_Factor    = parameters->_lambertScaleFactor;     
 
  390   coordinateType           = lcc.coordinateType;
 
  394   es_OVER_2                = lcc.es_OVER_2;
 
  395   Lambert_1_n              = lcc.Lambert_1_n;
 
  396   Lambert_1_rho0           = lcc.Lambert_1_rho0;
 
  397   Lambert_1_rho_olat       = lcc.Lambert_1_rho_olat;
 
  398   Lambert_1_t0             = lcc.Lambert_1_t0;
 
  399   Lambert_Origin_Long      = lcc.Lambert_Origin_Long;
 
  400   Lambert_Origin_Latitude  = lcc.Lambert_Origin_Latitude;
 
  401   Lambert_False_Easting    = lcc.Lambert_False_Easting;
 
  402   Lambert_False_Northing   = lcc.Lambert_False_Northing;
 
  403   Lambert_Scale_Factor     = lcc.Lambert_Scale_Factor;
 
  404   Lambert_2_Origin_Lat     = lcc.Lambert_2_Origin_Lat;
 
  405   Lambert_2_Std_Parallel_1 = lcc.Lambert_2_Std_Parallel_1;
 
  406   Lambert_2_Std_Parallel_2 = lcc.Lambert_2_Std_Parallel_2;
 
  407   Lambert_Delta_Easting    = lcc.Lambert_Delta_Easting;
 
  408   Lambert_Delta_Northing   = lcc.Lambert_Delta_Northing;
 
  422     coordinateType           = lcc.coordinateType;
 
  426     es_OVER_2                = lcc.es_OVER_2;
 
  427     Lambert_1_n              = lcc.Lambert_1_n;
 
  428     Lambert_1_rho0           = lcc.Lambert_1_rho0;
 
  429     Lambert_1_rho_olat       = lcc.Lambert_1_rho_olat;
 
  430     Lambert_1_t0             = lcc.Lambert_1_t0;
 
  431     Lambert_Origin_Long      = lcc.Lambert_Origin_Long;
 
  432     Lambert_Origin_Latitude  = lcc.Lambert_Origin_Latitude;
 
  433     Lambert_False_Easting    = lcc.Lambert_False_Easting;
 
  434     Lambert_False_Northing   = lcc.Lambert_False_Northing;
 
  435     Lambert_Scale_Factor     = lcc.Lambert_Scale_Factor;
 
  436     Lambert_2_Origin_Lat     = lcc.Lambert_2_Origin_Lat;
 
  437     Lambert_2_Std_Parallel_1 = lcc.Lambert_2_Std_Parallel_1;
 
  438     Lambert_2_Std_Parallel_2 = lcc.Lambert_2_Std_Parallel_2;
 
  439     Lambert_Delta_Easting    = lcc.Lambert_Delta_Easting;
 
  440     Lambert_Delta_Northing   = lcc.Lambert_Delta_Northing;
 
  484      Lambert_Origin_Long, Lambert_2_Origin_Lat,
 
  485      Lambert_2_Std_Parallel_1, Lambert_2_Std_Parallel_2,
 
  486      Lambert_False_Easting, Lambert_False_Northing );
 
  512   double longitude = geodeticCoordinates->
longitude();
 
  513   double latitude  = geodeticCoordinates->
latitude();
 
  519   if ((longitude < -
PI) || (longitude > 
TWO_PI))
 
  524   if (fabs(fabs(latitude) - 
PI_OVER_2) > 1.0e-10)
 
  526     t = lambertT(latitude, esSin(sin(latitude)));
 
  527     rho = Lambert_1_rho0 * pow(t / Lambert_1_t0, Lambert_1_n);
 
  531     if ((latitude * Lambert_1_n) <= 0)
 
  538   dlam = longitude - Lambert_Origin_Long;
 
  549   theta = Lambert_1_n * dlam;
 
  551   double easting = rho * sin(theta) + Lambert_False_Easting;
 
  552   double northing = Lambert_1_rho_olat - rho * cos(theta) + Lambert_False_Northing;
 
  576   double rho_olat_MINUS_dy;
 
  580   double tempPHI = 0.0;
 
  582   double tolerance = 4.85e-10;
 
  584   double longitude, latitude;
 
  586   double easting  = mapProjectionCoordinates->
easting();
 
  587   double northing = mapProjectionCoordinates->
northing();
 
  589   if ((easting < (Lambert_False_Easting - Lambert_Delta_Easting))
 
  590       ||(easting > (Lambert_False_Easting + Lambert_Delta_Easting)))
 
  594   if ((northing < (Lambert_False_Northing - Lambert_Delta_Northing))
 
  595       || (northing > (Lambert_False_Northing + Lambert_Delta_Northing)))
 
  600   dy                = northing - Lambert_False_Northing;
 
  601   dx                = easting  - Lambert_False_Easting;
 
  602   rho_olat_MINUS_dy = Lambert_1_rho_olat - dy;
 
  603   rho = sqrt(dx * dx + (rho_olat_MINUS_dy) * (rho_olat_MINUS_dy));
 
  605   if (Lambert_1_n < 0.0)
 
  609     rho_olat_MINUS_dy *= -1.0;
 
  614     theta = atan2(dx, rho_olat_MINUS_dy) / Lambert_1_n;
 
  615     t = Lambert_1_t0 * pow(rho / Lambert_1_rho0, 1 / Lambert_1_n);
 
  617     while (fabs(PHI - tempPHI) > tolerance && count)
 
  620       es_sin = esSin(sin(PHI));
 
  621       PHI = 
PI_OVER_2 - 2.0 * atan(t * pow((1.0 - es_sin) / (1.0 + es_sin), es_OVER_2));
 
  629     longitude = theta + Lambert_Origin_Long;
 
  631     if (fabs(latitude) < 2.0e-7)  
 
  640       if (longitude - 
PI < 3.5e-6) 
 
  647       if (fabs(longitude + 
PI) < 3.5e-6)
 
  653     if (fabs(longitude) < 2.0e-7)  
 
  657     else if (longitude < -
PI)
 
  662     if (Lambert_1_n > 0.0)
 
  666     longitude = Lambert_Origin_Long;
 
  673 LambertConformalConic::CommonParameters*
 
  674 LambertConformalConic::setCommonLambert1StandardParallelParameters(
 
  675    double originLatitude, 
double falseNorthing, 
double scaleFactor )
 
  692   if (((originLatitude < -
MAX_LAT) || (originLatitude > 
MAX_LAT)) ||
 
  702   CommonParameters* parameters = 
new CommonParameters();
 
  704   parameters->_lambertOriginLatitude = originLatitude;
 
  705   parameters->_lambertFalseNorthing  = falseNorthing;
 
  706   parameters->_lambertScaleFactor    = scaleFactor;
 
  708   parameters->_lambertN = sin(originLatitude);
 
  710   _esSin = esSin(sin(originLatitude));
 
  712   m0 = cos(originLatitude) / sqrt(1.0 - _esSin * _esSin);
 
  713   parameters->_lambertT0 = lambertT(originLatitude, _esSin);
 
  715   parameters->_lambertRho0 =
 
  718   parameters->_lambertRhoOlat = parameters->_lambertRho0;
 
  724 double LambertConformalConic::calculateLambert2StandardParallel(
 
  725    double es2, 
double phi, 
double tempPhi, 
double c)
 
  732   double tolerance = 1.0e-11;
 
  734   while (fabs(phi - tempPhi) > tolerance && count > 0)
 
  737     double sinPhi = sin(phi);
 
  738     double esSinPhi = es * sinPhi;
 
  739     double tPhi = lambertT(phi, esSinPhi);   
 
  740     double wPhi = sqrt(1 - es2 * sinPhi * sinPhi);
 
  741     double fPhi = cos(phi) / (wPhi * pow(tPhi, Lambert_1_n));
 
  742     double fprPhi = ((Lambert_1_n - sinPhi) * (1 - es2)) / (pow(wPhi, 3) * pow(tPhi, Lambert_1_n));
 
  744     phi = phi + (c - fPhi) / fprPhi;
 
  753 double LambertConformalConic::lambertM( 
double clat, 
double essin )
 
  755   return clat / sqrt(1.0 - essin * essin);
 
  759 double LambertConformalConic::lambertT( 
double lat, 
double essin )
 
  761   return tan(
PI_OVER_4 - lat / 2) / pow((1.0 - essin) / (1.0 + essin), es_OVER_2);
 
  765 double LambertConformalConic::esSin( 
double sinlat )