PostGIS  2.3.8dev-r@@SVN_REVISION@@

◆ cluster_within_distance_garray()

Datum cluster_within_distance_garray ( PG_FUNCTION_ARGS  )

Definition at line 3185 of file postgis/lwgeom_geos.c.

References ARRAY2LWGEOM(), array_nelems_not_null(), cluster_within_distance(), gserialized_from_lwgeom(), linemerge(), LW_SUCCESS, lwgeom_free(), lwgeom_geos_error(), PG_FUNCTION_INFO_V1(), and SRID_UNKNOWN.

Referenced by clusterintersecting_garray(), and pgis_geometry_clusterwithin_finalfn().

3186 {
3187  Datum* result_array_data;
3188  ArrayType *array, *result;
3189  int is3d = 0;
3190  uint32 nelems, nclusters, i;
3191  LWGEOM** lw_inputs;
3192  LWGEOM** lw_results;
3193  double tolerance;
3194  int srid=SRID_UNKNOWN;
3195 
3196  /* Parameters used to construct a result array */
3197  int16 elmlen;
3198  bool elmbyval;
3199  char elmalign;
3200 
3201  /* Null array, null geometry (should be empty?) */
3202  if (PG_ARGISNULL(0))
3203  PG_RETURN_NULL();
3204 
3205  array = PG_GETARG_ARRAYTYPE_P(0);
3206 
3207  tolerance = PG_GETARG_FLOAT8(1);
3208  if (tolerance < 0)
3209  {
3210  lwpgerror("Tolerance must be a positive number.");
3211  PG_RETURN_NULL();
3212  }
3213 
3214  nelems = array_nelems_not_null(array);
3215 
3216  POSTGIS_DEBUGF(3, "cluster_within_distance_garray: number of non-null elements: %d", nelems);
3217 
3218  if ( nelems == 0 ) PG_RETURN_NULL();
3219 
3220  /* TODO short-circuit for one element? */
3221 
3222  /* Ok, we really need geos now ;) */
3223  initGEOS(lwpgnotice, lwgeom_geos_error);
3224 
3225  lw_inputs = ARRAY2LWGEOM(array, nelems, &is3d, &srid);
3226  if (!lw_inputs)
3227  {
3228  PG_RETURN_NULL();
3229  }
3230 
3231  if (cluster_within_distance(lw_inputs, nelems, tolerance, &lw_results, &nclusters) != LW_SUCCESS)
3232  {
3233  elog(ERROR, "cluster_within: Error performing clustering");
3234  PG_RETURN_NULL();
3235  }
3236  pfree(lw_inputs); /* don't need to destroy items because GeometryCollections have taken ownership */
3237 
3238  if (!lw_results) PG_RETURN_NULL();
3239 
3240  result_array_data = palloc(nclusters * sizeof(Datum));
3241  for (i=0; i<nclusters; ++i)
3242  {
3243  result_array_data[i] = PointerGetDatum(gserialized_from_lwgeom(lw_results[i], NULL));
3244  lwgeom_free(lw_results[i]);
3245  }
3246  pfree(lw_results);
3247 
3248  get_typlenbyvalalign(array->elemtype, &elmlen, &elmbyval, &elmalign);
3249  result = (ArrayType*) construct_array(result_array_data, nclusters, array->elemtype, elmlen, elmbyval, elmalign);
3250 
3251  if (!result)
3252  {
3253  elog(ERROR, "clusterwithin: Error constructing return-array");
3254  PG_RETURN_NULL();
3255  }
3256 
3257  PG_RETURN_POINTER(result);
3258 }
uint32_t array_nelems_not_null(ArrayType *array)
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1063
#define LW_SUCCESS
Definition: liblwgeom.h:79
int cluster_within_distance(LWGEOM **geoms, uint32_t num_geoms, double tolerance, LWGEOM ***clusterGeoms, uint32_t *num_clusters)
Takes an array of LWGEOM* and constructs an array of LWGEOM*, where each element in the constructed a...
LWGEOM ** ARRAY2LWGEOM(ArrayType *array, uint32_t nelems, int *is3d, int *srid)
void lwgeom_geos_error(const char *fmt,...)
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:187
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
Definition: g_serialized.c:933
Here is the call graph for this function:
Here is the caller graph for this function: