python - 使用空间连接计算距离 - geopandas

导入请求、io、json 导入 geopandas 作为 gpd 导入 shapely.geometry 导入 pandas 作为 pd

我有两个 GeoPandas 数据帧。

gpd1POLYGON 几何 gpd2POINT 几何

示例数据:

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

相似文章

最新文章