# How to split line into specific number of parts?

I've seen a lot of questions involving splitting a line with the help of a point layer.

I want to split a line into fractions of its length.

For example, I have a line `400` meters long, I want to split it into four lines of 100 meters long each.

There is the grass module `v.split`, but I get an error message when I start it from the qgis toolbox :

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

So I'm not sure if I get it to work if this would be a solution.

• Please clarify: Do you want to split by length i.e. ever 100 meters or into a specific number of parts? Commented Oct 6, 2014 at 18:25
• Into a specific number of parts. Joseph, below, has given a good workaround. Commented Oct 22, 2014 at 15:34

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?

• Hello, thanks for your answer. It is working. It's not splitting the line in fractions of the lenght though, as I still have to calculate the number of segments from the measured length, but it's a good workaround. Thank you. Commented Oct 22, 2014 at 15:31
• If the "Maximum segment length" is set to 25 why did you get 4 segment longer than 25 (25.465) and not 5 segment (4 of 25 and one of 1.86 or 5 of 20,372 if the tool output equal length) ?
– J.R
Commented Oct 23, 2019 at 12:00
• @J.R - That's a good question to ask 5 years ago :). I don't have an answer to that, perhaps it was a bug in the tool considering it would have been an old QGIS version. Also, as it was in my early days of learning GIS, I should have used another CRS when measuring accurate distances in meters! Commented Oct 23, 2019 at 12:08
• @Joseph, I think you would choose PyQGIS today, do not you? =) Commented Oct 23, 2019 at 12:14
• @Taras - I would be more inclined, yes :) Commented Oct 23, 2019 at 12:22

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