PostGIS  3.0.6dev-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 351 of file lwgeom_geos_split.c.

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

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: