How can I speed up extraction of the proportion of land cover types in a buffer from a raster?
Asked Answered
O

1

6

I would like to extract spatial data in a buffer of 10 km around 30 000 objects of class SpatialLines and calculate proportion of each land cover type around buffered lines. In a first time, I used the function crop to crop my raster. Then, I used the function extract (package raster) to calculate proportion of 10 land cover types. Here is my code:

lapply(1:nrow(tab_lines), FUN=function(k){

First step: to build a buffer of 10 km around the line

buf_line <- gBuffer(seg_line[k], width=10000) ## seg_line =  Lines objects

Second step: to extract land cover types in the buffer from the raster

ha <-extract(x=data_raster,y=buf_line)

Third step: to calculate proportion of 10 land cover types

The proportion of each land cover type must be in columns (one column = one land cover type)

    ha_1 <-length(ha[[1]][ha[[1]]==1])/length(ha[[1]])
    ha_2 <-length(ha[[1]][ha[[1]]==2])/length(ha[[1]])
    ha_3 <-length(ha[[1]][ha[[1]]==3])/length(ha[[1]])
    ha_4 <-length(ha[[1]][ha[[1]]==4])/length(ha[[1]])
    ha_5 <-length(ha[[1]][ha[[1]]==5])/length(ha[[1]])
    ha_6 <-length(ha[[1]][ha[[1]]==6])/length(ha[[1]])
    ha_7 <-length(ha[[1]][ha[[1]]==7])/length(ha[[1]])
    ha_8 <-length(ha[[1]][ha[[1]]==8])/length(ha[[1]])
    ha_9 <-length(ha[[1]][ha[[1]]==9])/length(ha[[1]])
    ha_10 <-length(ha[[1]][ha[[1]]==10])/length(ha[[1]])

     return(cbind(ha_1, ha_2, ha_3, ha_4, ha_5, ha_6, ha_7, ha_8, ha_9, ha_10))  
    })

How can I speed up the processing time for 30 000 spatial lines? Is there any other packages in R that can provide faster processing for this type of extraction ?

Obligor answered 7/12, 2015 at 21:12 Comment(2)
The reason your code is slow is because it's inspecting all cells of the landcover grid, in case they overlap with the buffer. To speed it up you should create a subset of the grid matching the extent of the buffer you're inspecting at that point. If you put up some sample data it would be easier for someone to help you. GRASS (specifically <grass.osgeo.org/grass64/manuals/r.stats.html>) would work well and you can connect it to R. An example is here: <scottishsnow.wordpress.com/2014/08/24/many-rastered-beast>.Piero
scottishsnow.wordpress.com/2014/08/24/many-rastered-beastMariehamn
C
5

Here is a more concise formulation

library(raster)
library(rgeos)

buf_line <- gBuffer(seg_line, width=10000, byid=TRUE)
ha <- extract(x=data_raster, y=buf_line)
h <- sapply(ha, function(x) tabulate(x, 10))
h <- h / colSums(h)

But I do not think this will be much faster. Instead of extract you could try sp::over

Depending on your computer, things might speed up by first running

beginCluster()
Crt answered 7/12, 2015 at 22:17 Comment(2)
That is not what your question suggests. It that is the case you should ask a better question.Crt
I would like to test the function beginCluster() to paralellize the task. In my case, I suppose that the function should have the structure: beginCluster() extract(data_raster , y=buf_line) ha_1 <-length(ha[[1]][ha[[1]]==1])/length(ha[[1]]) ... tab_prop <- cbind(ha_1, ha_2, ha_3, ha_4, ha_5, ha_6, ha_7, ha_8, ha_9, ha_10) endCluster(). But I don't know how to paralellize the 30 000 lines with beginCluster() ?Obligor

© 2022 - 2024 — McMap. All rights reserved.