Interseção de polígono da linha Geopandas

11

Estou tentando descobrir onde várias linhas cruzam um polígono para dois geodataframes diferentes:

from shapely.geometry import Polygon, LineString
import geopandas as gpd

polygon = Polygon([(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)])
line1 = LineString([(0.5, 0.5), (0.7, 0.7)])
line2 = LineString([(0.9, 0.9), (0.2, 0.6)])


poly_gdf = gpd.GeoDataFrame(geometry=[polygon])
line_gdf = gpd.GeoDataFrame(geometry=[line1, line2])

É assim que os quadros de geodata acima se parecem (um com um polígono e o outro com duas linhas). Parece-me que as duas linhas cruzam o polígono:

Polígono e linhas

No entanto, a saída de interseção é muito confusa:

print(line_gdf.intersects(poly_gdf))

0 Verdadeiro

1 Falso

print(line1.intersects(polygon))
print(line2.intersects(polygon))

Verdade

Verdade

Por que o geopandas intersectmétodo fornece uma saída diferente da padrão shapely?

Estou usando o Python 3.5.3 e o Geopandas 0.2.1 no Anaconda.

bgordon
fonte
Quando você diz print(line.intersects(polygon))que está acessando uma variável que não está definida, tanto quanto eu posso ver. Você definiu line1e line2anteriormente no código. Não sei por que isso retornaria True.
Paulo
2
Eu gostaria de saber a resposta para isso também. Parece que você só pode atribuir uma única coluna de geometria a um quadro de geodados. Acho que seu quadro de dados line_gdf tenta adicionar duas colunas geométricas. Verifique geopandas.org/data_structures.html#geodataframe
Paul
@Paul minhas desculpas, print(line.intersects(polygon))foi um erro de digitação. Atualizei a pergunta para me referir a line1qual foi o que eu originalmente quis dizer.
bgordon
@ Paul Posso ver na documentação como ter duas colunas de geometria causaria um problema, mas não sei ao certo por que duas colunas de geometria seriam adicionadas em primeiro lugar.
bgordon
line_gdf.infoconfirma que você possui apenas uma coluna geométrica única. Estou perplexo. Vou acompanhar se encontrar alguma coisa.
Paulo

Respostas:

7

Ao comparar quadros geodados com operações de geometria no Geopandas, as geometrias são correspondidas primeiro pelo índice. No caso em que não há índice correspondente (porque você possui apenas um único polígono, por exemplo), o resultado será False.

Se fosse comparar cada objeto no, GeoSeriesseria necessário recuperar um quadro de dados retangular completo de valores booleanos, e isso provavelmente seria muito ineficiente.

Se você deseja comparar todas as geometrias, você tem duas opções. O primeiro (e provavelmente o mais fácil) é usar o sjoinmétodo geopandas :

gpd.sjoin(line_gdf, poly_gdf, op='intersects')

Isso retorna um novo GeoDataFramecom as geometrias para cada objeto no quadro de dados esquerdo repetido para cada geometria que eles cruzam à direita, com o índice do objeto à direita, ou seja:

                        geometry  index_right
0  LINESTRING (0.5 0.5, 0.7 0.7)            0
1  LINESTRING (0.9 0.9, 0.2 0.6)            0

O segundo método é o applymétodo pandas GeoSeriespara retornar o dataframe retangular:

line_gdf.geometry.apply(lambda g: poly_gdf.intersects(g))

O que, por sua vez, retorna (com ineficiência crescente à medida que os quadros de dados crescem):

index_right     0
index_left
0            True
1            True

Em geral, a menos que você precise da matriz quadrada, meu conselho seria seguir o sjoinmétodo.

om_henners
fonte