PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ SFCGAL2LWGEOM()

LWGEOM* SFCGAL2LWGEOM ( const sfcgal_geometry_t *  geom,
int  force3D,
int32_t  srid 
)

Definition at line 278 of file liblwgeom/lwgeom_sfcgal.c.

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))
349  ++nsolids;
350  }
351  geoms = (LWGEOM **)lwrealloc(geoms, sizeof(LWGEOM *) * ngeoms);
352  }
354  SFCGAL_type_to_lwgeom_type(sfcgal_geometry_type_id(geom)), srid, NULL, ngeoms, geoms);
355  if (ngeoms)
356  {
357  if (ngeoms == nsolids)
358  FLAGS_SET_SOLID(rgeom->flags, 1);
359  else if (nsolids)
360  lwnotice(
361  "SFCGAL2LWGEOM: SOLID in heterogeneous collection will be treated as a POLYHEDRALSURFACETYPE");
362  }
363  return rgeom;
364  }
365 
366 #if 0
367  case SFCGAL_TYPE_CIRCULARSTRING:
368  case SFCGAL_TYPE_COMPOUNDCURVE:
369  case SFCGAL_TYPE_CURVEPOLYGON:
370  case SFCGAL_TYPE_MULTICURVE:
371  case SFCGAL_TYPE_MULTISURFACE:
372  case SFCGAL_TYPE_CURVE:
373  case SFCGAL_TYPE_SURFACE:
374 
375  /* TODO curve types handling */
376 #endif
377 
378  case SFCGAL_TYPE_POLYHEDRALSURFACE:
379  {
380  ngeoms = sfcgal_polyhedral_surface_num_polygons(geom);
381 
382  LWGEOM **geoms = NULL;
383  if (ngeoms)
384  {
385  geoms = (LWGEOM **)lwalloc(sizeof(LWGEOM *) * ngeoms);
386  for (i = 0; i < ngeoms; i++)
387  {
388  const sfcgal_geometry_t *g = sfcgal_polyhedral_surface_polygon_n(geom, i);
389  geoms[i] = SFCGAL2LWGEOM(g, 0, srid);
390  }
391  }
392  return (LWGEOM *)lwcollection_construct(POLYHEDRALSURFACETYPE, srid, NULL, ngeoms, geoms);
393  }
394 
395  /* Solid is map as a closed PolyhedralSurface (for now) */
396  case SFCGAL_TYPE_SOLID:
397  {
398  nshells = sfcgal_solid_num_shells(geom);
399 
400  for (ngeoms = 0, i = 0; i < nshells; i++)
401  ngeoms += sfcgal_polyhedral_surface_num_polygons(sfcgal_solid_shell_n(geom, i));
402 
403  LWGEOM **geoms = 0;
404  if (ngeoms)
405  {
406  geoms = (LWGEOM **)lwalloc(sizeof(LWGEOM *) * ngeoms);
407  for (i = 0, k = 0; i < nshells; i++)
408  {
409  const sfcgal_geometry_t *shell = sfcgal_solid_shell_n(geom, i);
410  ngeoms = sfcgal_polyhedral_surface_num_polygons(shell);
411 
412  for (j = 0; j < ngeoms; j++)
413  {
414  const sfcgal_geometry_t *g = sfcgal_polyhedral_surface_polygon_n(shell, j);
415  geoms[k] = SFCGAL2LWGEOM(g, 1, srid);
416  k++;
417  }
418  }
419  }
420  LWGEOM *rgeom = (LWGEOM *)lwcollection_construct(POLYHEDRALSURFACETYPE, srid, NULL, ngeoms, geoms);
421  if (ngeoms)
422  FLAGS_SET_SOLID(rgeom->flags, 1);
423  return rgeom;
424  }
425 
426  case SFCGAL_TYPE_TRIANGULATEDSURFACE:
427  {
428  ngeoms = sfcgal_triangulated_surface_num_triangles(geom);
429  LWGEOM **geoms = NULL;
430  if (ngeoms)
431  {
432  geoms = (LWGEOM **)lwalloc(sizeof(LWGEOM *) * ngeoms);
433  for (i = 0; i < ngeoms; i++)
434  {
435  const sfcgal_geometry_t *g = sfcgal_triangulated_surface_triangle_n(geom, i);
436  geoms[i] = SFCGAL2LWGEOM(g, 0, srid);
437  }
438  }
439  return (LWGEOM *)lwcollection_construct(TINTYPE, srid, NULL, ngeoms, geoms);
440  }
441 
442  default:
443  lwerror("SFCGAL2LWGEOM: Unknown Type");
444  return NULL;
445  }
446 }
static POINTARRAY * ptarray_from_SFCGAL(const sfcgal_geometry_t *geom, int force3D)
static int SFCGAL_type_to_lwgeom_type(sfcgal_geometry_type_t type)
LWGEOM * SFCGAL2LWGEOM(const sfcgal_geometry_t *geom, int force3D, int32_t srid)
LWPOINT * lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
Definition: lwpoint.c:151
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:130
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:235
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
Definition: lwpoint.c:129
#define POLYHEDRALSURFACETYPE
Definition: liblwgeom.h:128
#define FLAGS_GET_SOLID(flags)
Definition: liblwgeom.h:184
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
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:191
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
lwflags_t flags
Definition: liblwgeom.h:447

References LWGEOM::flags, FLAGS_GET_SOLID, FLAGS_SET_SOLID, lwalloc(), lwcollection_construct(), lwerror(), lwline_construct(), lwline_construct_empty(), lwnotice(), lwpoint_construct(), lwpoint_construct_empty(), lwpoly_construct(), lwpoly_construct_empty(), lwrealloc(), lwtriangle_construct(), lwtriangle_construct_empty(), POLYHEDRALSURFACETYPE, ptarray_from_SFCGAL(), SFCGAL_type_to_lwgeom_type(), and TINTYPE.

Referenced by lwgeom_sfcgal_noop(), and SFCGALGeometry2POSTGIS().

Here is the call graph for this function:
Here is the caller graph for this function: