¿La forma más rápida de convertir grandes rásteres en polilíneas usando R o Python?

14

Tengo un gran archivo ráster (129600 por 64800 píxeles) con cuerpos de agua globales (valores de 1 bit 0 y 1) e intento extraer las costas de aguas continentales y oceánicas.

He intentado con ArcGIS y QGIS para convertir de ráster a polilínea, pero lleva años.

¿Alguien sabe una forma mejor / más rápida (Python o R) o una mejor herramienta para esta tarea?

Actualizar

  • R: rasterToContour puede ser rápido y preciso, pero si tiene un conjunto de datos muy grande como el mío (8,398,080,000 píxeles) necesita una gran cantidad de RAM (más de 16 GB) o obliga a R a hacer más procesamiento en el disco duro y También llevará años.
  • Python / GDAL: gdal_poligonize crea polígonos en lugar de polilíneas

Actualización 2

  • R rasterToContour: rasterToContour no entrega los resultados deseados. En comparación con ArcGIS (ráster a polígono seguido de entidad a línea), no extrae el contorno exacto del píxel, como se muestra en los ejemplos a continuación.

resultado rasterToContour resultado rasterToContour

Resultado de ArcGIS Resultado de ArcGIS

ACTUALIZACIÓN 3

Python / GDAL: ejecuté gdal_polygonize desde la línea de comandos contra ArcGIS en un conjunto de datos de prueba y los resultados fueron extremadamente claros:

  • gdal: 49 segundos
  • ArcGIS: 1.84 segundos
Wevers genéricos
fuente
Hice eso, vea la Actualización 3.
Wevers genéricos
¿Puede proporcionar ese conjunto de datos de prueba, para que podamos ver si las alternativas propuestas son más rápidas y / o producen los resultados requeridos?
Kersten
Para una trama tan grande, sería mucho mejor usar C / C ++ con la biblioteca gdal.
Rodrigo

Respuestas:

7

Estoy trabajando con R y utilicé rasterToPolygonsel rasterpaquete en el pasado, pero ahora prefiero gdal_polygonizeRJohn Baumgartner. Se basa en gdal_polygonize.pyy es mucho más rápido. John Baumgartner publicó el código y dio un ejemplo de uso en su blog .

Si está familiarizado con Python, puede usarlo gdal_polygonize.pydirectamente, por supuesto.

Iris
fuente
1
Lo daré, lo intento. La última vez que usé gdal_polygonize.py ArcGIS fue aún más rápido.
Wevers genéricos
No esperaba que ArcGis pueda ser más rápido que el gdal. @Generic Militzer
Iris
Ah, espera, esto creará polígonos pero necesito polilíneas.
Wevers genéricos
Si coloca sus datos en una Geodatabase de archivos, es bastante rápido. Pero aún no lo suficientemente rápido. Por eso estoy buscando alternativas.
Wevers genéricos
2
No es necesariamente un problema que obtengas polígonos, siempre puedes convertirlos en polilíneas (aunque, con eso, por supuesto, también podría tomar un tiempo).
Martin
7

Para la posteridad, he tenido éxito con el stars::paquete Rpara hacer este tipo de operación rápidamente.

library(raster)
library(stars)
library(sf)
library(magrittr)

f <- system.file("external/test.grd", package="raster")
r <- raster(f)
r[r[] < 750] <- 0
r[r[] >= 750] <- 1

x <- st_as_stars(r) %>% 
  st_as_sf() %>% # this is the raster to polygons part
  st_cast("MULTILINESTRING") # cast the polygons to polylines

plot(x)

ingrese la descripción de la imagen aquí

plot(r)
plot(x, add = TRUE)

ingrese la descripción de la imagen aquí

mikoontz
fuente
5

Probar rasterToContourdesde el paquete de trama .

f <- system.file("external/test.grd", package="raster")
r <- raster(f)
r[r[] < 750] <- 0
r[r[] >= 750] <- 1

x <- rasterToContour(r)
class(x)
> [1] "SpatialLinesDataFrame"
> attr(,"package")
> [1] "sp"

plot(r)
plot(x, add=TRUE)

ingrese la descripción de la imagen aquí

Luego, puede escribir fácilmente los archivos en una carpeta local, por ejemplo, como 'ESRI Shapefile' (.shp), utilizando el siguiente código. Eche un vistazo ogrDriversdesde rgdal para saber con qué controladores es compatible su sistema.

library(rgdal)
writeOGR(x, dsn = getwd(), layer = "coastlines", driver = "ESRI Shapefile")
fdetsch
fuente
Trataré de mantener los dedos cruzados, no matará mi RAM. Aunque tengo 16 GB, lo que espero sea suficiente, R a veces no es tan eficiente con grandes archivos ráster. Pero veamos.
Wevers genéricos
La conversión funcionó de alguna manera, pero no pude verificar en detalle. Como generalmente estoy más interesado en el procesamiento de datos ráster, ¿puede decirme cómo puedo transferir SpatialLineDataFrame a un shapefile o algo comparable? Busqué en Google y sigo luchando, ya que no sé el nombre de la capa (OGRwrite).
Wevers genéricos
Jaja, definitivamente entiendo tu punto. Ver actualización anterior.
fdetsch
2
Otra pista: intente configurar 'maxpixels' en rasterToContourun valor más alto, por ejemplo, 1e + 9. Terminarás con más detalles entonces. La configuración predeterminada crea líneas de contorno bastante generalizadas.
fdetsch
1
Si no está dispuesto a que resamplesus datos tengan una resolución espacial más gruesa, la única solución que puedo imaginar sería dividir sus datos en múltiples mosaicos (por ejemplo, 16 sub-rásteres), luego realizar rasterToContouren cada mosaico por separado de manera iterativa y , finalmente, mergelos archivos de forma resultantes en un gran archivo de formas. En caso de que esté interesado, el paquete de nuestro grupo de trabajo Rsenal ofrece una función llamada splitRasterpara crear múltiples sub-rásteres a partir de un gran ráster.
fdetsch
2

Si bien soy un gran admirador de GDAL, la herramienta de poligonalización también fue demasiado lenta para mis aplicaciones.

Una alternativa rápida es gdal_trace_outlinede los scripts Dans GDAL que también tiene más opciones con respecto a la tolerancia, donas, etc.

De gdal_polygonizeesta forma, también se producen polígonos con los que luego tendrías que convertirlos ogr2ogr -nlt MULTILINESTRING.

Lo malo es que debe compilarlo usted mismo, a menos que esté en un sistema OsX de Linux o Mac.

Kersten
fuente
Desafortunadamente, falló con el mensaje de error: "Error de segmentación (núcleo volcado)". Supongo que mi archivo es demasiado grande o más preciso, producirá demasiados polígonos pequeños.
Wevers genéricos