使用空间连接计算距离 - geopandas
Calculate distances with spatial join - geopandas
导入请求,io,json
将 geopandas 导入为 gpd
导入 shapely.geometry
将 pandas 导入为 pd
我有两个 GeoPandas DataFrame。
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
.
中
- 与您的问题一样,模棱两可或您的示例代码无法正常工作
- 有固定的示例代码来使用英国县和英国城镇/城市
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
导入请求,io,json 将 geopandas 导入为 gpd 导入 shapely.geometry 将 pandas 导入为 pd
我有两个 GeoPandas DataFrame。
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
.
- 与您的问题一样,模棱两可或您的示例代码无法正常工作
- 有固定的示例代码来使用英国县和英国城镇/城市
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 |