使用核密度计算R中的道路密度?[关闭]


13

我有一个很大的道路图形文件(约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

但是,无论哪种情况,内核方法都无法与上述更直接的方法保持一致。

因此,我的问题是:

  1. 如何解释density.psp函数的输出?单位是多少?
  2. 如何选择sigma参数,density.psp使结果与上面更直接,直观的方法保持一致?
  3. 奖励:内核线密度实际上是做什么的?我对这些方法如何适用于点有一定的了解,但看不到它如何延伸到线。

Answers:


8

我将这个问题发布在R-sig-Geo列表服务器上,并从spatstats的作者之一Adrian Baddeley 那里获得了有用的答案。我将在后文中发表我对他的回应的解释。

Adrian指出,该功能spatstat::pixellate.psp()与我的任务更加匹配。此函数将线段图案(或SpatialLines带有转换的对象)转换为像素图像(或RasterLayer带转换的对象),其中每个单元格中的值是穿过该单元格的线段的长度。正是我想要的!

可以使用eps参数或dimyx参数定义结果图像的分辨率,该参数可以设置尺寸(行数和列数)。

require(sp)
require(raster)
require(maptools)
require(spatstat)

# 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))

# Convert SpatialLines to psp object using maptools library
pspSl <- as.psp(sl)
# Pixellate with resolution of 0.5, i.e. 2x2 pixels
px <- pixellate(pspSl, eps=0.5)
# This can be converted to raster as desired
rLength <- raster(px)
# Values:
round(as.matrix(rLength),3)

     [,1] [,2]
[1,]  0.5  0.0
[2,]  1.0  0.5

结果完全符合要求。

阿德里安还回答了我有关的问题spatstat::density.psp()。他解释说该功能:

用直线计算高斯核的卷积。直观上,这意味着density.psp将线“涂抹”到二维空间中。因此 density(L)就像的模糊版本pixellate(L)。其实density(L)是非常相似的blur(pixellate(L))地方blur是另一种spatstat是模糊的图像功能。[参数] sigma是高斯内核的带宽。density.psp(L)给定像素u 的值类似于像素u周围半径sigma的圆中的线长总量,只是它实际上是来自不同圆半径的此类贡献的加权平均值。单位是长度^(-1),即每单位面积的线长。

对于高斯核方法density.psp()优于直接计算线长度的更直观的方法,我还是不清楚pixellate()。我想我得把这留给专家们。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.