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 )