103 using namespace MSP::CCS;
111 const double PI = 3.14159265358979323e0;
126 VanDerGrinten::VanDerGrinten(
double ellipsoidSemiMajorAxis,
double ellipsoidFlattening,
double centralMeridian,
double falseEasting,
double falseNorthing ) :
128 es2( 0.0066943799901413800 ),
129 es4( 4.4814723452405e-005 ),
130 es6( 3.0000678794350e-007 ),
131 Ra( 6371007.1810824 ),
132 PI_Ra( 20015109.356056 ),
133 Grin_Origin_Long( 0.0 ),
134 Grin_False_Easting( 0.0 ),
135 Grin_False_Northing( 0.0 )
153 double inv_f = 1 / ellipsoidFlattening;
155 if (ellipsoidSemiMajorAxis <= 0.0)
159 if ((inv_f < 250) || (inv_f > 350))
163 if ((centralMeridian < -
PI) || (centralMeridian >
TWO_PI))
175 Ra =
semiMajorAxis * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 /3024.0);
177 if (centralMeridian >
PI)
178 centralMeridian -=
TWO_PI;
179 Grin_Origin_Long = centralMeridian;
180 Grin_False_Easting = falseEasting;
181 Grin_False_Northing = falseNorthing;
194 Grin_Origin_Long = v.Grin_Origin_Long;
195 Grin_False_Easting = v.Grin_False_Easting;
196 Grin_False_Northing = v.Grin_False_Northing;
216 Grin_Origin_Long = v.Grin_Origin_Long;
217 Grin_False_Easting = v.Grin_False_Easting;
218 Grin_False_Northing = v.Grin_False_Northing;
264 double gg_MINUS_ppsqr, ppsqr_PLUS_aasqr;
267 double sin_theta, cos_theta;
269 double easting, northing;
271 double longitude = geodeticCoordinates->
longitude();
272 double latitude = geodeticCoordinates->
latitude();
278 if ((longitude < -
PI) || (longitude >
TWO_PI))
283 dlam = longitude - Grin_Origin_Long;
295 easting = Ra * dlam + Grin_False_Easting;
298 else if (dlam == 0.0 || floatEq(latitude,
MAX_LAT,.00001) || floatEq(latitude,-
MAX_LAT,.00001))
304 else if (in_theta < -1.0)
307 theta = asin(in_theta);
309 northing = PI_Ra * tan(theta / 2) + Grin_False_Northing;
315 aa = 0.5 * fabs(
PI / dlam - dlam /
PI);
320 else if (in_theta < -1.0)
323 theta = asin(in_theta);
324 sin_theta = sin(theta);
325 cos_theta = cos(theta);
326 gg = cos_theta / (sin_theta + cos_theta - 1);
327 pp = gg * (2 / sin_theta - 1);
330 gg_MINUS_ppsqr = gg - ppsqr;
331 ppsqr_PLUS_aasqr = ppsqr + aasqr;
333 easting = PI_Ra * (aa * (gg_MINUS_ppsqr) +
334 sqrt(aasqr * (gg_MINUS_ppsqr) * (gg_MINUS_ppsqr) -
335 (ppsqr_PLUS_aasqr) * (gg * gg - ppsqr))) /
336 (ppsqr_PLUS_aasqr) + Grin_False_Easting;
339 northing = PI_Ra * (pp * qq - aa * sqrt ((aasqr + 1) * (ppsqr_PLUS_aasqr) - qq * qq)) /
340 (ppsqr_PLUS_aasqr) + Grin_False_Northing;
366 double yy, yysqr, two_yysqr;
367 double xxsqr_PLUS_yysqr;
378 const double epsilon = 1.0e-2;
379 double delta = PI_Ra + epsilon;
380 double longitude, latitude;
382 double easting = mapProjectionCoordinates->
easting();
383 double northing = mapProjectionCoordinates->
northing();
385 if ((easting > (Grin_False_Easting + delta)) ||
386 (easting < (Grin_False_Easting - delta)))
390 if ((northing > (Grin_False_Northing + delta)) ||
391 (northing < (Grin_False_Northing - delta)))
396 temp = sqrt(easting * easting + northing * northing);
398 if ((temp > (Grin_False_Easting + PI_Ra + epsilon)) ||
399 (temp > (Grin_False_Northing + PI_Ra + epsilon)) ||
400 (temp < (Grin_False_Easting - PI_Ra - epsilon)) ||
401 (temp < (Grin_False_Northing - PI_Ra - epsilon)))
406 dy = northing - Grin_False_Northing;
407 dx = easting - Grin_False_Easting;
412 xxsqr_PLUS_yysqr = xxsqr + yysqr;
413 two_yysqr = 2 * yysqr;
419 c1 = - fabs(yy) * (1 + xxsqr_PLUS_yysqr);
420 c2 = c1 - two_yysqr + xxsqr;
421 c3 = - 2 * c1 + 1 + two_yysqr + (xxsqr_PLUS_yysqr) * (xxsqr_PLUS_yysqr);
422 c2_OVER_3c3 = c2 / (3.0 * c3);
424 dd = yysqr / c3 + ((2 * c2 * c2 * c2) / (c3sqr * c3) - (9 * c1 * c2) / (c3sqr)) / 27;
425 a1 = (c1 - c2 * c2_OVER_3c3) /c3;
427 i = 3 * dd/ (a1 * m1);
428 if ((i > 1.0)||(i < -1.0))
432 theta1 =
ONE_THIRD * acos(3 * dd / (a1 * m1));
433 latitude =
PI * (-m1 * cos(theta1 +
PI_OVER_3) - c2_OVER_3c3);
440 longitude = Grin_Origin_Long;
443 longitude =
PI * (xxsqr_PLUS_yysqr - 1 +
444 sqrt(1 + (2 * xxsqr - two_yysqr) + (xxsqr_PLUS_yysqr) * (xxsqr_PLUS_yysqr))) /
445 (2 * xx) + Grin_Origin_Long;
459 else if (longitude < -
PI)
466 double VanDerGrinten::floatEq(
double x,
double v,
double epsilon )
468 return (((v - epsilon) < x) && (x < (v + epsilon)));