PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ geography_centroid()

Datum geography_centroid ( PG_FUNCTION_ARGS  )

Definition at line 53 of file geography_centroid.c.

54 {
55  LWGEOM *lwgeom = NULL;
56  LWGEOM *lwgeom_out = NULL;
57  LWPOINT *lwpoint_out = NULL;
58  GSERIALIZED *g = NULL;
59  GSERIALIZED *g_out = NULL;
60  int32_t srid;
61  bool use_spheroid = true;
62  SPHEROID s;
63 
64  /* Get our geometry object loaded into memory. */
65  g = PG_GETARG_GSERIALIZED_P(0);
66  lwgeom = lwgeom_from_gserialized(g);
67 
68  if (g == NULL)
69  {
70  PG_RETURN_NULL();
71  }
72 
73  srid = lwgeom_get_srid(lwgeom);
74 
75  /* on empty input, return empty output */
76  if (gserialized_is_empty(g))
77  {
79  lwgeom_out = lwcollection_as_lwgeom(empty);
80  g_out = geography_serialize(lwgeom_out);
81  PG_RETURN_POINTER(g_out);
82  }
83 
84  /* Initialize spheroid */
85  spheroid_init_from_srid(fcinfo, srid, &s);
86 
87  /* Set to sphere if requested */
88  use_spheroid = PG_GETARG_BOOL(1);
89  if ( ! use_spheroid )
90  s.a = s.b = s.radius;
91 
92  switch (lwgeom_get_type(lwgeom))
93  {
94 
95  case POINTTYPE:
96  {
97  /* centroid of a point is itself */
98  PG_RETURN_POINTER(g);
99  break;
100  }
101 
102  case MULTIPOINTTYPE:
103  {
104  LWMPOINT* mpoints = lwgeom_as_lwmpoint(lwgeom);
105 
106  /* average between all points */
107  uint32_t size = mpoints->ngeoms;
108  POINT3DM* points = palloc(size*sizeof(POINT3DM));
109 
110  uint32_t i;
111  for (i = 0; i < size; i++) {
112  points[i].x = lwpoint_get_x(mpoints->geoms[i]);
113  points[i].y = lwpoint_get_y(mpoints->geoms[i]);
114  points[i].m = 1;
115  }
116 
117  lwpoint_out = geography_centroid_from_wpoints(srid, points, size);
118  pfree(points);
119  break;
120  }
121 
122  case LINETYPE:
123  {
124  LWLINE* line = lwgeom_as_lwline(lwgeom);
125 
126  /* reuse mline function */
127  LWMLINE* mline = lwmline_construct_empty(srid, 0, 0);
128  lwmline_add_lwline(mline, line);
129 
130  lwpoint_out = geography_centroid_from_mline(mline, &s);
131  lwmline_free(mline);
132  break;
133  }
134 
135  case MULTILINETYPE:
136  {
137  LWMLINE* mline = lwgeom_as_lwmline(lwgeom);
138  lwpoint_out = geography_centroid_from_mline(mline, &s);
139  break;
140  }
141 
142  case POLYGONTYPE:
143  {
144  LWPOLY* poly = lwgeom_as_lwpoly(lwgeom);
145 
146  /* reuse mpoly function */
147  LWMPOLY* mpoly = lwmpoly_construct_empty(srid, 0, 0);
148  lwmpoly_add_lwpoly(mpoly, poly);
149 
150  lwpoint_out = geography_centroid_from_mpoly(mpoly, use_spheroid, &s);
151  lwmpoly_free(mpoly);
152  break;
153  }
154 
155  case MULTIPOLYGONTYPE:
156  {
157  LWMPOLY* mpoly = lwgeom_as_lwmpoly(lwgeom);
158  lwpoint_out = geography_centroid_from_mpoly(mpoly, use_spheroid, &s);
159  break;
160  }
161  default:
162  elog(ERROR, "ST_Centroid(geography) unhandled geography type");
163  PG_RETURN_NULL();
164  }
165 
166  PG_FREE_IF_COPY(g, 0);
167 
168  lwgeom_out = lwpoint_as_lwgeom(lwpoint_out);
169  g_out = geography_serialize(lwgeom_out);
170 
171  PG_RETURN_POINTER(g_out);
172 }
char * s
Definition: cu_in_wkt.c:23
LWPOINT * geography_centroid_from_mpoly(const LWMPOLY *mpoly, bool use_spheroid, SPHEROID *s)
Split polygons into triangles and use centroid of the triangle with the triangle area as weight to ca...
LWPOINT * geography_centroid_from_mline(const LWMLINE *mline, SPHEROID *s)
Split lines into segments and calculate with middle of segment as weighted point.
LWPOINT * geography_centroid_from_wpoints(const int32_t srid, const POINT3DM *points, const uint32_t size)
Convert lat-lon-points to x-y-z-coordinates, calculate a weighted average point and return lat-lon-co...
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:239
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
Definition: gserialized.c:152
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:161
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition: lwgeom.c:291
#define COLLECTIONTYPE
Definition: liblwgeom.h:122
int32_t lwgeom_get_srid(const LWGEOM *geom)
Return SRID number.
Definition: lwgeom.c:909
LWMPOINT * lwgeom_as_lwmpoint(const LWGEOM *lwgeom)
Definition: lwgeom.c:224
void lwmpoly_free(LWMPOLY *mpoly)
Definition: lwmpoly.c:53
#define MULTILINETYPE
Definition: liblwgeom.h:120
#define LINETYPE
Definition: liblwgeom.h:117
#define MULTIPOINTTYPE
Definition: liblwgeom.h:119
double lwpoint_get_x(const LWPOINT *point)
Definition: lwpoint.c:63
LWMLINE * lwmline_add_lwline(LWMLINE *mobj, const LWLINE *obj)
Definition: lwmline.c:46
LWMPOLY * lwgeom_as_lwmpoly(const LWGEOM *lwgeom)
Definition: lwgeom.c:242
LWMLINE * lwmline_construct_empty(int32_t srid, char hasz, char hasm)
Definition: lwmline.c:38
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:116
LWMLINE * lwgeom_as_lwmline(const LWGEOM *lwgeom)
Definition: lwgeom.c:233
LWMPOLY * lwmpoly_add_lwpoly(LWMPOLY *mobj, const LWPOLY *obj)
Definition: lwmpoly.c:47
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:121
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition: lwgeom.c:326
#define POLYGONTYPE
Definition: liblwgeom.h:118
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
Definition: lwcollection.c:92
void lwmline_free(LWMLINE *mline)
Definition: lwmline.c:112
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
Definition: lwgeom.c:197
LWMPOLY * lwmpoly_construct_empty(int32_t srid, char hasz, char hasm)
Definition: lwmpoly.c:40
double lwpoint_get_y(const LWPOINT *point)
Definition: lwpoint.c:76
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Definition: lwinline.h:135
uint32_t ngeoms
Definition: liblwgeom.h:524
LWPOINT ** geoms
Definition: liblwgeom.h:519
double m
Definition: liblwgeom.h:394
double x
Definition: liblwgeom.h:394
double y
Definition: liblwgeom.h:394

References COLLECTIONTYPE, geography_centroid_from_mline(), geography_centroid_from_mpoly(), geography_centroid_from_wpoints(), LWMPOINT::geoms, gserialized_is_empty(), LINETYPE, lwcollection_as_lwgeom(), lwcollection_construct_empty(), lwgeom_as_lwline(), lwgeom_as_lwmline(), lwgeom_as_lwmpoint(), lwgeom_as_lwmpoly(), lwgeom_as_lwpoly(), lwgeom_from_gserialized(), lwgeom_get_srid(), lwgeom_get_type(), lwmline_add_lwline(), lwmline_construct_empty(), lwmline_free(), lwmpoly_add_lwpoly(), lwmpoly_construct_empty(), lwmpoly_free(), lwpoint_as_lwgeom(), lwpoint_get_x(), lwpoint_get_y(), POINT3DM::m, MULTILINETYPE, MULTIPOINTTYPE, MULTIPOLYGONTYPE, LWMPOINT::ngeoms, POINTTYPE, POLYGONTYPE, s, POINT3DM::x, and POINT3DM::y.

Here is the call graph for this function: