PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ LWGEOM_collect_garray()

Datum LWGEOM_collect_garray ( PG_FUNCTION_ARGS  )

Definition at line 1280 of file lwgeom_functions_basic.c.

1281 {
1282  ArrayType *array;
1283  int nelems;
1284  /*GSERIALIZED **geoms; */
1285  GSERIALIZED *result = NULL;
1286  LWGEOM **lwgeoms, *outlwg;
1287  uint32 outtype;
1288  int count;
1289  int32_t srid = SRID_UNKNOWN;
1290  GBOX *box = NULL;
1291 
1292  ArrayIterator iterator;
1293  Datum value;
1294  bool isnull;
1295 
1296  POSTGIS_DEBUG(2, "LWGEOM_collect_garray called.");
1297 
1298  if (PG_ARGISNULL(0))
1299  PG_RETURN_NULL();
1300 
1301  /* Get actual ArrayType */
1302  array = PG_GETARG_ARRAYTYPE_P(0);
1303  nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
1304 
1305  POSTGIS_DEBUGF(3,
1306  " array is %d-bytes in size, %ld w/out header",
1307  ARR_SIZE(array),
1308  ARR_SIZE(array) - ARR_OVERHEAD_NONULLS(ARR_NDIM(array)));
1309 
1310  POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: array has %d elements", nelems);
1311 
1312  /* Return null on 0-elements input array */
1313  if (nelems == 0)
1314  PG_RETURN_NULL();
1315 
1316  /*
1317  * Deserialize all geometries in array into the lwgeoms pointers
1318  * array. Check input types to form output type.
1319  */
1320  lwgeoms = palloc(sizeof(LWGEOM *) * nelems);
1321  count = 0;
1322  outtype = 0;
1323 
1324  iterator = array_create_iterator(array, 0, NULL);
1325 
1326  while (array_iterate(iterator, &value, &isnull))
1327  {
1328  GSERIALIZED *geom;
1329  uint8_t intype;
1330 
1331  /* Don't do anything for NULL values */
1332  if (isnull)
1333  continue;
1334 
1335  geom = (GSERIALIZED *)DatumGetPointer(value);
1336  intype = gserialized_get_type(geom);
1337 
1338  lwgeoms[count] = lwgeom_from_gserialized(geom);
1339 
1340  POSTGIS_DEBUGF(3, "%s: geom %d deserialized", __func__, count);
1341 
1342  if (!count)
1343  {
1344  /* Get first geometry SRID */
1345  srid = lwgeoms[count]->srid;
1346 
1347  /* COMPUTE_BBOX WHEN_SIMPLE */
1348  if (lwgeoms[count]->bbox)
1349  box = gbox_copy(lwgeoms[count]->bbox);
1350  }
1351  else
1352  {
1353  /* Check SRID homogeneity */
1354  gserialized_error_if_srid_mismatch_reference(geom, srid, __func__);
1355 
1356  /* COMPUTE_BBOX WHEN_SIMPLE */
1357  if (box)
1358  {
1359  if (lwgeoms[count]->bbox)
1360  gbox_merge(lwgeoms[count]->bbox, box);
1361  else
1362  {
1363  pfree(box);
1364  box = NULL;
1365  }
1366  }
1367  }
1368 
1369  lwgeom_drop_srid(lwgeoms[count]);
1370  lwgeom_drop_bbox(lwgeoms[count]);
1371 
1372  /* Output type not initialized */
1373  if (!outtype)
1374  {
1375  outtype = lwtype_get_collectiontype(intype);
1376  }
1377  /* Input type not compatible with output */
1378  /* make output type a collection */
1379  else if (outtype != COLLECTIONTYPE && lwtype_get_collectiontype(intype) != outtype)
1380  {
1381  outtype = COLLECTIONTYPE;
1382  }
1383 
1384  count++;
1385  }
1386  array_free_iterator(iterator);
1387 
1388  POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: outtype = %d", outtype);
1389 
1390  /* If we have been passed a complete set of NULLs then return NULL */
1391  if (!outtype)
1392  {
1393  PG_RETURN_NULL();
1394  }
1395  else
1396  {
1397  outlwg = (LWGEOM *)lwcollection_construct(outtype, srid, box, count, lwgeoms);
1398 
1399  result = geometry_serialize(outlwg);
1400 
1401  PG_RETURN_POINTER(result);
1402  }
1403 }
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition: cu_print.c:267
int gbox_merge(const GBOX *new_box, GBOX *merge_box)
Update the merged GBOX to be large enough to include itself and the new box.
Definition: gbox.c:257
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
Definition: gbox.c:426
void gserialized_error_if_srid_mismatch_reference(const GSERIALIZED *g1, const int32_t srid2, const char *funcname)
Definition: gserialized.c:418
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Definition: gserialized.c:239
uint32_t gserialized_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
Definition: gserialized.c:89
uint32_t lwtype_get_collectiontype(uint8_t type)
Given an lwtype number, what homogeneous collection can hold it?
Definition: lwgeom.c:1131
#define COLLECTIONTYPE
Definition: liblwgeom.h:123
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
Definition: lwgeom.c:682
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:230
void lwgeom_drop_srid(LWGEOM *lwgeom)
Definition: lwgeom.c:765
int value
Definition: genraster.py:62
int count
Definition: genraster.py:57
int32_t srid
Definition: liblwgeom.h:475

References COLLECTIONTYPE, genraster::count, gbox_copy(), gbox_merge(), gserialized_error_if_srid_mismatch_reference(), gserialized_get_type(), lwcollection_construct(), lwgeom_drop_bbox(), lwgeom_drop_srid(), lwgeom_from_gserialized(), lwtype_get_collectiontype(), result, LWGEOM::srid, SRID_UNKNOWN, and genraster::value.

Referenced by pgis_geometry_collect_finalfn().

Here is the call graph for this function:
Here is the caller graph for this function: