Bagaimana membagi garis menjadi beberapa bagian?

11

Saya telah melihat banyak pertanyaan yang melibatkan pemisahan garis dengan bantuan lapisan titik.

Saya ingin membagi garis menjadi pecahan dari panjangnya.

Misalnya, saya memiliki 400panjang garis meter, saya ingin membaginya menjadi empat baris masing-masing sepanjang 100 meter.

Ada modul rumput v.split, tapi saya mendapatkan pesan kesalahan ketika saya memulainya dari kotak alat qgis:

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

Jadi saya tidak yakin apakah saya bisa bekerja jika ini akan menjadi solusi.

Gilles
sumber
Tolong jelaskan: Apakah Anda ingin membagi dengan panjang yaitu 100 meter atau menjadi bagian-bagian tertentu?
underdark
Ke sejumlah bagian tertentu. Joseph, di bawah, telah memberikan solusi yang baik.
Gilles

Jawaban:

10

Fungsi v.split.length dari GRASS harus melakukan apa yang Anda inginkan dengan memisahkan garis menjadi segmen yang sama yang ditentukan oleh pengguna tanpa perlu layer titik. Berikut adalah contoh sederhana garis lurus (ini juga berfungsi pada garis tidak lurus dan banyak garis):

Garis sederhana

Saya menambahkan kolom untuk menghitung panjangnya menggunakan $lengthdalam ekspresi:

Atribut garis

Menggunakan fungsi v.split.length dari GRASS melalui Processing Toolbox , saya memilih untuk membagi garis menjadi segmen 25m yang akan menghasilkan total 4 bagian:

fungsi v.split.length

Saya kemudian memperbarui kolom Panjang dari lapisan output dan menggunakan perintah yang sama seperti di atas untuk menghitung ulang panjang:

Hasil atribut

Tidak yakin mengapa Anda menerima kesalahan, bisakah Anda membagikan lapisan garis Anda kepada orang-orang untuk diuji?

Yusuf
sumber
Halo, terima kasih atas jawaban Anda. Ini bekerja. Ini tidak memecah garis dalam fraksi panjang, karena saya masih harus menghitung jumlah segmen dari panjang yang diukur, tapi itu solusi yang baik. Terima kasih.
Gilles
2
Jika "Panjang segmen maksimum" ditetapkan ke 25 mengapa Anda mendapatkan 4 segmen lebih panjang dari 25 (25,465) dan bukan 5 segmen (4 dari 25 dan satu dari 1,86 atau 5 dari 20,372 jika alat menghasilkan panjang yang sama)?
JR
1
@JR - Itu pertanyaan yang bagus untuk ditanyakan 5 tahun yang lalu :). Saya tidak punya jawaban untuk itu, mungkin itu adalah bug di alat mengingat itu akan menjadi versi QGIS lama. Juga, seperti pada hari-hari awal saya belajar GIS, saya seharusnya menggunakan CRS lain saat mengukur jarak akurat dalam meter!
Joseph
1
@ Joseph, saya pikir Anda akan memilih PyQGIS hari ini, bukan? =)
Taras
1
@Taras - Saya akan lebih condong, ya :)
Joseph
2

Diuji pada QGIS 2.18 dan QGIS 3.4

Mari kita asumsikan ada lapisan polyline yang disebut "lines".

memasukkan

Saya dapat menyarankan menggunakan "Lapisan Virtual" melalui Layer > Add Layer > Add/Edit Virtual Layer...


Ada beberapa kemungkinan kasus:


Kasus 1. Memisahkan garis menjadi segmen yang sama, pada dasarnya panjang yang sama yang ditentukan oleh pengguna.

Dengan Permintaan berikut, dimungkinkan untuk mencapai hasil. Untuk menambah / mengurangi panjang segmen, harap sesuaikan 1000 AS step_lengthin -- 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 Virtual Layer akan terlihat sebagai berikut

output_1

Catatan: Jika 'delta' (misalnya yang terakhir segmen terpendek) tidak harus dimasukkan, kemudian masukkanWHERE sec_length >= step_lengthdalam-- query, lihat di bawah

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

Kasus 2. Membagi garis menjadi sejumlah segmen tertentu

Dengan Permintaan berikut, dimungkinkan untuk mencapai hasil. Untuk menambah / mengurangi jumlah segmen, harap sesuaikan 8 AS sectionsin -- 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 Virtual Layer akan terlihat sebagai berikut

output_2

Taras
sumber