Comment diviser la ligne en un nombre spécifique de pièces?

11

J'ai vu beaucoup de questions concernant le fractionnement d'une ligne à l'aide d'une couche de points.

Je veux diviser une ligne en fractions de sa longueur.

Par exemple, j'ai une ligne de 400mètres de long, je veux la diviser en quatre lignes de 100 mètres de long chacune.

Il y a le module grass v.split, mais je reçois un message d'erreur lorsque je le démarre à partir de la boîte à outils qgis:

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

Je ne sais donc pas si je vais le faire fonctionner si ce serait une solution.

Gilles
la source
Veuillez clarifier: Voulez-vous diviser par longueur, c'est-à-dire par 100 mètres ou en un nombre spécifique de pièces?
underdark
En un nombre spécifique de pièces. Joseph, ci-dessous, a donné une bonne solution de contournement.
Gilles

Réponses:

10

La fonction v.split.length de GRASS devrait faire exactement ce que vous voulez en divisant la ligne en segments égaux définis par l'utilisateur sans avoir besoin d'une couche de points. Voici un exemple simple de ligne droite (cela fonctionne également sur les lignes non droites et multiples):

Ligne simple

J'ai ajouté une colonne pour calculer sa longueur à l'aide $lengthde l'expression:

Attribut de ligne

En utilisant la fonction v.split.length de GRASS via la boîte à outils de traitement , j'ai choisi de diviser la ligne en segments de 25 m qui devraient faire un total de 4 parties:

Fonction v.split.length

J'ai ensuite mis à jour la colonne Longueur du calque de sortie et utilisé la même commande que ci-dessus pour recalculer la longueur:

Résultat d'attribut

Vous ne savez pas pourquoi vous recevez l'erreur, pourriez-vous partager votre couche de ligne pour que les gens puissent la tester?

Joseph
la source
Bonjour, merci pour votre réponse. Ça fonctionne. Il ne s'agit pas de diviser la ligne en fractions de longueur, car je dois encore calculer le nombre de segments à partir de la longueur mesurée, mais c'est une bonne solution de contournement. Je vous remercie.
Gilles
2
Si la "Longueur maximale de segment" est définie sur 25, pourquoi avez-vous obtenu 4 segments de plus de 25 (25,465) et non 5 segments (4 de 25 et un de 1,86 ou 5 de 20372 si l'outil sort la même longueur)?
JR
1
@JR - C'est une bonne question à poser il y a 5 ans :). Je n'ai pas de réponse à cela, c'était peut-être un bogue dans l'outil étant donné que cela aurait été une ancienne version de QGIS. De plus, comme c'était à mes débuts dans l'apprentissage des SIG, j'aurais dû utiliser un autre CRS pour mesurer des distances précises en mètres!
Joseph
1
@Joseph, je pense que vous choisiriez PyQGIS aujourd'hui, n'est-ce pas? =)
Taras
1
@Taras - Je serais plus enclin, oui :)
Joseph
2

Testé sur QGIS 2.18 et QGIS 3.4

Supposons qu'il existe un calque de polyligne appelé "lines".

contribution

Je peux suggérer d'utiliser une "couche virtuelle" via Layer > Add Layer > Add/Edit Virtual Layer...


Il existe plusieurs cas possibles:


Cas 1. Diviser la ligne en segments égaux, essentiellement une longueur égale qui est définie par l'utilisateur.

Avec la requête suivante, il est possible d'obtenir le résultat. Pour augmenter / diminuer la longueur du segment, s'il vous plaît régler la 1000 AS step_lengthdans -- 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

La couche virtuelle de sortie se présente comme suit

sortie_1

Note: Si « delta » (par exemplele dernier segmentplus court) ne doit pas être inclus, puis insérezWHERE sec_length >= step_lengthdans-- query, voir cidessous

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

Cas 2. Diviser la ligne en un certain nombre de segments

Avec la requête suivante, il est possible d'obtenir le résultat. Pour augmenter / diminuer le nombre de segments, s'il vous plaît régler la 8 AS sectionsdans -- 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

La couche virtuelle de sortie se présente comme suit

sortie_2

Taras
la source