Çekirdek yoğunluğunu kullanarak R'deki yol yoğunluğunu hesaplamak? [kapalı]


13

Yolların büyük bir (~ 70MB) şekil dosyası var ve bunu her hücrede yol yoğunluğu olan bir raster dönüştürmek istiyorum. İdeal olarak bunu GDAL komut satırı araçlarıyla birlikte R'de yapmak istiyorum.

İlk yaklaşımım, bu iş parçacığına göre her bir hücredeki çizgi parçalarının uzunluklarını doğrudan hesaplamaktı . Bu istenen sonuçları üretir, ancak benimkinden çok daha küçük şekil dosyaları için bile oldukça yavaştır. Doğru hücre değerlerinin açık olduğu çok basitleştirilmiş bir örnek:

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

Imgur

İyi görünüyor, ancak ölçeklenebilir değil! Diğer birkaç soruda spatstat::density.psp()bu görev için işlev önerilmiştir. Bu işlev bir çekirdek yoğunluğu yaklaşımı kullanır. Bunu uygulayabiliyorum ve yukarıdaki yaklaşımdan daha hızlı görünüyor, ancak parametreleri nasıl seçeceğimizi veya sonuçları nasıl yorumlayacağımı bilmiyorum. Yukarıdaki örnek şöyledir 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

Çekirdek yaklaşımının yoğunluğu hücre başına uzunluk yerine hesapladığını düşündüm, bu yüzden dönüştürdüm:

# 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

Ancak, her iki durumda da, çekirdek yaklaşımı yukarıdaki daha doğrudan yaklaşımla hizalanmaya yaklaşmaz.

Yani, sorularım:

  1. density.pspFonksiyonun çıktısını nasıl yorumlayabilirim ? Birimler nelerdir?
  2. Sonuçları yukarıdaki daha doğrudan, sezgisel bir yaklaşımla hizalanacak şekilde sigmaparametreyi nasıl seçebilirim density.psp?
  3. Bonus: Çekirdek çizgi yoğunluğu gerçekte ne yapıyor? Bu yaklaşımların puanlar için nasıl çalıştığına dair bir fikrim var, ama bunun çizgilere nasıl yayıldığını görmüyorum.

Yanıtlar:


8

Bu soruyu R-sig-Geo listerv'e gönderdim ve spatstats yazarlarından Adrian Baddeley'den yararlı bir cevap aldım . Burada, gelecek kuşaklara yönelik tepkisini yorumlayacağım.

Adrian, işlevin görevimle spatstat::pixellate.psp()daha iyi eşleştiğini belirtiyor . Bu fonksiyon, çizgi segmenti desenini (veya SpatialLinesdönüştürmeli nesneyi) piksel görüntüsüne (veya RasterLayerdönüştürmeyle) dönüştürür; burada her hücredeki değer, o hücreden geçen çizgi segmentlerinin uzunluğudur. Tam olarak aradığım şey!

Ortaya çıkan görüntünün çözünürlüğü eps, dimyxparametreleri (satır ve sütun sayısı) ayarlayan parametre veya parametre ile tanımlanabilir .

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

Sonuçlar aynen istendiği gibidir.

Adrian da hakkındaki sorularıma cevap verdi spatstat::density.psp(). Bu işlevi şöyle açıklıyor:

Gauss çekirdeğinin kıvrımlarını çizgilerle hesaplar. Sezgisel olarak, bu density.psp, çizgileri iki boyutlu uzaya 'bulaştıran' anlamına gelir . Yani density(L)bulanık bir versiyonu gibi pixellate(L). Aslında bir görüntüyü bulanıklaştıran başka bir fonksiyonun bulunduğu yere density(L)çok benzer . [Parametre] Gauss çekirdeğinin bant genişliğidir. Belirli bir piksel u'daki değeri, piksel u'nun etrafındaki yarıçap sigma çemberi içindeki toplam çizgi uzunluğu miktarı gibi bir şeydir, ancak farklı daire yarıçaplarından bu tür katkıların ağırlıklı ortalamasıdır. Birimler uzunluk ^ (- 1), yani birim alan başına satır uzunluğudur. blur(pixellate(L))blurspatstatsigmadensity.psp(L)

Gauss çekirdeği yaklaşımının, density.psp()hat uzunluklarını doğrudan hesaplamanın daha sezgisel yaklaşımı karşısında ne zaman tercih edileceği bana biraz açık değil pixellate(). Sanırım bunu uzmanlara bırakmak zorunda kalacağım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.