วิธีแยก line ออกเป็นจำนวนชิ้นส่วนที่ต้องการได้อย่างไร


11

ฉันเห็นคำถามมากมายเกี่ยวกับการแบ่งแถวด้วยความช่วยเหลือของเลเยอร์จุด

ฉันต้องการแยกเส้นเป็นเศษส่วนของความยาว

ตัวอย่างเช่นฉันมีความ400ยาวเส้นหนึ่งเมตรฉันต้องการแยกออกเป็นสี่เส้นยาว 100 เมตรแต่ละเส้น

มีโมดูลหญ้าv.splitแต่ฉันได้รับข้อความแสดงข้อผิดพลาดเมื่อฉันเริ่มต้นจากกล่องเครื่องมือ qgis:

*"TypeError: object of type 'NoneType' has no len()"*

ดังนั้นฉันไม่แน่ใจว่าฉันจะให้มันทำงานได้ไหมถ้านี่จะเป็นทางออก


โปรดอธิบาย: คุณต้องการแยกตามความยาวเช่นเคย 100 เมตรหรือเป็นจำนวนชิ้นส่วนเฉพาะหรือไม่
underdark

เป็นชิ้นส่วนเฉพาะจำนวนมาก โจเซฟด้านล่างให้วิธีแก้ปัญหาที่ดี
Gilles

คำตอบ:


10

v.split.lengthฟังก์ชั่นจาก GRASS ควรจะทำสิ่งที่คุณต้องการโดยแยกบรรทัดลงในส่วนเท่ากันกำหนดโดยผู้ใช้โดยไม่จำเป็นต้องชั้นจุด นี่เป็นตัวอย่างง่ายๆของเส้นตรง (มันสามารถใช้กับเส้นที่ไม่ตรงและหลายเส้นได้):

เส้นเรียบง่าย

ฉันเพิ่มคอลัมน์เพื่อคำนวณความยาวโดยใช้$lengthในนิพจน์:

แอตทริบิวต์ Line

การใช้ฟังก์ชั่นv.split.lengthจาก GRASS ผ่านเครื่องมือประมวลผลฉันเลือกที่จะแบ่งบรรทัดออกเป็นเซ็กเมนต์ 25m ซึ่งควรมีทั้งหมด 4 ส่วน:

ฟังก์ชัน v.split.length

ฉันอัปเดตคอลัมน์ความยาวของเลเยอร์ผลลัพธ์แล้วใช้คำสั่งเดียวกันข้างต้นเพื่อคำนวณความยาวใหม่:

คุณสมบัติของผลลัพธ์

ไม่แน่ใจว่าทำไมคุณถึงได้รับข้อผิดพลาดคุณสามารถแชร์เลเยอร์เลเยอร์ของคุณเพื่อให้ผู้คนทดสอบได้หรือไม่?


สวัสดีขอบคุณสำหรับคำตอบของคุณ มันใช้งานได้ มันไม่ได้แบ่งเส้นเป็นเศษส่วนของความยาว แต่เนื่องจากฉันยังต้องคำนวณจำนวนเซ็กเมนต์จากความยาวที่วัดได้ แต่มันก็เป็นวิธีที่ดี ขอบคุณ.
Gilles

2
หากตั้งค่า "ความยาวเซกเมนต์สูงสุด" เป็น 25 ทำไมคุณถึงได้ 4 เซกเมนต์ยาวกว่า 25 (25.465) และไม่ใช่ 5 เซกเมนต์ (4 จาก 25 และหนึ่งใน 1.86 หรือ 5 จาก 20,372 ถ้าเอาท์พุทของเครื่องมือยาวเท่ากัน)?
JR

1
@JR - เป็นคำถามที่ดีที่จะถามเมื่อ 5 ปีก่อน :) ฉันไม่มีคำตอบสำหรับเรื่องนี้บางทีมันอาจเป็นข้อผิดพลาดในเครื่องมือเมื่อพิจารณาว่าเป็นเวอร์ชั่น QGIS เก่า เช่นเดียวกับในสมัยแรก ๆ ที่ฉันได้เรียนรู้ GIS ฉันควรใช้ CRS อื่นเมื่อวัดระยะทางที่แม่นยำในหน่วยเมตร!
โจเซฟ

1
@ โจเซฟฉันคิดว่าคุณจะเลือก PyQGIS วันนี้ใช่ไหม? =)
Taras

1
@Taras - ฉันจะมีแนวโน้มมากขึ้นใช่ :)
โจเซฟ

2

ทดสอบบน QGIS 2.18 และ QGIS 3.4

"lines"สมมติว่ามีชั้นเส้นที่เรียกว่า

อินพุต

ฉันสามารถแนะนำให้ใช้ "Virtual Layer" ผ่าน Layer > Add Layer > Add/Edit Virtual Layer...


มีหลายกรณีที่เป็นไปได้:


กรณีที่ 1. การแบ่งบรรทัดออกเป็นเซ็กเมนต์ที่เท่ากันโดยทั่วไปความยาวเท่ากันซึ่งผู้ใช้กำหนด

ด้วย Query ต่อไปนี้เป็นไปได้ที่จะบรรลุผล เพื่อเพิ่ม / ลดความยาวส่วนโปรดปรับใน1000 AS step_length-- configurations

-- generate series
WITH RECURSIVE generate_sections(id, sec) AS (
SELECT conf.start + 1, conf.start
FROM conf
UNION ALL
SELECT id + conf.step, sec + conf.step_length/conf.length_line
FROM generate_sections, conf
WHERE sec + conf.step_length/conf.length_line <= 1
),

-- configurations
conf AS (
SELECT
0.0 AS start,
1.0 AS step,
1000 AS step_length,
ST_Length(l.geometry) AS length_line
FROM lines AS l
)

-- query
SELECT gs.id AS id,
        ROUND(ST_Length(ST_Line_Substring(l.geometry, start + sec, sec + conf.step_length/conf.length_line)),0) AS seg_length,
        ST_Line_Substring(l.geometry, start + sec, sec + conf.step_length/conf.length_line) AS geom
FROM generate_sections AS gs, lines AS l, conf
GROUP BY gs.id

เลเยอร์เสมือนเอาต์พุตจะมีลักษณะดังต่อไปนี้

output_1

หมายเหตุ:หาก 'เดลต้า' (เช่นส่วนที่สั้นที่สุดที่ผ่านมา) ไม่ควรรวมแล้วใส่WHERE sec_length >= step_lengthใน-- queryดูด้านล่าง

-- query
SELECT gs.id AS id,
        ROUND(ST_Length(ST_Line_Substring(l.geometry, start + sec, sec + conf.step_length/conf.length_line)),0) AS seg_length,
        ST_Line_Substring(l.geometry, start + sec, sec + conf.step_length/conf.length_line) AS geom
FROM generate_sections AS gs, lines AS l, conf
WHERE seg_length >= step_length
GROUP BY gs.id

กรณีที่ 2.แยกบรรทัดออกเป็นเซ็กเมนต์จำนวนหนึ่ง

ด้วย Query ต่อไปนี้เป็นไปได้ที่จะบรรลุผล เพื่อเพิ่ม / ลดจำนวนของกลุ่มโปรดปรับใน8 AS sections-- configurations

-- generate series
WITH RECURSIVE generate_sections(id, sec) AS (
SELECT conf.start + 1, conf.start
FROM conf
UNION ALL
SELECT id + conf.step, sec + conf.step
FROM generate_sections, conf
WHERE sec + conf.step < conf.sections
),

-- configurations
conf AS (
SELECT
8 AS sections,
0.0 AS start,
1.0 AS step
)

-- query
SELECT gs.id AS id,
    ST_Line_Substring(l.geometry, conf.start + sec/conf.sections, sec/conf.sections + step/conf.sections) AS geom,
    ROUND(ST_Length(ST_Line_Substring(l.geometry, conf.start + sec/conf.sections, sec/conf.sections + step/conf.sections)),2) AS seg_length
FROM generate_sections AS gs, lines AS l, conf
WHERE start + step < sections
GROUP BY gs.id

เลเยอร์เสมือนเอาต์พุตจะมีลักษณะดังต่อไปนี้

output_2

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