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

◆ pgis_geometry_union_finalfn()

Datum pgis_geometry_union_finalfn ( PG_FUNCTION_ARGS  )

Definition at line 515 of file postgis/lwgeom_geos.c.

516{
518 ListCell *l;
519 LWGEOM **geoms;
520 GSERIALIZED *gser_out;
521 size_t ngeoms = 0;
522 int empty_type = 0;
523 bool first = true;
524 int32_t srid = SRID_UNKNOWN;
525 int has_z = LW_FALSE;
526
527 if (PG_ARGISNULL(0))
528 PG_RETURN_NULL(); /* returns null iff no input values */
529
530 state = (CollectionBuildState *)PG_GETARG_POINTER(0);
531 geoms = palloc(list_length(state->geoms) * sizeof(LWGEOM*));
532
533 /* Read contents of list into an array of only non-null values */
534 foreach (l, state->geoms)
535 {
536 LWGEOM *geom = (LWGEOM*)(lfirst(l));
537 if (geom)
538 {
539 if (!lwgeom_is_empty(geom))
540 {
541 geoms[ngeoms++] = geom;
542 if (first)
543 {
544 srid = lwgeom_get_srid(geom);
545 has_z = lwgeom_has_z(geom);
546 first = false;
547 }
548 }
549 else
550 {
551 int type = lwgeom_get_type(geom);
552 empty_type = type > empty_type ? type : empty_type;
553 srid = (srid != SRID_UNKNOWN ? srid : lwgeom_get_srid(geom));
554 }
555 }
556 }
557
558 /*
559 ** Take our array of LWGEOM* and turn it into a GEOS collection,
560 ** then pass that into cascaded union.
561 */
562 if (ngeoms > 0)
563 {
564 GEOSGeometry *g = NULL;
565 GEOSGeometry *g_union = NULL;
566 LWCOLLECTION* col = lwcollection_construct(COLLECTIONTYPE, srid, NULL, ngeoms, geoms);
567
568 initGEOS(lwpgnotice, lwgeom_geos_error);
569 g = LWGEOM2GEOS((LWGEOM*)col, LW_FALSE);
570 if (!g)
571 HANDLE_GEOS_ERROR("Could not create GEOS COLLECTION from geometry array");
572
573 g_union = GEOSUnaryUnion(g);
574 GEOSGeom_destroy(g);
575 if (!g_union)
576 HANDLE_GEOS_ERROR("GEOSUnaryUnion");
577
578 GEOSSetSRID(g_union, srid);
579 gser_out = GEOS2POSTGIS(g_union, has_z);
580 GEOSGeom_destroy(g_union);
581 }
582 /* No real geometries in our array, any empties? */
583 else
584 {
585 /* If it was only empties, we'll return the largest type number */
586 if (empty_type > 0)
587 PG_RETURN_POINTER(
588 geometry_serialize(lwgeom_construct_empty(empty_type, srid, has_z, 0)));
589
590 /* Nothing but NULL, returns NULL */
591 else
592 PG_RETURN_NULL();
593 }
594
595 if (!gser_out)
596 {
597 /* Union returned a NULL geometry */
598 PG_RETURN_NULL();
599 }
600
601 PG_RETURN_POINTER(gser_out);
602}
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
void lwgeom_geos_error(const char *fmt,...)
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
#define LW_FALSE
Definition liblwgeom.h:108
#define COLLECTIONTYPE
Definition liblwgeom.h:122
int32_t lwgeom_get_srid(const LWGEOM *geom)
Return SRID number.
Definition lwgeom.c:909
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition lwgeom.c:916
LWGEOM * lwgeom_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
Definition lwgeom.c:2083
#define SRID_UNKNOWN
Unknown SRID value.
Definition liblwgeom.h:229
static uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
Definition lwinline.h:135
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition lwinline.h:193
GSERIALIZED * GEOS2POSTGIS(GEOSGeom geom, char want3d)
#define HANDLE_GEOS_ERROR(label)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)

References COLLECTIONTYPE, geometry_serialize(), CollectionBuildState::geoms, GEOS2POSTGIS(), HANDLE_GEOS_ERROR, LW_FALSE, lwcollection_construct(), LWGEOM2GEOS(), lwgeom_construct_empty(), lwgeom_geos_error(), lwgeom_get_srid(), lwgeom_get_type(), lwgeom_has_z(), lwgeom_is_empty(), and SRID_UNKNOWN.

Here is the call graph for this function: