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

Simple line

I added a column to calculate its length using $length in the expression:

Line attribute

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:

v.split.length function

I then updated the Length column of the output layer and used the same command as above to re-calculate the length:

Attribute result

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

input

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

output_1

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

output_2