PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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#ifndef NDEBUG
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 [%d] 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)
void lwgeom_geos_error(const char *fmt,...)
void(*) LWGEOM GEOS2LWGEOM)(const GEOSGeometry *geom, uint8_t want3d)
#define COLLECTIONTYPE
Definition liblwgeom.h:108
void * lwrealloc(void *mem, size_t size)
Definition lwutil.c:242
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:165
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
Datum contains(PG_FUNCTION_ARGS)
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
uint32_t ngeoms
Definition liblwgeom.h:580
LWGEOM ** geoms
Definition liblwgeom.h:575

References COLLECTIONTYPE, contains(), LWPOLY::flags, FLAGS_GET_Z, LWCOLLECTION::geoms, 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: