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

Definition at line 1180 of file lwgeom_functions_basic.c.

References LWGEOM::bbox, COLLECTIONTYPE, genraster::count, gbox_copy(), geometry_serialize(), gserialized_get_type(), lwcollection_construct(), lwgeom_drop_bbox(), lwgeom_drop_srid(), lwgeom_from_gserialized(), lwtype_get_collectiontype(), lwtype_is_collection(), result, LWGEOM::srid, SRID_UNKNOWN, GBOX::xmax, GBOX::xmin, GBOX::ymax, and GBOX::ymin.

Referenced by pgis_geometry_collect_finalfn().

1181 {
1182  Datum datum;
1183  ArrayType *array;
1184  int nelems;
1185  /*GSERIALIZED **geoms; */
1186  GSERIALIZED *result=NULL;
1187  LWGEOM **lwgeoms, *outlwg;
1188  uint32 outtype;
1189  int i, count;
1190  int srid=SRID_UNKNOWN;
1191  size_t offset;
1192  GBOX *box=NULL;
1193  bits8 *bitmap;
1194  int bitmask;
1195 
1196  POSTGIS_DEBUG(2, "LWGEOM_collect_garray called.");
1197 
1198  /* Get input datum */
1199  datum = PG_GETARG_DATUM(0);
1200 
1201  /* Return null on null input */
1202  if ( (Pointer *)datum == NULL )
1203  {
1204  elog(NOTICE, "NULL input");
1205  PG_RETURN_NULL();
1206  }
1207 
1208  /* Get actual ArrayType */
1209  array = DatumGetArrayTypeP(datum);
1210 
1211  POSTGIS_DEBUGF(3, " array is %d-bytes in size, %ld w/out header",
1212  ARR_SIZE(array), ARR_SIZE(array)-ARR_OVERHEAD_NONULLS(ARR_NDIM(array)));
1213 
1214 
1215  /* Get number of geometries in array */
1216  nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
1217 
1218  POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: array has %d elements", nelems);
1219 
1220  /* Return null on 0-elements input array */
1221  if ( nelems == 0 )
1222  {
1223  elog(NOTICE, "0 elements input array");
1224  PG_RETURN_NULL();
1225  }
1226 
1227  /*
1228  * Deserialize all geometries in array into the lwgeoms pointers
1229  * array. Check input types to form output type.
1230  */
1231  lwgeoms = palloc(sizeof(LWGEOM *)*nelems);
1232  count = 0;
1233  outtype = 0;
1234  offset = 0;
1235  bitmap = ARR_NULLBITMAP(array);
1236  bitmask = 1;
1237  for (i=0; i<nelems; i++)
1238  {
1239  /* Don't do anything for NULL values */
1240  if ((bitmap && (*bitmap & bitmask) != 0) || !bitmap)
1241  {
1242  GSERIALIZED *geom = (GSERIALIZED *)(ARR_DATA_PTR(array)+offset);
1243  uint8_t intype = gserialized_get_type(geom);
1244 
1245  offset += INTALIGN(VARSIZE(geom));
1246 
1247  lwgeoms[count] = lwgeom_from_gserialized(geom);
1248 
1249  POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: geom %d deserialized", i);
1250 
1251  if ( ! count )
1252  {
1253  /* Get first geometry SRID */
1254  srid = lwgeoms[count]->srid;
1255 
1256  /* COMPUTE_BBOX WHEN_SIMPLE */
1257  if ( lwgeoms[count]->bbox )
1258  {
1259  box = gbox_copy(lwgeoms[count]->bbox);
1260  }
1261  }
1262  else
1263  {
1264  /* Check SRID homogeneity */
1265  if ( lwgeoms[count]->srid != srid )
1266  {
1267  elog(ERROR,
1268  "Operation on mixed SRID geometries");
1269  PG_RETURN_NULL();
1270  }
1271 
1272  /* COMPUTE_BBOX WHEN_SIMPLE */
1273  if ( box )
1274  {
1275  if ( lwgeoms[count]->bbox )
1276  {
1277  box->xmin = Min(box->xmin, lwgeoms[count]->bbox->xmin);
1278  box->ymin = Min(box->ymin, lwgeoms[count]->bbox->ymin);
1279  box->xmax = Max(box->xmax, lwgeoms[count]->bbox->xmax);
1280  box->ymax = Max(box->ymax, lwgeoms[count]->bbox->ymax);
1281  }
1282  else
1283  {
1284  pfree(box);
1285  box = NULL;
1286  }
1287  }
1288  }
1289 
1290  lwgeom_drop_srid(lwgeoms[count]);
1291  lwgeom_drop_bbox(lwgeoms[count]);
1292 
1293  /* Output type not initialized */
1294  if ( ! outtype )
1295  {
1296  /* Input is single, make multi */
1297  if ( ! lwtype_is_collection(intype) )
1298  outtype = lwtype_get_collectiontype(intype);
1299  /* Input is multi, make collection */
1300  else
1301  outtype = COLLECTIONTYPE;
1302  }
1303 
1304  /* Input type not compatible with output */
1305  /* make output type a collection */
1306  else if ( outtype != COLLECTIONTYPE && intype != outtype-3 )
1307  {
1308  outtype = COLLECTIONTYPE;
1309  }
1310 
1311  count++;
1312  }
1313 
1314  /* Advance NULL bitmap */
1315  if (bitmap)
1316  {
1317  bitmask <<= 1;
1318  if (bitmask == 0x100)
1319  {
1320  bitmap++;
1321  bitmask = 1;
1322  }
1323  }
1324 
1325  }
1326 
1327  POSTGIS_DEBUGF(3, "LWGEOM_collect_garray: outtype = %d", outtype);
1328 
1329  /* If we have been passed a complete set of NULLs then return NULL */
1330  if (!outtype)
1331  {
1332  PG_RETURN_NULL();
1333  }
1334  else
1335  {
1336  outlwg = (LWGEOM *)lwcollection_construct(
1337  outtype, srid,
1338  box, count, lwgeoms);
1339 
1340  result = geometry_serialize(outlwg);
1341 
1342  PG_RETURN_POINTER(result);
1343  }
1344 }
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
Definition: g_box.c:362
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:56
GBOX * bbox
Definition: liblwgeom.h:354
int lwtype_get_collectiontype(uint8_t type)
Given an lwtype number, what homogeneous collection can hold it?
Definition: lwgeom.c:982
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.
double xmax
Definition: liblwgeom.h:249
char ** result
Definition: liblwgeom.h:218
void lwgeom_drop_bbox(LWGEOM *lwgeom)
Call this function to drop BBOX and SRID from LWGEOM.
Definition: lwgeom.c:542
int32_t srid
Definition: liblwgeom.h:355
unsigned int uint32
Definition: shpopen.c:274
double ymin
Definition: liblwgeom.h:250
LWGEOM * geom
double xmin
Definition: liblwgeom.h:248
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:154
int count
Definition: genraster.py:57
int lwtype_is_collection(uint8_t type)
Determine whether a type number is a collection or not.
Definition: lwgeom.c:955
double ymax
Definition: liblwgeom.h:251
void lwgeom_drop_srid(LWGEOM *lwgeom)
Definition: lwgeom.c:618
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
#define COLLECTIONTYPE
Definition: liblwgeom.h:66

Here is the call graph for this function:

Here is the caller graph for this function: