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