У мене є великий (~ 70 Мб) файл форм доріг і хочу перетворити це на растр із щільністю дороги в кожній комірці. В ідеалі я хотів би зробити це в R разом з інструментами командного рядка GDAL, якщо це необхідно.
Мій початковий підхід полягав у тому, щоб безпосередньо обчислити довжини відрізків рядків у кожній комірці відповідно до цієї нитки . Це дає бажані результати, але є досить повільним навіть для форм-файлів, значно менших за мої. Ось дуже спрощений приклад, для якого правильні значення комірок очевидні:
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
щоб результати узгоджувались з більш прямим, інтуїтивним підходом вище? - Бонус: чим насправді займається щільність лінії ядра? Я маю певне розуміння того, як ці підходи працюють для балів, але не бачу, як це поширюється на рядки.