คำนวณความหนาแน่นของถนนใน R โดยใช้ความหนาแน่นเคอร์เนลหรือไม่ [ปิด]


13

ฉันมีรูปร่างถนนขนาดใหญ่ (~ 70MB) และต้องการแปลงเป็นแรสเตอร์ด้วยความหนาแน่นของถนนในแต่ละเซลล์ เป็นการดีที่ฉันต้องการทำสิ่งนี้ใน 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

Imgur

ดูดี แต่ไม่สามารถปรับขนาดได้! ในคำถามอื่น ๆ อีกสองสาม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. โบนัส: ความหนาแน่นของสายเคอร์เนลกำลังทำอะไรอยู่? ฉันมีความรู้สึกเกี่ยวกับวิธีการทำงานของวิธีการเหล่านี้สำหรับจุด แต่ไม่เห็นว่าสิ่งที่ขยายไปถึงเส้น

คำตอบ:


8

ฉันโพสต์คำถามนี้ในรายการบริการ R-sig-Geoและได้รับคำตอบที่เป็นประโยชน์จาก Adrian Baddeley หนึ่งในผู้เขียนspatstats ฉันจะโพสต์การตีความคำตอบของเขาที่นี่เพื่อลูกหลาน

เอเดรียนตั้งข้อสังเกตว่าฟังก์ชั่น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เป็นแบนด์วิดท์ของเคอร์เนล Gaussian ค่าของdensity.psp(L)ที่พิกเซล u ที่ระบุคือจำนวนความยาวบรรทัดทั้งหมดในวงกลมรัศมี sigma รอบพิกเซล u ยกเว้นว่าเป็นค่าเฉลี่ยถ่วงน้ำหนักของการมีส่วนร่วมดังกล่าวจากรัศมีวงกลมที่แตกต่างกันจริงๆ หน่วยมีความยาว ^ (- 1) คือความยาวบรรทัดต่อพื้นที่หน่วย

มันยังคงค่อนข้างไม่ชัดเจนกับฉันเมื่อวิธีการเคอร์เนลเสียนจะเป็นที่ต้องการมากกว่าวิธีการที่ง่ายขึ้นในการคำนวณความยาวสายโดยตรงในdensity.psp() pixellate()ฉันเดาว่าฉันต้องทิ้งไว้ให้ผู้เชี่ยวชาญ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.