116 using namespace MSP::CCS;
124 const double PI = 3.14159265358979323e0;
129 #define MIN_SCALE_FACTOR 0.1
130 #define MAX_SCALE_FACTOR 3.0
139 double ellipsoidSemiMajorAxis,
140 double ellipsoidFlattening,
141 double centralMeridian,
142 double standardParallel,
144 double falseNorthing ) :
146 coordinateType(
CoordinateType::polarStereographicStandardParallel ),
147 es( 0.08181919084262188000 ),
148 es_OVER_2( .040909595421311 ),
149 Southern_Hemisphere( 0 ),
151 Polar_k90( 1.0033565552493 ),
152 Polar_a_mc( 6378137.0 ),
153 two_Polar_a( 12756274.0 ),
154 Polar_Central_Meridian( 0.0 ),
155 Polar_Standard_Parallel( ((
PI * 90) / 180) ),
156 Polar_False_Easting( 0.0 ),
157 Polar_False_Northing( 0.0 ),
158 Polar_Scale_Factor( 1.0 ),
159 Polar_Delta_Easting( 12713601.0 ),
160 Polar_Delta_Northing( 12713601.0 )
177 double slat, sinolat, cosolat;
179 double one_PLUS_es, one_MINUS_es;
180 double one_PLUS_es_sinolat, one_MINUS_es_sinolat;
182 double inv_f = 1 / ellipsoidFlattening;
184 if (ellipsoidSemiMajorAxis <= 0.0)
188 if ((inv_f < 250) || (inv_f > 350))
196 if ((centralMeridian < -
PI) || (centralMeridian >
TWO_PI))
206 if (centralMeridian >
PI)
207 centralMeridian -=
TWO_PI;
208 if (standardParallel < 0)
210 Southern_Hemisphere = 1;
211 Polar_Standard_Parallel = -standardParallel;
212 Polar_Central_Meridian = -centralMeridian;
216 Southern_Hemisphere = 0;
217 Polar_Standard_Parallel = standardParallel;
218 Polar_Central_Meridian = centralMeridian;
220 Polar_False_Easting = falseEasting;
221 Polar_False_Northing = falseNorthing;
225 es_OVER_2 = es / 2.0;
227 if (fabs(fabs(Polar_Standard_Parallel) -
PI_OVER_2) > 1.0e-10)
229 sinolat = sin(Polar_Standard_Parallel);
230 essin = es * sinolat;
231 pow_es = polarPow(essin);
232 cosolat = cos(Polar_Standard_Parallel);
233 double mc = cosolat / sqrt(1.0 - essin * essin);
235 Polar_tc = tan(
PI_OVER_4 - Polar_Standard_Parallel / 2.0) / pow_es;
238 one_PLUS_es = 1.0 + es;
239 one_MINUS_es = 1.0 - es;
240 Polar_k90 = sqrt(pow(one_PLUS_es, one_PLUS_es) * pow(one_MINUS_es, one_MINUS_es));
242 slat = sin(fabs(standardParallel));
243 one_PLUS_es_sinolat = 1.0 + es * slat;
244 one_MINUS_es_sinolat = 1.0 - es * slat;
245 Polar_Scale_Factor = ((1 + slat) / 2) * (Polar_k90 / sqrt(pow(one_PLUS_es_sinolat, one_PLUS_es) * pow(one_MINUS_es_sinolat, one_MINUS_es)));
251 Polar_Delta_Northing = tempCoordinates->
northing();
252 delete tempCoordinates;
254 if(Polar_False_Northing)
255 Polar_Delta_Northing -= Polar_False_Northing;
256 if (Polar_Delta_Northing < 0)
257 Polar_Delta_Northing = -Polar_Delta_Northing;
258 Polar_Delta_Northing *= 1.01;
260 Polar_Delta_Easting = Polar_Delta_Northing;
264 PolarStereographic::PolarStereographic(
double ellipsoidSemiMajorAxis,
double ellipsoidFlattening,
double centralMeridian,
double scaleFactor,
char hemisphere,
double falseEasting,
double falseNorthing ) :
267 es( 0.08181919084262188000 ),
268 es_OVER_2( .040909595421311 ),
269 Southern_Hemisphere( 0 ),
271 Polar_k90( 1.0033565552493 ),
272 Polar_a_mc( 6378137.0 ),
273 two_Polar_a( 12756274.0 ),
274 Polar_Central_Meridian( 0.0 ),
275 Polar_Standard_Parallel( ((
PI * 90) / 180) ),
276 Polar_False_Easting( 0.0 ),
277 Polar_False_Northing( 0.0 ),
278 Polar_Scale_Factor( 1.0 ),
279 Polar_Delta_Easting( 12713601.0 ),
280 Polar_Delta_Northing( 12713601.0 )
297 double sinolat, cosolat;
301 double one_PLUS_es, one_MINUS_es;
302 double one_PLUS_es_sk, one_MINUS_es_sk;
303 double sk, sk_PLUS_1;
304 double tolerance = 1.0e-15;
306 double inv_f = 1 / ellipsoidFlattening;
308 if (ellipsoidSemiMajorAxis <= 0.0)
312 if ((inv_f < 250) || (inv_f > 350))
320 if ((centralMeridian < -
PI) || (centralMeridian >
TWO_PI))
324 if ((hemisphere !=
'N') && (hemisphere !=
'S'))
329 Polar_Scale_Factor = scaleFactor;
330 Polar_False_Easting = falseEasting;
331 Polar_False_Northing = falseNorthing;
336 es_OVER_2 = es / 2.0;
338 one_PLUS_es = 1.0 + es;
339 one_MINUS_es = 1.0 - es;
340 Polar_k90 = sqrt(pow(one_PLUS_es, one_PLUS_es) * pow(one_MINUS_es, one_MINUS_es));
343 sk_PLUS_1 = -1 + 2 * Polar_Scale_Factor;
344 while (fabs(sk_PLUS_1 - sk) > tolerance && count)
347 one_PLUS_es_sk = 1.0 + es * sk;
348 one_MINUS_es_sk = 1.0 - es * sk;
349 sk_PLUS_1 = ((2 * Polar_Scale_Factor * sqrt(pow(one_PLUS_es_sk, one_PLUS_es) * pow(one_MINUS_es_sk, one_MINUS_es))) / Polar_k90) - 1;
356 double standardParallel = 0.0;
357 if(sk_PLUS_1 >= -1.0 && sk_PLUS_1 <= 1.0)
358 standardParallel = asin(sk_PLUS_1);
362 if (hemisphere ==
'S')
363 standardParallel *= -1.0;
365 if (centralMeridian >
PI)
366 centralMeridian -=
TWO_PI;
367 if (standardParallel < 0)
369 Southern_Hemisphere = 1;
370 Polar_Standard_Parallel = -standardParallel;
371 Polar_Central_Meridian = -centralMeridian;
375 Southern_Hemisphere = 0;
376 Polar_Standard_Parallel = standardParallel;
377 Polar_Central_Meridian = centralMeridian;
380 sinolat = sin(Polar_Standard_Parallel);
382 if (fabs(fabs(Polar_Standard_Parallel) -
PI_OVER_2) > 1.0e-10)
384 essin = es * sinolat;
385 pow_es = polarPow(essin);
386 cosolat = cos(Polar_Standard_Parallel);
387 mc = cosolat / sqrt(1.0 - essin * essin);
389 Polar_tc = tan(
PI_OVER_4 - Polar_Standard_Parallel / 2.0) / pow_es;
395 Polar_Delta_Northing = tempCoordinates->
northing();
396 delete tempCoordinates;
398 if(Polar_False_Northing)
399 Polar_Delta_Northing -= Polar_False_Northing;
400 if (Polar_Delta_Northing < 0)
401 Polar_Delta_Northing = -Polar_Delta_Northing;
402 Polar_Delta_Northing *= 1.01;
404 Polar_Delta_Easting = Polar_Delta_Northing;
410 coordinateType = ps.coordinateType;
414 es_OVER_2 = ps.es_OVER_2;
415 Southern_Hemisphere = ps.Southern_Hemisphere;
416 Polar_tc = ps.Polar_tc;
417 Polar_k90 = ps.Polar_k90;
418 Polar_a_mc = ps.Polar_a_mc;
419 two_Polar_a = ps.two_Polar_a;
420 Polar_Central_Meridian = ps.Polar_Central_Meridian;
421 Polar_Standard_Parallel = ps.Polar_Standard_Parallel;
422 Polar_False_Easting = ps.Polar_False_Easting;
423 Polar_False_Northing = ps.Polar_False_Northing;
424 Polar_Scale_Factor = ps.Polar_Scale_Factor;
425 Polar_Delta_Easting = ps.Polar_Delta_Easting;
426 Polar_Delta_Northing = ps.Polar_Delta_Northing;
439 coordinateType = ps.coordinateType;
443 es_OVER_2 = ps.es_OVER_2;
444 Southern_Hemisphere = ps.Southern_Hemisphere;
445 Polar_tc = ps.Polar_tc;
446 Polar_k90 = ps.Polar_k90;
447 Polar_a_mc = ps.Polar_a_mc;
448 two_Polar_a = ps.two_Polar_a;
449 Polar_Central_Meridian = ps.Polar_Central_Meridian;
450 Polar_Standard_Parallel = ps.Polar_Standard_Parallel;
451 Polar_False_Easting = ps.Polar_False_Easting;
452 Polar_False_Northing = ps.Polar_False_Northing;
453 Polar_Scale_Factor = ps.Polar_Scale_Factor;
454 Polar_Delta_Easting = ps.Polar_Delta_Easting;
455 Polar_Delta_Northing = ps.Polar_Delta_Northing;
494 if(Southern_Hemisphere == 0)
522 double easting, northing;
524 double longitude = geodeticCoordinates->
longitude();
525 double latitude = geodeticCoordinates->
latitude();
531 else if ((latitude < 0) && (Southern_Hemisphere == 0))
535 else if ((latitude > 0) && (Southern_Hemisphere == 1))
539 if ((longitude < -
PI) || (longitude >
TWO_PI))
544 if (fabs(fabs(latitude) -
PI_OVER_2) < 1.0e-10)
546 easting = Polar_False_Easting;
547 northing = Polar_False_Northing;
551 if (Southern_Hemisphere != 0)
556 dlam = longitude - Polar_Central_Meridian;
565 slat = sin(latitude);
567 pow_es = polarPow(essin);
568 t = tan(
PI_OVER_4 - latitude / 2.0) / pow_es;
570 if (fabs(fabs(Polar_Standard_Parallel) -
PI_OVER_2) > 1.0e-10)
571 rho = Polar_a_mc * t / Polar_tc;
573 rho = two_Polar_a * t / Polar_k90;
576 if (Southern_Hemisphere != 0)
578 easting = -(rho * sin(dlam) - Polar_False_Easting);
579 northing = rho * cos(dlam) + Polar_False_Northing;
583 easting = rho * sin(dlam) + Polar_False_Easting;
584 northing = -rho * cos(dlam) + Polar_False_Northing;
608 double dy = 0, dx = 0;
612 double tempPHI = 0.0;
616 double longitude, latitude;
618 double easting = mapProjectionCoordinates->
easting();
619 double northing = mapProjectionCoordinates->
northing();
621 double min_easting = Polar_False_Easting - Polar_Delta_Easting;
622 double max_easting = Polar_False_Easting + Polar_Delta_Easting;
623 double min_northing = Polar_False_Northing - Polar_Delta_Northing;
624 double max_northing = Polar_False_Northing + Polar_Delta_Northing;
626 if (easting > max_easting || easting < min_easting)
630 if (northing > max_northing || northing < min_northing)
635 dy = northing - Polar_False_Northing;
636 dx = easting - Polar_False_Easting;
639 rho = sqrt(dx * dx + dy * dy);
642 Polar_Delta_Easting * Polar_Delta_Easting +
643 Polar_Delta_Northing * Polar_Delta_Northing);
645 if(rho > delta_radius)
650 if ((dy == 0.0) && (dx == 0.0))
653 longitude = Polar_Central_Meridian;
657 if (Southern_Hemisphere != 0)
663 if (fabs(fabs(Polar_Standard_Parallel) -
PI_OVER_2) > 1.0e-10)
664 t = rho * Polar_tc / (Polar_a_mc);
666 t = rho * Polar_k90 / (two_Polar_a);
668 while (fabs(PHI - tempPHI) > 1.0e-10)
672 essin = es * sin_PHI;
673 pow_es = polarPow(essin);
674 PHI =
PI_OVER_2 - 2.0 * atan(t * pow_es);
677 longitude = Polar_Central_Meridian + atan2(dx, -dy);
681 else if (longitude < -
PI)
692 else if (longitude < -
PI)
696 if (Southern_Hemisphere != 0)
707 double PolarStereographic::polarPow(
double esSin )
709 return pow((1.0 - esSin) / (1.0 + esSin), es_OVER_2);