PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ LWGEOM2GEOS()

GEOSGeometry* LWGEOM2GEOS ( const LWGEOM lwgeom,
uint8_t  autofix 
)

Definition at line 390 of file liblwgeom/lwgeom_geos.c.

391 {
392  GEOSCoordSeq sq;
393  GEOSGeom g, shell;
394  GEOSGeom* geoms = NULL;
395  uint32_t ngeoms, i, j;
396  int geostype;
397 #if LWDEBUG_LEVEL >= 4
398  char* wkt;
399 #endif
400 
401  if (autofix)
402  {
403  /* cross fingers and try without autofix, maybe it'll work? */
404  g = LWGEOM2GEOS(lwgeom, LW_FALSE);
405  if (g) return g;
406  }
407 
408  LWDEBUGF(4, "LWGEOM2GEOS got a %s", lwtype_name(lwgeom->type));
409 
410  if (lwgeom_has_arc(lwgeom))
411  {
412  LWGEOM* lwgeom_stroked = lwgeom_stroke(lwgeom, 32);
413  GEOSGeometry* g = LWGEOM2GEOS(lwgeom_stroked, autofix);
414  lwgeom_free(lwgeom_stroked);
415  return g;
416  }
417 
418  LWPOINT* lwp = NULL;
419  LWPOLY* lwpoly = NULL;
420  LWLINE* lwl = NULL;
421  LWCOLLECTION* lwc = NULL;
422 
423  switch (lwgeom->type)
424  {
425  case POINTTYPE:
426  lwp = (LWPOINT*)lwgeom;
427 
428  if (lwgeom_is_empty(lwgeom))
429  g = GEOSGeom_createEmptyPolygon();
430  else
431  {
432 #if POSTGIS_GEOS_VERSION < 38
433  sq = ptarray_to_GEOSCoordSeq(lwp->point, 0);
434  g = GEOSGeom_createPoint(sq);
435 #else
436  if (lwgeom_has_z(lwgeom))
437  {
438  sq = ptarray_to_GEOSCoordSeq(lwp->point, 0);
439  g = GEOSGeom_createPoint(sq);
440  }
441  else
442  {
443  const POINT2D* p = getPoint2d_cp(lwp->point, 0);
444  g = GEOSGeom_createPointFromXY(p->x, p->y);
445  }
446 #endif
447  }
448  if (!g) return NULL;
449  break;
450 
451  case LINETYPE:
452  lwl = (LWLINE*)lwgeom;
453  /* TODO: if (autofix) */
454  if (lwl->points->npoints == 1)
455  {
456  /* Duplicate point, to make geos-friendly */
457  lwl->points = ptarray_addPoint(lwl->points,
458  getPoint_internal(lwl->points, 0),
459  FLAGS_NDIMS(lwl->points->flags),
460  lwl->points->npoints);
461  }
462  sq = ptarray_to_GEOSCoordSeq(lwl->points, 0);
463  g = GEOSGeom_createLineString(sq);
464  if (!g) return NULL;
465  break;
466 
467  case POLYGONTYPE:
468  lwpoly = (LWPOLY*)lwgeom;
469  if (lwgeom_is_empty(lwgeom))
470  g = GEOSGeom_createEmptyPolygon();
471  else
472  {
473  shell = ptarray_to_GEOSLinearRing(lwpoly->rings[0], autofix);
474  if (!shell) return NULL;
475  ngeoms = lwpoly->nrings - 1;
476  if (ngeoms > 0) geoms = lwalloc(sizeof(GEOSGeom) * ngeoms);
477 
478  for (i = 1; i < lwpoly->nrings; i++)
479  {
480  geoms[i - 1] = ptarray_to_GEOSLinearRing(lwpoly->rings[i], autofix);
481  if (!geoms[i - 1])
482  {
483  uint32_t k;
484  for (k = 0; k < i - 1; k++)
485  GEOSGeom_destroy(geoms[k]);
486  lwfree(geoms);
487  GEOSGeom_destroy(shell);
488  return NULL;
489  }
490  }
491  g = GEOSGeom_createPolygon(shell, geoms, ngeoms);
492  if (geoms) lwfree(geoms);
493  }
494  if (!g) return NULL;
495  break;
496  case MULTIPOINTTYPE:
497  case MULTILINETYPE:
498  case MULTIPOLYGONTYPE:
499  case COLLECTIONTYPE:
500  if (lwgeom->type == MULTIPOINTTYPE)
501  geostype = GEOS_MULTIPOINT;
502  else if (lwgeom->type == MULTILINETYPE)
503  geostype = GEOS_MULTILINESTRING;
504  else if (lwgeom->type == MULTIPOLYGONTYPE)
505  geostype = GEOS_MULTIPOLYGON;
506  else
507  geostype = GEOS_GEOMETRYCOLLECTION;
508 
509  lwc = (LWCOLLECTION*)lwgeom;
510 
511  ngeoms = lwc->ngeoms;
512  if (ngeoms > 0) geoms = lwalloc(sizeof(GEOSGeom) * ngeoms);
513 
514  j = 0;
515  for (i = 0; i < ngeoms; ++i)
516  {
517  GEOSGeometry* g;
518 
519  if (lwgeom_is_empty(lwc->geoms[i])) continue;
520 
521  g = LWGEOM2GEOS(lwc->geoms[i], 0);
522  if (!g)
523  {
524  uint32_t k;
525  for (k = 0; k < j; k++)
526  GEOSGeom_destroy(geoms[k]);
527  lwfree(geoms);
528  return NULL;
529  }
530  geoms[j++] = g;
531  }
532  g = GEOSGeom_createCollection(geostype, geoms, j);
533  if (ngeoms > 0) lwfree(geoms);
534  if (!g) return NULL;
535  break;
536 
537  default:
538  lwerror("Unknown geometry type: %d - %s", lwgeom->type, lwtype_name(lwgeom->type));
539  return NULL;
540  }
541 
542  GEOSSetSRID(g, lwgeom->srid);
543 
544 #if LWDEBUG_LEVEL >= 4
545  wkt = GEOSGeomToWKT(g);
546  LWDEBUGF(4, "LWGEOM2GEOS: GEOSGeom: %s", wkt);
547  free(wkt);
548 #endif
549 
550  return g;
551 }
static GEOSGeometry * ptarray_to_GEOSLinearRing(const POINTARRAY *pa, uint8_t autofix)
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
GEOSCoordSeq ptarray_to_GEOSCoordSeq(const POINTARRAY *, uint8_t fix_ring)
#define LW_FALSE
Definition: liblwgeom.h:77
#define COLLECTIONTYPE
Definition: liblwgeom.h:91
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1144
#define MULTILINETYPE
Definition: liblwgeom.h:89
#define LINETYPE
Definition: liblwgeom.h:86
uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition: ptarray.c:1750
POINTARRAY * ptarray_addPoint(const POINTARRAY *pa, uint8_t *p, size_t pdims, uint32_t where)
Add a point in a pointarray.
Definition: ptarray.c:503
LWGEOM * lwgeom_stroke(const LWGEOM *geom, uint32_t perQuad)
Definition: lwstroke.c:768
#define MULTIPOINTTYPE
Definition: liblwgeom.h:88
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:930
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:85
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:90
void lwfree(void *mem)
Definition: lwutil.c:244
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:152
#define POLYGONTYPE
Definition: liblwgeom.h:87
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:218
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:1393
void * lwalloc(size_t size)
Definition: lwutil.c:229
int lwgeom_has_arc(const LWGEOM *geom)
Definition: lwstroke.c:55
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwgeom_api.c:374
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
void free(void *)
uint32_t ngeoms
Definition: liblwgeom.h:510
LWGEOM ** geoms
Definition: liblwgeom.h:512
uint8_t type
Definition: liblwgeom.h:399
int32_t srid
Definition: liblwgeom.h:402
POINTARRAY * points
Definition: liblwgeom.h:425
POINTARRAY * point
Definition: liblwgeom.h:414
POINTARRAY ** rings
Definition: liblwgeom.h:460
uint32_t nrings
Definition: liblwgeom.h:458
double y
Definition: liblwgeom.h:331
double x
Definition: liblwgeom.h:331
uint32_t npoints
Definition: liblwgeom.h:374
uint8_t flags
Definition: liblwgeom.h:372
unsigned int uint32_t
Definition: uthash.h:78

References COLLECTIONTYPE, POINTARRAY::flags, FLAGS_NDIMS, free(), LWCOLLECTION::geoms, getPoint2d_cp(), getPoint_internal(), LINETYPE, LW_FALSE, lwalloc(), LWDEBUGF, lwerror(), lwfree(), lwgeom_free(), lwgeom_has_arc(), lwgeom_has_z(), lwgeom_is_empty(), lwgeom_stroke(), lwtype_name(), MULTILINETYPE, MULTIPOINTTYPE, MULTIPOLYGONTYPE, LWCOLLECTION::ngeoms, POINTARRAY::npoints, LWPOLY::nrings, LWPOINT::point, LWLINE::points, POINTTYPE, POLYGONTYPE, ptarray_addPoint(), ptarray_to_GEOSCoordSeq(), ptarray_to_GEOSLinearRing(), LWPOLY::rings, LWGEOM::srid, LWGEOM::type, POINT2D::x, and POINT2D::y.

Referenced by _lwt_CheckEdgeCrossing(), _lwt_FindFaceContainingRing(), _lwt_GetEqualEdge(), boundary(), isvalid(), lwgeom_buildarea(), lwgeom_centroid(), lwgeom_clip_by_rect(), lwgeom_delaunay_triangulation(), lwgeom_difference(), lwgeom_extract_unique_endpoints(), lwgeom_geos_noop(), lwgeom_intersection(), lwgeom_is_simple(), lwgeom_linemerge(), lwgeom_make_valid(), lwgeom_node(), lwgeom_normalize(), lwgeom_pointonsurface(), lwgeom_sharedpaths(), lwgeom_snap(), lwgeom_symdifference(), lwgeom_unaryunion(), lwgeom_union(), LWGEOMARRAY2GEOS(), lwline_offsetcurve(), lwline_split_by_line(), lwpoly_split_by_line(), lwpoly_to_points(), lwt_AddPolygon(), mvt_grid_and_validate_geos(), mvt_safe_clip_polygon_by_box(), POSTGIS2GEOS(), PrepGeomCacheBuilder(), rt_raster_compute_skewed_raster(), rt_raster_gdal_polygonize(), rt_raster_geos_spatial_relationship(), rt_raster_intersects(), and rt_raster_surface().

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