เปอร์เซ็นต์ของรูปหลายเหลี่ยมในหนึ่งรูปร่างไฟล์ภายในรูปหลายเหลี่ยมของอีกรูปหนึ่ง


13

ฉันเป็นมือใหม่ขอโทษถ้าเห็นได้ชัด / ถูกถามและตอบแล้ว แต่ฉันไม่พบอะไรเลย

ฉันมีสองรูปร่างไฟล์: 1.เลเยอร์ขอบเขตการบริหารสำหรับเขตในสหราชอาณาจักรที่รู้จักกันในชื่อขอบเขต LSOA ที่มี 500 โซนเล็ก ๆ ในนั้น2.โซนน้ำท่วม

ฉันต้องการค้นหาว่าโซน LSOA ขนาดเล็กใดอยู่ในเขตน้ำท่วม flood50% และจบลงด้วยการใช่ / ไม่ใช่หรือ 1/0 สำหรับแต่ละโซน 500 LSOA

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

ฉันคิดว่านี่เป็นปัญหา SQL แต่ไม่รู้ ฉันใหม่กับ QGIS และไม่เคยใช้ PostgreSQL

ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชมอย่างมาก. ฉันสามารถให้ข้อมูลอะไรก็ได้ที่คุณคนที่น่ารักต้องการช่วยเหลือฉัน

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

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

คำตอบ:


12

นี่เป็นงานที่ค่อนข้างง่ายโดยใช้เครื่องมือการประมวลผลทางภูมิศาสตร์ที่รวมอยู่ใน QGIS

  1. คำนวณพื้นที่ของโซน LSOA ของคุณ

    • เปิดตารางแอตทริบิวต์ของเลเยอร์ LSOA
    • เปิดใช้งานโหมดแก้ไข
    • เปิดเครื่องคิดเลขภาคสนาม
    • สร้างเขตข้อมูลใหม่ประเภท "จำนวนทศนิยม (จริง)" ด้วยนิพจน์ "$ area"
    • ปิดใช้งานโหมดแก้ไข (บันทึกการแก้ไข)
  2. รวมเลเยอร์ของเขตน้ำท่วมไว้ในคุณลักษณะหลายส่วนเดียว

    • Vector > Geometry Tools > Singleparts to Multipart.
    • เลือก "--- ผสานทั้งหมด ---" สำหรับฟิลด์ ID ที่ไม่ซ้ำ
  3. ตัดเลเยอร์โซน LSOA ด้วยเลเยอร์โซนน้ำท่วมหลายส่วน

    • Vector > Geoprocessing Tools > Intersect.
    • เลเยอร์อินพุตคือโซน LSOA ตัดกันเลเยอร์คือโซนน้ำท่วม
  4. เลเยอร์ที่ได้จะเป็นส่วนของโซน LSOA (พร้อมคุณสมบัติจากชั้นโซน LSOA) ซึ่งซ้อนทับกับเลเยอร์โซนน้ำท่วม วิธีคำนวณสัดส่วนของแต่ละโซน LSOA ภายในเขตน้ำท่วม:

    • คำนวณพื้นที่ของคุณสมบัติที่ตัดกัน (เช่นในขั้นตอนที่ 1) จากนั้น
    • เพิ่มเขตข้อมูลอื่นหารพื้นที่ (ทั้งหมด) ดั้งเดิมด้วยพื้นที่ที่ตัดกัน ผลลัพธ์จะเป็นทศนิยมตั้งแต่ 0 ถึง 1 คูณด้วย 100 เพื่อให้เป็นเปอร์เซ็นต์
  5. เข้าร่วมเลเยอร์ LSOA ดั้งเดิมกับเลเยอร์ที่ตัดกันโดยใช้ ID ที่ไม่ซ้ำกันซึ่งแบ่งใช้โดยเลเยอร์ทั้งสอง

  6. ส่งออกเลเยอร์ที่รวมเป็นรูปร่างไฟล์ใหม่

  7. ลบแอตทริบิวต์ที่ทำซ้ำ

และอื่น ๆ !

หากไม่มีขั้นตอน # 2 คุณลักษณะแต่ละรายการจะถูกสร้างขึ้นสำหรับคุณลักษณะโซนน้ำท่วมแต่ละประเภทสำหรับแต่ละคุณสมบัติ LSOA นี่อาจไม่ใช่สิ่งที่คุณต้องการถ้าคุณสนใจเพียงแค่ความครอบคลุมทั้งหมดของแต่ละโซน LSOA หากคุณต้องการแยกความแตกต่างระหว่างการไหลของน้ำท่วม / Tidal / Pluvial (และข้อมูลเขตน้ำท่วมสนับสนุน) คุณสามารถแปลง singleparts เป็น multipart โดยระบุฟิลด์ "TYPE" เป็นฟิลด์ ID ที่ไม่ซ้ำกัน


ขอขอบคุณสำหรับความช่วยเหลือของคุณ! ชื่นชมมาก อย่างไรก็ตามฉันมีปัญหา ฉันทำตามขั้นตอนแล้ว ขั้นตอนที่ 3 การตัดใช้เวลา 10 ชั่วโมงจึงจะเสร็จสมบูรณ์และเมื่อเสร็จสิ้นทั้งหมดที่ฉันได้รับคือรูปร่างที่ว่างเปล่า: i.imgur.com/QIM6Gtg.png มีบางอย่างที่ฉันพลาดหรือไม่ ฉันพยายามทำกระบวนการให้เสร็จสิ้นและทำตามขั้นตอนที่ 4 แต่ไม่มีข้อมูลที่จะคำนวณพื้นที่ตัดกัน
KJGarbutt

ฉันเคยมีปัญหาในการตัดกับชั้นน้ำท่วมมาก่อน คุณสมบัติมีขนาดใหญ่และซับซ้อน วิธีที่ฉันเคยทำมาก่อนในอดีตคือการแบ่งพวกมันออกเป็นฟีเจอร์ที่เล็กลงดังนั้นดัชนีเชิงพื้นที่สามารถทำงานได้มากขึ้น เมื่อต้องการทำสิ่งนี้ให้สร้างกริดเวกเตอร์ในระดับเดียวกับเลเยอร์น้ำท่วม ( Vector > Research Tools > Vector Grid... Output grid as polygons) แล้วตัดกันกริดกับเลเยอร์น้ำท่วม จากนั้นใช้เอาต์พุตแทนที่จะเป็นเลเยอร์น้ำท่วมในขั้นตอนที่ 3 ฉันเดาว่าเหตุผลที่เลเยอร์นั้นว่างเปล่าเพราะมันล้มเหลว
Snorfalorpagus

ขอบคุณอีกครั้ง. ปัญหาเดียวในขณะนี้คือ QGIS หยุดทำงานทุกครั้งที่ฉันพยายามสร้างตารางเวกเตอร์ ฉันได้ทำตามคำแนะนำจากที่นี่แต่มันล้มเหลวทุกครั้ง ฉันได้เปลี่ยนพารามิเตอร์หลายครั้งและลองใช้รูปร่างแฟ้มเขตน้ำท่วมแทนการเปิดแฟ้มโครงการทั้งหมดของฉันและมันล้มเหลวทุกครั้ง ความคิดใด ๆ ! ภาพหน้าจอที่นี่
KJGarbutt

พารามิเตอร์ X และ Y ที่คุณระบุมีขนาดเล็กเกินไป ลองทำอะไรเช่น 1,000 x 1,000 คุณสามารถทำได้หลายครั้งเช่นทำ 5,000 x 5000 ก่อนใช้ผลลัพธ์เพื่อสร้าง 500 x 500 ดูคำตอบที่เกี่ยวข้องที่นี่: gis.stackexchange.com/a/66319/12420
Snorfalorpagus

ฉันเกือบจะแตกด้วยความช่วยเหลือของคุณ! อย่างไรก็ตามเมื่อฉันไปเข้าร่วมเลเยอร์ LSOA ดั้งเดิมกับเลเยอร์ที่ตัดกันฉันสูญเสียข้อมูลจำนวนมาก ฉันคิดว่ามันเป็นเพราะสี่เหลี่ยมกริดเวกเตอร์บางส่วนสร้างอยู่ในพื้นที่ LSOA เดียวกันและมีรหัส LSOA เหมือนกัน ดังนั้นฉันสิ้นสุดด้วยตัวเลข 2+ เปอร์เซ็นต์สำหรับแต่ละพื้นที่ LSOA เมื่อฉันเข้าร่วมและดูเหมือนว่าจะได้รับเพียงหนึ่งในนั้น มีวิธีการหาผลรวมเปอร์เซ็นต์สำหรับสี่เหลี่ยมกริดเวกเตอร์แต่ละอันด้วย LSOA เดียวกันหรือไม่
KJGarbutt

6

คุณสามารถใช้ spatialite และฟังก์ชัน SQL เชิงพื้นที่บางอย่างได้

Select t1.geometry, t1.ID, area(t1.geometry), area(t2.geometry) ...... (anything you need to have in the table results)

(area(intersection(t1.geometry,t2.geometry))) as "Commun_AREA"

, ("Commun_AREA"*100/(area(t1.geometry))) as "Percent_AREA"

From lsoa as t1, flood_zone as t2

Where Intersects( t1.geometry,t2.geometry ) = 1

3

ดูเหมือนว่าบางสิ่งที่สามารถทำได้ง่ายกว่าคำตอบที่ส่งมา ฉันจะใช้สคริปต์หลามแบบง่าย ๆ เป็นการส่วนตัว:

floodName = "the layer name here"
boundryName = "the layer name here"
fieldName = "the name of the field to contain the output 1/0"
minCoverage = 0.5 # the minimum amount of area covered to write 1
updateMap = [] # this will store values to be written    

# get layers
floodLayer = QgsMapLayerRegistry.instance().mapLayersByName(floodName)[0]
boundryLayer = QgsMapLayerRegistry.instance().mapLayersByName(boundryName)[0]
fieldIndex = boundryLayer.dataProvider().fieldNameIndex(fieldName)    

# iterate through boundries
for b in boundryLayer.getFeatures():
    # get only flood features that intersect with this feature's bounding box
    # this will make the script go way faster than it would otherwise
    request = QgsFeatureRequest().setFilterRect(b.geometry().boundingBox())
    floodGeom = geometry()
    floodFeat = QgsFeature()
    iter = floodLayer.getFeatures(request)
    iter.nextFeature(feat)
    while iter.nextFeature(feat):
        floodGeom = floodGeom.combine(feat.geometry())
    intersectGeom = b.geometry().intersection(feat.geometry())
    if intersectGeom.area() > minCoverage * b.geometry().area():
        updateMap[b.id()] = {fieldIndex : 1}
    else:
        updateMap[b.id()] = {fieldIndex : 0}

boundryLayer.dataProvider().changeAttributeValues(updateMap)

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


2

ฉันมีปัญหาเดียวกับ KJ ที่ปฏิบัติตามคำแนะนำของ Snorfalorpagus โดยใช้วิธี "Intersect" ในขั้นตอนที่ 3 มันใช้เวลาค่อนข้างนานในการคำนวณและสิ่งที่ฉันทิ้งไว้ว่างเปล่า

ฉันลองทำตามขั้นตอนเดียวกันยกเว้นการใช้วิธี "คลิป" ใน QGIS แทนที่จะตัดกัน - ดังนั้นในตัวอย่างของคุณสิ่งที่เหลือจะเป็นส่วนต่าง ๆ ของพื้นที่ที่ไม่ครอบคลุมพื้นที่น้ำท่วม ดูเหมือนจะทำงานได้ด้วยเหตุผลบางอย่างและฉันสามารถใช้การคำนวณฟิลด์ "พื้นที่" จากขั้นตอนก่อนหน้ารวมทั้งการคำนวณ "พื้นที่" ใหม่ในส่วนที่เหลือของรูปหลายเหลี่ยมแต่ละอันเพื่อหา% ของแต่ละพื้นที่ที่ไม่ใช่ ปกคลุมด้วยชั้นรูปหลายเหลี่ยมอื่น ๆ

ในทางเทคนิคแล้วสิ่งที่ตรงกันข้ามกับสิ่งที่คุณขอ แต่จากตรงนั้นมันเป็นเรื่องของการลบแต่ละค่าจาก 1 เพื่อให้ได้สิ่งที่ถูกปกคลุมด้วยเขตน้ำท่วม

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