28 #include "../liblwgeom/liblwgeom.h" 30 #include "lwgeom_pg.h" 32 #include "../postgis_config.h" 73 sfcgal_set_error_handlers((sfcgal_error_handler_t) lwpgnotice, (sfcgal_error_handler_t) lwpgerror);
88 lwpgerror(
"POSTGIS2SFCGALGeometry: Unable to deserialize input");
100 sfcgal_geometry_t* g;
105 lwpgerror(
"POSTGIS2SFCGALPreparedGeometry: Unable to deserialize input");
135 force3D, sfcgal_prepared_geometry_srid(geom));
144 sfcgal_prepared_geometry_t* g;
145 text *wkttext = PG_GETARG_TEXT_P(0);
150 g = sfcgal_io_read_ewkt( cstring, strlen(cstring) );
153 sfcgal_prepared_geometry_delete( g );
154 PG_RETURN_POINTER(result);
162 sfcgal_geometry_t *geom;
167 input = PG_GETARG_GSERIALIZED_P(0);
170 result = sfcgal_geometry_area(geom);
171 sfcgal_geometry_delete(geom);
173 PG_FREE_IF_COPY(input, 0);
175 PG_RETURN_FLOAT8(result);
183 sfcgal_geometry_t *geom;
188 input = PG_GETARG_GSERIALIZED_P(0);
191 result = sfcgal_geometry_area_3d(geom);
192 sfcgal_geometry_delete(geom);
194 PG_FREE_IF_COPY(input, 0);
196 PG_RETURN_FLOAT8(result);
204 sfcgal_geometry_t *geom;
209 input = PG_GETARG_GSERIALIZED_P(0);
212 result = sfcgal_geometry_is_planar(geom);
213 sfcgal_geometry_delete(geom);
215 PG_FREE_IF_COPY(input, 0);
217 PG_RETURN_BOOL(result);
225 sfcgal_geometry_t *geom;
230 input = PG_GETARG_GSERIALIZED_P(0);
233 result = sfcgal_geometry_orientation(geom);
234 sfcgal_geometry_delete(geom);
236 PG_FREE_IF_COPY(input, 0);
238 PG_RETURN_INT32(result);
246 sfcgal_geometry_t *geom0, *geom1;
251 input0 = PG_GETARG_GSERIALIZED_P(0);
252 input1 = PG_GETARG_GSERIALIZED_P(1);
254 PG_FREE_IF_COPY(input0, 0);
256 PG_FREE_IF_COPY(input1, 1);
258 result = sfcgal_geometry_intersects(geom0, geom1);
259 sfcgal_geometry_delete(geom0);
260 sfcgal_geometry_delete(geom1);
262 PG_RETURN_BOOL(result);
270 sfcgal_geometry_t *geom0, *geom1;
275 input0 = PG_GETARG_GSERIALIZED_P(0);
276 input1 = PG_GETARG_GSERIALIZED_P(1);
278 PG_FREE_IF_COPY(input0, 0);
280 PG_FREE_IF_COPY(input1, 1);
282 result = sfcgal_geometry_intersects_3d(geom0, geom1);
283 sfcgal_geometry_delete(geom0);
284 sfcgal_geometry_delete(geom1);
286 PG_RETURN_BOOL(result);
294 sfcgal_geometry_t *geom0, *geom1;
299 input0 = PG_GETARG_GSERIALIZED_P(0);
300 input1 = PG_GETARG_GSERIALIZED_P(1);
302 PG_FREE_IF_COPY(input0, 0);
304 PG_FREE_IF_COPY(input1, 1);
306 result = sfcgal_geometry_distance(geom0, geom1);
307 sfcgal_geometry_delete(geom0);
308 sfcgal_geometry_delete(geom1);
310 PG_RETURN_FLOAT8(result);
318 sfcgal_geometry_t *geom0, *geom1;
323 input0 = PG_GETARG_GSERIALIZED_P(0);
324 input1 = PG_GETARG_GSERIALIZED_P(1);
326 PG_FREE_IF_COPY(input0, 0);
328 PG_FREE_IF_COPY(input1, 1);
330 result = sfcgal_geometry_distance_3d(geom0, geom1);
331 sfcgal_geometry_delete(geom0);
332 sfcgal_geometry_delete(geom1);
334 PG_RETURN_FLOAT8(result);
342 sfcgal_geometry_t *geom;
343 sfcgal_geometry_t *result;
348 input = PG_GETARG_GSERIALIZED_P(0);
351 PG_FREE_IF_COPY(input, 0);
353 result = sfcgal_geometry_tesselate(geom);
354 sfcgal_geometry_delete(geom);
357 sfcgal_geometry_delete(result);
359 PG_RETURN_POINTER(output);
367 sfcgal_geometry_t *geom;
368 sfcgal_geometry_t *result;
373 input = PG_GETARG_GSERIALIZED_P(0);
376 PG_FREE_IF_COPY(input, 0);
378 result = sfcgal_geometry_triangulate_2dz(geom);
379 sfcgal_geometry_delete(geom);
382 sfcgal_geometry_delete(result);
384 PG_RETURN_POINTER(output);
392 sfcgal_geometry_t *geom;
393 sfcgal_geometry_t *result;
398 input = PG_GETARG_GSERIALIZED_P(0);
401 PG_FREE_IF_COPY(input, 0);
403 result = sfcgal_geometry_force_lhr(geom);
404 sfcgal_geometry_delete(geom);
407 sfcgal_geometry_delete(result);
409 PG_RETURN_POINTER(output);
417 sfcgal_geometry_t *geom;
418 sfcgal_geometry_t *result;
423 input = PG_GETARG_GSERIALIZED_P(0);
426 PG_FREE_IF_COPY(input, 0);
428 result = sfcgal_geometry_straight_skeleton(geom);
429 sfcgal_geometry_delete(geom);
432 sfcgal_geometry_delete(result);
434 PG_RETURN_POINTER(output);
440 #if POSTGIS_SFCGAL_VERSION < 12 441 lwpgerror(
"The SFCGAL version this PostGIS binary " 442 "was compiled against (%d) doesn't support " 443 "'sfcgal_geometry_approximate_medial_axis' function (1.2.0+ required)",
448 sfcgal_geometry_t *geom;
449 sfcgal_geometry_t *result;
454 input = PG_GETARG_GSERIALIZED_P(0);
457 PG_FREE_IF_COPY(input, 0);
459 result = sfcgal_geometry_approximate_medial_axis(geom);
460 sfcgal_geometry_delete(geom);
463 sfcgal_geometry_delete(result);
465 PG_RETURN_POINTER(output);
474 sfcgal_geometry_t *geom0, *geom1;
475 sfcgal_geometry_t *result;
480 input0 = PG_GETARG_GSERIALIZED_P(0);
482 input1 = PG_GETARG_GSERIALIZED_P(1);
484 PG_FREE_IF_COPY(input0, 0);
486 PG_FREE_IF_COPY(input1, 1);
488 result = sfcgal_geometry_intersection(geom0, geom1);
489 sfcgal_geometry_delete(geom0);
490 sfcgal_geometry_delete(geom1);
493 sfcgal_geometry_delete(result);
495 PG_RETURN_POINTER(output);
503 sfcgal_geometry_t *geom0, *geom1;
504 sfcgal_geometry_t *result;
509 input0 = PG_GETARG_GSERIALIZED_P(0);
511 input1 = PG_GETARG_GSERIALIZED_P(1);
513 PG_FREE_IF_COPY(input0, 0);
515 PG_FREE_IF_COPY(input1, 1);
517 result = sfcgal_geometry_intersection_3d(geom0, geom1);
518 sfcgal_geometry_delete(geom0);
519 sfcgal_geometry_delete(geom1);
522 sfcgal_geometry_delete(result);
524 PG_RETURN_POINTER(output);
531 sfcgal_geometry_t *geom0, *geom1;
532 sfcgal_geometry_t *result;
537 input0 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
539 input1 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
541 PG_FREE_IF_COPY(input0, 0);
543 PG_FREE_IF_COPY(input1, 1);
545 result = sfcgal_geometry_difference(geom0, geom1);
546 sfcgal_geometry_delete(geom0);
547 sfcgal_geometry_delete(geom1);
550 sfcgal_geometry_delete(result);
552 PG_RETURN_POINTER(output);
560 sfcgal_geometry_t *geom0, *geom1;
561 sfcgal_geometry_t *result;
566 input0 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
568 input1 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
570 PG_FREE_IF_COPY(input0, 0);
572 PG_FREE_IF_COPY(input1, 1);
574 result = sfcgal_geometry_difference_3d(geom0, geom1);
575 sfcgal_geometry_delete(geom0);
576 sfcgal_geometry_delete(geom1);
579 sfcgal_geometry_delete(result);
581 PG_RETURN_POINTER(output);
588 sfcgal_geometry_t *geom0, *geom1;
589 sfcgal_geometry_t *result;
594 input0 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
596 input1 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
598 PG_FREE_IF_COPY(input0, 0);
600 PG_FREE_IF_COPY(input1, 1);
602 result = sfcgal_geometry_union(geom0, geom1);
603 sfcgal_geometry_delete(geom0);
604 sfcgal_geometry_delete(geom1);
607 sfcgal_geometry_delete(result);
609 PG_RETURN_POINTER(output);
617 sfcgal_geometry_t *geom0, *geom1;
618 sfcgal_geometry_t *result;
623 input0 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
625 input1 = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
627 PG_FREE_IF_COPY(input0, 0);
629 PG_FREE_IF_COPY(input1, 1);
631 result = sfcgal_geometry_union_3d(geom0, geom1);
632 sfcgal_geometry_delete(geom0);
633 sfcgal_geometry_delete(geom1);
636 sfcgal_geometry_delete(result);
638 PG_RETURN_POINTER(output);
645 sfcgal_geometry_t *geom;
650 input = (
GSERIALIZED*) PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
653 result = sfcgal_geometry_volume(geom);
654 sfcgal_geometry_delete(geom);
656 PG_FREE_IF_COPY(input, 0);
658 PG_RETURN_FLOAT8(result);
665 sfcgal_geometry_t *geom0, *geom1;
666 sfcgal_geometry_t *result;
671 input0 = PG_GETARG_GSERIALIZED_P(0);
673 input1 = PG_GETARG_GSERIALIZED_P(1);
675 PG_FREE_IF_COPY(input0, 0);
677 PG_FREE_IF_COPY(input1, 1);
679 result = sfcgal_geometry_minkowski_sum(geom0, geom1);
680 sfcgal_geometry_delete(geom0);
681 sfcgal_geometry_delete(geom1);
684 sfcgal_geometry_delete(result);
686 PG_RETURN_POINTER(output);
694 sfcgal_geometry_t *geom;
695 sfcgal_geometry_t *result;
701 input = PG_GETARG_GSERIALIZED_P(0);
705 PG_FREE_IF_COPY(input, 0);
707 dx = PG_GETARG_FLOAT8(1);
708 dy = PG_GETARG_FLOAT8(2);
709 dz = PG_GETARG_FLOAT8(3);
711 result = sfcgal_geometry_extrude(geom, dx, dy, dz);
712 sfcgal_geometry_delete(geom);
715 sfcgal_geometry_delete(result);
717 PG_RETURN_POINTER(output);
724 text *result = cstring2text(ver);
725 PG_RETURN_POINTER(result);
734 PG_FREE_IF_COPY(input, 0);
737 elog(ERROR,
"sfcgal_is_solid: Unable to deserialize input");
743 PG_RETURN_BOOL(result);
754 elog(ERROR,
"sfcgal_make_solid: Unable to deserialize input");
761 PG_FREE_IF_COPY(input, 0);
762 PG_RETURN_POINTER(output);
GSERIALIZED * SFCGALPreparedGeometry2POSTGIS(const sfcgal_prepared_geometry_t *geom, int force3D)
#define POSTGIS_SFCGAL_VERSION
Datum sfcgal_volume(PG_FUNCTION_ARGS)
#define FLAGS_SET_SOLID(flags, value)
Datum sfcgal_is_planar(PG_FUNCTION_ARGS)
Datum sfcgal_extrude(PG_FUNCTION_ARGS)
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
Datum sfcgal_union3D(PG_FUNCTION_ARGS)
Datum sfcgal_approximate_medial_axis(PG_FUNCTION_ARGS)
Datum sfcgal_is_solid(PG_FUNCTION_ARGS)
void lwgeom_free(LWGEOM *geom)
sfcgal_geometry_t * POSTGIS2SFCGALGeometry(GSERIALIZED *pglwgeom)
GSERIALIZED * SFCGALGeometry2POSTGIS(const sfcgal_geometry_t *geom, int force3D, int SRID)
#define FLAGS_GET_SOLID(flags)
Datum sfcgal_distance3D(PG_FUNCTION_ARGS)
Datum sfcgal_minkowski_sum(PG_FUNCTION_ARGS)
Datum sfcgal_orientation(PG_FUNCTION_ARGS)
Datum sfcgal_make_solid(PG_FUNCTION_ARGS)
const char * lwgeom_sfcgal_version()
Datum sfcgal_force_lhr(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(sfcgal_from_ewkt)
Datum sfcgal_intersection3D(PG_FUNCTION_ARGS)
sfcgal_geometry_t * LWGEOM2SFCGAL(const LWGEOM *geom)
Datum sfcgal_area3D(PG_FUNCTION_ARGS)
Datum sfcgal_triangulate(PG_FUNCTION_ARGS)
#define LW_TRUE
Return types for functions with status returns.
Datum sfcgal_difference3D(PG_FUNCTION_ARGS)
Datum sfcgal_intersects3D(PG_FUNCTION_ARGS)
char * text2cstring(const text *textptr)
Datum sfcgal_straight_skeleton(PG_FUNCTION_ARGS)
Datum postgis_sfcgal_version(PG_FUNCTION_ARGS)
sfcgal_prepared_geometry_t * POSTGIS2SFCGALPreparedGeometry(GSERIALIZED *pglwgeom)
Datum sfcgal_union(PG_FUNCTION_ARGS)
void sfcgal_postgis_init(void)
Datum sfcgal_from_ewkt(PG_FUNCTION_ARGS)
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
Datum sfcgal_intersects(PG_FUNCTION_ARGS)
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
Datum sfcgal_distance(PG_FUNCTION_ARGS)
Datum sfcgal_intersection(PG_FUNCTION_ARGS)
Datum sfcgal_area(PG_FUNCTION_ARGS)
Datum sfcgal_difference(PG_FUNCTION_ARGS)
void * lwalloc(size_t size)
int lwgeom_needs_bbox(const LWGEOM *geom)
Check whether or not a lwgeom is big enough to warrant a bounding box.
Datum sfcgal_tesselate(PG_FUNCTION_ARGS)
LWGEOM * SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int srid)
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)...