PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ ST_GeometricMedian()

Datum ST_GeometricMedian ( PG_FUNCTION_ARGS  )

Definition at line 1217 of file lwgeom_functions_analytic.c.

References FP_MAX, FP_MIN, dumpnode::geom, geometry_serialize(), LW_FALSE, lwgeom_free(), lwgeom_from_gserialized(), lwgeom_get_bbox(), lwgeom_has_z(), lwgeom_median(), lwpoint_as_lwgeom(), PG_FUNCTION_INFO_V1(), ST_IsPolygonCW(), GBOX::xmax, GBOX::xmin, GBOX::ymax, GBOX::ymin, GBOX::zmax, and GBOX::zmin.

Referenced by ST_MinimumBoundingCircle().

1218 {
1219  GSERIALIZED* geom;
1220  GSERIALIZED* result;
1221  LWGEOM* input;
1222  LWPOINT* lwresult;
1223  static const double min_default_tolerance = 1e-8;
1224  double tolerance = min_default_tolerance;
1225  bool compute_tolerance_from_box;
1226  bool fail_if_not_converged;
1227  int max_iter;
1228 
1229  /* Read and validate our input arguments */
1230  if (PG_ARGISNULL(0))
1231  PG_RETURN_NULL();
1232 
1233  compute_tolerance_from_box = PG_ARGISNULL(1);
1234 
1235  if (!compute_tolerance_from_box)
1236  {
1237  tolerance = PG_GETARG_FLOAT8(1);
1238  if (tolerance < 0)
1239  {
1240  lwpgerror("Tolerance must be positive.");
1241  PG_RETURN_NULL();
1242  }
1243  }
1244 
1245  max_iter = PG_ARGISNULL(2) ? -1 : PG_GETARG_INT32(2);
1246  fail_if_not_converged = PG_ARGISNULL(3) ? LW_FALSE : PG_GETARG_BOOL(3);
1247 
1248  if (max_iter < 0)
1249  {
1250  lwpgerror("Maximum iterations must be positive.");
1251  PG_RETURN_NULL();
1252  }
1253 
1254  /* OK, inputs are valid. */
1255  geom = PG_GETARG_GSERIALIZED_P(0);
1256  input = lwgeom_from_gserialized(geom);
1257 
1258  if (compute_tolerance_from_box)
1259  {
1260  /* Compute a default tolerance based on the smallest dimension
1261  * of the geometry's bounding box.
1262  */
1263  static const double tolerance_coefficient = 1e-6;
1264  const GBOX* box = lwgeom_get_bbox(input);
1265 
1266  if (box)
1267  {
1268  double min_dim = FP_MIN(box->xmax - box->xmin, box->ymax - box->ymin);
1269  if (lwgeom_has_z(input))
1270  min_dim = FP_MIN(min_dim, box->zmax - box->zmin);
1271 
1272  /* Apply a lower bound to the computed default tolerance to
1273  * avoid a tolerance of zero in the case of collinear
1274  * points.
1275  */
1276  tolerance = FP_MAX(min_default_tolerance, tolerance_coefficient * min_dim);
1277  }
1278  }
1279 
1280  lwresult = lwgeom_median(input, tolerance, max_iter, fail_if_not_converged);
1281  lwgeom_free(input);
1282 
1283  if(!lwresult)
1284  {
1285  lwpgerror("Error computing geometric median.");
1286  PG_RETURN_NULL();
1287  }
1288 
1289  result = geometry_serialize(lwpoint_as_lwgeom(lwresult));
1290 
1291  PG_RETURN_POINTER(result);
1292 }
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
double xmax
Definition: liblwgeom.h:293
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1099
#define FP_MIN(A, B)
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:885
double zmax
Definition: liblwgeom.h:297
double ymin
Definition: liblwgeom.h:294
LWGEOM * geom
double xmin
Definition: liblwgeom.h:292
#define LW_FALSE
Definition: liblwgeom.h:77
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
Definition: lwgeom.c:689
double ymax
Definition: liblwgeom.h:295
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
double zmin
Definition: liblwgeom.h:296
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition: lwgeom.c:303
LWPOINT * lwgeom_median(const LWGEOM *g, double tol, uint32_t maxiter, char fail_if_not_converged)
#define FP_MAX(A, B)
Here is the call graph for this function:
Here is the caller graph for this function: