เครื่องมือโมเดล Gravity / Huff


26

ฉันกำลังมองหาวิธีจำลองโมเดลแรงโน้มถ่วงโดยใช้เลเยอร์แบบอิงจุด

คะแนนของฉันทั้งหมดได้รับการกำหนดค่า z และยิ่งค่านี้ยิ่งสูง อิทธิพลนี้แปรผกผันกับระยะทางไปยังศูนย์กลาง

มันเป็นรูปแบบ Huff ทั่วไปแต่ละจุดเป็นค่าสูงสุดในท้องถิ่นและหุบเขาระหว่างพวกเขาบ่งบอกถึงขอบเขตของเขตอิทธิพลระหว่างพวกเขา

ฉันลองอัลกอริทึมหลายอย่างจาก Arcgis (IDW, การจัดสรรต้นทุน, การแก้ไขโพลิโนเมียล) และ QGIS (ปลั๊กอิน heatmap) แต่ฉันไม่พบสิ่งใดที่สามารถช่วยฉันได้ ฉันพบเธรดนี้ด้วย แต่ก็ไม่เป็นประโยชน์สำหรับฉัน

เป็นอีกทางเลือกหนึ่งฉันสามารถสร้างความพึงพอใจให้กับวิธีการสร้างไดอะแกรม Voronoi หากมีวิธีที่จะมีผลต่อขนาดของแต่ละเซลล์ด้วยค่า z ของจุดที่สอดคล้องกัน

คำตอบ:


13

นี่คือฟังก์ชั่น QGIS หลามเล็กน้อยที่ใช้สิ่งนี้ มันต้องการปลั๊กอิน rasterlang (พื้นที่เก็บข้อมูลจะต้องถูกเพิ่มลงใน QGIS ด้วยตนเอง)

โดยคาดว่าจะมีสามพารามิเตอร์ที่จำเป็น: เลเยอร์จุด, เลเยอร์แรสเตอร์ (เพื่อกำหนดขนาดและความละเอียดของเอาต์พุต) และชื่อไฟล์สำหรับเลเยอร์เอาท์พุท นอกจากนี้คุณยังสามารถระบุอาร์กิวเมนต์ที่เป็นทางเลือกเพื่อกำหนดเลขชี้กำลังของฟังก์ชันการลดระยะทาง

น้ำหนักของคะแนนต้องอยู่ในคอลัมน์แอตทริบิวต์แรกของเลเยอร์คะแนน

แรสเตอร์ที่ได้จะถูกเพิ่มไปยัง Canvas โดยอัตโนมัติ

นี่คือตัวอย่างของวิธีการเรียกใช้สคริปต์ คะแนนมีน้ำหนักระหว่าง 20 ถึง 90 และตารางมีขนาด 60 ถึง 50 หน่วยในแผนที่

points = qgis.utils.iface.mapCanvas().layer(0)
raster = qgis.utils.iface.mapCanvas().layer(1)
huff(points,raster,"output.tiff",2)

from rasterlang.layers import layerAsArray
from rasterlang.layers import writeGeoTiff
import numpy as np

def huff(points, raster, outputfile, decay=1):
    if points.type() != QgsMapLayer.VectorLayer:
        print "Error: First argument is not a vector layer (but it has to be)"
        return
    if raster.type() != QgsMapLayer.RasterLayer:
        print "Error: Second argument is not a raster layer (but it has to be)"
        return
    b = layerAsArray(raster)
    e = raster.extent()
    provider = points.dataProvider()
    extent = [e.xMinimum(),e.yMinimum(),e.xMaximum(),e.yMaximum()]
    xcols = np.size(layerAsArray(raster),1)
    ycols = np.size(layerAsArray(raster),0)
    xvec = np.linspace(extent[0], extent[2], xcols, endpoint=False)
    xvec = xvec + (xvec[1]-xvec[0])/2
    yvec = np.linspace(extent[3], extent[1], ycols, endpoint=False)
    yvec = yvec + (yvec[1]-yvec[0])/2
    coordArray = np.meshgrid(xvec,yvec)
    gravity = b
    point = QgsFeature()
    provider.select( provider.attributeIndexes() )
    while provider.nextFeature(point):
      coord = point.geometry().asPoint()
      weight = point.attributeMap()[0].toFloat()[0]
      curGravity = weight * ( (coordArray[0]-coord[0])**2 + (coordArray[1]-coord[1])**2)**(-decay/2)
      gravity = np.dstack((gravity, curGravity))
    gravitySum = np.sum(gravity,2)
    huff = np.max(gravity,2)/gravitySum
    np.shape(huff) 
    writeGeoTiff(huff,extent,outputfile)
    rlayer = QgsRasterLayer(outputfile)
    QgsMapLayerRegistry.instance().addMapLayer(rlayer)

3
(+1) วิธีการดูดี แต่ทำไมคุณจะใช้รากและ re-ตารางในการคำนวณcurGravity? นั่นเป็นการเสียเวลาในการคำนวณ การคำนวณที่สูญเปล่าอีกชุดหนึ่งเกี่ยวข้องกับการทำให้กริด "แรงโน้มถ่วง" เป็นปกติทั้งหมดก่อนที่จะหาค่าสูงสุด: หาค่าสูงสุดและทำให้เป็นมาตรฐานด้วยผลรวม
whuber

นั่นไม่ได้ยกกำลังสองเศษส่วนทั้งหมดใช่ไหม
lynxlynxlynx

1
เจคคุณยังไม่ต้องการรากที่สอง: เพียงแค่ลืมมันไปเลยและใช้เลขชี้กำลังที่ตั้งใจครึ่งหนึ่ง กล่าวอีกนัยหนึ่งถ้าzเป็นผลรวมของกำลังสองของความแตกต่างพิกัดแทนการคำนวณ (sqrt (z)) ^ p ซึ่งเป็นสองการดำเนินการที่มีราคาแพงปานกลางเพียงแค่คำนวณ z ^ (p / 2) ซึ่ง (เพราะ p / 2 เป็นหมายเลขที่คำนวณล่วงหน้าแล้ว) เป็นเพียงการดำเนินการแบบแรสเตอร์เดียวและนำไปสู่โค้ดที่ชัดเจนยิ่งขึ้น แนวคิดนี้มาก่อนเมื่อคุณใช้แบบจำลองแรงโน้มถ่วงตามที่ตั้งใจไว้เดิมคือเวลาในการเดินทาง ไม่มีสูตรรากที่สองอีกต่อไปดังนั้นคุณจึงเพิ่มเวลาในการเดินทางไปที่กำลัง -p / 2
whuber

ขอบคุณมากดูเหมือนว่าสิ่งที่ฉันต้องการ เพียงแค่มีปัญหาฉันไม่คุ้นเคยกับงูหลามและฉันไม่เคยใช้ส่วนขยาย Rasterlang ฉันติดตั้งในรุ่น QGIS ของฉัน แต่ฉันติดอยู่กับ "ข้อผิดพลาดทางไวยากรณ์" ฟังก์ชั่นของคุณมีการใช้งานในส่วนขยาย rasterlang หรือไม่ ถ้าไม่ฉันจะทำอย่างไร ขอบคุณสำหรับความช่วยเหลือของคุณ! http://i.imgur.com/NhiAe9p.png
ดาเมีย

1
@ เจค: ตกลงฉันคิดว่าฉันเริ่มเข้าใจวิธีการทำงานของคอนโซล ฉันทำตามที่คุณพูดและดูเหมือนว่ารหัสจะเข้าใจอย่างถูกต้อง ตอนนี้ฉันมีข้อผิดพลาดอื่นที่เกี่ยวข้องกับแพคเกจหลาม "shape_base.py" QGIS ของฉันติดตั้งขาดคุณสมบัติบางอย่างหรือไม่? http://i.imgur.com/TT0i2Cl.png
ดาเมีย
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.