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.
355 {
361 int gvcount = 0;
362 GEOSGeometry *gc = NULL;
363 GEOSGeometry *gunion = NULL;
364 GEOSGeometry **geoms = NULL;
365 int geomscount = 0;
366 int i = 0;
367
368 assert(surface != NULL);
369
370
371 *surface = NULL;
372
373
376
377
378 if (nband < 0) {
379
380
381
382
383
384
386 rterror(
"rt_raster_surface: Could not get convex hull of raster");
388 }
393
396 }
397
399 rterror(
"rt_raster_surface: The band index %d is invalid", nband);
401 }
402
403
405 if (band == NULL) {
406 rterror(
"rt_raster_surface: Error getting band %d from raster", nband);
408 }
409
410
412
413
414
415
416
417
419 rterror(
"rt_raster_surface: Could not get convex hull of raster");
421 }
426
429 }
430
434 }
435
436
438
439 if (gvcount < 1) {
440 RASTER_DEBUG(3,
"All pixels of band are NODATA. Returning NULL");
443 }
444
445 else if (gvcount > 1) {
446
447 geomscount = gvcount;
448 geoms =
rtalloc(
sizeof(GEOSGeometry *) * geomscount);
449 if (geoms == NULL) {
450 rterror(
"rt_raster_surface: Could not allocate memory for pixel polygons as GEOSGeometry");
451 for (i = 0; i < gvcount; i++)
lwpoly_free(gv[i].geom);
454 }
455 for (i = 0; i < gvcount; i++) {
456#if POSTGIS_DEBUG_LEVEL > 3
457 {
461 }
462#endif
463
466 }
468
469
470 gc = GEOSGeom_createCollection(GEOS_GEOMETRYCOLLECTION, geoms, geomscount);
471
472 if (gc == NULL) {
473 rterror(
"rt_raster_surface: Could not create GEOS GEOMETRYCOLLECTION from set of pixel polygons");
474
475 for (i = 0; i < geomscount; i++)
476 GEOSGeom_destroy(geoms[i]);
479 }
480
481
482 gunion = GEOSUnaryUnion(gc);
483
484 GEOSGeom_destroy(gc);
486
487 if (gunion == NULL) {
488 rterror(
"rt_raster_surface: Could not union the pixel polygons using GEOSUnaryUnion()");
490 }
491
492
494
495
496
497
498
499 do {
500 LWGEOM *mpolyValid = NULL;
501
502 if (GEOSisValid(gunion))
503 break;
504
505
507 if (mpolyValid == NULL) {
508 rtwarn(
"Cannot fix invalid geometry");
509 break;
510 }
511
513 mpoly = mpolyValid;
514 }
515 while (0);
516
517 GEOSGeom_destroy(gunion);
518 }
519 else {
522
523#if POSTGIS_DEBUG_LEVEL > 3
524 {
528 }
529#endif
530 }
531
532
534
535 if (mpoly != NULL) {
536
538 tmp = mpoly;
539
540#if POSTGIS_DEBUG_LEVEL > 3
541 {
545 }
546#endif
547
549
550
551
552
553
554
555
560 mpoly = clone;
561
563
564#if POSTGIS_DEBUG_LEVEL > 3
565 {
569 }
570#endif
571 }
572
573#if POSTGIS_DEBUG_LEVEL > 3
574 {
578 }
579#endif
580
583 }
584
586}
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.