J'ai un grand fichier de formes (~ 70 Mo) de routes et je souhaite le convertir en un raster avec une densité de route dans chaque cellule. Idéalement, je voudrais le faire en R avec les outils de ligne de commande GDAL si nécessaire.
Mon approche initiale était de calculer directement les longueurs des segments de ligne dans chaque cellule selon ce fil . Cela produit les résultats souhaités, mais est assez lent, même pour des fichiers de formes beaucoup plus petits que le mien. Voici un exemple très simplifié pour lequel les valeurs de cellule correctes sont évidentes:
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
Semble bon, mais pas évolutif! Dans quelques autres questions, la spatstat::density.psp()
fonction a été recommandée pour cette tâche. Cette fonction utilise une approche de densité du noyau. Je suis capable de l'implémenter et cela semble plus rapide que l'approche ci-dessus, mais je ne sais pas comment choisir les paramètres ou interpréter les résultats. Voici l'exemple ci-dessus en utilisant 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
J'ai pensé que cela pourrait être le cas si l'approche du noyau calcule la densité plutôt que la longueur par cellule, j'ai donc converti:
# 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
Mais, dans aucun des cas, l'approche du noyau ne se rapproche de l'approche plus directe ci-dessus.
Donc, mes questions sont:
- Comment puis-je interpréter la sortie de la
density.psp
fonction? Quelles sont les unités? - Comment puis-je choisir le
sigma
paramètre pourdensity.psp
que les résultats s'alignent sur l'approche plus directe et intuitive ci-dessus? - Bonus: que fait réellement la densité de la ligne du noyau? J'ai une idée de la façon dont ces approches fonctionnent pour les points, mais je ne vois pas comment cela s'étend aux lignes.