PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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 */
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(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.
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition lwgeom.c:372
#define COLLECTIONTYPE
Definition liblwgeom.h:108
int32_t lwgeom_get_srid(const LWGEOM *geom)
Return SRID number.
Definition lwgeom.c:955
LWMPOLY * lwmpoly_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwmpoly.c:40
LWMLINE * lwmline_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwmline.c:38
void lwmpoly_free(LWMPOLY *mpoly)
Definition lwmpoly.c:53
#define MULTILINETYPE
Definition liblwgeom.h:106
#define LINETYPE
Definition liblwgeom.h:103
#define MULTIPOINTTYPE
Definition liblwgeom.h:105
double lwpoint_get_x(const LWPOINT *point)
Definition lwpoint.c:63
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
Definition lwgeom.c:243
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:107
#define POLYGONTYPE
Definition liblwgeom.h:104
LWMLINE * lwmline_add_lwline(LWMLINE *mobj, const LWLINE *obj)
Definition lwmline.c:46
LWMLINE * lwgeom_as_lwmline(const LWGEOM *lwgeom)
Definition lwgeom.c:279
LWMPOLY * lwgeom_as_lwmpoly(const LWGEOM *lwgeom)
Definition lwgeom.c:288
LWMPOLY * lwmpoly_add_lwpoly(LWMPOLY *mobj, const LWPOLY *obj)
Definition lwmpoly.c:47
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition lwgeom.c:207
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
LWMPOINT * lwgeom_as_lwmpoint(const LWGEOM *lwgeom)
Definition lwgeom.c:270
void lwmline_free(LWMLINE *mline)
Definition lwmline.c:112
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition lwgeom.c:337
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:141
uint32_t ngeoms
Definition liblwgeom.h:538
LWPOINT ** geoms
Definition liblwgeom.h:533
double m
Definition liblwgeom.h:408
double x
Definition liblwgeom.h:408
double y
Definition liblwgeom.h:408

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: