备注

互动在线版: Binder badge

使用Folium绘制多边形#

此示例演示如何在Folium贴图上绘制多边形。

[1]:
import geopandas as gpd
import folium
import matplotlib.pyplot as plt

加载几何图形#

本例使用包含纽约区的多边形的NIBB数据集。

[2]:
path = gpd.datasets.get_path('nybb')
df = gpd.read_file(path)
df.head()
[2]:
BoroCode BoroName Shape_Leng Shape_Area geometry
0 5 Staten Island 330470.010332 1.623820e+09 MULTIPOLYGON (((970217.022 145643.332, 970227....
1 4 Queens 896344.047763 3.045213e+09 MULTIPOLYGON (((1029606.077 156073.814, 102957...
2 3 Brooklyn 741080.523166 1.937479e+09 MULTIPOLYGON (((1021176.479 151374.797, 102100...
3 1 Manhattan 359299.096471 6.364715e+08 MULTIPOLYGON (((981219.056 188655.316, 980940....
4 2 Bronx 464392.991824 1.186925e+09 MULTIPOLYGON (((1012821.806 229228.265, 101278...

从原始数据集绘制

[3]:
df.plot(figsize=(6, 6))
plt.show()
../_images/gallery_polygon_plotting_with_folium_5_0.png

请注意,多边形几何图形的值并不直接表示地理坐标系中的经纬度的值。要查看几何图形列的坐标参考系,请访问 crs 属性:

[4]:
df.crs
[4]:
<Derived Projected CRS: EPSG:2263>
Name: NAD83 / New York Long Island (ftUS)
Axis Info [cartesian]:
- X[east]: Easting (US survey foot)
- Y[north]: Northing (US survey foot)
Area of Use:
- name: United States (USA) - New York - counties of Bronx; Kings; Nassau; New York; Queens; Richmond; Suffolk.
- bounds: (-74.26, 40.47, -71.8, 41.3)
Coordinate Operation:
- name: SPCS83 New York Long Island zone (US Survey feet)
- method: Lambert Conic Conformal (2SP)
Datum: North American Datum 1983
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich

这个 epsg:2263 CRS是使用线性单位(在本例中为ft)的投影坐标参考系。由于Folium(即,Folium)默认接受纬度和经度(角度单位)的值作为输入,因此我们需要首先将几何体投影到地理坐标系。

[5]:
# Use WGS 84 (epsg:4326) as the geographic coordinate system
df = df.to_crs(epsg=4326)
print(df.crs)
df.head()
epsg:4326
[5]:
BoroCode BoroName Shape_Leng Shape_Area geometry
0 5 Staten Island 330470.010332 1.623820e+09 MULTIPOLYGON (((-74.05051 40.56642, -74.05047 ...
1 4 Queens 896344.047763 3.045213e+09 MULTIPOLYGON (((-73.83668 40.59495, -73.83678 ...
2 3 Brooklyn 741080.523166 1.937479e+09 MULTIPOLYGON (((-73.86706 40.58209, -73.86769 ...
3 1 Manhattan 359299.096471 6.364715e+08 MULTIPOLYGON (((-74.01093 40.68449, -74.01193 ...
4 2 Bronx 464392.991824 1.186925e+09 MULTIPOLYGON (((-73.89681 40.79581, -73.89694 ...
[6]:
df.plot(figsize=(6, 6))
plt.show()
../_images/gallery_polygon_plotting_with_folium_10_0.png

创建Folium贴图#

[7]:
m = folium.Map(location=[40.70, -73.94], zoom_start=10, tiles='CartoDB positron')
m
[7]:
Make this Notebook Trusted to load map: File -> Trust Notebook

将面添加到地图#

在地图上使用弹出的行政区名称覆盖行政区的边界:

[8]:
for _, r in df.iterrows():
    # Without simplifying the representation of each borough,
    # the map might not be displayed
    sim_geo = gpd.GeoSeries(r['geometry']).simplify(tolerance=0.001)
    geo_j = sim_geo.to_json()
    geo_j = folium.GeoJson(data=geo_j,
                           style_function=lambda x: {'fillColor': 'orange'})
    folium.Popup(r['BoroName']).add_to(geo_j)
    geo_j.add_to(m)
m
[8]:
Make this Notebook Trusted to load map: File -> Trust Notebook

添加质心标记#

为了正确计算几何图形的几何属性,在本例中为质心,我们需要将数据投影到投影坐标系。

[9]:
# Project to NAD83 projected crs
df = df.to_crs(epsg=2263)

# Access the centroid attribute of each polygon
df['centroid'] = df.centroid

由于我们再次向Folium地图添加新的几何体,因此需要将该几何体投影回具有经纬度值的地理坐标系。

[10]:
# Project to WGS84 geographic crs

# geometry (active) column
df = df.to_crs(epsg=4326)

# Centroid column
df['centroid'] = df['centroid'].to_crs(epsg=4326)

df.head()
[10]:
BoroCode BoroName Shape_Leng Shape_Area geometry centroid
0 5 Staten Island 330470.010332 1.623820e+09 MULTIPOLYGON (((-74.05051 40.56642, -74.05047 ... POINT (-74.15340 40.58085)
1 4 Queens 896344.047763 3.045213e+09 MULTIPOLYGON (((-73.83668 40.59495, -73.83678 ... POINT (-73.81847 40.70757)
2 3 Brooklyn 741080.523166 1.937479e+09 MULTIPOLYGON (((-73.86706 40.58209, -73.86769 ... POINT (-73.94768 40.64472)
3 1 Manhattan 359299.096471 6.364715e+08 MULTIPOLYGON (((-74.01093 40.68449, -74.01193 ... POINT (-73.96719 40.77725)
4 2 Bronx 464392.991824 1.186925e+09 MULTIPOLYGON (((-73.89681 40.79581, -73.89694 ... POINT (-73.86653 40.85262)
[11]:
for _, r in df.iterrows():
    lat = r['centroid'].y
    lon = r['centroid'].x
    folium.Marker(location=[lat, lon],
                  popup='length: {} <br> area: {}'.format(r['Shape_Leng'], r['Shape_Area'])).add_to(m)

m
[11]:
Make this Notebook Trusted to load map: File -> Trust Notebook