导入请求、io、json 导入 geopandas 作为 gpd 导入 shapely.geometry 导入 pandas 作为 pd
我有两个 GeoPandas 数据帧。
gpd1
与 POLYGON
几何 gpd2
与 POINT
几何
示例数据:
res = requests.get(
"https://opendata.arcgis.com/datasets/69dc11c7386943b4ad8893c45648b1e1_0.geojson"
)
gpd1 = gpd.GeoDataFrame.from_features(res.json()["features"], crs="CRS84").pipe(
lambda d: d.rename(columns={c: c.lower() for c in d.columns})
).rename(columns={"lad20cd": "areaCode","lad20nm":"areaName"})
# get some public addressess - hospitals. data that can be scattered
dfhos = pd.read_csv(io.StringIO(requests.get("http://media.nhschoices.nhs.uk/data/foi/Hospital.csv").text),
sep="¬",engine="python",)
# create a geo dataframe of hospitals
gpd2 = gpd.GeoDataFrame(
data=dfhos,
geometry=dfhos.apply(lambda r: shapely.geometry.Point(r["Longitude"],r["Latitude"]), axis=1), crs="EPSG:4326"
)
我空间加入他们:
gpd1.sjoin(gpd2, how='left')
我还想计算加入的每一行的距离。如何计算距离并将 distance
作为一列包含在内?请注意,gpd2
中的每个 POINT
都在 POLYGON
内。
回答1
- 与您的问题一样,模棱两可或您的示例代码无法开始工作
- 有固定的示例代码使用英国县和英国城镇/城市
sjoin()
的结果是列 right_index 这可用于构造一系列点- 那么这是一个使用 geopandas
distance()
来获取距离的简单案例
import pandas as pd
import geopandas as gpd
import requests, io
# some polygons
gpd1 = gpd.read_file(
requests.get("https://www.geoboundaries.org/api/current/gbOpen/GBR/ADM2").json()[
"simplifiedGeometryGeoJSON"
]
)
# some points
df = pd.read_csv(
io.StringIO(
requests.get("https://simplemaps.com/static/data/country-cities/gb/gb.csv").text
)
)
gpd2 = gpd.GeoDataFrame(
df, geometry=gpd.points_from_xy(df["lng"], df["lat"]), crs="epsg:4326"
)
gpd_sj = gpd1.sjoin(gpd2, how="inner").reset_index()
gpd_sj["distance"] = gpd_sj.distance(gpd2.loc[gpd_sj["index_right"]])
gpd_sj.loc[:, ["index", "shapeName", "index_right", "city", "distance"]]
index | shapeName | index_right | city | distance | |
---|---|---|---|---|---|
0 | 0 | Hartlepool | 1606 | Seaton Carew | 3.29536 |
1 | 0 | Hartlepool | 96 | Hartlepool | 2.22489 |
2 | 1 | Middlesbrough | 2466 | Stainton | 1.41667 |
3 | 1 | Middlesbrough | 1849 | Nunthorpe | 0.766652 |
4 | 1 | Middlesbrough | 1129 | Marton | 0.581443 |
5 | 1 | Middlesbrough | 36 | Middlesbrough | 1.8294 |
6 | 2 | Redcar and Cleveland | 1628 | Ormesby | 3.30945 |
7 | 2 | Redcar and Cleveland | 635 | Guisborough | 2.11976 |
8 | 2 | Redcar and Cleveland | 1330 | Loftus | 3.68467 |
9 | 2 | Redcar and Cleveland | 1167 | Skelton | 3.60919 |