PostGIS  3.7.0dev-r@@SVN_REVISION@@
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 
38 static int SFCGAL_type_to_lwgeom_type(sfcgal_geometry_type_t type);
39 static POINTARRAY *ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int force3D);
40 static sfcgal_geometry_t *ptarray_to_SFCGAL(const POINTARRAY *pa, int type);
41 
42 /* Return SFCGAL version string */
43 const 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 */
52 const 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  */
72 static int
73 SFCGAL_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:
121  return POLYHEDRALSURFACETYPE;
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  */
141 static POINTARRAY *
142 ptarray_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 
239 static sfcgal_geometry_t *
240 create_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 
264 static sfcgal_geometry_t *
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  */
322 LWGEOM *
323 SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
324 {
325  uint32_t ngeoms, nshells, nsolids;
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 
485 sfcgal_geometry_t *
486 LWGEOM2SFCGAL(const LWGEOM *geom)
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 
564  case POLYHEDRALSURFACETYPE: {
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  */
608 LWGEOM *
609 lwgeom_sfcgal_noop(const LWGEOM *geom_in)
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 }
LWPOINT * lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
Definition: lwpoint.c:151
#define COLLECTIONTYPE
Definition: liblwgeom.h:108
#define COMPOUNDTYPE
Definition: liblwgeom.h:110
#define CURVEPOLYTYPE
Definition: liblwgeom.h:111
#define MULTILINETYPE
Definition: liblwgeom.h:106
#define MULTISURFACETYPE
Definition: liblwgeom.h:113
#define LINETYPE
Definition: liblwgeom.h:103
#define MULTIPOINTTYPE
Definition: liblwgeom.h:105
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
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:102
#define FLAGS_GET_Z(flags)
Definition: liblwgeom.h:165
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
LWTRIANGLE * lwtriangle_construct_empty(int32_t srid, char hasz, char hasm)
Definition: lwtriangle.c:58
#define TINTYPE
Definition: liblwgeom.h:116
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:107
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:242
#define POLYGONTYPE
Definition: liblwgeom.h:104
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
Definition: lwpoint.c:129
#define POLYHEDRALSURFACETYPE
Definition: liblwgeom.h:114
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:109
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:216
#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
#define MULTICURVETYPE
Definition: liblwgeom.h:112
#define TRIANGLETYPE
Definition: liblwgeom.h:115
void * lwalloc(size_t size)
Definition: lwutil.c:227
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:42
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:215
LWPOLY * lwpoly_construct_empty(int32_t srid, char hasz, char hasm)
Definition: lwpoly.c:161
LWPOLY * lwpoly_construct(int32_t srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
Definition: lwpoly.c:43
#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
LWLINE * lwline_construct_empty(int32_t srid, char hasz, char hasm)
Definition: lwline.c:55
LWTRIANGLE * lwtriangle_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition: lwtriangle.c:40
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.
sfcgal_geometry_t * LWGEOM2SFCGAL(const LWGEOM *geom)
static POINTARRAY * ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int force3D)
static int SFCGAL_type_to_lwgeom_type(sfcgal_geometry_type_t type)
Definition: lwgeom_sfcgal.c:73
LWGEOM * lwgeom_sfcgal_noop(const LWGEOM *geom_in)
LWGEOM * SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
const char * lwgeom_sfcgal_version()
Definition: lwgeom_sfcgal.c:44
#define MAX_LENGTH_SFCGAL_FULL_VERSION
Definition: lwgeom_sfcgal.c:50
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()
Definition: lwgeom_sfcgal.c:53
static sfcgal_geometry_t * ptarray_to_SFCGAL(const POINTARRAY *pa, int type)
Convert a PostGIS pointarray to SFCGAL structure.
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
type
Definition: ovdump.py:42
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