27 #include "../postgis_config.h"
32 #include "lwgeom_pg.h"
33 #include "lwgeom_transform.h"
57 bool use_spheroid =
true;
62 g = PG_GETARG_GSERIALIZED_P(0);
79 PG_RETURN_POINTER(g_out);
83 spheroid_init_from_srid(fcinfo, srid, &
s);
86 use_spheroid = PG_GETARG_BOOL(1);
111 for (i = 0; i < size; i++) {
162 elog(ERROR,
"ST_Centroid(geography) unhandled geography type");
166 PG_FREE_IF_COPY(g, 0);
172 PG_RETURN_POINTER(g_out);
185 double_t weight_sum = 0;
191 for (i = 0; i < size; i++ )
194 weight = points[i].
m;
196 x_sum += point->
x * weight;
197 y_sum += point->
y * weight;
198 z_sum += point->
z * weight;
200 weight_sum += weight;
216 lat = (raw_lat + 90) / 180 * M_PI;
219 lon = raw_lon / 180 * M_PI;
225 point->
x = sin_lat * cosl(lon);
226 point->
y = sin_lat * sinl(lon);
227 point->
z = cosl(lat);
234 double_t
x = x_sum / weight_sum;
235 double_t
y = y_sum / weight_sum;
236 double_t z = z_sum / weight_sum;
239 double_t
r = sqrtl(powl(
x, 2) + powl(
y, 2) + powl(z, 2));
241 double_t lon = atan2l(
y,
x) * 180 / M_PI;
242 double_t lat = acosl(z /
r) * 180 / M_PI - 90;
253 double_t tolerance = 0.0;
260 for (i = 0; i < mline->
ngeoms; i++) {
264 points = palloc(size*
sizeof(
POINT3DM));
266 for (i = 0; i < mline->
ngeoms; i++) {
288 points[j].
m = weight;
293 points[j].
m = weight;
316 POINT4D* reference_point = NULL;
319 for (ip = 0; ip < mpoly->
ngeoms; ip++) {
320 for (ir = 0; ir < mpoly->
geoms[ip]->
nrings; ir++) {
325 points = palloc(size*
sizeof(
POINT3DM));
331 for (ip = 0; ip < mpoly->
ngeoms; ip++) {
334 for (ir = 0; ir < poly->
nrings; ir++) {
338 for (i = 0; i < ring->
npoints - 1; i++) {
369 triangle[0].
x = p1->
x;
370 triangle[0].
y = p1->
y;
373 triangle[1].
x = p2->
x;
374 triangle[1].
y = p2->
y;
377 triangle[2].
x = reference_point->
x;
378 triangle[2].
y = reference_point->
y;
386 points[j].
m = weight;
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.
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
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.
PG_FUNCTION_INFO_V1(geography_centroid)
geography_centroid(GSERIALIZED *g) returns centroid as point
POINT3D * lonlat_to_cart(const double_t raw_lon, const double_t raw_lat)
LWPOINT * cart_to_lwpoint(const double_t x_sum, const double_t y_sum, const double_t z_sum, const double_t weight_sum, const uint32_t srid)
LWPOINT * geography_centroid_from_wpoints(const uint32_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...
Datum geography_centroid(PG_FUNCTION_ARGS)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
void lwgeom_set_geodetic(LWGEOM *geom, int value)
Set the FLAGS geodetic bit on geometry an all sub-geometries and pointlists.
LWPOINT * lwpoint_make2d(int srid, double x, double y)
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
int32_t lwgeom_get_srid(const LWGEOM *geom)
Return SRID number.
LWMPOINT * lwgeom_as_lwmpoint(const LWGEOM *lwgeom)
void lwpoint_free(LWPOINT *pt)
LWMPOLY * lwmpoly_construct_empty(int srid, char hasz, char hasm)
double lwgeom_distance_spheroid(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2, const SPHEROID *spheroid, double tolerance)
Calculate the geodetic distance from lwgeom1 to lwgeom2 on the spheroid.
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
void lwgeom_free(LWGEOM *geom)
void lwmpoly_free(LWMPOLY *mpoly)
LWMLINE * lwmline_construct_empty(int srid, char hasz, char hasm)
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
double lwgeom_area_spheroid(const LWGEOM *lwgeom, const SPHEROID *spheroid)
Calculate the geodetic area of a lwgeom on the spheroid.
double lwpoint_get_x(const LWPOINT *point)
LWMLINE * lwmline_add_lwline(LWMLINE *mobj, const LWLINE *obj)
int lwpoly_add_ring(LWPOLY *poly, POINTARRAY *pa)
Add a ring, allocating extra space if necessary.
LWMPOLY * lwgeom_as_lwmpoly(const LWGEOM *lwgeom)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
LWMLINE * lwgeom_as_lwmline(const LWGEOM *lwgeom)
LWMPOLY * lwmpoly_add_lwpoly(LWMPOLY *mobj, const LWPOLY *obj)
int ptarray_insert_point(POINTARRAY *pa, const POINT4D *p, uint32_t where)
Insert a point into an existing POINTARRAY.
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
void * lwalloc(size_t size)
void lwmline_free(LWMLINE *mline)
#define LW_TRUE
Return types for functions with status returns.
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
LWPOLY * lwpoly_construct_empty(int srid, char hasz, char hasm)
double lwpoint_get_y(const LWPOINT *point)
double lwgeom_area_sphere(const LWGEOM *lwgeom, const SPHEROID *spheroid)
Calculate the geodetic area of a lwgeom on the sphere.
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
This library is the generic geometry handling section of PostGIS.