PostGIS  2.5.0dev-r@@SVN_REVISION@@
GEOSGeometry* LWGEOM2GEOS ( const LWGEOM g,
int  autofix 
)

Definition at line 354 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_AddPoint(), _lwt_CheckEdgeCrossing(), _lwt_EdgeMotionArea(), _lwt_FindFaceContainingRing(), _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_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().

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

Here is the call graph for this function:

Here is the caller graph for this function: