Returns a set of "geomval" value, one for each group of pixel sharing the same value for the provided band.
From GDALPolygonize function header: "Polygon features will be created on the output layer, with polygon geometries representing the polygons". So,the WKB geometry type should be "wkbPolygon"
Optimization: Apply a OGR SQL filter to the layer to select the features different from NODATA value.
Thanks to David Zwarg.
983 CPLErr cplerr = CE_None;
986 OGRSFDriverH ogr_drv = NULL;
987 GDALDriverH gdal_drv = NULL;
988 int destroy_gdal_drv = 0;
989 GDALDatasetH memdataset = NULL;
990 GDALRasterBandH gdal_band = NULL;
991 OGRDataSourceH memdatasource = NULL;
993 OGRLayerH hLayer = NULL;
994 OGRFeatureH hFeature = NULL;
995 OGRGeometryH hGeom = NULL;
996 OGRFieldDefnH hFldDfn = NULL;
997 unsigned char *wkb = NULL;
1000 int nFeatureCount = 0;
1003 double dValue = 0.0;
1004 int iBandHasNodataValue =
FALSE;
1005 double dBandNoData = 0.0;
1008 GEOSGeometry *ggeom = NULL;
1010 LWGEOM *lwgeomValid = NULL;
1012 uint32_t bandNums[1] = {
nband};
1013 int excludeNodataValues[1] = {exclude_nodata_value};
1017 assert(NULL != pnElements);
1028 rterror(
"rt_raster_gdal_polygonize: Error getting band %d from raster",
nband);
1032 if (exclude_nodata_value) {
1042 if (iBandHasNodataValue)
1045 exclude_nodata_value =
FALSE;
1052 if (NULL == memdataset) {
1053 rterror(
"rt_raster_gdal_polygonize: Couldn't convert raster to GDAL MEM dataset");
1060 #ifdef GDAL_DCAP_RASTER
1072 ogr_drv = OGRGetDriverByName(
"Memory");
1073 memdatasource = OGR_Dr_CreateDataSource(ogr_drv,
"", NULL);
1074 if (NULL == memdatasource) {
1075 rterror(
"rt_raster_gdal_polygonize: Couldn't create a OGR Datasource to store pols");
1076 GDALClose(memdataset);
1077 if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
1082 if (!OGR_DS_TestCapability(memdatasource, ODsCCreateLayer)) {
1083 rterror(
"rt_raster_gdal_polygonize: MEM driver can't create new layers, aborting");
1086 GDALClose(memdataset);
1087 if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
1088 OGRReleaseDataSource(memdatasource);
1104 hLayer = OGR_DS_CreateLayer(memdatasource,
"PolygonizedLayer", NULL, wkbPolygon, NULL);
1106 if (NULL == hLayer) {
1107 rterror(
"rt_raster_gdal_polygonize: Couldn't create layer to store polygons");
1109 GDALClose(memdataset);
1110 if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
1111 OGRReleaseDataSource(memdatasource);
1121 hFldDfn = OGR_Fld_Create(
"PixelValue", OFTReal);
1124 if (OGR_L_CreateField(hLayer, hFldDfn,
TRUE) != OGRERR_NONE) {
1125 rtwarn(
"Couldn't create a field in OGR Layer. The polygons generated won't be able to store the pixel value");
1134 gdal_band = GDALGetRasterBand(memdataset, 1);
1135 if (NULL == gdal_band) {
1136 rterror(
"rt_raster_gdal_polygonize: Couldn't get GDAL band to polygonize");
1138 GDALClose(memdataset);
1139 if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
1140 OGR_Fld_Destroy(hFldDfn);
1141 OGR_DS_DeleteLayer(memdatasource, 0);
1142 OGRReleaseDataSource(memdatasource);
1148 cplerr = GDALFPolygonize(gdal_band, NULL, hLayer, iPixVal, NULL, NULL, NULL);
1150 if (cplerr != CE_None) {
1151 rterror(
"rt_raster_gdal_polygonize: Could not polygonize GDAL band");
1153 GDALClose(memdataset);
1154 if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
1155 OGR_Fld_Destroy(hFldDfn);
1156 OGR_DS_DeleteLayer(memdatasource, 0);
1157 OGRReleaseDataSource(memdatasource);
1168 if (iBandHasNodataValue) {
1169 size_t sz = 50 *
sizeof (char);
1170 pszQuery = (
char *)
rtalloc(sz);
1171 snprintf(pszQuery, sz,
"PixelValue != %f", dBandNoData );
1172 OGRErr e = OGR_L_SetAttributeFilter(hLayer, pszQuery);
1173 if (e != OGRERR_NONE) {
1174 rtwarn(
"Error filtering NODATA values for band. All values will be treated as data values");
1187 nFeatureCount = OGR_L_GetFeatureCount(hLayer,
TRUE);
1193 rterror(
"rt_raster_gdal_polygonize: Could not allocate memory for geomval set");
1195 GDALClose(memdataset);
1196 if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
1197 OGR_Fld_Destroy(hFldDfn);
1198 OGR_DS_DeleteLayer(memdatasource, 0);
1199 if (NULL != pszQuery)
1201 OGRReleaseDataSource(memdatasource);
1212 OGR_L_ResetReading(hLayer);
1214 for (j = 0; j < nFeatureCount; j++) {
1215 hFeature = OGR_L_GetNextFeature(hLayer);
1216 dValue = OGR_F_GetFieldAsDouble(hFeature, iPixVal);
1218 hGeom = OGR_F_GetGeometryRef(hFeature);
1219 wkbsize = OGR_G_WkbSize(hGeom);
1222 wkb =
rtalloc(
sizeof(
unsigned char) * wkbsize);
1224 rterror(
"rt_raster_gdal_polygonize: Could not allocate memory for WKB buffer");
1226 OGR_F_Destroy(hFeature);
1227 GDALClose(memdataset);
1228 if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
1229 OGR_Fld_Destroy(hFldDfn);
1230 OGR_DS_DeleteLayer(memdatasource, 0);
1231 if (NULL != pszQuery)
1233 OGRReleaseDataSource(memdatasource);
1239 OGR_G_ExportToWkb(hGeom, wkbNDR, wkb);
1243 if (!lwgeom)
rterror(
"%s: invalid wkb", __func__);
1245 #if POSTGIS_DEBUG_LEVEL > 3
1248 OGR_G_ExportToWkt(hGeom, &wkt);
1252 d_print_binary_hex(
"GDAL wkb", wkb, wkbsize);
1261 OGR_F_Destroy(hFeature);
1272 if (ggeom == NULL) {
1273 rtwarn(
"Cannot test geometry for validity");
1277 isValid = GEOSisValid(ggeom);
1279 GEOSGeom_destroy(ggeom);
1290 if (lwgeomValid == NULL) {
1291 rtwarn(
"Cannot fix invalid geometry");
1296 lwgeom = lwgeomValid;
1303 #if POSTGIS_DEBUG_LEVEL > 3
1312 d_print_binary_hex(
"LWGEOM wkb", (
const uint8_t *)lwwkb->
data, lwwkbsize);
1319 pols[j].
val = dValue;
1322 *pnElements = nFeatureCount;
1325 GDALClose(memdataset);
1326 if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
1329 OGR_Fld_Destroy(hFldDfn);
1330 OGR_DS_DeleteLayer(memdatasource, 0);
1331 if (NULL != pszQuery)
rtdealloc(pszQuery);
1332 OGRReleaseDataSource(memdatasource);
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
void lwgeom_geos_error(const char *fmt,...)
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)
#define LW_PARSER_CHECK_NONE
#define LWSIZE_GET(varsize)
Macro for reading the size from the GSERIALIZED size attribute.
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
LWPOLY * lwgeom_as_lwpoly(const LWGEOM *lwgeom)
LWGEOM * lwgeom_from_wkb(const uint8_t *wkb, const size_t wkb_size, const char check)
WKB inputs must have a declared size, to prevent malformed WKB from reading off the end of the memory...
lwvarlena_t * lwgeom_to_wkb_varlena(const LWGEOM *geom, uint8_t variant)
LWGEOM * lwgeom_make_valid(LWGEOM *geom)
Attempts to make an invalid geometries valid w/out losing points.
void rterror(const char *fmt,...)
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.
int rt_util_gdal_register_all(int force_register_all)
#define RASTER_DEBUGF(level, msg,...)
void rtinfo(const char *fmt,...)
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.
void rtwarn(const char *fmt,...)
struct rt_geomval_t * rt_geomval
rt_errorstate rt_band_get_nodata(rt_band band, double *nodata)
Get NODATA value.
void rtdealloc(void *mem)
GDALDatasetH rt_raster_to_gdal_mem(rt_raster raster, const char *srs, uint32_t *bandNums, int *excludeNodataValues, int count, GDALDriverH *rtn_drv, int *destroy_rtn_drv)
Return GDAL dataset using GDAL MEM driver from raster.
rt_band rt_raster_get_band(rt_raster raster, int bandNum)
Return Nth band, or NULL if unavailable.
raster
Be careful!! Zeros function's input parameter can be a (height x width) array, not (width x height): ...