我有一个很大的道路图形文件(约70MB),并希望将其转换为每个单元格中具有道路密度的栅格。理想情况下,如有必要,我想在R中与GDAL命令行工具一起使用。
我最初的方法是按照此线程直接计算每个单元格中线段的长度。这样可以产生所需的结果,但是即使对于比我的小得多的shapefile也非常慢。这是一个非常简单的示例,其正确的单元格值显而易见:
require(sp)
require(raster)
require(rgeos)
require(RColorBrewer)
# Create some sample lines
l1 <- Lines(Line(cbind(c(0,1),c(.25,0.25))), ID="a")
l2 <- Lines(Line(cbind(c(0.25,0.25),c(0,1))), ID="b")
sl <- SpatialLines(list(l1,l2))
# Function to calculate lengths of lines in given raster cell
lengthInCell <- function(i, r, l) {
r[i] <- 1
rpoly <- rasterToPolygons(r, na.rm=T)
lc <- crop(l, rpoly)
if (!is.null(lc)) {
return(gLength(lc))
} else {
return(0)
}
}
# Make template
rLength <- raster(extent(sl), res=0.5)
# Calculate lengths
lengths <- sapply(1:ncell(rLength), lengthInCell, rLength, sl)
rLength[] <- lengths
# Plot results
spplot(rLength, scales = list(draw=TRUE), xlab="x", ylab="y",
col.regions=colorRampPalette(brewer.pal(9, "YlOrRd")),
sp.layout=list("sp.lines", sl),
par.settings=list(fontsize=list(text=15)))
round(as.matrix(rLength),3)
#### Results
[,1] [,2]
[1,] 0.5 0.0
[2,] 1.0 0.5
看起来不错,但无法缩放!在其他几个问题中,spatstat::density.psp()
建议将该功能用于此任务。此函数使用内核密度方法。我能够实现它,它似乎比上述方法快,但是我不清楚如何选择参数或解释结果。这是上面的示例,使用density.psp()
:
require(spatstat)
require(maptools)
# Convert SpatialLines to psp object using maptools library
pspSl <- as.psp(sl)
# Kernel density, sigma chosen more or less arbitrarily
d <- density(pspSl, sigma=0.01, eps=0.5)
# Convert to raster
rKernDensity <- raster(d)
# Values:
round(as.matrix(rKernDensity),3)
#### Results
[,1] [,2]
[1,] 0.100 0.0
[2,] 0.201 0.1
我认为内核方法可能会计算密度而不是每个单元格的长度,因此我进行了转换:
# Convert from density to length per cell for comparison
rKernLength <- rKernDensity * res(rKernDensity)[1] * res(rKernDensity)[2]
round(as.matrix(rKernLength),3)
#### Results
[,1] [,2]
[1,] 0.025 0.000
[2,] 0.050 0.025
但是,无论哪种情况,内核方法都无法与上述更直接的方法保持一致。
因此,我的问题是:
- 如何解释
density.psp
函数的输出?单位是多少? - 如何选择
sigma
参数,density.psp
使结果与上面更直接,直观的方法保持一致? - 奖励:内核线密度实际上是做什么的?我对这些方法如何适用于点有一定的了解,但看不到它如何延伸到线。