PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ ST_LargestEmptyCircle()

Datum ST_LargestEmptyCircle ( PG_FUNCTION_ARGS  )

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

392{
393#if POSTGIS_GEOS_VERSION < 30900
394
395 lwpgerror("The GEOS version this PostGIS binary "
396 "was compiled against (%d) doesn't support "
397 "'GEOSMaximumInscribedCircle' function (3.9.0+ required)",
399 PG_RETURN_NULL();
400
401#else /* POSTGIS_GEOS_VERSION >= 30900 */
402 GSERIALIZED* geom;
404 GSERIALIZED* center;
405 GSERIALIZED* nearest;
406 TupleDesc resultTupleDesc;
407 HeapTuple resultTuple;
408 Datum result;
409 Datum result_values[3];
410 bool result_is_null[3];
411 double radius = 0.0, tolerance = 0.0;
412 int32 srid = SRID_UNKNOWN;
413 bool is3d = false, hasBoundary = false;
414
415 if (PG_ARGISNULL(0))
416 PG_RETURN_NULL();
417
418 geom = PG_GETARG_GSERIALIZED_P(0);
419 tolerance = PG_GETARG_FLOAT8(1);
420 boundary = PG_GETARG_GSERIALIZED_P(2);
421 srid = gserialized_get_srid(geom);
422 is3d = gserialized_has_z(geom);
423
425 hasBoundary = true;
426
427 /* Empty geometry? Return POINT EMPTY with zero radius */
428 if (gserialized_is_empty(geom))
429 {
432 center = geometry_serialize(lwcenter);
433 nearest = geometry_serialize(lwnearest);
434 radius = 0.0;
435 }
436 else
437 {
438 GEOSGeometry *ginput, *gcircle, *gcenter, *gnearest;
439 GEOSGeometry *gboundary = NULL;
440 double width, height, size;
441 GBOX gbox;
442 LWGEOM *lwg;
443 lwg = lwgeom_from_gserialized(geom);
444 if (!lwgeom_isfinite(lwg))
445 {
446 lwpgerror("Geometry contains invalid coordinates");
447 PG_RETURN_NULL();
448 }
449 lwgeom_free(lwg);
450
451
452 if (!gserialized_get_gbox_p(geom, &gbox))
453 PG_RETURN_NULL();
454
455 if (tolerance <= 0)
456 {
457 width = gbox.xmax - gbox.xmin;
458 height = gbox.ymax - gbox.ymin;
459 size = width > height ? width : height;
460 tolerance = size / 1000.0;
461 }
462
463 initGEOS(lwpgnotice, lwgeom_geos_error);
464
465 ginput = POSTGIS2GEOS(geom);
466 if (!ginput)
467 HANDLE_GEOS_ERROR("Geometry could not be converted to GEOS");
468
469 if (hasBoundary)
470 {
471 gboundary = POSTGIS2GEOS(boundary);
472 if (!gboundary)
473 HANDLE_GEOS_ERROR("Boundary could not be converted to GEOS");
474 }
475
476 gcircle = GEOSLargestEmptyCircle(ginput, gboundary, tolerance);
477 if (!gcircle)
478 {
479 lwpgerror("Error calculating GEOSLargestEmptyCircle.");
480 GEOSGeom_destroy(ginput);
481 PG_RETURN_NULL();
482 }
483
484 gcenter = GEOSGeomGetStartPoint(gcircle);
485 gnearest = GEOSGeomGetEndPoint(gcircle);
486 GEOSDistance(gcenter, gnearest, &radius);
487 GEOSSetSRID(gcenter, srid);
488 GEOSSetSRID(gnearest, srid);
489
490 center = GEOS2POSTGIS(gcenter, is3d);
491 nearest = GEOS2POSTGIS(gnearest, is3d);
492 GEOSGeom_destroy(gcenter);
493 GEOSGeom_destroy(gnearest);
494 GEOSGeom_destroy(gcircle);
495 GEOSGeom_destroy(ginput);
496 if (gboundary) GEOSGeom_destroy(gboundary);
497 }
498
499 get_call_result_type(fcinfo, NULL, &resultTupleDesc);
500 BlessTupleDesc(resultTupleDesc);
501
502 result_values[0] = PointerGetDatum(center);
503 result_is_null[0] = false;
504 result_values[1] = PointerGetDatum(nearest);
505 result_is_null[1] = false;
506 result_values[2] = Float8GetDatum(radius);
507 result_is_null[2] = false;
508 resultTuple = heap_form_tuple(resultTupleDesc, result_values, result_is_null);
509
510 result = HeapTupleGetDatum(resultTuple);
511
512 PG_RETURN_DATUM(result);
513
514#endif /* POSTGIS_GEOS_VERSION >= 30900 */
515}
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition cu_print.c:267
int32_t gserialized_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *gbox)
Read the box from the GSERIALIZED or calculate it if necessary.
Definition gserialized.c:94
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
int gserialized_has_z(const GSERIALIZED *g)
Check if a GSERIALIZED has a Z ordinate.
void lwgeom_geos_error(const char *fmt,...)
#define LW_FALSE
Definition liblwgeom.h:94
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
int lwgeom_isfinite(const LWGEOM *lwgeom)
Check if a LWGEOM has any non-finite (NaN or Inf) coordinates.
Definition lwgeom.c:2835
LWPOINT * lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwpoint.c:151
#define SRID_UNKNOWN
Unknown SRID value.
Definition liblwgeom.h:215
GSERIALIZED * GEOS2POSTGIS(GEOSGeom geom, char want3d)
GEOSGeometry * POSTGIS2GEOS(const GSERIALIZED *pglwgeom)
Datum boundary(PG_FUNCTION_ARGS)
#define HANDLE_GEOS_ERROR(label)
unsigned int int32
Definition shpopen.c:54
#define POSTGIS_GEOS_VERSION
Definition sqldefines.h:11
double ymax
Definition liblwgeom.h:357
double xmax
Definition liblwgeom.h:355
double ymin
Definition liblwgeom.h:356
double xmin
Definition liblwgeom.h:354

References boundary(), GEOS2POSTGIS(), gserialized_get_gbox_p(), gserialized_get_srid(), gserialized_has_z(), gserialized_is_empty(), HANDLE_GEOS_ERROR, LW_FALSE, lwgeom_free(), lwgeom_from_gserialized(), lwgeom_geos_error(), lwgeom_isfinite(), lwpoint_construct_empty(), POSTGIS2GEOS(), POSTGIS_GEOS_VERSION, result, SRID_UNKNOWN, GBOX::xmax, GBOX::xmin, GBOX::ymax, and GBOX::ymin.

Here is the call graph for this function: