使用 Pydeck 可视化 3D 空间数据
在本文中,我将向您介绍 Python 包PyDeck,这是一个在 Python 中创建 3D 地图的工具。
作为示例,我将使用城市3D 建筑模型数据库。
建筑数据
数据来源于公开的布达佩斯开放数据图集 https://atlo.team/boda/

快速下载后,让我们打开文件并快速查看一下:
# import geopandas
import geopandas as gpd
# parse the building height data set
gdf = gpd.read_file('/home/mw/input/ThreeDBuilding6834/epuletmagassag.geojson')
gdf.plot()
len(gdf)

该图显示,建筑物占地面积(总计超过 35 万平方米)遍布布达佩斯市各处。
数据结构如下:
gdf.head(3)

为了进一步使用,需要从该表中提取两件事:包含建筑物高度信息的列 DN 和包含建筑物足迹几何的几何图形。
数据准备
解析了 35 万行的 GeoDataframe 后,您还会意识到,对于快速演示来说,这有点太多了。因此,为了确保我们能够专注于此处的酷炫和高效的视觉效果,我决定将数据集缩小到布达佩斯中部地区第 5 区。
admin_district = gpd.read_file('/home/mw/project/Budapest.shp')
admin_district.plot()

# filter out the bulding footprints that fall into my selected districts
gdf2 = gpd.overlay(gdf, admin_district)
len(gdf2)
这个叠加的 GeoDataFrame 显示我们成功过滤了数据——现在我们只有大约 8k 个足迹。
顺便说一句,下面的快速柱状图告诉我们,该地区只有三座建筑的高度超过 60 米,经过数据框过滤后,发现是两座建筑——大教堂和议会大厦。
gdf2.DN.hist()
gdf2[gdf2.DN>60][['DN', 'name_1']]

创造视觉效果
首先,让我们通过将每栋建筑的颜色设置为红色来创建更基本的 3D 建筑地图版本。使用 Pydeck,最好使用 RGB 代码。此外,通过更改 view_state,我们可以设置地图的中心以及缩放级别。
扫描二维码关注公众号,回复:
17514269 查看本文章

import pydeck as pdk
layer = pdk.Layer(
'PolygonLayer',
data=gdf2,
get_polygon='geometry.coordinates',
extruded=True,
get_elevation='DN',
get_fill_color = [255, 0, 0],
)
view_state = pdk.ViewState(
latitude=47.499919,
longitude=19.0530236,
zoom=13,
)
# Create the 3D map
r = pdk.Deck(layers=[layer], initial_view_state=view_state)
r

放大后细节还不错:

然后,我们可以进一步微调绘图,例如,通过改变高程比例使高度差异更加明显,得出一个比例参数,我们可以将其纳入着色中。这样,我们可以根据任何参数为建筑模型着色,或者也可以更改线条颜色。
import math
# do the scaling
max_val = max(gdf2.DN)
gdf2['scaled'] = [0.2 + (d/max_val) for d in gdf2.DN.to_list()]
# add the data
layer = pdk.Layer(
'PolygonLayer',
data=gdf2,
get_polygon='geometry.coordinates',
extruded=True,
get_elevation='DN',
elevation_scale=4,
get_line_color=[255, 255, 255],
get_fill_color="[255, 0, scaled * 255]"
)
# set the view state
view_state = pdk.ViewState(
latitude=47.499919,
longitude=19.0530236,
zoom=13,
)
# Create the 3D map
r = pdk.Deck(layers=[layer], initial_view_state=view_state)
r

最后,使用相机方向设置进一步调整视图状态,并将输出保存为 html 文件。
import math
# do the scaling
max_val = max(gdf2.DN)
gdf2['scaled'] = [0.2 + (d/max_val) for d in gdf2.DN.to_list()]
# add the data
layer = pdk.Layer(
'PolygonLayer',
data=gdf2,
get_polygon='geometry.coordinates',
extruded=True,
get_elevation='DN',
elevation_scale=4,
get_line_color=[255, 255, 255],
get_fill_color="[255, 0, scaled * 255]"
)
# set the view state
view_state = pdk.ViewState(
latitude=47.499919,
longitude=19.0530236,
zoom=14,
pitch=45, # controls the angle of the camera relative to the ground
bearing = 30 # controls the rotation of the camera around the vertical axis
)
# Create the 3D map
r = pdk.Deck(layers=[layer], initial_view_state=view_state)
r

细节相当好
