GRASS 8 Programmer's Manual  8.5.0dev(2025)-c070206eb1
gis/area.c
Go to the documentation of this file.
1 /*!
2  * \file lib/gis/area.c
3  *
4  * \brief GIS Library - Area calculation functions.
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 
14 #include <grass/gis.h>
15 
16 static struct state {
17  struct Cell_head window;
18  double square_meters;
19  int projection;
20 
21  double units_to_meters_squared;
22 
23  /* these next are for lat-long only */
24  int next_row;
25  double north_value;
26  double north;
27  double (*darea0)(double);
28 } state;
29 
30 static struct state *st = &state;
31 
32 /*!
33  * \brief Begin cell area calculations.
34  *
35  * This routine must be called once before any call to
36  * G_area_of_cell_at_row(). It perform all initializations needed to
37  * do area calculations for grid cells, based on the current window
38  * "projection" field. It can be used in either planimetric
39  * projections or the latitude-longitude projection.
40  *
41  * \return 0 if the projection is not measurable (ie. imagery or xy)
42  * \return 1 if the projection is planimetric (ie. UTM or SP)
43  * \return 2 if the projection is non-planimetric (ie. latitude-longitude)
44  */
46 {
47  double a, e2;
48  double factor;
49 
50  G_get_set_window(&st->window);
51  switch (st->projection = st->window.proj) {
52  case PROJECTION_LL:
54  if (e2) {
55  G_begin_zone_area_on_ellipsoid(a, e2, st->window.ew_res / 360.0);
56  st->darea0 = G_darea0_on_ellipsoid;
57  }
58  else {
59  G_begin_zone_area_on_sphere(a, st->window.ew_res / 360.0);
60  st->darea0 = G_darea0_on_sphere;
61  }
62  st->next_row = 0;
63  st->north = st->window.north;
64  st->north_value = st->darea0(st->north);
65  return 2;
66  default:
67  st->square_meters = st->window.ns_res * st->window.ew_res;
69  if (factor > 0.0)
70  st->square_meters *= (factor * factor);
71  return (factor > 0.0);
72  }
73 }
74 
75 /*!
76  * \brief Cell area in specified row.
77  *
78  * This routine returns the area in square meters of a cell in the
79  * specified <i>row</i>. This value is constant for planimetric grids
80  * and varies with the row if the projection is latitude-longitude.
81  *
82  * \param row row number
83  *
84  * \return cell area
85  */
86 double G_area_of_cell_at_row(int row)
87 {
88  double south_value;
89  double cell_area;
90 
91  if (st->projection != PROJECTION_LL)
92  return st->square_meters;
93 
94  if (row != st->next_row) {
95  st->north = st->window.north - row * st->window.ns_res;
96  st->north_value = st->darea0(st->north);
97  }
98 
99  st->north -= st->window.ns_res;
100  south_value = st->darea0(st->north);
101  cell_area = st->north_value - south_value;
102 
103  st->next_row = row + 1;
104  st->north_value = south_value;
105 
106  return cell_area;
107 }
108 
109 /*!
110  * \brief Begin polygon area calculations.
111  *
112  * This initializes the polygon area calculation routines. It is used
113  * both for planimetric and latitude-longitude projections.
114  *
115  * \return 0 if the projection is not measurable (ie. imagery or xy)
116  * \return 1 if the projection is planimetric (ie. UTM or SP)
117  * \return 2 if the projection is non-planimetric (ie. latitude-longitude)
118  */
120 {
121  double a, e2;
122  double factor;
123 
124  if ((st->projection = G_projection()) == PROJECTION_LL) {
127  return 2;
128  }
130  if (factor > 0.0) {
131  st->units_to_meters_squared = factor * factor;
132  return 1;
133  }
134  st->units_to_meters_squared = 1.0;
135  return 0;
136 }
137 
138 /*!
139  * \brief Area in square meters of polygon.
140  *
141  * Returns the area in square meters of the polygon described by the
142  * <i>n</i> pairs of <i>x,y</i> coordinate vertices. It is used both for
143  * planimetric and latitude-longitude projections.
144  *
145  * You should call G_begin_polygon_area_calculations() function before
146  * calling this function.
147  *
148  * <b>Note:</b> If the database is planimetric with the non-meter grid,
149  * this routine performs the required unit conversion to produce square
150  * meters.
151  *
152  * \param x array of x coordinates
153  * \param y array of y coordinates
154  * \param n number of x,y coordinate pairs
155  *
156  * \return area in square meters of the polygon
157  */
158 double G_area_of_polygon(const double *x, const double *y, int n)
159 {
160  double area;
161 
162  if (st->projection == PROJECTION_LL)
163  area = G_ellipsoid_polygon_area(x, y, n);
164  else
165  area =
166  G_planimetric_polygon_area(x, y, n) * st->units_to_meters_squared;
167 
168  return area;
169 }
void G_begin_ellipsoid_polygon_area(double, double)
Begin area calculations.
Definition: area_poly1.c:65
double G_darea0_on_sphere(double)
Calculates integral for area between two latitudes.
Definition: area_sphere.c:47
int G_get_ellipsoid_parameters(double *, double *)
get ellipsoid parameters
Definition: get_ellipse.c:66
double G_database_units_to_meters_factor(void)
Conversion to meters.
Definition: proj3.c:146
void G_get_set_window(struct Cell_head *)
Get the current working window (region)
double G_planimetric_polygon_area(const double *, const double *, int)
Calculates planimetric polygon area.
Definition: area_poly2.c:25
void G_begin_zone_area_on_sphere(double, double)
Initialize calculations for sphere.
Definition: area_sphere.c:35
double G_darea0_on_ellipsoid(double)
Calculate integral for area between two latitudes.
Definition: area_ellipse.c:63
void G_begin_zone_area_on_ellipsoid(double, double, double)
Begin area calculations for ellipsoid.
Definition: area_ellipse.c:47
double G_ellipsoid_polygon_area(const double *, const double *, int)
Area of lat-long polygon.
Definition: area_poly1.c:133
int G_projection(void)
Query cartographic projection.
Definition: proj1.c:32
double G_area_of_cell_at_row(int row)
Cell area in specified row.
Definition: gis/area.c:86
int G_begin_cell_area_calculations(void)
Begin cell area calculations.
Definition: gis/area.c:45
double G_area_of_polygon(const double *x, const double *y, int n)
Area in square meters of polygon.
Definition: gis/area.c:158
int G_begin_polygon_area_calculations(void)
Begin polygon area calculations.
Definition: gis/area.c:119
#define PROJECTION_LL
Projection code - Latitude-Longitude.
Definition: gis.h:129
struct state state
Definition: parser.c:103
struct state * st
Definition: parser.c:104
2D/3D raster map header (used also for region)
Definition: gis.h:446
double north
Extent coordinates (north)
Definition: gis.h:492
#define x