การหารูปหลายเหลี่ยมโดยทางโปรแกรม> 90% ซ้อนทับโดยชั้นรูปหลายเหลี่ยมเวกเตอร์อื่นโดยใช้ QGIS?


9

เลเยอร์ตัวอย่าง

ฉันพยายามหาวิธีใช้ python เพื่อแยกรูปหลายเหลี่ยมในเวกเตอร์หนึ่งที่ซ้อนทับด้วย> 90% โดยเวกเตอร์อื่น ฉันต้องการมีเวกเตอร์ / แผนที่ที่จะแสดงรูปหลายเหลี่ยมเหล่านั้นเท่านั้น ภาพตัวอย่างแสดงเลเยอร์ของฉัน ฉันต้องการรูปหลายเหลี่ยมสีเทาทั้งหมดที่> แดง 90%

ฉันต้องทำสิ่งนี้ผ่านทาง python (หรือวิธีการแบบอัตโนมัติในทำนองเดียวกัน) ฉันมีแผนที่ประมาณ 1,000 แผนที่เพื่อดำเนินการในลักษณะเดียวกัน


คุณต้องการที่จะทำการซ้อนทับ 'union' (ดูinfogeoblog.wordpress.com/2013/01/08/geo-processing-in-qgisสำหรับพื้นฐานบางอย่าง) จากนั้นสำหรับรูปหลายเหลี่ยมเดิมแต่ละอันจะคำนวณสถิติ 'ใน' และ 'ออก' gis.stackexchange.com/questions/43037/ …เพื่อกำหนดเปอร์เซ็นต์การซ้อนทับ ... เคล็ดลับ : คุณต้องมีการวัดพื้นที่gis.stackexchange.com/questions/23355/…
Michael Stimson

ขอบคุณสำหรับเคล็ดลับ นั่นเป็นวิธีเดียวกับที่ฉันพยายาม ฉันสามารถทำสหภาพผ่านคอนโซลหลามได้ง่ายพอ เพิ่มไปแล้วในค่าคุณสมบัติพื้นที่ เป็นขั้นตอนต่อไปที่ฉันไม่แน่ใจ ฉันจะใช้ไพ ธ อนเพื่อคำนวณสถิติ 'ใน' และ 'ออก' เพื่อให้ฉันสามารถระบุ / เลือก / คลิปเป็นต้น 90% ของรูปหลายเหลี่ยมได้อย่างไร
ผิดปกติ

ฉันคิดว่ามันเป็นไปได้โดยไม่ต้องหลาม คุณต้องการไพทอนอย่างสมบูรณ์หรือโซลูชันที่มีเลเยอร์เสมือนนั้นดีสำหรับคุณหรือไม่?
Pierma

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

1
Pierma - ฉันต้องการวิธีอัตโนมัติในการค้นหารูปหลายเหลี่ยม
ผิดปกติ

คำตอบ:


3

รหัสต่อไปทำงานได้ใน Python Console ของ QGIS มันสร้างเลเยอร์หน่วยความจำที่มีรูปหลายเหลี่ยมซึ่งมากกว่า 90% ซ้อนทับกันด้วยพื้นที่สีแดง

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

#for polygon_intersects
feats_lyr1 = [ feat for feat in layers[0].getFeatures() ]

#for xwRcl
feats_lyr2 = [ feat for feat in layers[1].getFeatures() ]

selected_feats = []

for i, feat1 in enumerate(feats_lyr1):
    area1 = 0
    area2 = 0
    for j, feat2 in enumerate(feats_lyr2):
        if feat1.geometry().intersects(feat2.geometry()):
            area = feat1.geometry().intersection(feat2.geometry()).area()
            print i, j, area, feat2.attribute('class')
            if feat2.attribute('class') == 1:
                area1 += area
            else:
                area2 += area
    crit = area1/(area1 + area2)
    print crit
    if crit > 0.9:
        selected_feats.append(feat1)

epsg = layers[0].crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           "mem_layer",
                           "memory")

prov = mem_layer.dataProvider()

for i, feat in enumerate(selected_feats):
    feat.setAttributes([i])

prov.addFeatures(selected_feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

ฉันลองใช้โค้ดกับเลเยอร์เวกเตอร์สองตัวนี้:

ป้อนคำอธิบายรูปภาพที่นี่

หลังจากรันโค้ดที่ Python Console ของ QGIS เพื่อผลลัพธ์การยืนยันมีการพิมพ์ดัชนี i, j ของคุณสมบัติที่เกี่ยวข้อง, พื้นที่ทางแยก, แอตทริบิวต์ของฟิลด์ในpolygons_intersects (1 สำหรับพื้นที่สีแดงและ 2 สำหรับพื้นที่สีเทา) และเกณฑ์ที่ทับซ้อนกัน .

0 0 9454207.56892 1
0 1 17429206.7906 2
0 2 10326705.2376 2
0 4 40775341.6814 1
0 5 26342803.0964 2
0 7 11875753.3216 2
0.432253120382
1 6 1198411.02558 2
1 7 1545489.96614 2
1 10 27511427.9909 1
0.90930850584
2 7 750262.940888 2
2 8 12012343.5859 1
0.941213972294
3 6 23321277.5158 2
0.0

เลเยอร์หน่วยความจำที่สร้างขึ้น (คุณสมบัติสีเขียว) สามารถดูได้ในภาพถัดไป มันเป็นไปตามที่คาดไว้

ป้อนคำอธิบายรูปภาพที่นี่


6

นี่คือวิธีการแก้ปัญหาที่ไม่ต้องใช้งูหลาม

เพิ่มเลเยอร์เสมือนใหม่ด้วยข้อความค้นหาเช่น:

WITH r AS (
SELECT 
    Basins800.rowid AS idGray, 
    area(Basins800.geometry) AS areaGray, 
    area(Intersection(Basins800.geometry, Severity.geometry)) AS aeraInter, 
    Basins800.geometry AS geomGray 
  FROM Basins800, Severity
)

SELECT *, areaInterSum/areaGray  AS overlap , geomGray 
    FROM (
        SELECT 
           idGray, 
           areaGray, 
           sum(areaInter) AS areaInterSum, 
           geomGray 
        FROM r 
        GROUP BY idGray) 
     WHERE areaInterSum/areaGray > 0.9

ด้วย:

  • Basins800 เป็นเลเยอร์ของคุณคุณต้องการตัวกรองที่มีรูปหลายเหลี่ยมสีเทา

  • ความรุนแรง: ชั้นสีแดงของคุณทับซ้อนกัน

ผลลัพธ์จะเป็นเลเยอร์ใหม่ที่มีรูปหลายเหลี่ยมสีเทาทั้งหมด> 90% ที่ทับซ้อนกันด้วยรูปหลายเหลี่ยมสีแดงที่มีเขตข้อมูลใหม่ที่มีเปอร์เซ็นต์การทับซ้อน

ป้อนคำอธิบายรูปภาพที่นี่

หวังว่างานนี้ ฉันสามารถเพิ่มรายละเอียดเพิ่มเติมเกี่ยวกับแบบสอบถามหากจำเป็น

หมายเหตุ: ข้อมูลของคุณมีรูปหลายเหลี่ยมขนาดเล็กมาก (มาจากการประมวลผลแบบแรสเตอร์ของคุณและสอดคล้องกับพิกเซลแบบแรสเตอร์ (ในภาพเราจะเห็นรูปหลายเหลี่ยม 4 รูป แต่มีรูปหลายเหลี่ยมขนาดเล็กอีก 25) สิ่งนี้ทำให้แบบสอบถามทำงานช้ามาก สร้างหนึ่งคุณลักษณะสำหรับแต่ละฟีเจอร์จากสองเลเยอร์)


ฉันได้รับข้อผิดพลาดเมื่อฉันเรียกใช้แบบสอบถามผ่านปุ่ม 'สร้างเลเยอร์เสมือน' "ข้อผิดพลาดในการประมวลผลข้อความค้นหา CREATE TEMP VIEW _tview AS with r AS (" .... รหัสที่เหลือ ... ตามด้วย: "1 - ใกล้" With ": ข้อผิดพลาดทางไวยากรณ์" ฉันค่อนข้างใหม่กับ QGIS ฉันสามารถ สร้างเลเยอร์เสมือนนี้โดยทางโปรแกรมหรือไม่ขอบคุณสำหรับความช่วยเหลือของคุณ!
dnormous

นี่คือลิงค์สำหรับดาวน์โหลดไฟล์
รูปร่าง

ขออภัยสำเนาที่ไม่ดีระหว่างสีเทาและสีเทา (ขออภัยสำหรับภาษาอังกฤษที่ประมาณของฉัน) ฉันแก้ไขข้อความค้นหา ควรใช้งานได้แล้ว ทำไมคุณต้องการสร้างเลเยอร์อย่างเป็นทางการ? ข้อดีของเลเยอร์เสมือนคือมันไม่ทำลายและถ้าคุณแก้ไขข้อมูล (สีเทาหรือรูปหลายเหลี่ยมสีแดง) เลเยอร์เสมือนจะอัปเดตโดยอัตโนมัติ
Pierma

นี่เป็นกระบวนการเล็ก ๆ เพียงชิ้นเดียว ฉันมีแผนที่ประมาณ 1,000 รายการที่จะทำดังนั้นการดำเนินการอัตโนมัติจะเป็นประโยชน์อย่างยิ่ง
ผิดปกติ

ฉันยังคงได้รับข้อผิดพลาดเดิม -> "1 - ใกล้" กับ ": ข้อผิดพลาดทางไวยากรณ์" ฉันเสียบชื่อโลคัลสำหรับเลเยอร์แต่ละรายการสำหรับ grayLayer และ redLayer ชื่อท้องถิ่นที่ฉันควรใช้คืออะไร เช่น: เลเยอร์สีเทามีป้ายกำกับว่า "Basins_800" ดังนั้นฉันมีรหัสเช่น "Basins_800.geometry"
dnormous

2

หลังจากเห็นลิงก์ไปยังรูปร่างSeverityและBasins800ฉันสามารถเข้าใจกระบวนการทางภูมิศาสตร์ที่จำเป็น ฉันแก้ไขรหัสใน:

การหารูปหลายเหลี่ยมโดยทางโปรแกรม> 90% ซ้อนทับโดยชั้นรูปหลายเหลี่ยมเวกเตอร์อื่นโดยใช้ QGIS?

สำหรับการรับอันนี้:

mapcanvas = iface.mapCanvas()

layers = mapcanvas.layers()

#for Severity
feats_lyr1 = [ feat for feat in layers[0].getFeatures() ]

#for Basins800
feats_lyr2 = [ feat for feat in layers[1].getFeatures() ]

selected_feats = []

print "processing..."

for i, feat1 in enumerate(feats_lyr1):
    for j, feat2 in enumerate(feats_lyr2):
        if feat1.geometry().intersects(feat2.geometry()):
            area1 = feat1.geometry().intersection(feat2.geometry()).area()
            area2 = feat1.geometry().area()
            print i, j, area1, area2
    crit = area1/area2
    print crit
    if crit > 0.9:
        selected_feats.append(feat1)

epsg = layers[0].crs().postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           "mem_layer",
                           "memory")

prov = mem_layer.dataProvider()

for i, feat in enumerate(selected_feats):
    feat.setAttributes([i])

prov.addFeatures(selected_feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

หลังจากรันโค้ดด้วย shapefiles เหล่านี้ที่ Python Console ของ QGIS ในไม่กี่นาทีฉันก็ได้ผลลัพธ์ที่คล้ายกันกับPierma ; ที่หน่วยความจำเลเยอร์มี 31 คุณลักษณะ (แตกต่างจาก 29 รูปหลายเหลี่ยมได้โดยเขา)

ป้อนคำอธิบายรูปภาพที่นี่

ฉันจะไม่ตรวจแก้จุดบกพร่องผลลัพธ์เนื่องจากมีการโต้ตอบกับคุณสมบัติ 1901 * 3528 = 6706728 อย่างไรก็ตามรหัสดูมีแนวโน้ม

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