PostGIS  2.1.10dev-r@@SVN_REVISION@@
GEOSGeometry* LWGEOM2GEOS ( const LWGEOM lwgeom)

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

References COLLECTIONTYPE, POINTARRAY::flags, FLAGS_NDIMS, LWCOLLECTION::geoms, getPoint_internal(), LINETYPE, LWDEBUG, LWDEBUGF, lwerror(), LWGEOM2GEOS(), lwgeom_has_arc(), lwgeom_has_m(), lwgeom_has_z(), lwgeom_is_empty(), lwtype_name(), MULTILINETYPE, MULTIPOINTTYPE, MULTIPOLYGONTYPE, LWCOLLECTION::ngeoms, POINTARRAY::npoints, LWPOLY::nrings, LWPOINT::point, LWLINE::points, POINTTYPE, POLYGONTYPE, ptarray_addPoint(), ptarray_construct_empty(), ptarray_to_GEOSCoordSeq(), LWPOLY::rings, LWGEOM::srid, and LWGEOM::type.

Referenced by boundary(), isvalid(), LWGEOM2GEOS(), lwgeom_buildarea(), lwgeom_delaunay_triangulation(), lwgeom_difference(), lwgeom_extract_unique_endpoints(), lwgeom_geos_noop(), lwgeom_intersection(), lwgeom_make_valid(), lwgeom_node(), lwgeom_normalize(), lwgeom_offsetcurve(), lwgeom_sharedpaths(), lwgeom_snap(), lwgeom_symdifference(), lwgeom_union(), lwline_split_by_line(), lwpoly_split_by_line(), 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().

253 {
254  GEOSCoordSeq sq;
255  GEOSGeom g, shell;
256  GEOSGeom *geoms = NULL;
257  /*
258  LWGEOM *tmp;
259  */
260  uint32_t ngeoms, i, j;
261  int geostype;
262 #if LWDEBUG_LEVEL >= 4
263  char *wkt;
264 #endif
265 
266  LWDEBUGF(4, "LWGEOM2GEOS got a %s", lwtype_name(lwgeom->type));
267 
268  if (lwgeom_has_arc(lwgeom))
269  {
270  LWDEBUG(3, "LWGEOM2GEOS: arced geometry found.");
271 
272  lwerror("Exception in LWGEOM2GEOS: curved geometry not supported.");
273  return NULL;
274  }
275 
276  switch (lwgeom->type)
277  {
278  LWPOINT *lwp = NULL;
279  LWPOLY *lwpoly = NULL;
280  LWLINE *lwl = NULL;
281  LWCOLLECTION *lwc = NULL;
282 #if POSTGIS_GEOS_VERSION < 33
283  POINTARRAY *pa = NULL;
284 #endif
285 
286  case POINTTYPE:
287  lwp = (LWPOINT *)lwgeom;
288 
289  if ( lwgeom_is_empty(lwgeom) )
290  {
291 #if POSTGIS_GEOS_VERSION < 33
292  pa = ptarray_construct_empty(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
293  sq = ptarray_to_GEOSCoordSeq(pa);
294  shell = GEOSGeom_createLinearRing(sq);
295  g = GEOSGeom_createPolygon(shell, NULL, 0);
296 #else
297  g = GEOSGeom_createEmptyPolygon();
298 #endif
299  }
300  else
301  {
302  sq = ptarray_to_GEOSCoordSeq(lwp->point);
303  g = GEOSGeom_createPoint(sq);
304  }
305  if ( ! g )
306  {
307  /* lwnotice("Exception in LWGEOM2GEOS"); */
308  return NULL;
309  }
310  break;
311  case LINETYPE:
312  lwl = (LWLINE *)lwgeom;
313  if ( lwl->points->npoints == 1 ) {
314  /* Duplicate point, to make geos-friendly */
315  lwl->points = ptarray_addPoint(lwl->points,
316  getPoint_internal(lwl->points, 0),
317  FLAGS_NDIMS(lwl->points->flags),
318  lwl->points->npoints);
319  }
320  sq = ptarray_to_GEOSCoordSeq(lwl->points);
321  g = GEOSGeom_createLineString(sq);
322  if ( ! g )
323  {
324  /* lwnotice("Exception in LWGEOM2GEOS"); */
325  return NULL;
326  }
327  break;
328 
329  case POLYGONTYPE:
330  lwpoly = (LWPOLY *)lwgeom;
331  if ( lwgeom_is_empty(lwgeom) )
332  {
333 #if POSTGIS_GEOS_VERSION < 33
334  POINTARRAY *pa = ptarray_construct_empty(lwgeom_has_z(lwgeom), lwgeom_has_m(lwgeom), 2);
335  sq = ptarray_to_GEOSCoordSeq(pa);
336  shell = GEOSGeom_createLinearRing(sq);
337  g = GEOSGeom_createPolygon(shell, NULL, 0);
338 #else
339  g = GEOSGeom_createEmptyPolygon();
340 #endif
341  }
342  else
343  {
344  sq = ptarray_to_GEOSCoordSeq(lwpoly->rings[0]);
345  /* TODO: check ring for being closed and fix if not */
346  shell = GEOSGeom_createLinearRing(sq);
347  if ( ! shell ) return NULL;
348  /*lwerror("LWGEOM2GEOS: exception during polygon shell conversion"); */
349  ngeoms = lwpoly->nrings-1;
350  if ( ngeoms > 0 )
351  geoms = malloc(sizeof(GEOSGeom)*ngeoms);
352 
353  for (i=1; i<lwpoly->nrings; ++i)
354  {
355  sq = ptarray_to_GEOSCoordSeq(lwpoly->rings[i]);
356  geoms[i-1] = GEOSGeom_createLinearRing(sq);
357  if ( ! geoms[i-1] )
358  {
359  --i;
360  while (i) GEOSGeom_destroy(geoms[--i]);
361  free(geoms);
362  GEOSGeom_destroy(shell);
363  return NULL;
364  }
365  /*lwerror("LWGEOM2GEOS: exception during polygon hole conversion"); */
366  }
367  g = GEOSGeom_createPolygon(shell, geoms, ngeoms);
368  if (geoms) free(geoms);
369  }
370  if ( ! g ) return NULL;
371  break;
372  case MULTIPOINTTYPE:
373  case MULTILINETYPE:
374  case MULTIPOLYGONTYPE:
375  case COLLECTIONTYPE:
376  if ( lwgeom->type == MULTIPOINTTYPE )
377  geostype = GEOS_MULTIPOINT;
378  else if ( lwgeom->type == MULTILINETYPE )
379  geostype = GEOS_MULTILINESTRING;
380  else if ( lwgeom->type == MULTIPOLYGONTYPE )
381  geostype = GEOS_MULTIPOLYGON;
382  else
383  geostype = GEOS_GEOMETRYCOLLECTION;
384 
385  lwc = (LWCOLLECTION *)lwgeom;
386 
387  ngeoms = lwc->ngeoms;
388 
389  if ( ngeoms > 0 )
390  geoms = malloc(sizeof(GEOSGeom)*ngeoms);
391 
392  for (i=0, j=0; i<ngeoms; ++i)
393  {
394  GEOSGeometry* g;
395 
396  if( lwgeom_is_empty(lwc->geoms[i]) )
397  continue;
398 
399  g = LWGEOM2GEOS(lwc->geoms[i]);
400  if ( ! g )
401  {
402  while (j) GEOSGeom_destroy(geoms[--j]);
403  free(geoms);
404  return NULL;
405  }
406  geoms[j++] = g;
407  }
408  g = GEOSGeom_createCollection(geostype, geoms, j);
409  if ( geoms ) free(geoms);
410  if ( ! g ) return NULL;
411  break;
412 
413  default:
414  lwerror("Unknown geometry type: %d - %s", lwgeom->type, lwtype_name(lwgeom->type));
415  return NULL;
416  }
417 
418  GEOSSetSRID(g, lwgeom->srid);
419 
420 #if LWDEBUG_LEVEL >= 4
421  wkt = GEOSGeomToWKT(g);
422  LWDEBUGF(4, "LWGEOM2GEOS: GEOSGeom: %s", wkt);
423  free(wkt);
424 #endif
425 
426  return g;
427 }
#define LINETYPE
Definition: liblwgeom.h:61
int npoints
Definition: liblwgeom.h:327
#define POLYGONTYPE
Definition: liblwgeom.h:62
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:57
#define MULTIPOINTTYPE
Definition: liblwgeom.h:63
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:50
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom)
POINTARRAY * point
Definition: liblwgeom.h:367
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:792
int32_t srid
Definition: liblwgeom.h:355
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:67
GEOSCoordSeq ptarray_to_GEOSCoordSeq(const POINTARRAY *)
POINTARRAY * ptarray_addPoint(const POINTARRAY *pa, uint8_t *p, size_t pdims, uint32_t where)
Add a point in a pointarray.
Definition: ptarray.c:481
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:164
uint8_t flags
Definition: liblwgeom.h:325
LWGEOM ** geoms
Definition: liblwgeom.h:465
uint8_t * getPoint_internal(const POINTARRAY *pa, int n)
Definition: ptarray.c:1645
POINTARRAY ** rings
Definition: liblwgeom.h:413
int nrings
Definition: liblwgeom.h:411
int lwgeom_has_arc(const LWGEOM *geom)
Definition: lwsegmentize.c:42
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:65
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:60
uint8_t type
Definition: liblwgeom.h:352
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:1229
#define MULTILINETYPE
Definition: liblwgeom.h:64
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:55
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:118
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition: lwgeom.c:799
#define COLLECTIONTYPE
Definition: liblwgeom.h:66
POINTARRAY * points
Definition: liblwgeom.h:378

Here is the call graph for this function:

Here is the caller graph for this function: