28 #include "utils/builtins.h"
29 #include "../liblwgeom/liblwgeom.h"
31 #include "lwgeom_pg.h"
33 #include "../postgis_config.h"
74 sfcgal_set_error_handlers((sfcgal_error_handler_t) lwpgnotice, (sfcgal_error_handler_t) lwpgerror);
89 lwpgerror(
"POSTGIS2SFCGALGeometry: Unable to deserialize input");
101 sfcgal_geometry_t* g;
106 lwpgerror(
"POSTGIS2SFCGALPreparedGeometry: Unable to deserialize input");
136 force3D, sfcgal_prepared_geometry_srid(geom));
145 sfcgal_prepared_geometry_t* g;
146 text *wkttext = PG_GETARG_TEXT_P(0);
151 g = sfcgal_io_read_ewkt( cstring, strlen(cstring) );
154 sfcgal_prepared_geometry_delete( g );
155 PG_RETURN_POINTER(result);
163 sfcgal_geometry_t *geom;
168 input = PG_GETARG_GSERIALIZED_P(0);
171 result = sfcgal_geometry_area(geom);
172 sfcgal_geometry_delete(geom);
174 PG_FREE_IF_COPY(input, 0);
176 PG_RETURN_FLOAT8(result);
184 sfcgal_geometry_t *geom;
189 input = PG_GETARG_GSERIALIZED_P(0);
192 result = sfcgal_geometry_area_3d(geom);
193 sfcgal_geometry_delete(geom);
195 PG_FREE_IF_COPY(input, 0);
197 PG_RETURN_FLOAT8(result);
205 sfcgal_geometry_t *geom;
210 input = PG_GETARG_GSERIALIZED_P(0);
213 result = sfcgal_geometry_is_planar(geom);
214 sfcgal_geometry_delete(geom);
216 PG_FREE_IF_COPY(input, 0);
218 PG_RETURN_BOOL(result);
226 sfcgal_geometry_t *geom;
231 input = PG_GETARG_GSERIALIZED_P(0);
234 result = sfcgal_geometry_orientation(geom);
235 sfcgal_geometry_delete(geom);
237 PG_FREE_IF_COPY(input, 0);
239 PG_RETURN_INT32(result);
247 sfcgal_geometry_t *geom0, *geom1;
252 input0 = PG_GETARG_GSERIALIZED_P(0);
253 input1 = PG_GETARG_GSERIALIZED_P(1);
255 PG_FREE_IF_COPY(input0, 0);
257 PG_FREE_IF_COPY(input1, 1);
259 result = sfcgal_geometry_intersects(geom0, geom1);
260 sfcgal_geometry_delete(geom0);
261 sfcgal_geometry_delete(geom1);
263 PG_RETURN_BOOL(result);
271 sfcgal_geometry_t *geom0, *geom1;
276 input0 = PG_GETARG_GSERIALIZED_P(0);
277 input1 = PG_GETARG_GSERIALIZED_P(1);
279 PG_FREE_IF_COPY(input0, 0);
281 PG_FREE_IF_COPY(input1, 1);
283 result = sfcgal_geometry_intersects_3d(geom0, geom1);
284 sfcgal_geometry_delete(geom0);
285 sfcgal_geometry_delete(geom1);
287 PG_RETURN_BOOL(result);
295 sfcgal_geometry_t *geom0, *geom1;
300 input0 = PG_GETARG_GSERIALIZED_P(0);
301 input1 = PG_GETARG_GSERIALIZED_P(1);
303 PG_FREE_IF_COPY(input0, 0);
305 PG_FREE_IF_COPY(input1, 1);
307 result = sfcgal_geometry_distance(geom0, geom1);
308 sfcgal_geometry_delete(geom0);
309 sfcgal_geometry_delete(geom1);
311 PG_RETURN_FLOAT8(result);
319 sfcgal_geometry_t *geom0, *geom1;
324 input0 = PG_GETARG_GSERIALIZED_P(0);
325 input1 = PG_GETARG_GSERIALIZED_P(1);
327 PG_FREE_IF_COPY(input0, 0);
329 PG_FREE_IF_COPY(input1, 1);
331 result = sfcgal_geometry_distance_3d(geom0, geom1);
332 sfcgal_geometry_delete(geom0);
333 sfcgal_geometry_delete(geom1);
335 PG_RETURN_FLOAT8(result);
343 sfcgal_geometry_t *geom;
344 sfcgal_geometry_t *result;
349 input = PG_GETARG_GSERIALIZED_P(0);
352 PG_FREE_IF_COPY(input, 0);
354 result = sfcgal_geometry_tesselate(geom);
355 sfcgal_geometry_delete(geom);
358 sfcgal_geometry_delete(result);
360 PG_RETURN_POINTER(output);
368 sfcgal_geometry_t *geom;
369 sfcgal_geometry_t *result;
374 input = PG_GETARG_GSERIALIZED_P(0);
377 PG_FREE_IF_COPY(input, 0);
379 result = sfcgal_geometry_triangulate_2dz(geom);
380 sfcgal_geometry_delete(geom);
383 sfcgal_geometry_delete(result);
385 PG_RETURN_POINTER(output);
393 sfcgal_geometry_t *geom;
394 sfcgal_geometry_t *result;
399 input = PG_GETARG_GSERIALIZED_P(0);
402 PG_FREE_IF_COPY(input, 0);
404 result = sfcgal_geometry_force_lhr(geom);
405 sfcgal_geometry_delete(geom);
408 sfcgal_geometry_delete(result);
410 PG_RETURN_POINTER(output);
418 sfcgal_geometry_t *geom;
419 sfcgal_geometry_t *result;
424 input = PG_GETARG_GSERIALIZED_P(0);
427 PG_FREE_IF_COPY(input, 0);
429 result = sfcgal_geometry_straight_skeleton(geom);
430 sfcgal_geometry_delete(geom);
433 sfcgal_geometry_delete(result);
435 PG_RETURN_POINTER(output);
441 #if POSTGIS_SFCGAL_VERSION < 12
442 lwpgerror(
"The SFCGAL version this PostGIS binary "
443 "was compiled against (%d) doesn't support "
444 "'sfcgal_geometry_approximate_medial_axis' function (1.2.0+ required)",
449 sfcgal_geometry_t *geom;
450 sfcgal_geometry_t *result;
455 input = PG_GETARG_GSERIALIZED_P(0);
458 PG_FREE_IF_COPY(input, 0);
460 result = sfcgal_geometry_approximate_medial_axis(geom);
461 sfcgal_geometry_delete(geom);
464 sfcgal_geometry_delete(result);
466 PG_RETURN_POINTER(output);
475 sfcgal_geometry_t *geom0, *geom1;
476 sfcgal_geometry_t *result;
481 input0 = PG_GETARG_GSERIALIZED_P(0);
483 input1 = PG_GETARG_GSERIALIZED_P(1);
485 PG_FREE_IF_COPY(input0, 0);
487 PG_FREE_IF_COPY(input1, 1);
489 result = sfcgal_geometry_intersection(geom0, geom1);
490 sfcgal_geometry_delete(geom0);
491 sfcgal_geometry_delete(geom1);
494 sfcgal_geometry_delete(result);
496 PG_RETURN_POINTER(output);
504 sfcgal_geometry_t *geom0, *geom1;
505 sfcgal_geometry_t *result;
510 input0 = PG_GETARG_GSERIALIZED_P(0);
512 input1 = PG_GETARG_GSERIALIZED_P(1);
514 PG_FREE_IF_COPY(input0, 0);
516 PG_FREE_IF_COPY(input1, 1);
518 result = sfcgal_geometry_intersection_3d(geom0, geom1);
519 sfcgal_geometry_delete(geom0);
520 sfcgal_geometry_delete(geom1);
523 sfcgal_geometry_delete(result);
525 PG_RETURN_POINTER(output);
532 sfcgal_geometry_t *geom0, *geom1;
533 sfcgal_geometry_t *result;
538 input0 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
540 input1 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
542 PG_FREE_IF_COPY(input0, 0);
544 PG_FREE_IF_COPY(input1, 1);
546 result = sfcgal_geometry_difference(geom0, geom1);
547 sfcgal_geometry_delete(geom0);
548 sfcgal_geometry_delete(geom1);
551 sfcgal_geometry_delete(result);
553 PG_RETURN_POINTER(output);
561 sfcgal_geometry_t *geom0, *geom1;
562 sfcgal_geometry_t *result;
567 input0 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
569 input1 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
571 PG_FREE_IF_COPY(input0, 0);
573 PG_FREE_IF_COPY(input1, 1);
575 result = sfcgal_geometry_difference_3d(geom0, geom1);
576 sfcgal_geometry_delete(geom0);
577 sfcgal_geometry_delete(geom1);
580 sfcgal_geometry_delete(result);
582 PG_RETURN_POINTER(output);
589 sfcgal_geometry_t *geom0, *geom1;
590 sfcgal_geometry_t *result;
595 input0 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
597 input1 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
599 PG_FREE_IF_COPY(input0, 0);
601 PG_FREE_IF_COPY(input1, 1);
603 result = sfcgal_geometry_union(geom0, geom1);
604 sfcgal_geometry_delete(geom0);
605 sfcgal_geometry_delete(geom1);
608 sfcgal_geometry_delete(result);
610 PG_RETURN_POINTER(output);
618 sfcgal_geometry_t *geom0, *geom1;
619 sfcgal_geometry_t *result;
624 input0 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
626 input1 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
628 PG_FREE_IF_COPY(input0, 0);
630 PG_FREE_IF_COPY(input1, 1);
632 result = sfcgal_geometry_union_3d(geom0, geom1);
633 sfcgal_geometry_delete(geom0);
634 sfcgal_geometry_delete(geom1);
637 sfcgal_geometry_delete(result);
639 PG_RETURN_POINTER(output);
646 sfcgal_geometry_t *geom;
651 input = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
654 result = sfcgal_geometry_volume(geom);
655 sfcgal_geometry_delete(geom);
657 PG_FREE_IF_COPY(input, 0);
659 PG_RETURN_FLOAT8(result);
666 sfcgal_geometry_t *geom0, *geom1;
667 sfcgal_geometry_t *result;
672 input0 = PG_GETARG_GSERIALIZED_P(0);
674 input1 = PG_GETARG_GSERIALIZED_P(1);
676 PG_FREE_IF_COPY(input0, 0);
678 PG_FREE_IF_COPY(input1, 1);
680 result = sfcgal_geometry_minkowski_sum(geom0, geom1);
681 sfcgal_geometry_delete(geom0);
682 sfcgal_geometry_delete(geom1);
685 sfcgal_geometry_delete(result);
687 PG_RETURN_POINTER(output);
695 sfcgal_geometry_t *geom;
696 sfcgal_geometry_t *result;
702 input = PG_GETARG_GSERIALIZED_P(0);
706 PG_FREE_IF_COPY(input, 0);
708 dx = PG_GETARG_FLOAT8(1);
709 dy = PG_GETARG_FLOAT8(2);
710 dz = PG_GETARG_FLOAT8(3);
712 result = sfcgal_geometry_extrude(geom, dx, dy, dz);
713 sfcgal_geometry_delete(geom);
716 sfcgal_geometry_delete(result);
718 PG_RETURN_POINTER(output);
725 text *result = cstring_to_text(ver);
726 PG_RETURN_POINTER(result);
735 PG_FREE_IF_COPY(input, 0);
738 elog(ERROR,
"sfcgal_is_solid: Unable to deserialize input");
744 PG_RETURN_BOOL(result);
755 elog(ERROR,
"sfcgal_make_solid: Unable to deserialize input");
762 PG_FREE_IF_COPY(input, 0);
763 PG_RETURN_POINTER(output);
int32_t gserialized_get_srid(const GSERIALIZED *s)
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.
sfcgal_geometry_t * LWGEOM2SFCGAL(const LWGEOM *geom)
const char * lwgeom_sfcgal_version()
LWGEOM * SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int srid)
void lwgeom_free(LWGEOM *geom)
int lwgeom_needs_bbox(const LWGEOM *geom)
Check whether or not a lwgeom is big enough to warrant a bounding box.
#define FLAGS_GET_SOLID(flags)
void * lwalloc(size_t size)
#define LW_TRUE
Return types for functions with status returns.
#define FLAGS_SET_SOLID(flags, value)
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
Datum sfcgal_difference(PG_FUNCTION_ARGS)
Datum sfcgal_make_solid(PG_FUNCTION_ARGS)
char * text_to_cstring(const text *textptr)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
Datum sfcgal_force_lhr(PG_FUNCTION_ARGS)
Datum sfcgal_distance(PG_FUNCTION_ARGS)
Datum postgis_sfcgal_version(PG_FUNCTION_ARGS)
Datum sfcgal_intersects3D(PG_FUNCTION_ARGS)
sfcgal_geometry_t * POSTGIS2SFCGALGeometry(GSERIALIZED *pglwgeom)
PG_FUNCTION_INFO_V1(sfcgal_from_ewkt)
sfcgal_prepared_geometry_t * POSTGIS2SFCGALPreparedGeometry(GSERIALIZED *pglwgeom)
Datum sfcgal_from_ewkt(PG_FUNCTION_ARGS)
Datum sfcgal_orientation(PG_FUNCTION_ARGS)
Datum sfcgal_intersects(PG_FUNCTION_ARGS)
Datum sfcgal_intersection3D(PG_FUNCTION_ARGS)
Datum sfcgal_approximate_medial_axis(PG_FUNCTION_ARGS)
Datum sfcgal_triangulate(PG_FUNCTION_ARGS)
Datum sfcgal_is_solid(PG_FUNCTION_ARGS)
Datum sfcgal_area3D(PG_FUNCTION_ARGS)
Datum sfcgal_area(PG_FUNCTION_ARGS)
void sfcgal_postgis_init(void)
Datum sfcgal_is_planar(PG_FUNCTION_ARGS)
Datum sfcgal_difference3D(PG_FUNCTION_ARGS)
Datum sfcgal_extrude(PG_FUNCTION_ARGS)
Datum sfcgal_intersection(PG_FUNCTION_ARGS)
Datum sfcgal_tesselate(PG_FUNCTION_ARGS)
Datum sfcgal_minkowski_sum(PG_FUNCTION_ARGS)
Datum sfcgal_distance3D(PG_FUNCTION_ARGS)
Datum sfcgal_union(PG_FUNCTION_ARGS)
GSERIALIZED * SFCGALPreparedGeometry2POSTGIS(const sfcgal_prepared_geometry_t *geom, int force3D)
Datum sfcgal_straight_skeleton(PG_FUNCTION_ARGS)
Datum sfcgal_volume(PG_FUNCTION_ARGS)
Datum sfcgal_union3D(PG_FUNCTION_ARGS)
GSERIALIZED * SFCGALGeometry2POSTGIS(const sfcgal_geometry_t *geom, int force3D, int SRID)
#define POSTGIS_SFCGAL_VERSION