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