How to split line into specific number of parts?
The v.split.length function from GRASS should do exactly what you want by splitting the line into equal segments defined by the user without the need for a point layer. Here's a simple example of a straight line (it also works on non-straight and multiple lines):
I added a column to calculate its length using $length
in the expression:
Using the v.split.length function from GRASS via the Processing Toolbox, I chose to split the line into 25m segments which should make a total of 4 parts:
I then updated the Length column of the output layer and used the same command as above to re-calculate the length:
Not sure why you are receiving the error, could you share your line layer for people to test?
Tested on QGIS 2.18 and QGIS 3.4
Let's assume there is a polyline layer called "lines"
.
I can suggest using a "Virtual Layer" through Layer > Add Layer > Add/Edit Virtual Layer...
There are possible several cases:
Case 1. Splitting the line into equal segments, basically equal length which is defined by the user.
With the following Query, it is possible to achieve the result. To increase/decrease the segment length, please adjust the 1000 AS step_length
in -- 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
The output Virtual Layer will look as following
Note: If 'delta' (e.g. the last shortest segment) should not be included, then insert WHERE sec_length >= step_length
in -- query
, see below
-- 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
Case 2. Splitting the line into a certain number of segments
With the following Query, it is possible to achieve the result. To increase/decrease the number of segments, please adjust the 8 AS sections
in -- 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
The output Virtual Layer will look as following