Wie teilt man die Linie in eine bestimmte Anzahl von Teilen?

10

Ich habe viele Fragen gesehen, bei denen es darum ging, eine Linie mithilfe einer Punktebene zu teilen.

Ich möchte eine Linie in Bruchteile ihrer Länge aufteilen.

Zum Beispiel habe ich eine Linie mit 400einer Länge von Metern, die ich in vier Linien mit einer Länge von jeweils 100 Metern aufteilen möchte.

Es gibt v.splitdas Grasmodul, aber ich erhalte eine Fehlermeldung, wenn ich es über die qgis-Toolbox starte:

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

Ich bin mir also nicht sicher, ob es funktioniert, wenn dies eine Lösung wäre.

Gilles
quelle
Bitte stellen Sie klar: Möchten Sie nach Länge, dh je 100 Meter, oder in eine bestimmte Anzahl von Teilen aufteilen?
Underdark
In eine bestimmte Anzahl von Teilen. Joseph unten hat eine gute Problemumgehung gegeben.
Gilles

Antworten:

9

Die Funktion v.split.length von GRASS sollte genau das tun, was Sie möchten, indem Sie die Linie in gleiche Segmente aufteilen, die vom Benutzer definiert wurden, ohne dass eine Punktebene erforderlich ist. Hier ist ein einfaches Beispiel für eine gerade Linie (sie funktioniert auch bei nicht geraden und mehreren Linien):

Einfache Linie

Ich habe eine Spalte hinzugefügt, um ihre Länge mit $lengthdem folgenden Ausdruck zu berechnen :

Linienattribut

Mit der Funktion v.split.length von GRASS über die Processing Toolbox habe ich die Linie in 25 m lange Segmente aufgeteilt, die insgesamt 4 Teile umfassen sollen:

v.split.length Funktion

Ich habe dann die Längenspalte der Ausgabeebene aktualisiert und den gleichen Befehl wie oben verwendet, um die Länge neu zu berechnen:

Attributergebnis

Sie sind sich nicht sicher, warum Sie den Fehler erhalten. Können Sie Ihre Linienebene für Testzwecke freigeben?

Joseph
quelle
Hallo, danke für deine Antwort. Es funktioniert. Es wird zwar nicht in Bruchteilen der Länge aufgeteilt, da ich immer noch die Anzahl der Segmente aus der gemessenen Länge berechnen muss, aber es ist eine gute Problemumgehung. Vielen Dank.
Gilles
2
Wenn die "Maximale Segmentlänge" auf 25 eingestellt ist, warum haben Sie 4 Segmente länger als 25 (25,465) und nicht 5 Segmente (4 von 25 und eines von 1,86 oder 5 von 20.372, wenn die Werkzeugausgabe gleich lang ist) erhalten?
JR
1
@JR - Das ist eine gute Frage vor 5 Jahren :). Ich habe keine Antwort darauf, vielleicht war es ein Fehler im Tool, wenn man bedenkt, dass es eine alte QGIS-Version gewesen wäre. Wie in meinen frühen Tagen beim Erlernen von GIS hätte ich auch ein anderes CRS verwenden sollen, um genaue Entfernungen in Metern zu messen!
Joseph
1
@ Joseph, ich denke du würdest heute PyQGIS wählen, nicht wahr? =)
Taras
1
@ Taras - Ich wäre eher geneigt, ja :)
Joseph
2

Getestet mit QGIS 2.18 und QGIS 3.4

Nehmen wir an, es gibt eine Polylinienebene namens "lines".

Eingang

Ich kann vorschlagen, eine "virtuelle Schicht" durch zu verwenden Layer > Add Layer > Add/Edit Virtual Layer...


Es gibt mehrere mögliche Fälle:


Fall 1. Aufteilen der Linie in gleiche Segmente, im Grunde gleiche Länge, die vom Benutzer definiert wird.

Mit der folgenden Abfrage ist es möglich, das Ergebnis zu erzielen. Um die Segmentlänge zu erhöhen / zu verringern, stellen Sie bitte den Eingang 1000 AS step_lengthein -- 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

Die virtuelle Ausgabeebene sieht wie folgt aus

output_1

Hinweis: Wenn 'Delta' (z. B. das letzte kürzeste Segment) nicht enthalten sein soll, fügen Sie esWHERE sec_length >= step_lengthein-- query, siehe unten

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

Fall 2. Aufteilen der Linie in eine bestimmte Anzahl von Segmenten

Mit der folgenden Abfrage ist es möglich, das Ergebnis zu erzielen. Um die Anzahl der Segmente zu erhöhen / zu verringern, passen Sie bitte den Eingang 8 AS sectionsan -- 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

Die virtuelle Ausgabeebene sieht wie folgt aus

output_2

Taras
quelle