PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ LWGEOM2GEOS()

GEOSGeometry* LWGEOM2GEOS ( const LWGEOM lwgeom,
int  autofix 
)

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

References COLLECTIONTYPE, POINTARRAY::flags, FLAGS_NDIMS, free(), LWCOLLECTION::geoms, getPoint_internal(), LINETYPE, LWDEBUGF, lwerror(), LWGEOM2GEOS(), lwgeom_free(), lwgeom_has_arc(), lwgeom_is_empty(), lwgeom_stroke(), lwtype_name(), malloc(), 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, and LWGEOM::type.

Referenced by _lwt_AddFaceSplit(), _lwt_CheckEdgeCrossing(), _lwt_EdgeMotionArea(), _lwt_GetEqualEdge(), boundary(), isvalid(), LWGEOM2GEOS(), 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_offsetcurve(), lwgeom_sharedpaths(), lwgeom_snap(), lwgeom_symdifference(), lwgeom_unaryunion(), lwgeom_union(), LWGEOMARRAY2GEOS(), lwline_split_by_line(), lwpoly_split_by_line(), lwpoly_to_points(), lwt_AddPoint(), lwt_AddPolygon(), lwt_ChangeEdgeGeom(), POSTGIS2GEOS(), PrepGeomCacheBuilder(), rt_raster_compute_skewed_raster(), rt_raster_gdal_polygonize(), rt_raster_gdal_rasterize(), rt_raster_geos_spatial_relationship(), rt_raster_intersects(), and rt_raster_surface().

358 {
359  GEOSCoordSeq sq;
360  GEOSGeom g, shell;
361  GEOSGeom *geoms = NULL;
362  /*
363  LWGEOM *tmp;
364  */
365  uint32_t ngeoms, i, j;
366  int geostype;
367 #if LWDEBUG_LEVEL >= 4
368  char *wkt;
369 #endif
370 
371  LWDEBUGF(4, "LWGEOM2GEOS got a %s", lwtype_name(lwgeom->type));
372 
373  if (lwgeom_has_arc(lwgeom))
374  {
375  LWGEOM *lwgeom_stroked = lwgeom_stroke(lwgeom, 32);
376  GEOSGeometry *g = LWGEOM2GEOS(lwgeom_stroked, autofix);
377  lwgeom_free(lwgeom_stroked);
378  return g;
379  }
380 
381  switch (lwgeom->type)
382  {
383  LWPOINT *lwp = NULL;
384  LWPOLY *lwpoly = NULL;
385  LWLINE *lwl = NULL;
386  LWCOLLECTION *lwc = NULL;
387 
388  case POINTTYPE:
389  lwp = (LWPOINT *)lwgeom;
390 
391  if ( lwgeom_is_empty(lwgeom) )
392  {
393  g = GEOSGeom_createEmptyPolygon();
394  }
395  else
396  {
397  sq = ptarray_to_GEOSCoordSeq(lwp->point, 0);
398  g = GEOSGeom_createPoint(sq);
399  }
400  if ( ! g )
401  {
402  /* lwnotice("Exception in LWGEOM2GEOS"); */
403  return NULL;
404  }
405  break;
406  case LINETYPE:
407  lwl = (LWLINE *)lwgeom;
408  /* TODO: if (autofix) */
409  if ( lwl->points->npoints == 1 ) {
410  /* Duplicate point, to make geos-friendly */
411  lwl->points = ptarray_addPoint(lwl->points,
412  getPoint_internal(lwl->points, 0),
413  FLAGS_NDIMS(lwl->points->flags),
414  lwl->points->npoints);
415  }
416  sq = ptarray_to_GEOSCoordSeq(lwl->points, 0);
417  g = GEOSGeom_createLineString(sq);
418  if ( ! g )
419  {
420  /* lwnotice("Exception in LWGEOM2GEOS"); */
421  return NULL;
422  }
423  break;
424 
425  case POLYGONTYPE:
426  lwpoly = (LWPOLY *)lwgeom;
427  if ( lwgeom_is_empty(lwgeom) )
428  {
429  g = GEOSGeom_createEmptyPolygon();
430  }
431  else
432  {
433  shell = ptarray_to_GEOSLinearRing(lwpoly->rings[0], autofix);
434  if ( ! shell ) return NULL;
435  /*lwerror("LWGEOM2GEOS: exception during polygon shell conversion"); */
436  ngeoms = lwpoly->nrings-1;
437  if ( ngeoms > 0 )
438  geoms = malloc(sizeof(GEOSGeom)*ngeoms);
439 
440  for (i=1; i<lwpoly->nrings; ++i)
441  {
442  geoms[i-1] = ptarray_to_GEOSLinearRing(lwpoly->rings[i], autofix);
443  if ( ! geoms[i-1] )
444  {
445  --i;
446  while (i) GEOSGeom_destroy(geoms[--i]);
447  free(geoms);
448  GEOSGeom_destroy(shell);
449  return NULL;
450  }
451  /*lwerror("LWGEOM2GEOS: exception during polygon hole conversion"); */
452  }
453  g = GEOSGeom_createPolygon(shell, geoms, ngeoms);
454  if (geoms) free(geoms);
455  }
456  if ( ! g ) return NULL;
457  break;
458  case MULTIPOINTTYPE:
459  case MULTILINETYPE:
460  case MULTIPOLYGONTYPE:
461  case COLLECTIONTYPE:
462  if ( lwgeom->type == MULTIPOINTTYPE )
463  geostype = GEOS_MULTIPOINT;
464  else if ( lwgeom->type == MULTILINETYPE )
465  geostype = GEOS_MULTILINESTRING;
466  else if ( lwgeom->type == MULTIPOLYGONTYPE )
467  geostype = GEOS_MULTIPOLYGON;
468  else
469  geostype = GEOS_GEOMETRYCOLLECTION;
470 
471  lwc = (LWCOLLECTION *)lwgeom;
472 
473  ngeoms = lwc->ngeoms;
474  if ( ngeoms > 0 )
475  geoms = malloc(sizeof(GEOSGeom)*ngeoms);
476 
477  j = 0;
478  for (i=0; i<ngeoms; ++i)
479  {
480  GEOSGeometry* g;
481 
482  if( lwgeom_is_empty(lwc->geoms[i]) )
483  continue;
484 
485  g = LWGEOM2GEOS(lwc->geoms[i], 0);
486  if ( ! g )
487  {
488  while (j) GEOSGeom_destroy(geoms[--j]);
489  free(geoms);
490  return NULL;
491  }
492  geoms[j++] = g;
493  }
494  g = GEOSGeom_createCollection(geostype, geoms, j);
495  if ( geoms ) free(geoms);
496  if ( ! g ) return NULL;
497  break;
498 
499  default:
500  lwerror("Unknown geometry type: %d - %s", lwgeom->type, lwtype_name(lwgeom->type));
501  return NULL;
502  }
503 
504  GEOSSetSRID(g, lwgeom->srid);
505 
506 #if LWDEBUG_LEVEL >= 4
507  wkt = GEOSGeomToWKT(g);
508  LWDEBUGF(4, "LWGEOM2GEOS: GEOSGeom: %s", wkt);
509  free(wkt);
510 #endif
511 
512  return g;
513 }
#define LINETYPE
Definition: liblwgeom.h:86
LWGEOM * lwgeom_stroke(const LWGEOM *geom, uint32_t perQuad)
Definition: lwstroke.c:767
int npoints
Definition: liblwgeom.h:371
#define POLYGONTYPE
Definition: liblwgeom.h:87
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1099
#define MULTIPOINTTYPE
Definition: liblwgeom.h:88
POINTARRAY * point
Definition: liblwgeom.h:411
int32_t srid
Definition: liblwgeom.h:399
unsigned int uint32_t
Definition: uthash.h:78
POINTARRAY * ptarray_addPoint(const POINTARRAY *pa, uint8_t *p, size_t pdims, uint32_t where)
Add a point in a pointarray.
Definition: ptarray.c:504
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:218
uint8_t flags
Definition: liblwgeom.h:369
LWGEOM ** geoms
Definition: liblwgeom.h:509
uint8_t * getPoint_internal(const POINTARRAY *pa, int n)
Definition: ptarray.c:1753
POINTARRAY ** rings
Definition: liblwgeom.h:457
int nrings
Definition: liblwgeom.h:455
int lwgeom_has_arc(const LWGEOM *geom)
Definition: lwstroke.c:54
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, int autofix)
GEOSCoordSeq ptarray_to_GEOSCoordSeq(const POINTARRAY *, int fix_ring)
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:90
static GEOSGeometry * ptarray_to_GEOSLinearRing(const POINTARRAY *pa, int autofix)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:85
uint8_t type
Definition: liblwgeom.h:396
void free(void *)
void * malloc(YYSIZE_T)
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:1346
#define MULTILINETYPE
Definition: liblwgeom.h:89
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:152
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
#define COLLECTIONTYPE
Definition: liblwgeom.h:91
POINTARRAY * points
Definition: liblwgeom.h:422
Here is the call graph for this function:
Here is the caller graph for this function: