PageRenderTime 20ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/Proj4/pj_ell_set.c

http://github.com/route-me/route-me
C | 107 lines | 97 code | 4 blank | 6 comment | 37 complexity | 168563f4bd08b883dfc0c6ea4f079261 MD5 | raw file
  1. /* set ellipsoid parameters a and es */
  2. #ifndef lint
  3. static const char SCCSID[]="@(#)pj_ell_set.c 4.5 93/06/12 GIE REL";
  4. #endif
  5. #include "projects.h"
  6. #include <string.h>
  7. #define SIXTH .1666666666666666667 /* 1/6 */
  8. #define RA4 .04722222222222222222 /* 17/360 */
  9. #define RA6 .02215608465608465608 /* 67/3024 */
  10. #define RV4 .06944444444444444444 /* 5/72 */
  11. #define RV6 .04243827160493827160 /* 55/1296 */
  12. int /* initialize geographic shape parameters */
  13. pj_ell_set(paralist *pl, double *a, double *es) {
  14. int i;
  15. double b=0.0, e;
  16. char *name;
  17. paralist *start = 0, *curr;
  18. /* check for varying forms of ellipsoid input */
  19. *a = *es = 0.;
  20. /* R takes precedence */
  21. if (pj_param(pl, "tR").i)
  22. *a = pj_param(pl, "dR").f;
  23. else { /* probable elliptical figure */
  24. /* check if ellps present and temporarily append its values to pl */
  25. name = pj_param(pl, "sellps").s;
  26. if (name && pl) {
  27. char *s;
  28. for (start = pl; start && start->next ; start = start->next) ;
  29. curr = start;
  30. for (i = 0; (s = pj_ellps[i].id) && strcmp(name, s) ; ++i) ;
  31. if (!s) { pj_errno = -9; return 1; }
  32. curr->next = pj_mkparam(pj_ellps[i].major);
  33. curr = curr->next;
  34. curr->next = pj_mkparam(pj_ellps[i].ell);
  35. }
  36. *a = pj_param(pl, "da").f;
  37. if (pj_param(pl, "tes").i) /* eccentricity squared */
  38. *es = pj_param(pl, "des").f;
  39. else if (pj_param(pl, "te").i) { /* eccentricity */
  40. e = pj_param(pl, "de").f;
  41. *es = e * e;
  42. } else if (pj_param(pl, "trf").i) { /* recip flattening */
  43. *es = pj_param(pl, "drf").f;
  44. if (!*es) {
  45. pj_errno = -10;
  46. goto bomb;
  47. }
  48. *es = 1./ *es;
  49. *es = *es * (2. - *es);
  50. } else if (pj_param(pl, "tf").i) { /* flattening */
  51. *es = pj_param(pl, "df").f;
  52. *es = *es * (2. - *es);
  53. } else if (pj_param(pl, "tb").i) { /* minor axis */
  54. b = pj_param(pl, "db").f;
  55. *es = 1. - (b * b) / (*a * *a);
  56. } /* else *es == 0. and sphere of radius *a */
  57. if (!b)
  58. b = *a * sqrt(1. - *es);
  59. /* following options turn ellipsoid into equivalent sphere */
  60. if (pj_param(pl, "bR_A").i) { /* sphere--area of ellipsoid */
  61. *a *= 1. - *es * (SIXTH + *es * (RA4 + *es * RA6));
  62. *es = 0.;
  63. } else if (pj_param(pl, "bR_V").i) { /* sphere--vol. of ellipsoid */
  64. *a *= 1. - *es * (SIXTH + *es * (RV4 + *es * RV6));
  65. *es = 0.;
  66. } else if (pj_param(pl, "bR_a").i) { /* sphere--arithmetic mean */
  67. *a = .5 * (*a + b);
  68. *es = 0.;
  69. } else if (pj_param(pl, "bR_g").i) { /* sphere--geometric mean */
  70. *a = sqrt(*a * b);
  71. *es = 0.;
  72. } else if (pj_param(pl, "bR_h").i) { /* sphere--harmonic mean */
  73. *a = 2. * *a * b / (*a + b);
  74. *es = 0.;
  75. } else if ((i = pj_param(pl, "tR_lat_a").i) || /* sphere--arith. */
  76. pj_param(pl, "tR_lat_g").i) { /* or geom. mean at latitude */
  77. double tmp;
  78. tmp = sin(pj_param(pl, i ? "rR_lat_a" : "rR_lat_g").f);
  79. if (fabs(tmp) > HALFPI) {
  80. pj_errno = -11;
  81. goto bomb;
  82. }
  83. tmp = 1. - *es * tmp * tmp;
  84. *a *= i ? .5 * (1. - *es + tmp) / ( tmp * sqrt(tmp)) :
  85. sqrt(1. - *es) / tmp;
  86. *es = 0.;
  87. }
  88. bomb:
  89. if (start) { /* clean up temporary extension of list */
  90. pj_dalloc(start->next->next);
  91. pj_dalloc(start->next);
  92. start->next = 0;
  93. }
  94. if (pj_errno)
  95. return 1;
  96. }
  97. /* some remaining checks */
  98. if (*es < 0.)
  99. { pj_errno = -12; return 1; }
  100. if (*a <= 0.)
  101. { pj_errno = -13; return 1; }
  102. return 0;
  103. }