J'extrais la superficie et le pourcentage de couverture de différents types d'utilisation des terres à partir d'un raster basé sur plusieurs milliers de limites de polygones. J'ai trouvé que la fonction d'extraction fonctionne beaucoup plus rapidement si j'itère à travers chaque polygone individuel et recadre puis masque le raster jusqu'à la taille du polygone particulier. Néanmoins, c'est assez lent, et je me demande si quelqu'un a des suggestions pour améliorer l'efficacité et la vitesse de mon code.
La seule chose que j'ai trouvée à ce sujet est cette réponse de Roger Bivand qui a suggéré d'utiliser GDAL.open()
et GDAL.close()
ainsi que getRasterTable()
et getRasterData()
. J'ai étudié ces problèmes, mais j'ai eu des problèmes avec gdal dans le passé et je ne le connais pas assez bien pour savoir comment le mettre en œuvre.
Exemple reproductible:
library(maptools) ## For wrld_simpl
library(raster)
## Example SpatialPolygonsDataFrame
data(wrld_simpl) #polygon of world countries
bound <- wrld_simpl[1:25,] #name it this to subset to 25 countries and because my loop is set up with that variable
## Example RasterLayer
c <- raster(nrow=2e3, ncol=2e3, crs=proj4string(wrld_simpl), xmn=-180, xmx=180, ymn=-90, ymx=90)
c[] <- 1:length(c)
#plot, so you can see it
plot(c)
plot(bound, add=TRUE)
Méthode la plus rapide à ce jour
result <- data.frame() #empty result dataframe
system.time(
for (i in 1:nrow(bound)) { #this is the number of polygons to iterate through
single <- bound[i,] #selects a single polygon
clip1 <- crop(c, extent(single)) #crops the raster to the extent of the polygon, I do this first because it speeds the mask up
clip2 <- mask(clip1,single) #crops the raster to the polygon boundary
ext<-extract(clip2,single) #extracts data from the raster based on the polygon bound
tab<-lapply(ext,table) #makes a table of the extract output
s<-sum(tab[[1]]) #sums the table for percentage calculation
mat<- as.data.frame(tab)
mat2<- as.data.frame(tab[[1]]/s) #calculates percent
final<-cbind(single@data$NAME,mat,mat2$Freq) #combines into single dataframe
result<-rbind(final,result)
})
user system elapsed
39.39 0.11 39.52
Traitement parallèle
Le traitement parallèle a réduit de moitié le temps de l'utilisateur, mais a annulé l'avantage en doublant le temps système. Raster l'utilise pour la fonction d'extrait, mais malheureusement pas pour la fonction de recadrage ou de masque. Malheureusement, cela laisse un peu plus de temps total écoulé en raison de «l'attente» par le «IO».
beginCluster( detectCores() -1) #use all but one core
exécuter du code sur plusieurs cœurs:
user system elapsed
23.31 0.68 42.01
puis terminez le cluster
endCluster()
Méthode lente: la méthode alternative de faire un extrait directement à partir de la fonction raster prend beaucoup plus de temps, et je ne suis pas sûr de la gestion des données pour les mettre sous la forme que je veux:
system.time(ext<-extract(c,bound))
user system elapsed
1170.64 14.41 1186.14