PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ combine_geometries()

static int combine_geometries ( UNIONFIND uf,
void **  geoms,
uint32_t  num_geoms,
void ***  clusterGeoms,
uint32_t num_clusters,
char  is_lwgeom 
)
static

Uses a UNIONFIND to identify the set with which each input geometry is associated, and groups the geometries into GeometryCollections.

Supplied geometry array may be of either LWGEOM* or GEOSGeometry*; is_lwgeom is used to identify which. Caller is responsible for freeing input geometry array but not the items contained within it.

Definition at line 542 of file lwgeom_geos_cluster.c.

References COLLECTIONTYPE, LW_FAILURE, LW_SUCCESS, lwalloc(), lwcollection_construct(), lwfree(), UNIONFIND::num_clusters, UF_find(), and UF_ordered_by_cluster().

Referenced by cluster_intersecting(), and cluster_within_distance().

543 {
544  size_t i, j, k;
545 
546  /* Combine components of each cluster into their own GeometryCollection */
547  *num_clusters = uf->num_clusters;
548  *clusterGeoms = lwalloc(*num_clusters * sizeof(void*));
549 
550  void** geoms_in_cluster = lwalloc(num_geoms * sizeof(void*));
551  uint32_t* ordered_components = UF_ordered_by_cluster(uf);
552  for (i = 0, j = 0, k = 0; i < num_geoms; i++)
553  {
554  geoms_in_cluster[j++] = geoms[ordered_components[i]];
555 
556  /* Is this the last geometry in the component? */
557  if ((i == num_geoms - 1) ||
558  (UF_find(uf, ordered_components[i]) != UF_find(uf, ordered_components[i+1])))
559  {
560  if (k >= uf->num_clusters) {
561  /* Should not get here - it means that we have more clusters than uf->num_clusters thinks we should. */
562  return LW_FAILURE;
563  }
564 
565  if (is_lwgeom)
566  {
567  LWGEOM** components = lwalloc(j * sizeof(LWGEOM*));
568  memcpy(components, geoms_in_cluster, j * sizeof(LWGEOM*));
569  (*clusterGeoms)[k++] = lwcollection_construct(COLLECTIONTYPE, components[0]->srid, NULL, j, (LWGEOM**) components);
570  }
571  else
572  {
573  int srid = GEOSGetSRID(((GEOSGeometry**) geoms_in_cluster)[0]);
574  GEOSGeometry* combined = GEOSGeom_createCollection(GEOS_GEOMETRYCOLLECTION, (GEOSGeometry**) geoms_in_cluster, j);
575  GEOSSetSRID(combined, srid);
576  (*clusterGeoms)[k++] = combined;
577  }
578  j = 0;
579  }
580  }
581 
582  lwfree(geoms_in_cluster);
583  lwfree(ordered_components);
584 
585  return LW_SUCCESS;
586 }
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:43
void lwfree(void *mem)
Definition: lwutil.c:244
#define LW_SUCCESS
Definition: liblwgeom.h:80
#define LW_FAILURE
Definition: liblwgeom.h:79
unsigned int uint32_t
Definition: uthash.h:78
uint32_t UF_find(UNIONFIND *uf, uint32_t i)
Definition: lwunionfind.c:61
uint32_t * UF_ordered_by_cluster(UNIONFIND *uf)
Definition: lwunionfind.c:112
uint32_t num_clusters
Definition: lwunionfind.h:35
void * lwalloc(size_t size)
Definition: lwutil.c:229
#define COLLECTIONTYPE
Definition: liblwgeom.h:91
Here is the call graph for this function:
Here is the caller graph for this function: