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