-
-
Save Pakillo/c6b076eceb0ef5a70e3b to your computer and use it in GitHub Desktop.
| polygonizer <- function(x, outshape=NULL, gdalformat = 'ESRI Shapefile', | |
| pypath=NULL, readpoly=TRUE, quietish=TRUE) { | |
| # x: an R Raster layer, or the file path to a raster file recognised by GDAL | |
| # outshape: the path to the output shapefile (if NULL, a temporary file will be created) | |
| # gdalformat: the desired OGR vector format | |
| # pypath: the path to gdal_polygonize.py (if NULL, an attempt will be made to determine the location | |
| # readpoly: should the polygon shapefile be read back into R, and returned by this function? (logical) | |
| # quietish: should (some) messages be suppressed? (logical) | |
| if (isTRUE(readpoly)) require(rgdal) | |
| if (is.null(pypath)) { | |
| pypath <- Sys.which('gdal_polygonize.py') | |
| } | |
| ## The line below has been commented: | |
| # if (!file.exists(pypath)) stop("Can't find gdal_polygonize.py on your system.") | |
| owd <- getwd() | |
| on.exit(setwd(owd)) | |
| setwd(dirname(pypath)) | |
| if (!is.null(outshape)) { | |
| outshape <- sub('\\.shp$', '', outshape) | |
| f.exists <- file.exists(paste(outshape, c('shp', 'shx', 'dbf'), sep='.')) | |
| if (any(f.exists)) | |
| stop(sprintf('File already exists: %s', | |
| toString(paste(outshape, c('shp', 'shx', 'dbf'), | |
| sep='.')[f.exists])), call.=FALSE) | |
| } else outshape <- tempfile() | |
| if (is(x, 'Raster')) { | |
| require(raster) | |
| writeRaster(x, {f <- tempfile(fileext='.asc')}) | |
| rastpath <- normalizePath(f) | |
| } else if (is.character(x)) { | |
| rastpath <- normalizePath(x) | |
| } else stop('x must be a file path (character string), or a Raster object.') | |
| ## Now 'python' has to be substituted by OSGeo4W | |
| #system2('python', | |
| system2('C:\\OSGeo4W64\\OSGeo4W.bat', | |
| args=(sprintf('"%1$s" "%2$s" -f "%3$s" "%4$s.shp"', | |
| pypath, rastpath, gdalformat, outshape))) | |
| if (isTRUE(readpoly)) { | |
| shp <- readOGR(dirname(outshape), layer = basename(outshape), verbose=!quietish) | |
| return(shp) | |
| } | |
| return(NULL) | |
| } |
Hi Francisco,
Thanks for sharing this.
I have tried to run this but I am getting this error.
Error in ogrInfo(dsn = dsn, layer = layer, encoding = encoding, use_iconv = use_iconv, :
Cannot open data source
Any idea of what could be causing this?
I have python and OSGeo4W installed within QGIS 3.16 so I modified the paths to get to both OSGeo4w.bat and the python path.
Muchas gracias de antemano
Luis
Hi Luis,
I haven't used this function for a few years so it may be outdated. Note it was integrated in the APfun package, which probably still works: https://rdrr.io/cran/APfun/man/APpolygonize.html. Check out also further changes in the original function @johnbaums: https://gist.github.com/johnbaums/26e8091f082f2b3dd279
I'd probably try using terra::as.polygons, as shown here: https://stackoverflow.com/a/65335878. It can work with very large rasters and should be fast.
Other alternatives:
- Using sf and stars: https://gis.stackexchange.com/a/357792 & https://gis.stackexchange.com/a/313550
- spex package: https://mdsumner.github.io/spex/reference/polygonize.html
- fasterVectorize: https://rdrr.io/github/adamlilith/fasterRaster/man/fasterVectorize.html
Hope this helps
@luisrua I posted an alternative approach, using sf: https://gist.github.com/johnbaums/26e8091f082f2b3dd279#gistcomment-3142562
Dear @johnbaums and @Pakillo.
Thanks so much for your help. I will try the different options proposed.
Regards
Luis
I'm getting this error despite putting in a formal raster layer as 'x':
"x must be a file path (character string), or a Raster object."