Làm thế nào để chia dòng thành số phần cụ thể?


10

Tôi đã thấy rất nhiều câu hỏi liên quan đến việc tách một dòng với sự trợ giúp của một lớp điểm.

Tôi muốn chia một dòng thành các phần có độ dài của nó.

Ví dụ, tôi có một hàng 400dài hàng mét, tôi muốn chia nó thành bốn dòng dài 100 mét mỗi dòng.

Có mô-đun cỏ v.split, nhưng tôi nhận được thông báo lỗi khi tôi khởi động nó từ hộp công cụ qgis:

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

Vì vậy, tôi không chắc chắn nếu tôi làm cho nó hoạt động nếu đây sẽ là một giải pháp.


Xin làm rõ: Bạn có muốn chia theo chiều dài tức là 100 mét hoặc thành một số phần cụ thể không?
underdark

Vào một số phần cụ thể. Joseph, bên dưới, đã đưa ra một cách giải quyết tốt.
Gilles

Câu trả lời:


9

Hàm v.split.length từ GRASS sẽ thực hiện chính xác những gì bạn muốn bằng cách chia dòng thành các phân đoạn bằng nhau được xác định bởi người dùng mà không cần lớp điểm. Đây là một ví dụ đơn giản về một đường thẳng (nó cũng hoạt động trên các đường thẳng và nhiều đường thẳng):

Dòng đơn giản

Tôi đã thêm một cột để tính chiều dài của nó bằng $lengthbiểu thức:

Thuộc tính dòng

Sử dụng hàm v.split.length từ GRASS thông qua Hộp công cụ xử lý , tôi đã chọn chia dòng thành 25m, sẽ tạo thành tổng cộng 4 phần:

hàm v.split.length

Sau đó tôi đã cập nhật cột Độ dài của lớp đầu ra và sử dụng lệnh tương tự như trên để tính lại độ dài:

Kết quả thuộc tính

Không chắc chắn tại sao bạn nhận được lỗi, bạn có thể chia sẻ lớp dòng của mình để mọi người kiểm tra không?


Xin chào, cảm ơn câu trả lời của bạn. Nó đang làm việc. Mặc dù vậy, nó không phân chia dòng theo phân số chiều dài, vì tôi vẫn phải tính số lượng phân đoạn từ độ dài đo được, nhưng đó là một cách giải quyết tốt. Cảm ơn bạn.
Gilles

2
Nếu "Độ dài phân đoạn tối đa" được đặt thành 25, tại sao bạn lại có 4 đoạn dài hơn 25 (25.465) chứ không phải 5 đoạn (4 của 25 và một trong 1.86 hoặc 5 của 20.372 nếu đầu ra của công cụ có độ dài bằng nhau)?
JR

1
@JR - Đó là một câu hỏi hay để hỏi 5 năm trước :). Tôi không có câu trả lời cho điều đó, có lẽ đó là một lỗi trong công cụ xem xét nó sẽ là một phiên bản cũ của QGIS. Ngoài ra, như trong những ngày đầu học GIS, tôi nên sử dụng một CRS khác khi đo khoảng cách chính xác bằng mét!
Joseph

1
@Joseph, tôi nghĩ bạn sẽ chọn PyQGIS ngay hôm nay phải không? =)
Taras

1
@Tara - Tôi sẽ nghiêng nhiều hơn, vâng :)
Joseph

2

Đã thử nghiệm trên QGIS 2.18 và QGIS 3.4

Giả sử có một lớp polyline được gọi là "lines".

đầu vào

Tôi có thể đề xuất sử dụng "Lớp ảo" thông qua Layer > Add Layer > Add/Edit Virtual Layer...


Có thể có một số trường hợp:


Trường hợp 1. Chia dòng thành các đoạn bằng nhau, về cơ bản là độ dài bằng nhau được xác định bởi người dùng.

Với Truy vấn sau, có thể đạt được kết quả. Để tăng / giảm độ dài đoạn, vui lòng điều chỉnh 1000 AS step_lengthtrong -- 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

Lớp ảo đầu ra sẽ trông như sau

đầu ra_1

Lưu ý: Nếukhông bao gồm 'delta' (ví dụ: đoạn ngắn nhất cuối cùng), sau đó chènWHERE sec_length >= step_lengthvào-- query, xem bên dưới

-- 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

Trường hợp 2. Chia dòng thành một số phân đoạn nhất định

Với Truy vấn sau, có thể đạt được kết quả. Để tăng / giảm số lượng phân khúc, vui lòng điều chỉnh 8 AS sectionstrong -- 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

Lớp ảo đầu ra sẽ trông như sau

đầu ra_2

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.