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