PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ pgis_geometry_union_finalfn()

Datum pgis_geometry_union_finalfn ( PG_FUNCTION_ARGS  )

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

516 {
517  CollectionBuildState *state;
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,...)
#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
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:42
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:229
LWGEOM * lwgeom_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
Definition: lwgeom.c:2083
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
type
Definition: ovdump.py:42
#define HANDLE_GEOS_ERROR(label)
GSERIALIZED * GEOS2POSTGIS(GEOSGeom geom, char want3d)
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(), SRID_UNKNOWN, and ovdump::type.

Here is the call graph for this function: