Tôi có một hình dạng đường lớn (~ 70 MB) và muốn chuyển đổi nó thành một raster với mật độ đường trong mỗi ô. Lý tưởng nhất là tôi muốn làm điều này trong R cùng với các công cụ dòng lệnh GDAL nếu cần thiết.
Cách tiếp cận ban đầu của tôi là tính trực tiếp độ dài của các đoạn đường trong mỗi ô theo luồng này . Điều này tạo ra kết quả mong muốn, nhưng khá chậm ngay cả đối với các shapefile nhỏ hơn nhiều so với của tôi. Đây là một ví dụ rất đơn giản mà các giá trị ô chính xác là rõ ràng:
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
Có vẻ tốt, nhưng không thể mở rộng! Trong một vài câu hỏi khác, spatstat::density.psp()
chức năng đã được đề xuất cho nhiệm vụ này. Hàm này sử dụng cách tiếp cận mật độ nhân. Tôi có thể thực hiện nó và nó có vẻ nhanh hơn cách tiếp cận ở trên, nhưng tôi không rõ làm thế nào để chọn các tham số hoặc giải thích kết quả. Dưới đây là ví dụ trên sử dụng 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
Tôi nghĩ rằng đó có thể là trường hợp phương pháp nhân tính toán mật độ trái ngược với chiều dài trên mỗi ô, vì vậy tôi đã chuyển đổi:
# 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
Nhưng, trong cả hai trường hợp, cách tiếp cận kernel có gần với việc liên kết với cách tiếp cận trực tiếp hơn ở trên không.
Vì vậy, câu hỏi của tôi là:
- Làm thế nào tôi có thể giải thích đầu ra của
density.psp
chức năng? Các đơn vị là gì? - Làm cách nào tôi có thể chọn
sigma
tham sốdensity.psp
để kết quả phù hợp với cách tiếp cận trực tiếp, trực quan hơn ở trên? - Tiền thưởng: mật độ dòng nhân thực sự đang làm gì? Tôi có một số ý nghĩa về cách các phương pháp này hoạt động cho các điểm, nhưng không thấy cách nó mở rộng ra các dòng.