PostGIS  3.3.9dev-r@@SVN_REVISION@@

◆ LWGEOM2GEOS()

GEOSGeometry* LWGEOM2GEOS ( const LWGEOM lwgeom,
uint8_t  autofix 
)

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

411 {
412  GEOSCoordSeq sq;
413  GEOSGeom g, shell;
414  GEOSGeom* geoms = NULL;
415  uint32_t ngeoms, i, j;
416  int geostype;
417 #if LWDEBUG_LEVEL >= 4
418  char* wkt;
419 #endif
420 
421  if (autofix)
422  {
423  /* cross fingers and try without autofix, maybe it'll work? */
424  g = LWGEOM2GEOS(lwgeom, LW_FALSE);
425  if (g) return g;
426  }
427 
428  LWDEBUGF(4, "LWGEOM2GEOS got a %s", lwtype_name(lwgeom->type));
429 
430  if (lwgeom_type_arc(lwgeom))
431  {
432  LWGEOM* lwgeom_stroked = lwgeom_stroke(lwgeom, 32);
433  GEOSGeometry* g = LWGEOM2GEOS(lwgeom_stroked, autofix);
434  lwgeom_free(lwgeom_stroked);
435  return g;
436  }
437 
438  LWPOINT* lwp = NULL;
439  LWPOLY* lwpoly = NULL;
440  LWLINE* lwl = NULL;
441  LWCOLLECTION* lwc = NULL;
442 
443  switch (lwgeom->type)
444  {
445  case POINTTYPE:
446  lwp = (LWPOINT*)lwgeom;
447 
448  if (lwgeom_is_empty(lwgeom))
449  g = GEOSGeom_createEmptyPoint();
450  else
451  {
452 #if POSTGIS_GEOS_VERSION < 30800
453  sq = ptarray_to_GEOSCoordSeq(lwp->point, 0);
454  g = GEOSGeom_createPoint(sq);
455 #else
456  if (lwgeom_has_z(lwgeom))
457  {
458  sq = ptarray_to_GEOSCoordSeq(lwp->point, 0);
459  g = GEOSGeom_createPoint(sq);
460  }
461  else
462  {
463  const POINT2D* p = getPoint2d_cp(lwp->point, 0);
464  g = GEOSGeom_createPointFromXY(p->x, p->y);
465  }
466 #endif
467  }
468  if (!g) return NULL;
469  break;
470 
471  case LINETYPE:
472  lwl = (LWLINE*)lwgeom;
473  /* TODO: if (autofix) */
474  if (lwl->points->npoints == 1)
475  {
476  /* Duplicate point, to make geos-friendly */
477  lwl->points = ptarray_addPoint(lwl->points,
478  getPoint_internal(lwl->points, 0),
479  FLAGS_NDIMS(lwl->points->flags),
480  lwl->points->npoints);
481  }
482  sq = ptarray_to_GEOSCoordSeq(lwl->points, 0);
483  g = GEOSGeom_createLineString(sq);
484  if (!g) return NULL;
485  break;
486 
487  case POLYGONTYPE:
488  lwpoly = (LWPOLY*)lwgeom;
489  if (lwgeom_is_empty(lwgeom))
490  g = GEOSGeom_createEmptyPolygon();
491  else
492  {
493  shell = ptarray_to_GEOSLinearRing(lwpoly->rings[0], autofix);
494  if (!shell) return NULL;
495  ngeoms = lwpoly->nrings - 1;
496  if (ngeoms > 0) geoms = lwalloc(sizeof(GEOSGeom) * ngeoms);
497 
498  for (i = 1; i < lwpoly->nrings; i++)
499  {
500  geoms[i - 1] = ptarray_to_GEOSLinearRing(lwpoly->rings[i], autofix);
501  if (!geoms[i - 1])
502  {
503  uint32_t k;
504  for (k = 0; k < i - 1; k++)
505  GEOSGeom_destroy(geoms[k]);
506  lwfree(geoms);
507  GEOSGeom_destroy(shell);
508  return NULL;
509  }
510  }
511  g = GEOSGeom_createPolygon(shell, geoms, ngeoms);
512  if (geoms) lwfree(geoms);
513  }
514  if (!g) return NULL;
515  break;
516 
517  case TRIANGLETYPE:
518  if (lwgeom_is_empty(lwgeom))
519  g = GEOSGeom_createEmptyPolygon();
520  else
521  {
522  LWTRIANGLE *lwt = (LWTRIANGLE *)lwgeom;
523  shell = ptarray_to_GEOSLinearRing(lwt->points, autofix);
524  if (!shell)
525  return NULL;
526  g = GEOSGeom_createPolygon(shell, NULL, 0);
527  }
528  if (!g)
529  return NULL;
530  break;
531  case MULTIPOINTTYPE:
532  case MULTILINETYPE:
533  case MULTIPOLYGONTYPE:
534  case TINTYPE:
535  case COLLECTIONTYPE:
536  if (lwgeom->type == MULTIPOINTTYPE)
537  geostype = GEOS_MULTIPOINT;
538  else if (lwgeom->type == MULTILINETYPE)
539  geostype = GEOS_MULTILINESTRING;
540  else if (lwgeom->type == MULTIPOLYGONTYPE)
541  geostype = GEOS_MULTIPOLYGON;
542  else
543  geostype = GEOS_GEOMETRYCOLLECTION;
544 
545  lwc = (LWCOLLECTION*)lwgeom;
546 
547  ngeoms = lwc->ngeoms;
548  if (ngeoms > 0) geoms = lwalloc(sizeof(GEOSGeom) * ngeoms);
549 
550  j = 0;
551  for (i = 0; i < ngeoms; ++i)
552  {
553  GEOSGeometry* g;
554 
555  /* if (lwgeom_is_empty(lwc->geoms[i])) continue; */
556 
557  g = LWGEOM2GEOS(lwc->geoms[i], 0);
558  if (!g)
559  {
560  uint32_t k;
561  for (k = 0; k < j; k++)
562  GEOSGeom_destroy(geoms[k]);
563  lwfree(geoms);
564  return NULL;
565  }
566  geoms[j++] = g;
567  }
568  g = GEOSGeom_createCollection(geostype, geoms, j);
569  if (ngeoms > 0) lwfree(geoms);
570  if (!g) return NULL;
571  break;
572 
573  default:
574  lwerror("Unknown geometry type: %d - %s", lwgeom->type, lwtype_name(lwgeom->type));
575  return NULL;
576  }
577 
578  GEOSSetSRID(g, lwgeom->srid);
579 
580 #if LWDEBUG_LEVEL >= 4
581  wkt = GEOSGeomToWKT(g);
582  LWDEBUGF(4, "LWGEOM2GEOS: GEOSGeom: %s", wkt);
583  free(wkt);
584 #endif
585 
586  return g;
587 }
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:109
#define COLLECTIONTYPE
Definition: liblwgeom.h:123
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1155
#define MULTILINETYPE
Definition: liblwgeom.h:121
#define LINETYPE
Definition: liblwgeom.h:118
POINTARRAY * ptarray_addPoint(const POINTARRAY *pa, uint8_t *p, size_t pdims, uint32_t where)
Add a point in a pointarray.
Definition: ptarray.c:509
LWGEOM * lwgeom_stroke(const LWGEOM *geom, uint32_t perQuad)
Convert type with arcs into equivalent linearized type.
Definition: lwstroke.c:871
#define MULTIPOINTTYPE
Definition: liblwgeom.h:120
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:934
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:117
int lwgeom_type_arc(const LWGEOM *geom)
Geometry type is one of the potentially "arc containing" types (circstring, multicurve,...
Definition: lwstroke.c:89
#define TINTYPE
Definition: liblwgeom.h:131
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:122
void lwfree(void *mem)
Definition: lwutil.c:242
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:194
#define POLYGONTYPE
Definition: liblwgeom.h:119
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:216
#define TRIANGLETYPE
Definition: liblwgeom.h:130
void * lwalloc(size_t size)
Definition: lwutil.c:227
#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 *)
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwinline.h:101
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition: lwinline.h:77
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
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
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
POINTARRAY * points
Definition: liblwgeom.h:510
double y
Definition: liblwgeom.h:405
double x
Definition: liblwgeom.h:405
lwflags_t flags
Definition: liblwgeom.h:446
uint32_t npoints
Definition: liblwgeom.h:442

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

Referenced by _lwt_CheckEdgeCrossing(), _lwt_FindFaceContainingRing(), _lwt_GetEqualEdge(), isvalid(), lwgeom_buildarea(), lwgeom_centroid(), lwgeom_clip_by_rect(), lwgeom_delaunay_triangulation(), lwgeom_difference_prec(), lwgeom_extract_unique_endpoints(), lwgeom_geos_noop(), lwgeom_intersection_prec(), lwgeom_is_simple(), lwgeom_linemerge_directed(), lwgeom_make_valid_params(), lwgeom_node(), lwgeom_normalize(), lwgeom_pointonsurface(), lwgeom_reduceprecision(), lwgeom_sharedpaths(), lwgeom_snap(), lwgeom_symdifference_prec(), lwgeom_unaryunion_prec(), lwgeom_union_prec(), LWGEOMARRAY2GEOS(), lwline_offsetcurve(), lwline_split_by_line(), lwpoly_split_by_line(), lwpoly_to_points(), lwt_AddPolygon(), POSTGIS2GEOS(), PrepGeomCacheBuilder(), rt_raster_compute_skewed_raster(), rt_raster_geos_spatial_relationship(), rt_raster_intersects(), rt_raster_surface(), and topologypreservesimplify().

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