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