การจัดแนวหลายจุดให้เป็นบรรทัดใน QGIS?


11

ฉันต้องการจัดตำแหน่งหลายจุดให้เป็นหนึ่งบรรทัดหรือหลายบรรทัดภายในเลเยอร์โดยใช้เกณฑ์ความคลาดเคลื่อนหรือบัฟเฟอร์รอบวัตถุเส้นตรง โปรดดูตัวอย่างร่างที่แนบมา

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

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


ดังนั้นจุดจะต้องเป็น 0 หน่วยแผนที่ในแนวเส้นข้างของเส้น แต่คุณสนใจว่าจุดนั้นจบลงในแนวยาวของเส้นตรงตามตำแหน่งดั้งเดิมของจุดหรือไม่?
โจ

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

ไม่แน่ใจว่านี่เป็นวิธีที่ดีที่สุด แต่วิธีหนึ่งที่ฉันคิดได้คือการเขียนโค้ดไพ ธ อนเพื่อวิเคราะห์ชุดข้อมูลสองชุดและสร้างพิกัดจุด หากนี่คือสิ่งที่คุณคิดว่าคุณต้องการแจ้งให้เราทราบและฉันสามารถให้คำตอบสำหรับคุณ เช่นสำหรับทุกจุดหากค่าสัมบูรณ์ของ lat dist จากบรรทัด <= 5 หน่วยดังนั้นระยะทางด้านข้าง = 0 คุณจะต้องนำเข้าไลบรารี gdal เพื่อแปลงค่า x, y เป็น coords ดูความคิดเห็นใน: gis.stackexchange.com/questions/185445/…
โจ

ด้วย PyQGIS มันสามารถสร้างเลเยอร์หน่วยความจำที่มีจุดที่จัดชิดตามความอดทนที่ได้รับการพิจารณาก่อนหน้านี้ 5 หน่วยแผนที่และเส้นทางตั้งฉากกับเส้น ดูคำตอบของฉัน
xunilk

คำตอบ:


15

มีเครื่องมือในตัวให้ทำเช่นนี้ในเวอร์ชัน QGIS 3.0 (ไม่ได้เผยแพร่) คุณสามารถรับภาพรวมจากเว็บไซต์ QGIS ทุกคืนเพื่อทดสอบล่วงหน้า

เพื่อทำสิ่งนี้:

  1. เรียกใช้อัลกอริทึมการประมวลผล "Snap geometries to layer"
  2. เลือกเลเยอร์คะแนนของคุณเป็น "เลเยอร์อินพุต"
  3. เลือกเลเยอร์บรรทัดเป็น "เลเยอร์อ้างอิง"
  4. ป้อนความคลาดเคลื่อนที่เหมาะสม (ระยะทางสูงสุดในการเคลื่อนย้ายจุดขณะถ่ายภาพ)
  5. เปลี่ยนพฤติกรรมเป็น "ชอบจุดที่ใกล้ที่สุด"

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

นี่คือผลลัพธ์โดยแสดงจุดเดิมเป็น "x" และจุดที่จัดชิดเป็นจุดสีเขียว ฉันใช้ความอดทนที่นี่เพื่อให้มีเพียงบางจุดอินพุตเท่านั้น

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


นี่คือสิ่งที่ฉันต้องการ น่าเสียดายที่นายจ้างของฉันติดตั้ง QGIS รุ่น LTR เท่านั้นและเราทุกคนถูก จำกัด ไม่ให้ดาวน์โหลดและติดตั้งรุ่นทดสอบ (ถอนหายใจ) ฉันคิดว่ามันเป็นเรื่องของการรอ นี่เป็นฟังก์ชั่นมาตรฐาน / ในตัวหรือปลั๊กอินหรือไม่?
Ed Camden

ฟังก์ชั่นมาตรฐานอาศัยการเปลี่ยนแปลงในคลาส c ++ - ไม่มีทางที่จะคัดลอกสิ่งนี้ไปยังรุ่นเก่ากว่าได้ คุณอาจลองติดตั้งโดยใช้ OSGEO4W บนเครื่องอื่นแล้วคัดลอกโฟลเดอร์ osgeo4w ไปยังแท่ง USB เพื่อเรียกใช้บนเวิร์กสเตชันของคุณ ฉันมีโชคกับวิธีการที่ผ่านมา
ndawson

1
สำหรับรุ่นเก่าดูที่ปลั๊กอินนี้ docs.qgis.org/2.14/th/docs/user_manual/plugins/ …
iRfAn

ดูเหมือนว่าปลั๊กอินไม่รองรับเลเยอร์คะแนน
Mykola Kozyr

7

นี้สามารถ afforded กับPyQGIS สำหรับสถานการณ์ต่อไป:

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

รหัสต่อไปนี้เมื่อพิจารณาถึงความทนทานต่อแผนที่ 5 หน่วยถูกเรียกใช้ที่ Python Console ของ QGIS:

from math import sqrt

registry = QgsMapLayerRegistry.instance()

points = registry.mapLayersByName('points')
line = registry.mapLayersByName('line')

feat_points = [ feat for feat in points[0].getFeatures() ]
feat_line = line[0].getFeatures().next()

new_points = []

for feat in feat_points:
    pt = feat.geometry().asPoint()
    sqrdist, point, vertex = feat_line.geometry().closestSegmentWithContext(pt)
    if sqrt(sqrdist) <= 5:
        new_points.append(point)
    else:
        new_points.append(pt)

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

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

mem_layer = QgsVectorLayer(uri,
                           'new_points',
                           'memory')

prov = mem_layer.dataProvider()

feats = [ QgsFeature() for i in range(len(new_points)) ]

for i, feat in enumerate(feats):
    feat.setAttributes([i])
    feat.setGeometry(QgsGeometry.fromPoint(new_points[i]))

prov.addFeatures(feats)

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

มันผลิตเลเยอร์หน่วยความจำที่มีการหักคะแนนตามความคลาดเคลื่อนที่พิจารณาก่อนหน้านี้ของ 5 หน่วยแผนที่และเส้นทางตั้งฉากกับเส้น

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


2

คุณยังสามารถทำสิ่งนี้ได้ใน Field Calculator ด้วยปลั๊กอิน refFunctions คุณสามารถใช้เครื่องคำนวณภาคสนามเพื่ออัปเดตรูปทรงเรขาคณิตของเลเยอร์และฟิลด์ refFunctions ให้ฟังก์ชัน "geomdistance" เพื่อค้นหาบรรทัดที่ใกล้ที่สุดภายในระยะทางที่กำหนด (หรือ "geomnearest" หากคุณไม่ต้องการขีด จำกัด ) และจะส่งคืนแอตทริบิวต์หรือเรขาคณิตและฟังก์ชัน "closest_point" จะค้นหาสิ่งที่ใกล้เคียงที่สุด ชี้ไปที่รูปทรงเรขาคณิตที่กำหนด สตริงพวกมันเข้าด้วยกันอย่างนั้นเพื่อคำนวณรูปทรงเรขาคณิตใหม่สำหรับเลเยอร์จุดของคุณ:

closest_point(geom_from_wkt(geomdistance('snap_lines','$geometry',10)) , $geometry)

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

มีข้อ จำกัด บางประการเช่นนี้เลเยอร์ทั้งคู่ต้องเป็น CRS เดียวกันและฟังก์ชัน geomdistance จะให้ข้อผิดพลาดหากคุณมีมากกว่า 100,000 คะแนน แต่คุณสามารถเปลี่ยนข้อ จำกัด นี้ได้หากคุณแก้ไขไฟล์ปลั๊กอิน refFunctions

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