Get a raster as a surface (multipolygon).
If a band is specified, those pixels with value (not NODATA) contribute to the area of the output multipolygon.
If a band is specified, those pixels with value (not NODATA) contribute to the area of the output multipolygon.
356 {
362 int gvcount = 0;
363 GEOSGeometry *gc = NULL;
364 GEOSGeometry *gunion = NULL;
365 GEOSGeometry **geoms = NULL;
366 int geomscount = 0;
367 int i = 0;
368
369 assert(surface != NULL);
370
371
372 *surface = NULL;
373
374
377
378
379 if (nband < 0) {
380
381
382
383
384
385
387 rterror(
"rt_raster_surface: Could not get convex hull of raster");
389 }
394
397 }
398
400 rterror(
"rt_raster_surface: The band index %d is invalid", nband);
402 }
403
404
406 if (band == NULL) {
407 rterror(
"rt_raster_surface: Error getting band %d from raster", nband);
409 }
410
411
413
414
415
416
417
418
420 rterror(
"rt_raster_surface: Could not get convex hull of raster");
422 }
427
430 }
431
435 }
436
437
439
440 if (gvcount < 1) {
441 RASTER_DEBUG(3,
"All pixels of band are NODATA. Returning NULL");
444 }
445
446 else if (gvcount > 1) {
447
448 geomscount = gvcount;
449 geoms =
rtalloc(
sizeof(GEOSGeometry *) * geomscount);
450 if (geoms == NULL) {
451 rterror(
"rt_raster_surface: Could not allocate memory for pixel polygons as GEOSGeometry");
452 for (i = 0; i < gvcount; i++)
lwpoly_free(gv[i].geom);
455 }
456 for (i = 0; i < gvcount; i++) {
457#if POSTGIS_DEBUG_LEVEL > 3
458 {
462 }
463#endif
464
467 }
469
470
471 gc = GEOSGeom_createCollection(GEOS_GEOMETRYCOLLECTION, geoms, geomscount);
472
473 if (gc == NULL) {
474 rterror(
"rt_raster_surface: Could not create GEOS GEOMETRYCOLLECTION from set of pixel polygons");
475
476 for (i = 0; i < geomscount; i++)
477 GEOSGeom_destroy(geoms[i]);
480 }
481
482
483 gunion = GEOSUnaryUnion(gc);
484
485 GEOSGeom_destroy(gc);
487
488 if (gunion == NULL) {
489 rterror(
"rt_raster_surface: Could not union the pixel polygons using GEOSUnaryUnion()");
491 }
492
493
495
496
497
498
499
500 do {
501 LWGEOM *mpolyValid = NULL;
502
503 if (GEOSisValid(gunion))
504 break;
505
506
508 if (mpolyValid == NULL) {
509 rtwarn(
"Cannot fix invalid geometry");
510 break;
511 }
512
514 mpoly = mpolyValid;
515 }
516 while (0);
517
518 GEOSGeom_destroy(gunion);
519 }
520 else {
523
524#if POSTGIS_DEBUG_LEVEL > 3
525 {
529 }
530#endif
531 }
532
533
535
536 if (mpoly != NULL) {
537
539 tmp = mpoly;
540
541#if POSTGIS_DEBUG_LEVEL > 3
542 {
546 }
547#endif
548
550
551
552
553
554
555
556
561 mpoly = clone;
562
564
565#if POSTGIS_DEBUG_LEVEL > 3
566 {
570 }
571#endif
572 }
573
574#if POSTGIS_DEBUG_LEVEL > 3
575 {
579 }
580#endif
581
584 }
585
587}
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
void(*) LWGEOM GEOS2LWGEOM)(const GEOSGeometry *geom, uint8_t want3d)
void lwgeom_set_srid(LWGEOM *geom, int32_t srid)
Set the SRID on an LWGEOM For collections, only the parent gets an SRID, all the children get SRID_UN...
void lwgeom_free(LWGEOM *geom)
LWGEOM * lwgeom_as_multi(const LWGEOM *lwgeom)
Create a new LWGEOM of the appropriate MULTI* type.
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
int lwgeom_is_collection(const LWGEOM *lwgeom)
Determine whether a LWGEOM contains sub-geometries or not This basically just checks that the struct ...
LWMPOLY * lwgeom_as_lwmpoly(const LWGEOM *lwgeom)
void lwpoly_free(LWPOLY *poly)
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
LWGEOM * lwgeom_make_valid(LWGEOM *geom)
Attempts to make an invalid geometries valid w/out losing points.
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
void rterror(const char *fmt,...) __attribute__((format(printf
Wrappers used for reporting errors and info.
void * rtalloc(size_t size)
Wrappers used for managing memory.
#define RASTER_DEBUG(level, msg)
int32_t rt_raster_get_srid(rt_raster raster)
Get raster's SRID.
#define RASTER_DEBUGF(level, msg,...)
void void void rtwarn(const char *fmt,...) __attribute__((format(printf
int rt_band_get_hasnodata_flag(rt_band band)
Get hasnodata flag value.
int rt_band_get_isnodata_flag(rt_band band)
Get isnodata flag value.
uint16_t rt_raster_get_num_bands(rt_raster raster)
void rtdealloc(void *mem)
int rt_raster_is_empty(rt_raster raster)
Return TRUE if the raster is empty.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
rt_geomval rt_raster_gdal_polygonize(rt_raster raster, int nband, int exclude_nodata_value, int *pnElements)
Returns a set of "geomval" value, one for each group of pixel sharing the same value for the provided...
rt_errorstate rt_raster_get_convex_hull(rt_raster raster, LWGEOM **hull)
Get raster's convex hull.