786{
791 static const double min_default_tolerance = 1e-8;
792 double tolerance = min_default_tolerance;
793 bool compute_tolerance_from_box;
794 bool fail_if_not_converged;
795 int max_iter;
796
797
798 if (PG_ARGISNULL(0))
799 PG_RETURN_NULL();
800
801 compute_tolerance_from_box = PG_ARGISNULL(1);
802
803 if (!compute_tolerance_from_box)
804 {
805 tolerance = PG_GETARG_FLOAT8(1);
806 if (tolerance < 0)
807 {
808 lwpgerror("Tolerance must be positive.");
809 PG_RETURN_NULL();
810 }
811 }
812
813 max_iter = PG_ARGISNULL(2) ? -1 : PG_GETARG_INT32(2);
814 fail_if_not_converged = PG_ARGISNULL(3) ?
LW_FALSE : PG_GETARG_BOOL(3);
815
816 if (max_iter < 0)
817 {
818 lwpgerror("Maximum iterations must be positive.");
819 PG_RETURN_NULL();
820 }
821
822
823 geom = PG_GETARG_GSERIALIZED_P(0);
825
826 if (compute_tolerance_from_box)
827 {
828
829
830
831 static const double tolerance_coefficient = 1e-6;
833
834 if (box)
835 {
839
840
841
842
843
844 tolerance =
FP_MAX(min_default_tolerance, tolerance_coefficient * min_dim);
845 }
846 }
847
848 lwresult =
lwgeom_median(input, tolerance, max_iter, fail_if_not_converged);
850
851 if(!lwresult)
852 {
853 lwpgerror("Error computing geometric median.");
854 PG_RETURN_NULL();
855 }
856
858
859 PG_RETURN_POINTER(
result);
860}
char result[OUT_DOUBLE_BUFFER_SIZE]
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
void lwgeom_free(LWGEOM *geom)
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
LWPOINT * lwgeom_median(const LWGEOM *g, double tol, uint32_t maxiter, char fail_if_not_converged)
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.