Я пытаюсь привязать две линии друг к другу, используя Shapely / Geopandas, но результат привязки очень странный. Я старался :
import geopandas as gpd
from shapely.geometry import *
from shapely.ops import snap
lines1 = gpd.GeoDataFrame.from_file('lines1.shp')
lines1 = lines1.to_crs({'init': 'epsg:2227'})
lines2 = gpd.GeoDataFrame.from_file('lines2.shp')
lines2 = lines2.to_crs({'init': 'epsg:2227'})
res = lines1
lines2_union = lines2.geometry.unary_union
res.geometry = res.geometry.apply(lambda x: snap(x, lines2_union, 14))
res.to_file('result.shp', driver="ESRI Shapefile")
И получил этот результат:
линии1 = красные линии
линии2 = черные линии
После привязки (с допуском 14): синие линии - результат привязки
В этом случае линии правильно отрезаны
Другой пример, где это не сработало, как ожидалось: (до щелчка)
И вот результат после привязки. Только часть привязана к черной линии (южная сторона). Хотя оригинальные линии довольно близки и в пределах 14 футов
Если я увеличиваю допуск, я получаю неправильный вывод, что-то вроде этого (после определения 20 как допуск привязки, зеленая линия - результат):
Любые идеи о том, почему привязка не работает должным образом? Любые предложения о том, как решить эту проблему?
Ответы:
shapely.ops.snap
Функция привязывается к вершинам только геометрий.Смотрите иллюстрацию ниже. Слева красная вершина находится в пределах допуска привязки к синей вершине, поэтому она будет привязана. Справа красная вершина находится вне допустимого отклонения (несмотря на то, что она ближе к краю!).
Shapely не предоставляет алгоритм привязки вершин к ребрам. Это не должно быть слишком сложно, чтобы написать один, используя
shapely.ops.nearest_points
хотя. Примерно так (не проверено и не особенно эффективно):источник
if p1.distance(p2 <= threshold):
должно бытьif p1.distance(p2) <= threshold: