PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ LWGEOM_collect_garray()

Datum LWGEOM_collect_garray ( PG_FUNCTION_ARGS  )

Definition at line 1205 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(), LWGEOM_line_from_mpoint(), lwtype_get_collectiontype(), PG_FUNCTION_INFO_V1(), LWGEOM::srid, SRID_UNKNOWN, and genraster::value.

Referenced by LWGEOM_collect(), and pgis_geometry_collect_finalfn().

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