Verschweißen Sie einzelne Liniensegmente mit Shapely zu einer LineString
12
Ich benutze Shapely in Python und bekomme eine MultiLineStringmit ein paar LinestringObjekten. Ich kann garantieren, dass alle LineStringObjekte einfache Linien mit nur 2 Eckpunkten sind und dass sie alle Teil einer einzelnen Linie sind (keine Verzweigungen).
Ich möchte "die Punkte verbinden" und eine einzelne erstellen LineString. Muss ich dafür eine rekursive Schweißmethode schreiben oder gibt es einen schnelleren Weg?
Sie können shapely's verwenden ops.linemerge, um dies zu erreichen:
from shapely import geometry, ops
# create three lines
line_a = geometry.LineString([[0,0],[1,1]])
line_b = geometry.LineString([[1,1],[1,0]])
line_c = geometry.LineString([[1,0],[2,0]])# combine them into a multi-linestring
multi_line = geometry.MultiLineString([line_a, line_b, line_c])print(multi_line)# prints MULTILINESTRING ((0 0, 1 1), (1 1, 2 2), (2 2, 3 3))# you can now merge the lines
merged_line = ops.linemerge(multi_line)print(merged_line)# prints LINESTRING (0 0, 1 1, 2 2, 3 3)# if your lines aren't contiguous
line_a = geometry.LineString([[0,0],[1,1]])
line_b = geometry.LineString([[1,1],[1,0]])
line_c = geometry.LineString([[2,0],[3,0]])# combine them into a multi-linestring
multi_line = geometry.MultiLineString([line_a, line_b, line_c])print(multi_line)# prints MULTILINESTRING ((0 0, 1 1), (1 1, 1 0), (2 0, 3 0))# note that it will now merge only the contiguous portions into a component of a new multi-linestring
merged_line = ops.linemerge(multi_line)print(merged_line)# prints MULTILINESTRING ((0 0, 1 1, 1 0), (2 0, 3 0))
Woher kann ich wissen, welche Linienfolge zusammengeführt wurde? Ich möchte eine Liste wie folgt erhalten: merged = [[line_a, line_b], [line_c]]
James
Sie können eine Liste Ihrer einzelnen Zeilen durchlaufen und prüfen, ob die neue zusammengeführte Zeile contains()die einzelnen Zeilen enthält. Die nicht enthaltenen wären nicht zusammengeführt worden. zB merged_line.contains(line_a)was einen booleschen TrueoderFalse
songololo
Vielen Dank. Wie prüft man, ob die Zeile in den merged_lines enthalten ist?
James
1
ah, ich habe nicht verstanden, dass ".contains (line_a)" eine vorab geschriebene Funktion ist. perfekt. Vielen Dank !
James
1
Entschuldigung, um Sie wieder zu stören ... aber wissen Sie, wen Sie Linien zusammenführen sollen, die "nah" sind (innerhalb eines bestimmten maximalen Abstands voneinander)? Ich frage, weil ich viele Zeilen sehe, die zusammengeführt werden sollten, aber aufgrund einer kleinen Unterbrechung zwischen ihnen werden sie nicht zusammengeführt.
James
2
Ich denke, Sie könnten es mit Shapely tun, indem Sie die shapely.ops.linemerge () -Methode verwenden.
Es sieht so aus, als könnte eine Liste von Zeilen als Eingabe verwendet und zusammengeführt werden. Ich habe zuvor die Methode 'polygonize' verwendet und es wird eine Liste von Zeilen benötigt.
Wissen Sie, wie Sie Linien zusammenführen, die "nah" sind (innerhalb eines bestimmten maximalen Abstands voneinander)?
James
polygonize_full funktioniert etwas besser, aber ich habe einige seltsame Datenstrukturen als Ergebnis
Danuker
1
shapely.ops.linemerge()Bei einigen meiner Leitungen ist ein Fehler aufgetreten, sodass ich es manuell ausführen musste. Es scheint für die Linien, die zu sich selbst "zurückgekehrt" sind, zu scheitern, dh den gleichen Punkt mehr als einmal zu durchlaufen. In meinem Fall weiß ich, dass die Zeilen in der richtigen Reihenfolge sind, sodass es einfach war, eine kleine Funktion zu schreiben, um sie zusammenzuführen.
from shapely.geometry importLineStringfrom typing importListdef merge_lines(lines:List[LineString])->LineString:
last =None
points =[]for line in merged_line:
current = line.coords[0]if last isNone:
points.extend(line.coords)else:if last == current:
points.extend(line.coords[1:])else:print('Skipping to merge {} {}'.format(last, current))returnNone
last = line.coords[-1]returnLineString(points)
shapely.ops.linemergeFunktioniert, wenn die Linien zusammenhängend sind ("Tips" stimmen mit den "Tails" der konstituierenden Linien überein), aber wenn sie nicht zusammenhängend sind (wenn es eine Lücke zwischen den Tips und Tails gibt), wird ein weiterer MultiLineString zurückgegeben. Wenn Ihre konstituierenden Linien geordnet sind (wobei eine Linie nahe dem Beginn der nächsten Linie endet), aber eine Lücke von Spitze zu Ende aufweist, können Sie die Koordinaten extrahieren und daraus eine neue einfache Linie erstellen. Dieser Ansatz funktioniert auch für Mehrfachlinien, die aus komplexeren Unterlinien bestehen (dh Unterlinien mit mehr als zwei Punkten).
import shapely
# Make a MultiLineString to use for the example
inlines = shapely.geometry.MultiLineString([shapely.geometry.LineString([(0,0),(0,0.9)]),
shapely.geometry.LineString([(0,1),(1,1)])])# Put the sub-line coordinates into a list of sublists
outcoords =[list(i.coords)for i in inlines]# Flatten the list of sublists and use it to make a new line
outline = shapely.geometry.LineString([i for sublist in outcoords for i in sublist])
contains()
die einzelnen Zeilen enthält. Die nicht enthaltenen wären nicht zusammengeführt worden. zBmerged_line.contains(line_a)
was einen booleschenTrue
oderFalse
Ich denke, Sie könnten es mit Shapely tun, indem Sie die shapely.ops.linemerge () -Methode verwenden.
Es sieht so aus, als könnte eine Liste von Zeilen als Eingabe verwendet und zusammengeführt werden. Ich habe zuvor die Methode 'polygonize' verwendet und es wird eine Liste von Zeilen benötigt.
Schauen Sie sich das Dokument hier an: http://toblerity.org/shapely/manual.html#shapely.ops.linemerge
quelle
shapely.ops.linemerge()
Bei einigen meiner Leitungen ist ein Fehler aufgetreten, sodass ich es manuell ausführen musste. Es scheint für die Linien, die zu sich selbst "zurückgekehrt" sind, zu scheitern, dh den gleichen Punkt mehr als einmal zu durchlaufen. In meinem Fall weiß ich, dass die Zeilen in der richtigen Reihenfolge sind, sodass es einfach war, eine kleine Funktion zu schreiben, um sie zusammenzuführen.Hoffe es hilft jemandem
quelle
shapely.ops.linemerge
Funktioniert, wenn die Linien zusammenhängend sind ("Tips" stimmen mit den "Tails" der konstituierenden Linien überein), aber wenn sie nicht zusammenhängend sind (wenn es eine Lücke zwischen den Tips und Tails gibt), wird ein weiterer MultiLineString zurückgegeben. Wenn Ihre konstituierenden Linien geordnet sind (wobei eine Linie nahe dem Beginn der nächsten Linie endet), aber eine Lücke von Spitze zu Ende aufweist, können Sie die Koordinaten extrahieren und daraus eine neue einfache Linie erstellen. Dieser Ansatz funktioniert auch für Mehrfachlinien, die aus komplexeren Unterlinien bestehen (dh Unterlinien mit mehr als zwei Punkten).quelle