#python #pandas #geopandas #shapely
#python #pandas #геопанды #стройный
Вопрос:
У меня есть фрейм данных с полигонами, и я хотел бы выполнить цикл, чтобы создать новый столбец, проверяющий, находится ли определенная точка в пределах одного или нескольких полигонов (поскольку они не являются эксклюзивными). Я пытался следовать руководству geopandas, но, похоже, это не работает, так как все столбцы возвращают «False». Можно ли указать, что я делаю неправильно? Большое спасибо. На всякий случай, файл «quartier_paris.geojson» является классическим файлом geojson, он читается без проблем (появляются фигуры, и я могу пройти все quartiers.explore(), например, и увидеть все полигоны на карте, и я на 100% уверен, что точка находится внутри этих полигонов. Размер файла слишком велик для загрузки, хотя это ссылка на него на всякий случай https://parisdata.opendatasoft.com/explore/dataset/quartier_paris/download/?format=geojsonamp;timezone=Europe/Berlinamp;lang=fr)
import pandas as pd
import geopandas
import os
import shapely
from shapely.geometry import Polygon, LineString, Point
quartiers = geopandas.read_file("quartier_paris.geojson")
p1 = Point(48.823, 2.30)
quartiers["Match"] =quartiers["geometry"].apply(lambda x: p1.within(x))
Ответ №1:
- ваша точка не находится ни в одной из геометрий. Кроме того, вы перенесли долготу и широту
- при транспонировании он находится в пределах прямоугольной границы геометрии
- приведенный ниже код показывает тесты и графическое отображение для демонстрации
import requests
import geopandas as gpd
from shapely.geometry import Polygon, LineString, Point, box
import plotly.express as px
import plotly.graph_objects as go
res = requests.get(
"https://parisdata.opendatasoft.com/explore/dataset/quartier_paris/download/?format=geojsonamp;timezone=Europe/Berlinamp;lang=fr"
)
gdf = gpd.GeoDataFrame.from_features(res.json())
p1 = Point(48.823, 2.30)
p2 = Point(2.30, 48.823)
print(
f"""
p1 in total bounds: {p1.within(box(*gdf.total_bounds))}
p2 in total bounds: {p2.within(box(*gdf.total_bounds))}
p2 in any geometry: gdf["geometry"].apply(lambda g: p2.within(g)).any()
"""
)
px.scatter_mapbox(lon=[p2.x], lat=[p2.y]).update_layout(
mapbox={
"style": "carto-positron",
"zoom": 10,
"layers": [
{"source": gdf["geometry"].__geo_interface__, "type": "line"},
{
"source": gdf["geometry"]
.apply(lambda g: box(*g.bounds))
.__geo_interface__,
"type": "line",
"color": "skyblue",
},
{
"source": box(*gdf.total_bounds).__geo_interface__,
"type": "line",
"color": "blue",
},
],
},
margin={"l": 0, "r": 0, "t": 0, "b": 0},
).update_traces(marker_size=20)