PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ LWGEOM_collect_garray()

Datum LWGEOM_collect_garray ( PG_FUNCTION_ARGS  )

Definition at line 1209 of file lwgeom_functions_basic.c.

1210 {
1211  ArrayType *array;
1212  int nelems;
1213  /*GSERIALIZED **geoms; */
1214  GSERIALIZED *result = NULL;
1215  LWGEOM **lwgeoms, *outlwg;
1216  uint32 outtype;
1217  int count;
1218  int srid = SRID_UNKNOWN;
1219  GBOX *box = NULL;
1220 
1221  ArrayIterator iterator;
1222  Datum value;
1223  bool isnull;
1224 
1225  POSTGIS_DEBUG(2, "LWGEOM_collect_garray called.");
1226 
1227  if ( PG_ARGISNULL(0) )
1228  PG_RETURN_NULL();
1229 
1230  /* Get actual ArrayType */
1231  array = PG_GETARG_ARRAYTYPE_P(0);
1232  nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
1233 
1234  POSTGIS_DEBUGF(3, " array is %d-bytes in size, %ld w/out header",
1235  ARR_SIZE(array), ARR_SIZE(array)-ARR_OVERHEAD_NONULLS(ARR_NDIM(array)));
1236 
1237  POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: array has %d elements", nelems);
1238 
1239  /* Return null on 0-elements input array */
1240  if ( nelems == 0 )
1241  PG_RETURN_NULL();
1242 
1243  /*
1244  * Deserialize all geometries in array into the lwgeoms pointers
1245  * array. Check input types to form output type.
1246  */
1247  lwgeoms = palloc(sizeof(LWGEOM*) * nelems);
1248  count = 0;
1249  outtype = 0;
1250 
1251 #if POSTGIS_PGSQL_VERSION >= 95
1252  iterator = array_create_iterator(array, 0, NULL);
1253 #else
1254  iterator = array_create_iterator(array, 0);
1255 #endif
1256 
1257  while( array_iterate(iterator, &value, &isnull) )
1258  {
1259  GSERIALIZED *geom;
1260  uint8_t intype;
1261 
1262  /* Don't do anything for NULL values */
1263  if ( isnull )
1264  continue;
1265 
1266  geom = (GSERIALIZED *)DatumGetPointer(value);
1267  intype = gserialized_get_type(geom);
1268 
1269  lwgeoms[count] = lwgeom_from_gserialized(geom);
1270 
1271  POSTGIS_DEBUGF(3, "%s: geom %d deserialized", __func__, count);
1272 
1273  if ( ! count )
1274  {
1275  /* Get first geometry SRID */
1276  srid = lwgeoms[count]->srid;
1277 
1278  /* COMPUTE_BBOX WHEN_SIMPLE */
1279  if ( lwgeoms[count]->bbox )
1280  {
1281  box = gbox_copy(lwgeoms[count]->bbox);
1282  }
1283  }
1284  else
1285  {
1286  /* Check SRID homogeneity */
1287  error_if_srid_mismatch(lwgeoms[count]->srid, srid);
1288 
1289  /* COMPUTE_BBOX WHEN_SIMPLE */
1290  if ( box )
1291  {
1292  if ( lwgeoms[count]->bbox )
1293  {
1294  gbox_merge(lwgeoms[count]->bbox, box);
1295  }
1296  else
1297  {
1298  pfree(box);
1299  box = NULL;
1300  }
1301  }
1302  }
1303 
1304  lwgeom_drop_srid(lwgeoms[count]);
1305  lwgeom_drop_bbox(lwgeoms[count]);
1306 
1307  /* Output type not initialized */
1308  if ( ! outtype )
1309  {
1310  outtype = lwtype_get_collectiontype(intype);
1311  }
1312  /* Input type not compatible with output */
1313  /* make output type a collection */
1314  else if ( outtype != COLLECTIONTYPE && lwtype_get_collectiontype(intype) != outtype )
1315  {
1316  outtype = COLLECTIONTYPE;
1317  }
1318 
1319  count++;
1320 
1321  }
1322  array_free_iterator(iterator);
1323 
1324 
1325  POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: outtype = %d", outtype);
1326 
1327  /* If we have been passed a complete set of NULLs then return NULL */
1328  if (!outtype)
1329  {
1330  PG_RETURN_NULL();
1331  }
1332  else
1333  {
1334  outlwg = (LWGEOM *)lwcollection_construct(
1335  outtype, srid,
1336  box, count, lwgeoms);
1337 
1338  result = geometry_serialize(outlwg);
1339 
1340  PG_RETURN_POINTER(result);
1341  }
1342 }
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: g_box.c:264
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
Definition: g_box.c:433
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
Definition: g_serialized.c:86
uint32_t lwtype_get_collectiontype(uint8_t type)
Given an lwtype number, what homogeneous collection can hold it?
Definition: lwgeom.c:1120
#define COLLECTIONTYPE
Definition: liblwgeom.h:91
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
Definition: lwgeom.c:673
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:43
void error_if_srid_mismatch(int srid1, int srid2)
Definition: lwutil.c:338
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:188
void lwgeom_drop_srid(LWGEOM *lwgeom)
Definition: lwgeom.c:756
int value
Definition: genraster.py:61
int count
Definition: genraster.py:56
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
int32_t srid
Definition: liblwgeom.h:402
unsigned char uint8_t
Definition: uthash.h:79

References COLLECTIONTYPE, genraster::count, error_if_srid_mismatch(), gbox_copy(), gbox_merge(), geometry_serialize(), gserialized_get_type(), lwcollection_construct(), lwgeom_drop_bbox(), lwgeom_drop_srid(), lwgeom_from_gserialized(), lwtype_get_collectiontype(), 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: