PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ LWGEOM_collect_garray()

Datum LWGEOM_collect_garray ( PG_FUNCTION_ARGS  )

Definition at line 1283 of file lwgeom_functions_basic.c.

1284 {
1285  ArrayType *array;
1286  int nelems;
1287  /*GSERIALIZED **geoms; */
1288  GSERIALIZED *result = NULL;
1289  LWGEOM **lwgeoms, *outlwg;
1290  uint32 outtype;
1291  int count;
1292  int32_t srid = SRID_UNKNOWN;
1293  GBOX *box = NULL;
1294 
1295  ArrayIterator iterator;
1296  Datum value;
1297  bool isnull;
1298 
1299  POSTGIS_DEBUG(2, "LWGEOM_collect_garray called.");
1300 
1301  if (PG_ARGISNULL(0))
1302  PG_RETURN_NULL();
1303 
1304  /* Get actual ArrayType */
1305  array = PG_GETARG_ARRAYTYPE_P(0);
1306  nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
1307 
1308  POSTGIS_DEBUGF(3,
1309  " array is %d-bytes in size, %ld w/out header",
1310  ARR_SIZE(array),
1311  ARR_SIZE(array) - ARR_OVERHEAD_NONULLS(ARR_NDIM(array)));
1312 
1313  POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: array has %d elements", nelems);
1314 
1315  /* Return null on 0-elements input array */
1316  if (nelems == 0)
1317  PG_RETURN_NULL();
1318 
1319  /*
1320  * Deserialize all geometries in array into the lwgeoms pointers
1321  * array. Check input types to form output type.
1322  */
1323  lwgeoms = palloc(sizeof(LWGEOM *) * nelems);
1324  count = 0;
1325  outtype = 0;
1326 
1327  iterator = array_create_iterator(array, 0, NULL);
1328 
1329  while (array_iterate(iterator, &value, &isnull))
1330  {
1331  GSERIALIZED *geom;
1332  uint8_t intype;
1333 
1334  /* Don't do anything for NULL values */
1335  if (isnull)
1336  continue;
1337 
1338  geom = (GSERIALIZED *)DatumGetPointer(value);
1339  intype = gserialized_get_type(geom);
1340 
1341  lwgeoms[count] = lwgeom_from_gserialized(geom);
1342 
1343  POSTGIS_DEBUGF(3, "%s: geom %d deserialized", __func__, count);
1344 
1345  if (!count)
1346  {
1347  /* Get first geometry SRID */
1348  srid = lwgeoms[count]->srid;
1349 
1350  /* COMPUTE_BBOX WHEN_SIMPLE */
1351  if (lwgeoms[count]->bbox)
1352  box = gbox_copy(lwgeoms[count]->bbox);
1353  }
1354  else
1355  {
1356  /* Check SRID homogeneity */
1357  gserialized_error_if_srid_mismatch_reference(geom, srid, __func__);
1358 
1359  /* COMPUTE_BBOX WHEN_SIMPLE */
1360  if (box)
1361  {
1362  if (lwgeoms[count]->bbox)
1363  gbox_merge(lwgeoms[count]->bbox, box);
1364  else
1365  {
1366  pfree(box);
1367  box = NULL;
1368  }
1369  }
1370  }
1371 
1372  lwgeom_drop_srid(lwgeoms[count]);
1373  lwgeom_drop_bbox(lwgeoms[count]);
1374 
1375  /* Output type not initialized */
1376  if (!outtype)
1377  {
1378  outtype = lwtype_get_collectiontype(intype);
1379  }
1380  /* Input type not compatible with output */
1381  /* make output type a collection */
1382  else if (outtype != COLLECTIONTYPE && lwtype_get_collectiontype(intype) != outtype)
1383  {
1384  outtype = COLLECTIONTYPE;
1385  }
1386 
1387  count++;
1388  }
1389  array_free_iterator(iterator);
1390 
1391  POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: outtype = %d", outtype);
1392 
1393  /* If we have been passed a complete set of NULLs then return NULL */
1394  if (!outtype)
1395  {
1396  PG_RETURN_NULL();
1397  }
1398  else
1399  {
1400  outlwg = (LWGEOM *)lwcollection_construct(outtype, srid, box, count, lwgeoms);
1401 
1402  result = geometry_serialize(outlwg);
1403 
1404  PG_RETURN_POINTER(result);
1405  }
1406 }
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition: cu_print.c:262
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:108
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:215
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:460

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: