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

Definition at line 1159 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().

1160 {
1161  ArrayType *array;
1162  int nelems;
1163  /*GSERIALIZED **geoms; */
1164  GSERIALIZED *result = NULL;
1165  LWGEOM **lwgeoms, *outlwg;
1166  uint32 outtype;
1167  int count;
1168  int srid = SRID_UNKNOWN;
1169  GBOX *box = NULL;
1170 
1171  ArrayIterator iterator;
1172  Datum value;
1173  bool isnull;
1174 
1175  POSTGIS_DEBUG(2, "LWGEOM_collect_garray called.");
1176 
1177  if ( PG_ARGISNULL(0) )
1178  PG_RETURN_NULL();
1179 
1180  /* Get actual ArrayType */
1181  array = PG_GETARG_ARRAYTYPE_P(0);
1182  nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
1183 
1184  POSTGIS_DEBUGF(3, " array is %d-bytes in size, %ld w/out header",
1185  ARR_SIZE(array), ARR_SIZE(array)-ARR_OVERHEAD_NONULLS(ARR_NDIM(array)));
1186 
1187  POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: array has %d elements", nelems);
1188 
1189  /* Return null on 0-elements input array */
1190  if ( nelems == 0 )
1191  PG_RETURN_NULL();
1192 
1193  /*
1194  * Deserialize all geometries in array into the lwgeoms pointers
1195  * array. Check input types to form output type.
1196  */
1197  lwgeoms = palloc(sizeof(LWGEOM*) * nelems);
1198  count = 0;
1199  outtype = 0;
1200 
1201 #if POSTGIS_PGSQL_VERSION >= 95
1202  iterator = array_create_iterator(array, 0, NULL);
1203 #else
1204  iterator = array_create_iterator(array, 0);
1205 #endif
1206 
1207  while( array_iterate(iterator, &value, &isnull) )
1208  {
1209  GSERIALIZED *geom;
1210  uint8_t intype;
1211 
1212  /* Don't do anything for NULL values */
1213  if ( isnull )
1214  continue;
1215 
1216  geom = (GSERIALIZED *)DatumGetPointer(value);
1217  intype = gserialized_get_type(geom);
1218 
1219  lwgeoms[count] = lwgeom_from_gserialized(geom);
1220 
1221  POSTGIS_DEBUGF(3, "%s: geom %d deserialized", __func__, count);
1222 
1223  if ( ! count )
1224  {
1225  /* Get first geometry SRID */
1226  srid = lwgeoms[count]->srid;
1227 
1228  /* COMPUTE_BBOX WHEN_SIMPLE */
1229  if ( lwgeoms[count]->bbox )
1230  {
1231  box = gbox_copy(lwgeoms[count]->bbox);
1232  }
1233  }
1234  else
1235  {
1236  /* Check SRID homogeneity */
1237  error_if_srid_mismatch(lwgeoms[count]->srid, srid);
1238 
1239  /* COMPUTE_BBOX WHEN_SIMPLE */
1240  if ( box )
1241  {
1242  if ( lwgeoms[count]->bbox )
1243  {
1244  gbox_merge(lwgeoms[count]->bbox, box);
1245  }
1246  else
1247  {
1248  pfree(box);
1249  box = NULL;
1250  }
1251  }
1252  }
1253 
1254  lwgeom_drop_srid(lwgeoms[count]);
1255  lwgeom_drop_bbox(lwgeoms[count]);
1256 
1257  /* Output type not initialized */
1258  if ( ! outtype )
1259  {
1260  outtype = lwtype_get_collectiontype(intype);
1261  }
1262  /* Input type not compatible with output */
1263  /* make output type a collection */
1264  else if ( outtype != COLLECTIONTYPE && lwtype_get_collectiontype(intype) != outtype )
1265  {
1266  outtype = COLLECTIONTYPE;
1267  }
1268 
1269  count++;
1270 
1271  }
1272  array_free_iterator(iterator);
1273 
1274 
1275  POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: outtype = %d", outtype);
1276 
1277  /* If we have been passed a complete set of NULLs then return NULL */
1278  if (!outtype)
1279  {
1280  PG_RETURN_NULL();
1281  }
1282  else
1283  {
1284  outlwg = (LWGEOM *)lwcollection_construct(
1285  outtype, srid,
1286  box, count, lwgeoms);
1287 
1288  result = geometry_serialize(outlwg);
1289 
1290  PG_RETURN_POINTER(result);
1291  }
1292 }
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
Definition: g_box.c:403
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:55
int lwtype_get_collectiontype(uint8_t type)
Given an lwtype number, what homogeneous collection can hold it?
Definition: lwgeom.c:1026
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:30
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:341
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
Definition: lwgeom.c:586
int32_t srid
Definition: liblwgeom.h:383
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:234
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:172
int count
Definition: genraster.py:56
void lwgeom_drop_srid(LWGEOM *lwgeom)
Definition: lwgeom.c:662
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
#define COLLECTIONTYPE
Definition: liblwgeom.h:76

Here is the call graph for this function:

Here is the caller graph for this function: