Сварка отдельных сегментов линии в одну LineString с помощью Shapely
13
Я использую Shapely в Python, и мне дают MultiLineStringс кучей Linestringобъектов. Я могу гарантировать, что все LineStringобъекты являются простыми линиями, имеющими только 2 вершины, и что все они являются частью одной отдельной линии (без ветвей).
Я хочу «соединить точки» и создать сингл LineString. Мне нужно написать метод рекурсивной сварки для этого или есть более быстрый способ?
Вы можете использовать shapely«S ops.linemergeдля достижения этой цели :
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))
Как я могу узнать, какая строка была объединена? Я хочу получить список вроде: merged = [[line_a, line_b], [line_c]]
james
Вы можете перебрать список ваших отдельных строк и проверить, соответствуют ли новые объединенные строки contains()отдельным линиям. Те, которые не содержались, не были бы объединены. например, merged_line.contains(line_a)который будет возвращать логическое значение TrueилиFalse
songololo
большое спасибо. Как проверить, содержится ли строка в merged_lines?
Джеймс
1
ах, я не понял, что ".contains (line_a)" - это заранее написанная функция. идеально. Большое спасибо !
Джеймс
1
извините, что беспокою вас снова ... но знаете ли вы, кто объединяет линии, которые "близки" (в пределах определенного максимального расстояния друг от друга)? Я спрашиваю, потому что я вижу много строк, которые должны быть объединены, но из-за небольшого разрыва между ними они не объединены.
Джеймс
2
Я думаю, что вы можете сделать это с помощью Shapely, используя метод shapely.ops.linemerge ().
Похоже, что он может принять список строк в качестве входных данных и объединить их. Я использовал метод 'polygonize' ранее, и он принимает список строк.
Вы знаете, как объединять линии, которые «близки» (в пределах определенного максимального расстояния друг от друга)?
Джеймс
polygonize_full работает несколько лучше, но в результате я получил несколько странных структур данных
danuker
1
shapely.ops.linemerge()не удалось для некоторых из моих строк, поэтому мне пришлось сделать это вручную. Кажется, что он не работает для линий, которые «вернулись» к себе, т. Е. Проходят одну и ту же точку более одного раза. Для моего случая я знаю, что строки расположены в правильном порядке, поэтому было легко написать небольшую функцию для их объединения.
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.linemergeработает, если линии являются смежными («подсказки» совпадают с «хвостами» составляющих линий), но если они не являются смежными (если есть промежуток между кончиками и хвостами), он возвращает другую MultiLineString. Если ваши составляющие линии хорошо упорядочены (с одной линией, заканчивающейся рядом с началом следующей строки), но имеют разрыв от кончика до хвоста, вы можете извлечь координаты и использовать их для создания новой простой линии. Этот подход также работает для многолинейных линий, состоящих из более сложных сублиней (т. Е. Сублиней, содержащих более двух точек).
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()
отдельным линиям. Те, которые не содержались, не были бы объединены. например,merged_line.contains(line_a)
который будет возвращать логическое значениеTrue
илиFalse
Я думаю, что вы можете сделать это с помощью Shapely, используя метод shapely.ops.linemerge ().
Похоже, что он может принять список строк в качестве входных данных и объединить их. Я использовал метод 'polygonize' ранее, и он принимает список строк.
Посмотрите документ здесь: http://toblerity.org/shapely/manual.html#shapely.ops.linemerge
источник
shapely.ops.linemerge()
не удалось для некоторых из моих строк, поэтому мне пришлось сделать это вручную. Кажется, что он не работает для линий, которые «вернулись» к себе, т. Е. Проходят одну и ту же точку более одного раза. Для моего случая я знаю, что строки расположены в правильном порядке, поэтому было легко написать небольшую функцию для их объединения.Надеюсь, это поможет кому-то
источник
shapely.ops.linemerge
работает, если линии являются смежными («подсказки» совпадают с «хвостами» составляющих линий), но если они не являются смежными (если есть промежуток между кончиками и хвостами), он возвращает другую MultiLineString. Если ваши составляющие линии хорошо упорядочены (с одной линией, заканчивающейся рядом с началом следующей строки), но имеют разрыв от кончика до хвоста, вы можете извлечь координаты и использовать их для создания новой простой линии. Этот подход также работает для многолинейных линий, состоящих из более сложных сублиней (т. Е. Сублиней, содержащих более двух точек).источник