PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ lwpoly_split_by_line()

static LWGEOM * lwpoly_split_by_line ( const LWPOLY lwgeom_in,
const LWGEOM blade_in 
)
static

Definition at line 346 of file lwgeom_geos_split.c.

347 {
348  LWCOLLECTION* out;
349  GEOSGeometry* g1;
350  GEOSGeometry* g2;
351  GEOSGeometry* g1_bounds;
352  GEOSGeometry* polygons;
353  const GEOSGeometry *vgeoms[1];
354  int i,n;
355  int hasZ = FLAGS_GET_Z(lwpoly_in->flags);
356 
357 
358  /* Possible outcomes:
359  *
360  * 1. The line does not split the polygon
361  * -> Return a collection with single element
362  * 2. The line does split the polygon
363  * -> Return a collection of all elements resulting from the split
364  */
365 
367 
368  g1 = LWGEOM2GEOS((LWGEOM*)lwpoly_in, 0);
369  if ( NULL == g1 )
370  {
371  lwerror("LWGEOM2GEOS: %s", lwgeom_geos_errmsg);
372  return NULL;
373  }
374  g1_bounds = GEOSBoundary(g1);
375  if ( NULL == g1_bounds )
376  {
377  GEOSGeom_destroy(g1);
378  lwerror("GEOSBoundary: %s", lwgeom_geos_errmsg);
379  return NULL;
380  }
381 
382  g2 = LWGEOM2GEOS(blade_in, 0);
383  if ( NULL == g2 )
384  {
385  GEOSGeom_destroy(g1);
386  GEOSGeom_destroy(g1_bounds);
387  lwerror("LWGEOM2GEOS: %s", lwgeom_geos_errmsg);
388  return NULL;
389  }
390 
391  vgeoms[0] = GEOSUnion(g1_bounds, g2);
392  if ( NULL == vgeoms[0] )
393  {
394  GEOSGeom_destroy(g1);
395  GEOSGeom_destroy(g2);
396  GEOSGeom_destroy(g1_bounds);
397  lwerror("GEOSUnion: %s", lwgeom_geos_errmsg);
398  return NULL;
399  }
400 
401  polygons = GEOSPolygonize(vgeoms, 1);
402  if ( NULL == polygons )
403  {
404  GEOSGeom_destroy(g1);
405  GEOSGeom_destroy(g2);
406  GEOSGeom_destroy(g1_bounds);
407  GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]);
408  lwerror("GEOSPolygonize: %s", lwgeom_geos_errmsg);
409  return NULL;
410  }
411 
412 #if PARANOIA_LEVEL > 0
413  if ( GEOSGeomTypeId(polygons) != COLLECTIONTYPE )
414  {
415  GEOSGeom_destroy(g1);
416  GEOSGeom_destroy(g2);
417  GEOSGeom_destroy(g1_bounds);
418  GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]);
419  GEOSGeom_destroy(polygons);
420  lwerror("%s [%s] Unexpected return from GEOSpolygonize", __FILE__, __LINE__);
421  return 0;
422  }
423 #endif
424 
425  /* We should now have all polygons, just skip
426  * the ones which are in holes of the original
427  * geometries and return the rest in a collection
428  */
429  n = GEOSGetNumGeometries(polygons);
430  out = lwcollection_construct_empty(COLLECTIONTYPE, lwpoly_in->srid,
431  hasZ, 0);
432  /* Allocate space for all polys */
433  out->geoms = lwrealloc(out->geoms, sizeof(LWGEOM*)*n);
434  assert(0 == out->ngeoms);
435  for (i=0; i<n; ++i)
436  {
437  GEOSGeometry* pos; /* point on surface */
438  const GEOSGeometry* p = GEOSGetGeometryN(polygons, i);
439  int contains;
440 
441  pos = GEOSPointOnSurface(p);
442  if ( ! pos )
443  {
444  GEOSGeom_destroy(g1);
445  GEOSGeom_destroy(g2);
446  GEOSGeom_destroy(g1_bounds);
447  GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]);
448  GEOSGeom_destroy(polygons);
449  lwerror("GEOSPointOnSurface: %s", lwgeom_geos_errmsg);
450  return NULL;
451  }
452 
453  contains = GEOSContains(g1, pos);
454  if ( 2 == contains )
455  {
456  GEOSGeom_destroy(g1);
457  GEOSGeom_destroy(g2);
458  GEOSGeom_destroy(g1_bounds);
459  GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]);
460  GEOSGeom_destroy(polygons);
461  GEOSGeom_destroy(pos);
462  lwerror("GEOSContains: %s", lwgeom_geos_errmsg);
463  return NULL;
464  }
465 
466  GEOSGeom_destroy(pos);
467 
468  if ( 0 == contains )
469  {
470  /* Original geometry doesn't contain
471  * a point in this ring, must be an hole
472  */
473  continue;
474  }
475 
476  out->geoms[out->ngeoms++] = GEOS2LWGEOM(p, hasZ);
477  }
478 
479  GEOSGeom_destroy(g1);
480  GEOSGeom_destroy(g2);
481  GEOSGeom_destroy(g1_bounds);
482  GEOSGeom_destroy((GEOSGeometry*)vgeoms[0]);
483  GEOSGeom_destroy(polygons);
484 
485  return (LWGEOM*)out;
486 }
char lwgeom_geos_errmsg[LWGEOM_GEOS_ERRMSG_MAXSIZE]
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
LWGEOM * GEOS2LWGEOM(const GEOSGeometry *geom, uint8_t want3d)
void lwgeom_geos_error(const char *fmt,...)
#define COLLECTIONTYPE
Definition: liblwgeom.h:91
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
Definition: lwcollection.c:94
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
Definition: liblwgeom.h:140
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:237
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
Datum contains(PG_FUNCTION_ARGS)
uint32_t ngeoms
Definition: liblwgeom.h:510
LWGEOM ** geoms
Definition: liblwgeom.h:512

References COLLECTIONTYPE, contains(), LWPOLY::flags, FLAGS_GET_Z, LWCOLLECTION::geoms, GEOS2LWGEOM(), lwcollection_construct_empty(), lwerror(), LWGEOM2GEOS(), lwgeom_geos_errmsg, lwgeom_geos_error(), lwrealloc(), LWCOLLECTION::ngeoms, and LWPOLY::srid.

Referenced by lwpoly_split().

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