PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
lwgeom_sfcgal.c
Go to the documentation of this file.
1/**********************************************************************
2 *
3 * PostGIS - Spatial Types for PostgreSQL
4 * http://postgis.net
5 *
6 * PostGIS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * PostGIS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18 *
19 **********************************************************************
20 *
21 * Copyright 2012-2013 Oslandia <infos@oslandia.com>
22 *
23 **********************************************************************/
24
25#include "lwgeom_sfcgal.h"
26#include <stdio.h>
27
28#if POSTGIS_SFCGAL_VERSION >= 20100
29#define sfcgal_triangulated_surface_num_triangles(g) sfcgal_triangulated_surface_num_patches((g))
30#define sfcgal_triangulated_surface_triangle_n(g, i) sfcgal_triangulated_surface_patch_n((g), (i))
31#define sfcgal_triangulated_surface_add_triangle(g, p) sfcgal_triangulated_surface_add_patch((g), (p))
32#define sfcgal_polyhedral_surface_num_polygons(g) sfcgal_polyhedral_surface_num_patches((g))
33#define sfcgal_polyhedral_surface_polygon_n(g, i) sfcgal_polyhedral_surface_patch_n((g), (i))
34#define sfcgal_geometry_collection_num_geometries(g) sfcgal_geometry_num_geometries((g))
35#define sfcgal_polyhedral_surface_add_polygon(g, p) sfcgal_polyhedral_surface_add_patch((g), (p))
36#endif
37
38static int SFCGAL_type_to_lwgeom_type(sfcgal_geometry_type_t type);
39static POINTARRAY *ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int force3D);
40static sfcgal_geometry_t *ptarray_to_SFCGAL(const POINTARRAY *pa, int type);
41
42/* Return SFCGAL version string */
43const char *
45{
46 const char *version = sfcgal_version();
47 return version;
48}
49
50#define MAX_LENGTH_SFCGAL_FULL_VERSION 50
51/* Return SFCGAL full version string */
52const char *
54{
55#if POSTGIS_SFCGAL_VERSION >= 10400
56 const char *version = sfcgal_full_version();
57#else
58 char *version = (char *)lwalloc(MAX_LENGTH_SFCGAL_FULL_VERSION);
59 snprintf(version,
61 "SFCGAL=\"%s\" CGAL=\"Unknown\" Boost=\"Unknown\"",
62 sfcgal_version());
63#endif
64 return version;
65}
66
67/*
68 * Mapping between SFCGAL and PostGIS types
69 *
70 * Throw an error if type is unsupported
71 */
72static int
73SFCGAL_type_to_lwgeom_type(sfcgal_geometry_type_t type)
74{
75 switch (type)
76 {
77 case SFCGAL_TYPE_POINT:
78 return POINTTYPE;
79
80 case SFCGAL_TYPE_LINESTRING:
81 return LINETYPE;
82
83 case SFCGAL_TYPE_POLYGON:
84 return POLYGONTYPE;
85
86 case SFCGAL_TYPE_MULTIPOINT:
87 return MULTIPOINTTYPE;
88
89 case SFCGAL_TYPE_MULTILINESTRING:
90 return MULTILINETYPE;
91
92 case SFCGAL_TYPE_MULTIPOLYGON:
93 return MULTIPOLYGONTYPE;
94
95 case SFCGAL_TYPE_MULTISOLID:
96 return COLLECTIONTYPE; /* Nota: PolyhedralSurface closed inside
97 aim is to use true solid type as soon
98 as available in OGC SFS */
99
100 case SFCGAL_TYPE_GEOMETRYCOLLECTION:
101 return COLLECTIONTYPE;
102
103#if 0
104 case SFCGAL_TYPE_CIRCULARSTRING:
105 return CIRCSTRINGTYPE;
106
107 case SFCGAL_TYPE_COMPOUNDCURVE:
108 return COMPOUNDTYPE;
109
110 case SFCGAL_TYPE_CURVEPOLYGON:
111 return CURVEPOLYTYPE;
112
113 case SFCGAL_TYPE_MULTICURVE:
114 return MULTICURVETYPE;
115
116 case SFCGAL_TYPE_MULTISURFACE:
117 return MULTISURFACETYPE;
118#endif
119
120 case SFCGAL_TYPE_POLYHEDRALSURFACE:
122
123 case SFCGAL_TYPE_TRIANGULATEDSURFACE:
124 return TINTYPE;
125
126 case SFCGAL_TYPE_TRIANGLE:
127 return TRIANGLETYPE;
128
129 default:
130 lwerror("SFCGAL_type_to_lwgeom_type: Unknown Type");
131 return 0;
132 }
133}
134
135/*
136 * Return a PostGIS pointarray from a simple SFCGAL geometry:
137 * POINT, LINESTRING or TRIANGLE
138 *
139 * Throw an error on others types
140 */
141static POINTARRAY *
142ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int want3d)
143{
144 POINT4D point;
145 uint32_t i, npoints;
146 POINTARRAY *pa = NULL;
147 int is_3d;
148 int is_measured = 0;
149
150 assert(geom);
151
152 is_3d = sfcgal_geometry_is_3d(geom);
153
154#if POSTGIS_SFCGAL_VERSION >= 10308
155 is_measured = sfcgal_geometry_is_measured(geom);
156#endif
157
158 switch (sfcgal_geometry_type_id(geom))
159 {
160 case SFCGAL_TYPE_POINT: {
161 pa = ptarray_construct(want3d, is_measured, 1);
162 point.x = sfcgal_point_x(geom);
163 point.y = sfcgal_point_y(geom);
164
165 if (is_3d)
166 point.z = sfcgal_point_z(geom);
167 else if (want3d)
168 point.z = 0.0;
169
170#if POSTGIS_SFCGAL_VERSION >= 10308
171 if (is_measured)
172 point.m = sfcgal_point_m(geom);
173#endif
174
175 ptarray_set_point4d(pa, 0, &point);
176 }
177 break;
178
179 case SFCGAL_TYPE_LINESTRING: {
180 npoints = sfcgal_linestring_num_points(geom);
181 pa = ptarray_construct(want3d, is_measured, npoints);
182
183 for (i = 0; i < npoints; i++)
184 {
185 const sfcgal_geometry_t *pt = sfcgal_linestring_point_n(geom, i);
186 point.x = sfcgal_point_x(pt);
187 point.y = sfcgal_point_y(pt);
188
189 if (is_3d)
190 point.z = sfcgal_point_z(pt);
191 else if (want3d)
192 point.z = 0.0;
193
194#if POSTGIS_SFCGAL_VERSION >= 10308
195 if (is_measured)
196 point.m = sfcgal_point_m(pt);
197#endif
198
199 ptarray_set_point4d(pa, i, &point);
200 }
201 }
202 break;
203
204 case SFCGAL_TYPE_TRIANGLE: {
205 pa = ptarray_construct(want3d, is_measured, 4);
206
207 for (i = 0; i < 4; i++)
208 {
209 const sfcgal_geometry_t *pt = sfcgal_triangle_vertex(geom, (i % 3));
210 point.x = sfcgal_point_x(pt);
211 point.y = sfcgal_point_y(pt);
212
213 if (is_3d)
214 point.z = sfcgal_point_z(pt);
215 else if (want3d)
216 point.z = 0.0;
217
218#if POSTGIS_SFCGAL_VERSION >= 10308
219 if (is_measured)
220 point.m = sfcgal_point_m(pt);
221#endif
222
223 ptarray_set_point4d(pa, i, &point);
224 }
225 }
226 break;
227
228 /* Other types should not be called directly ... */
229 default:
230 lwerror("ptarray_from_SFCGAL: Unknown Type");
231 break;
232 }
233 return pa;
234}
235
239static sfcgal_geometry_t *
240create_sfcgal_point_by_dimensions(double x, double y, double z, double m, int is_3d, int is_measured)
241{
242#if POSTGIS_SFCGAL_VERSION >= 10500
243 if (is_3d && is_measured)
244 return sfcgal_point_create_from_xyzm(x, y, z, m);
245 else if (is_3d)
246 return sfcgal_point_create_from_xyz(x, y, z);
247 else if (is_measured)
248 return sfcgal_point_create_from_xym(x, y, m);
249 else
250 return sfcgal_point_create_from_xy(x, y);
251#else
252 (void)is_measured;
253 (void)m;
254 if (is_3d)
255 return sfcgal_point_create_from_xyz(x, y, z);
256 else
257 return sfcgal_point_create_from_xy(x, y);
258#endif
259}
260
264static sfcgal_geometry_t *
265ptarray_to_SFCGAL(const POINTARRAY *pa, int type)
266{
267 POINT4D point;
268 int is_3d, is_measured;
269 uint32_t i;
270
271 assert(pa);
272
273 is_3d = FLAGS_GET_Z(pa->flags) != 0;
274 is_measured = FLAGS_GET_M(pa->flags) != 0;
275
276 switch (type)
277 {
278 case POINTTYPE: {
279 getPoint4d_p(pa, 0, &point);
280 return create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured);
281 }
282 break;
283 case LINETYPE: {
284 sfcgal_geometry_t *line = sfcgal_linestring_create();
285 for (i = 0; i < pa->npoints; i++)
286 {
287 getPoint4d_p(pa, i, &point);
288 sfcgal_linestring_add_point(
289 line,
290 create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured));
291 }
292 return line;
293 }
294 break;
295 case TRIANGLETYPE: {
296 sfcgal_geometry_t *triangle = sfcgal_triangle_create();
297 for (i = 0; i < 3; i++)
298 {
299 getPoint4d_p(pa, i, &point);
300 sfcgal_geometry_t *vertex =
301 create_sfcgal_point_by_dimensions(point.x, point.y, point.z, point.m, is_3d, is_measured);
302 if (vertex)
303 {
304 sfcgal_triangle_set_vertex(triangle, i, vertex);
305 sfcgal_geometry_delete(vertex);
306 }
307 }
308 return triangle;
309 }
310 break;
311 default:
312 lwerror("ptarray_to_SFCGAL: Unknown Type");
313 return NULL;
314 }
315}
316
317/*
318 * Convert a SFCGAL structure to PostGIS LWGEOM
319 *
320 * Throws an error on unsupported type
321 */
322LWGEOM *
323SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
324{
325 uint32_t ngeoms = 0, nshells = 0, nsolids = 0;
326 uint32_t i, j, k;
327 int want3d;
328
329 assert(geom);
330
331 want3d = force3D || sfcgal_geometry_is_3d(geom);
332
333 switch (sfcgal_geometry_type_id(geom))
334 {
335 case SFCGAL_TYPE_POINT: {
336 if (sfcgal_geometry_is_empty(geom))
337 return (LWGEOM *)lwpoint_construct_empty(srid, want3d, 0);
338
339 POINTARRAY *pa = ptarray_from_SFCGAL(geom, want3d);
340 return (LWGEOM *)lwpoint_construct(srid, NULL, pa);
341 }
342
343 case SFCGAL_TYPE_LINESTRING: {
344 if (sfcgal_geometry_is_empty(geom))
345 return (LWGEOM *)lwline_construct_empty(srid, want3d, 0);
346
347 POINTARRAY *pa = ptarray_from_SFCGAL(geom, want3d);
348 return (LWGEOM *)lwline_construct(srid, NULL, pa);
349 }
350
351 case SFCGAL_TYPE_TRIANGLE: {
352 if (sfcgal_geometry_is_empty(geom))
353 return (LWGEOM *)lwtriangle_construct_empty(srid, want3d, 0);
354
355 POINTARRAY *pa = ptarray_from_SFCGAL(geom, want3d);
356 return (LWGEOM *)lwtriangle_construct(srid, NULL, pa);
357 }
358
359 case SFCGAL_TYPE_POLYGON: {
360 if (sfcgal_geometry_is_empty(geom))
361 return (LWGEOM *)lwpoly_construct_empty(srid, want3d, 0);
362
363 uint32_t nrings = sfcgal_polygon_num_interior_rings(geom) + 1;
364 POINTARRAY **pa = (POINTARRAY **)lwalloc(sizeof(POINTARRAY *) * nrings);
365
366 pa[0] = ptarray_from_SFCGAL(sfcgal_polygon_exterior_ring(geom), want3d);
367 for (i = 1; i < nrings; i++)
368 pa[i] = ptarray_from_SFCGAL(sfcgal_polygon_interior_ring_n(geom, i - 1), want3d);
369
370 return (LWGEOM *)lwpoly_construct(srid, NULL, nrings, pa);
371 }
372
373 case SFCGAL_TYPE_MULTIPOINT:
374 case SFCGAL_TYPE_MULTILINESTRING:
375 case SFCGAL_TYPE_MULTIPOLYGON:
376 case SFCGAL_TYPE_MULTISOLID:
377 case SFCGAL_TYPE_GEOMETRYCOLLECTION: {
378 ngeoms = sfcgal_geometry_collection_num_geometries(geom);
379 LWGEOM **geoms = NULL;
380 if (ngeoms)
381 {
382 nsolids = 0;
383 geoms = (LWGEOM **)lwalloc(sizeof(LWGEOM *) * ngeoms);
384 for (i = 0; i < ngeoms; i++)
385 {
386 const sfcgal_geometry_t *g = sfcgal_geometry_collection_geometry_n(geom, i);
387 geoms[i] = SFCGAL2LWGEOM(g, 0, srid);
388 if (FLAGS_GET_SOLID(geoms[i]->flags))
389 ++nsolids;
390 }
391 geoms = (LWGEOM **)lwrealloc(geoms, sizeof(LWGEOM *) * ngeoms);
392 }
394 SFCGAL_type_to_lwgeom_type(sfcgal_geometry_type_id(geom)), srid, NULL, ngeoms, geoms);
395 if (ngeoms)
396 {
397 if (ngeoms == nsolids)
398 FLAGS_SET_SOLID(rgeom->flags, 1);
399 else if (nsolids)
400 lwnotice(
401 "SFCGAL2LWGEOM: SOLID in heterogeneous collection will be treated as a POLYHEDRALSURFACETYPE");
402 }
403 return rgeom;
404 }
405
406#if 0
407 case SFCGAL_TYPE_CIRCULARSTRING:
408 case SFCGAL_TYPE_COMPOUNDCURVE:
409 case SFCGAL_TYPE_CURVEPOLYGON:
410 case SFCGAL_TYPE_MULTICURVE:
411 case SFCGAL_TYPE_MULTISURFACE:
412 case SFCGAL_TYPE_CURVE:
413 case SFCGAL_TYPE_SURFACE:
414
415 /* TODO curve types handling */
416#endif
417
418 case SFCGAL_TYPE_POLYHEDRALSURFACE: {
419 ngeoms = sfcgal_polyhedral_surface_num_polygons(geom);
420
421 LWGEOM **geoms = NULL;
422 if (ngeoms)
423 {
424 geoms = (LWGEOM **)lwalloc(sizeof(LWGEOM *) * ngeoms);
425 for (i = 0; i < ngeoms; i++)
426 {
427 const sfcgal_geometry_t *g = sfcgal_polyhedral_surface_polygon_n(geom, i);
428 geoms[i] = SFCGAL2LWGEOM(g, 0, srid);
429 }
430 }
431 return (LWGEOM *)lwcollection_construct(POLYHEDRALSURFACETYPE, srid, NULL, ngeoms, geoms);
432 }
433
434 /* Solid is map as a closed PolyhedralSurface (for now) */
435 case SFCGAL_TYPE_SOLID: {
436 nshells = sfcgal_solid_num_shells(geom);
437
438 for (ngeoms = 0, i = 0; i < nshells; i++)
439 ngeoms += sfcgal_polyhedral_surface_num_polygons(sfcgal_solid_shell_n(geom, i));
440
441 LWGEOM **geoms = 0;
442 if (ngeoms)
443 {
444 geoms = (LWGEOM **)lwalloc(sizeof(LWGEOM *) * ngeoms);
445 for (i = 0, k = 0; i < nshells; i++)
446 {
447 const sfcgal_geometry_t *shell = sfcgal_solid_shell_n(geom, i);
448 ngeoms = sfcgal_polyhedral_surface_num_polygons(shell);
449
450 for (j = 0; j < ngeoms; j++)
451 {
452 const sfcgal_geometry_t *g = sfcgal_polyhedral_surface_polygon_n(shell, j);
453 geoms[k] = SFCGAL2LWGEOM(g, 1, srid);
454 k++;
455 }
456 }
457 }
458 LWGEOM *rgeom = (LWGEOM *)lwcollection_construct(POLYHEDRALSURFACETYPE, srid, NULL, ngeoms, geoms);
459 if (ngeoms)
460 FLAGS_SET_SOLID(rgeom->flags, 1);
461 return rgeom;
462 }
463
464 case SFCGAL_TYPE_TRIANGULATEDSURFACE: {
465 ngeoms = sfcgal_triangulated_surface_num_triangles(geom);
466 LWGEOM **geoms = NULL;
467 if (ngeoms)
468 {
469 geoms = (LWGEOM **)lwalloc(sizeof(LWGEOM *) * ngeoms);
470 for (i = 0; i < ngeoms; i++)
471 {
472 const sfcgal_geometry_t *g = sfcgal_triangulated_surface_triangle_n(geom, i);
473 geoms[i] = SFCGAL2LWGEOM(g, 0, srid);
474 }
475 }
476 return (LWGEOM *)lwcollection_construct(TINTYPE, srid, NULL, ngeoms, geoms);
477 }
478
479 default:
480 lwerror("SFCGAL2LWGEOM: Unknown Type");
481 return NULL;
482 }
483}
484
485sfcgal_geometry_t *
487{
488 uint32_t i;
489 sfcgal_geometry_t *ret_geom = NULL;
490
491 assert(geom);
492
493 switch (geom->type)
494 {
495 case POINTTYPE: {
496 const LWPOINT *lwp = (const LWPOINT *)geom;
497 if (lwgeom_is_empty(geom))
498 return sfcgal_point_create();
499
500 return ptarray_to_SFCGAL(lwp->point, POINTTYPE);
501 }
502 break;
503
504 case LINETYPE: {
505 const LWLINE *line = (const LWLINE *)geom;
506 if (lwgeom_is_empty(geom))
507 return sfcgal_linestring_create();
508
509 return ptarray_to_SFCGAL(line->points, LINETYPE);
510 }
511 break;
512
513 case TRIANGLETYPE: {
514 const LWTRIANGLE *triangle = (const LWTRIANGLE *)geom;
515 if (lwgeom_is_empty(geom))
516 return sfcgal_triangle_create();
517 return ptarray_to_SFCGAL(triangle->points, TRIANGLETYPE);
518 }
519 break;
520
521 case POLYGONTYPE: {
522 const LWPOLY *poly = (const LWPOLY *)geom;
523 uint32_t nrings = poly->nrings - 1;
524
525 if (lwgeom_is_empty(geom))
526 return sfcgal_polygon_create();
527
528 sfcgal_geometry_t *exterior_ring = ptarray_to_SFCGAL(poly->rings[0], LINETYPE);
529 ret_geom = sfcgal_polygon_create_from_exterior_ring(exterior_ring);
530
531 for (i = 0; i < nrings; i++)
532 {
533 sfcgal_geometry_t *ring = ptarray_to_SFCGAL(poly->rings[i + 1], LINETYPE);
534 sfcgal_polygon_add_interior_ring(ret_geom, ring);
535 }
536 return ret_geom;
537 }
538 break;
539
540 case MULTIPOINTTYPE:
541 case MULTILINETYPE:
542 case MULTIPOLYGONTYPE:
543 case COLLECTIONTYPE: {
544 if (geom->type == MULTIPOINTTYPE)
545 ret_geom = sfcgal_multi_point_create();
546 else if (geom->type == MULTILINETYPE)
547 ret_geom = sfcgal_multi_linestring_create();
548 else if (geom->type == MULTIPOLYGONTYPE)
549 ret_geom = sfcgal_multi_polygon_create();
550 else
551 ret_geom = sfcgal_geometry_collection_create();
552
553 const LWCOLLECTION *lwc = (const LWCOLLECTION *)geom;
554 for (i = 0; i < lwc->ngeoms; i++)
555 {
556 sfcgal_geometry_t *g = LWGEOM2SFCGAL(lwc->geoms[i]);
557 sfcgal_geometry_collection_add_geometry(ret_geom, g);
558 }
559
560 return ret_geom;
561 }
562 break;
563
565 const LWPSURFACE *lwp = (const LWPSURFACE *)geom;
566 ret_geom = sfcgal_polyhedral_surface_create();
567
568 for (i = 0; i < lwp->ngeoms; i++)
569 {
570 sfcgal_geometry_t *g = LWGEOM2SFCGAL((const LWGEOM *)lwp->geoms[i]);
571 sfcgal_polyhedral_surface_add_polygon(ret_geom, g);
572 }
573 /* We treat polyhedral surface as the only exterior shell,
574 since we can't distinguish exterior from interior shells ... */
575 if (FLAGS_GET_SOLID(lwp->flags))
576 {
577 return sfcgal_solid_create_from_exterior_shell(ret_geom);
578 }
579
580 return ret_geom;
581 }
582 break;
583
584 case TINTYPE: {
585 const LWTIN *lwp = (const LWTIN *)geom;
586 ret_geom = sfcgal_triangulated_surface_create();
587
588 for (i = 0; i < lwp->ngeoms; i++)
589 {
590 sfcgal_geometry_t *g = LWGEOM2SFCGAL((const LWGEOM *)lwp->geoms[i]);
591 sfcgal_triangulated_surface_add_triangle(ret_geom, g);
592 }
593
594 return ret_geom;
595 }
596 break;
597
598 default:
599 lwerror("LWGEOM2SFCGAL: Unsupported geometry type %s !", lwtype_name(geom->type));
600 return NULL;
601 }
602}
603
604/*
605 * No Operation SFCGAL function, used (only) for cunit tests
606 * Take a PostGIS geometry, send it to SFCGAL and return it unchanged (in theory)
607 */
608LWGEOM *
610{
611 sfcgal_geometry_t *converted;
612
613 assert(geom_in);
614
615 converted = LWGEOM2SFCGAL(geom_in);
616 assert(converted);
617
618 LWGEOM *geom_out = SFCGAL2LWGEOM(converted, 0, SRID_UNKNOWN);
619 sfcgal_geometry_delete(converted);
620
621 /* copy SRID (SFCGAL does not store the SRID) */
622 geom_out->srid = geom_in->srid;
623 return geom_out;
624}
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition lwutil.c:216
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
#define COLLECTIONTYPE
Definition liblwgeom.h:108
#define COMPOUNDTYPE
Definition liblwgeom.h:110
void * lwrealloc(void *mem, size_t size)
Definition lwutil.c:242
#define CURVEPOLYTYPE
Definition liblwgeom.h:111
#define MULTILINETYPE
Definition liblwgeom.h:106
#define MULTISURFACETYPE
Definition liblwgeom.h:113
#define LINETYPE
Definition liblwgeom.h:103
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
Definition lwpoint.c:129
#define MULTIPOINTTYPE
Definition liblwgeom.h:105
LWTRIANGLE * lwtriangle_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwtriangle.c:58
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:165
void * lwalloc(size_t size)
Definition lwutil.c:227
#define TINTYPE
Definition liblwgeom.h:116
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition lwline.c:42
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:107
#define POLYGONTYPE
Definition liblwgeom.h:104
#define POLYHEDRALSURFACETYPE
Definition liblwgeom.h:114
#define CIRCSTRINGTYPE
Definition liblwgeom.h:109
LWPOINT * lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwpoint.c:151
#define FLAGS_GET_M(flags)
Definition liblwgeom.h:166
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
Definition lwgeom_api.c:125
#define FLAGS_GET_SOLID(flags)
Definition liblwgeom.h:170
LWPOLY * lwpoly_construct(int32_t srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
Definition lwpoly.c:43
#define MULTICURVETYPE
Definition liblwgeom.h:112
#define TRIANGLETYPE
Definition liblwgeom.h:115
LWPOLY * lwpoly_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwpoly.c:161
#define SRID_UNKNOWN
Unknown SRID value.
Definition liblwgeom.h:215
LWLINE * lwline_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwline.c:55
#define FLAGS_SET_SOLID(flags, value)
Definition liblwgeom.h:177
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
Definition lwgeom_api.c:369
LWTRIANGLE * lwtriangle_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition lwtriangle.c:40
POINTARRAY * ptarray_construct(char hasz, char hasm, uint32_t npoints)
Construct an empty pointarray, allocating storage and setting the npoints, but not filling in any inf...
Definition ptarray.c:51
void lwnotice(const char *fmt,...) __attribute__((format(printf
Write a notice out to the notice handler.
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
static sfcgal_geometry_t * create_sfcgal_point_by_dimensions(double x, double y, double z, double m, int is_3d, int is_measured)
Create a SFCGAL point based on dimensional flags (XY, XYZ, XYM, XYZM).
const char * lwgeom_sfcgal_full_version()
static POINTARRAY * ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int force3D)
static int SFCGAL_type_to_lwgeom_type(sfcgal_geometry_type_t type)
#define MAX_LENGTH_SFCGAL_FULL_VERSION
sfcgal_geometry_t * LWGEOM2SFCGAL(const LWGEOM *geom)
const char * lwgeom_sfcgal_version()
LWGEOM * lwgeom_sfcgal_noop(const LWGEOM *geom_in)
static sfcgal_geometry_t * ptarray_to_SFCGAL(const POINTARRAY *pa, int type)
Convert a PostGIS pointarray to SFCGAL structure.
LWGEOM * SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition lwinline.h:199
uint32_t ngeoms
Definition liblwgeom.h:580
LWGEOM ** geoms
Definition liblwgeom.h:575
uint8_t type
Definition liblwgeom.h:462
int32_t srid
Definition liblwgeom.h:460
lwflags_t flags
Definition liblwgeom.h:461
POINTARRAY * points
Definition liblwgeom.h:483
POINTARRAY * point
Definition liblwgeom.h:471
POINTARRAY ** rings
Definition liblwgeom.h:519
uint32_t nrings
Definition liblwgeom.h:524
lwflags_t flags
Definition liblwgeom.h:647
LWPOLY ** geoms
Definition liblwgeom.h:645
uint32_t ngeoms
Definition liblwgeom.h:650
uint32_t ngeoms
Definition liblwgeom.h:664
LWTRIANGLE ** geoms
Definition liblwgeom.h:659
POINTARRAY * points
Definition liblwgeom.h:495
double m
Definition liblwgeom.h:414
double x
Definition liblwgeom.h:414
double z
Definition liblwgeom.h:414
double y
Definition liblwgeom.h:414
lwflags_t flags
Definition liblwgeom.h:431
uint32_t npoints
Definition liblwgeom.h:427