Le moyen le plus rapide de convertir un gros raster en polyligne en utilisant R ou Python?

14

J'ai un gros fichier raster (129600 par 64800 pixels) avec les plans d'eau mondiaux (valeurs 1 bit 0 et 1) et j'essaie d'extraire les rives des océans et des eaux intérieures.

J'ai essayé avec ArcGIS et QGIS de convertir de raster en polyligne, mais cela prend des siècles.

Quelqu'un connaît-il un moyen meilleur / plus rapide (Python ou R) ou un meilleur outil pour cette tâche?

Mise à jour

  • R: rasterToContour peut être rapide et précis, mais si vous avez un très grand ensemble de données comme le mien (8 398 080 000 pixels), vous avez besoin d'une très grande quantité de RAM (plus de 16 Go) ou vous forcez R à faire plus de traitement sur le disque dur et prendra également des âges.
  • Python / GDAL: gdal_poligonize crée des polygones au lieu de polylignes

Update 2

  • R rasterToContour: rasterToContour ne fournit pas les résultats souhaités. Comparé à ArcGIS (raster sur polygone suivi d'une entité sur ligne), il n'extrait pas le contour exact des pixels, comme indiqué dans les exemples ci-dessous.

Résultat rasterToContour Résultat rasterToContour

Résultat ArcGIS Résultat ArcGIS

MISE À JOUR 3

Python / GDAL: j'ai exécuté gdal_polygonize à partir de la ligne de commande contre ArcGIS sur un jeu de données de test et les résultats étaient extrêmement clairs:

  • gdal: 49 secondes
  • ArcGIS: 1,84 secondes
Generic Wevers
la source
Oui, voir la mise à jour 3.
Generic Wevers
Pouvez-vous fournir cet ensemble de données de test, afin que nous puissions voir si les alternatives proposées sont plus rapides et / ou produisent les résultats requis?
Kersten
Pour un raster aussi énorme, il serait préférable d'utiliser C / C ++ avec la bibliothèque gdal.
Rodrigo

Réponses:

8

Je travaille avec R et utilisé à rasterToPolygonspartir du rasterpackage dans le passé, mais maintenant je préfère gdal_polygonizeRpar John Baumgartner. Il se base sur gdal_polygonize.pyet est beaucoup plus rapide. John Baumgartner a publié le code et a donné un exemple d'utilisation dans son blog .

Si vous êtes familier avec python, vous pouvez gdal_polygonize.pybien sûr l' utiliser directement.

Iris
la source
1
Je vais le donner j'essaye. La dernière fois que j'ai utilisé gdal_polygonize.py, ArcGIS était encore plus rapide.
Generic Wevers du
Je ne m'attendais pas à ce qu'ArcGis soit plus rapide que gdal. @Generic Militzer
Iris
Ah attendez, cela va créer des polygones mais j'ai besoin de polylignes.
Generic Wevers du
Si vous placez vos données dans une géodatabase fichier, c'est assez rapide. Mais toujours pas assez vite. C'est pourquoi je recherche des alternatives.
Generic Wevers du
2
Ce n'est pas nécessairement un problème que vous obteniez des polygones, vous pouvez toujours les convertir en polylignes (bien que, avec ce nombre, cela puisse bien sûr prendre un certain temps).
Martin
7

Pour la postérité, j'ai eu du succès avec le stars::package Rpour faire ce type d'opération rapidement.

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)

entrez la description de l'image ici

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

entrez la description de l'image ici

mikoontz
la source
5

Essayez à rasterToContourpartir du package raster .

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)

entrez la description de l'image ici

Vous pouvez ensuite facilement écrire les fichiers dans un dossier local, par exemple sous la forme «ESRI Shapefile» (.shp), en utilisant le code ci-dessous. Jetez un oeil à ogrDriversde rgdal pour les pilotes de votre système est compatible avec.

library(rgdal)
writeOGR(x, dsn = getwd(), layer = "coastlines", driver = "ESRI Shapefile")
fdetsch
la source
Je vais essayer de garder les doigts croisés, cela ne tuera pas ma RAM. Même si j'ai 16 Go, ce qui, espérons-le, est suffisant, R n'est parfois pas aussi efficace avec de gros fichiers raster. Mais voyons.
Generic Wevers
La conversion a fonctionné d'une manière ou d'une autre, mais je n'ai pas pu vérifier les détails. Comme je suis généralement plus dans le traitement des données raster, pouvez-vous me dire comment je peux transférer le SpatialLineDataFrame dans un fichier de formes ou quelque chose de comparable. J'ai googlé et j'ai toujours du mal, car je ne connais pas le nom de la couche (OGRwrite).
Generic Wevers du
Haha, je vois vraiment votre point. Voir la mise à jour ci-dessus.
fdetsch
2
Un autre indice: essayez de définir «maxpixels» rasterToContoursur une valeur plus élevée, par exemple 1e + 9. Vous vous retrouverez alors avec plus de détails. Le paramètre par défaut crée des lignes de contour assez généralisées.
fdetsch
1
Si vous n'êtes pas prêt à resamplevos données à une résolution spatiale plus grossière, la seule solution que j'imagine alors serait de diviser vos données en plusieurs tuiles (par exemple 16 sous-rasters), puis de les exécuter rasterToContoursur chaque tuile séparément de manière itérative et , enfin, mergeles fichiers de formes résultants en un seul fichier de formes énorme. Si vous êtes intéressé, le package Rsenal de notre groupe de travail offre une fonction appelée splitRasterpour créer plusieurs sous-rasters à partir d'un seul raster énorme.
fdetsch
2

Bien que je sois un grand fan de GDAL, l'outil de polygonisation était également trop lent pour mes applications.

Une alternative rapide est gdal_trace_outlinedes scripts Dans GDAL qui ont également plus d'options concernant la tolérance, les beignets, etc.

De gdal_polygonizecette façon, vous obtenez également des polygones avec lesquels vous devrez ensuite convertir ogr2ogr -nlt MULTILINESTRING.

L'inconvénient est que vous devez le compiler vous-même, sauf si vous êtes sur un système Linux ou Mac OsX.

Kersten
la source
Malheureusement, il a échoué avec le message d'erreur: "Erreur de segmentation (core dumped)". Je suppose que mon fichier est trop gros ou plus précis, il produira trop de petits polygones.
Generic Wevers