area_ellipse.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*!
  2. * \file lib/gis/area_ellipse.c
  3. *
  4. * \brief GIS Library - Ellipse area routines.
  5. *
  6. * (C) 2001-2009 by the GRASS Development Team
  7. *
  8. * This program is free software under the GNU General Public License
  9. * (>=v2). Read the file COPYING that comes with GRASS for details.
  10. *
  11. * \author Original author CERL
  12. */
  13. #include <math.h>
  14. #include <grass/gis.h>
  15. #include "pi.h"
  16. static struct state {
  17. double E;
  18. double M;
  19. } state;
  20. static struct state *st = &state;
  21. /*
  22. * a is semi-major axis, e2 is eccentricity squared, s is a scale factor
  23. * code will fail if e2==0 (sphere)
  24. */
  25. /*!
  26. * \brief Begin area calculations for ellipsoid.
  27. *
  28. * Initializes raster area calculations for an ellipsoid, where <i>a</i>
  29. * is the semi-major axis of the ellipse (in meters), <i>e2</i> is the
  30. * ellipsoid eccentricity squared, and <i>s</i> is a scale factor to
  31. * allow for calculations of part of the zone (<i>s</i>=1.0 is full
  32. * zone, <i>s</i>=0.5 is half the zone, and <i>s</i>=360/ew_res is for a
  33. * single grid cell).
  34. *
  35. * <b>Note:</b> <i>e2</i> must be positive. A negative value makes no
  36. * sense, and zero implies a sphere.
  37. *
  38. * \param a semi-major axis
  39. * \param e2 ellipsoid eccentricity
  40. * \param s scale factor
  41. */
  42. void G_begin_zone_area_on_ellipsoid(double a, double e2, double s)
  43. {
  44. st->E = sqrt(e2);
  45. st->M = s * a * a * M_PI * (1 - e2) / st->E;
  46. }
  47. /*!
  48. * \brief Calculate integral for area between two latitudes.
  49. *
  50. * This routine is part of the integral for the area between two
  51. * latitudes.
  52. *
  53. * \param lat latitude
  54. *
  55. * \return cell area
  56. */
  57. double G_darea0_on_ellipsoid(double lat)
  58. {
  59. double x;
  60. x = st->E * sin(Radians(lat));
  61. return (st->M * (x / (1.0 - x * x) + 0.5 * log((1.0 + x) / (1.0 - x))));
  62. }
  63. /*!
  64. * \brief Calculates area between latitudes.
  65. *
  66. * This routine shows how to calculate area between two lats, but
  67. * isn't efficient for row by row since G_darea0_on_ellipsoid()
  68. * will be called twice for the same lat, once as a <i>south</i> then
  69. * again as a <i>north</i>.
  70. *
  71. * Returns the area between latitudes <i>north</i> and <i>south</i>
  72. * scaled by the factor <i>s</i> passed to
  73. * G_begin_zone_area_on_ellipsoid().
  74. *
  75. * \param north north coordinate
  76. * \param south south coordinate
  77. *
  78. * \return cell area
  79. */
  80. double G_area_for_zone_on_ellipsoid(double north, double south)
  81. {
  82. return (G_darea0_on_ellipsoid(north) - G_darea0_on_ellipsoid(south));
  83. }