PostGIS  2.5.0dev-r@@SVN_REVISION@@
Datum LWGEOM_collect_garray ( PG_FUNCTION_ARGS  )

Definition at line 1206 of file lwgeom_functions_basic.c.

References COLLECTIONTYPE, genraster::count, error_if_srid_mismatch(), gbox_copy(), gbox_merge(), dumpnode::geom, 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().

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

Here is the call graph for this function:

Here is the caller graph for this function: