/*! * \file lib/gis/area_ellipse.c * * \brief GIS Library - Ellipse area routines. * * (C) 2001-2009 by the GRASS Development Team * * This program is free software under the GNU General Public License * (>=v2). Read the file COPYING that comes with GRASS for details. * * \author Original author CERL */ #include #include #include "pi.h" static struct state { double E; double M; } state; static struct state *st = &state; /* * a is semi-major axis, e2 is eccentricity squared, s is a scale factor * code will fail if e2==0 (sphere) */ /*! * \brief Begin area calculations for ellipsoid. * * Initializes raster area calculations for an ellipsoid, where a * is the semi-major axis of the ellipse (in meters), e2 is the * ellipsoid eccentricity squared, and s is a scale factor to * allow for calculations of part of the zone (s=1.0 is full * zone, s=0.5 is half the zone, and s=360/ew_res is for a * single grid cell). * * Note: e2 must be positive. A negative value makes no * sense, and zero implies a sphere. * * \param a semi-major axis * \param e2 ellipsoid eccentricity * \param s scale factor */ void G_begin_zone_area_on_ellipsoid(double a, double e2, double s) { st->E = sqrt(e2); st->M = s * a * a * M_PI * (1 - e2) / st->E; } /*! * \brief Calculate integral for area between two latitudes. * * This routine is part of the integral for the area between two * latitudes. * * \param lat latitude * * \return cell area */ double G_darea0_on_ellipsoid(double lat) { double x; x = st->E * sin(Radians(lat)); return (st->M * (x / (1.0 - x * x) + 0.5 * log((1.0 + x) / (1.0 - x)))); } /*! * \brief Calculates area between latitudes. * * This routine shows how to calculate area between two lats, but * isn't efficient for row by row since G_darea0_on_ellipsoid() * will be called twice for the same lat, once as a south then * again as a north. * * Returns the area between latitudes north and south * scaled by the factor s passed to * G_begin_zone_area_on_ellipsoid(). * * \param north north coordinate * \param south south coordinate * * \return cell area */ double G_area_for_zone_on_ellipsoid(double north, double south) { return (G_darea0_on_ellipsoid(north) - G_darea0_on_ellipsoid(south)); }