Estou tentando encaixar duas linhas entre si usando Shapely / Geopandas, mas o resultado do encaixe é muito estranho. Eu tentei :
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")
E conseguiu este resultado:
lines1 = linhas vermelhas
lines2 = linhas pretas
Após o encaixe (com 14 como tolerância): as linhas azuis são o resultado do encaixe
Nesse caso, as linhas estão corretamente ajustadas
Outro exemplo em que não funcionou conforme o esperado: (antes do snap)
E aqui está o resultado após o encaixe. Apenas uma parte é encaixada na linha preta (lado sul). Embora as linhas originais estejam bem próximas e dentro dos 14 pés
Se eu aumentar a tolerância, obtenho uma saída errada, algo assim (depois de definir 20 como a tolerância do snap, a linha verde é o resultado):
Alguma idéia de por que o snap não está funcionando corretamente? Alguma sugestão sobre como resolver este problema?
Respostas:
A
shapely.ops.snap
função é ajustada apenas aos vértices das geometrias.Veja a ilustração abaixo. À esquerda, o vértice vermelho está dentro da tolerância de snap ao vértice azul; À direita, o vértice vermelho está fora da tolerância de encaixe (apesar de estar mais próximo da borda!).
Shapely não fornece um algoritmo para ajustar vértices às arestas.
shapely.ops.nearest_points
Porém, não deve ser muito difícil escrever um usando . Algo assim (não testado e não especialmente eficiente):fonte
if p1.distance(p2 <= threshold):
deveria serif p1.distance(p2) <= threshold: