- 已将英格兰的医院用作数据源(有效地车站和医院并且可互换)
- 具有英格兰边界的几何图形(以裁剪 Voronoi 多边形)
- 然后生成代表所有医院的多边形变得简单
- 使用
sjoin() 将多边形与带有所有相关属性的点相关联
- 已使用 plotly 来可视化和演示具有与其相关联的医院属性的多边形
import shapely.ops
# points for hospitals
gdf = gpd.GeoDataFrame(
geometry=dfhos.loc[:, ["Longitude", "Latitude"]].apply(
shapely.geometry.Point, axis=1
)
)
# generate voroni polygon for each hospital
gdfv = gpd.GeoDataFrame(
geometry=[
p.intersection(uk)
for p in shapely.ops.voronoi_diagram(
shapely.geometry.MultiPoint(gdf["geometry"].values)
).geoms
]
)
# spatial join polygons to points to pick up full details of hospital
gdf3 = gpd.sjoin(gdfv, gdf, how="left").merge(
dfhos, left_on="index_right", right_index=True
)
gdf3["Color"] = pd.factorize(gdf3["Postcode"], sort=True)[0]
# and visualize
fig = (
px.choropleth_mapbox(
gdf3,
geojson=gdf3.__geo_interface__,
locations=gdf3.index,
hover_data=["OrganisationCode","OrganisationName","Postcode"],
color="Color",
color_continuous_scale="phase",
)
.update_layout(
mapbox={
"style": "carto-positron",
"center": {
"lon": sum(gdf3.total_bounds[[0, 2]]) / 2,
"lat": sum(gdf3.total_bounds[[1, 3]]) / 2,
},
"zoom": 5,
},
margin={"l": 0, "r": 0, "t": 0, "b": 0},
coloraxis={"showscale":False}
)
)
fig
获取英格兰医院的位置和英格兰边界的多边形
import geopandas as gpd
import shapely.geometry
import numpy as np
import plotly.express as px
import requests, io
from pathlib import Path
from zipfile import ZipFile
import urllib
import pandas as pd
# fmt: off
# uk geometry
url = "http://geoportal1-ons.opendata.arcgis.com/datasets/687f346f5023410ba86615655ff33ca9_1.zip"
f = Path.cwd().joinpath(urllib.parse.urlparse(url).path.split("/")[-1])
if not f.exists():
r = requests.get(url, stream=True, headers={"User-Agent": "XY"})
with open(f, "wb") as fd:
for chunk in r.iter_content(chunk_size=128):
fd.write(chunk)
zfile = ZipFile(f)
zfile.extractall(f.stem)
f2 = Path.cwd().joinpath("uk.geojson")
if not f2.exists():
gdf2 = gpd.read_file(list(f.parent.joinpath(f.stem).glob("*.shp"))[0])
gdf2 = gdf2.loc[gdf2["ctyua16cd"].str[0] == "E"]
uk = gpd.GeoDataFrame(geometry=[p for p in shapely.ops.unary_union(gdf2.to_crs(gdf2.estimate_utm_crs())["geometry"].values).simplify(5000).geoms]).set_crs(gdf2.estimate_utm_crs()).to_crs("EPSG:4326")
uk.to_file(Path.cwd().joinpath("uk.geojson"), driver='GeoJSON')
uk = gpd.read_file(f2)
uk = shapely.geometry.MultiPolygon(uk["geometry"].values)
# fmt: on
# get hospitals in UK
dfhos = pd.read_csv(io.StringIO(requests.get("https://assets.nhs.uk/data/foi/Hospital.csv").text),sep="Č",engine="python",)
dfhos = dfhos.loc[lambda d: d["Sector"].eq("NHS Sector") & d["SubType"].eq("Hospital")].groupby("ParentODSCode").first()