基于Azure高程API数据用Plotly绘制3D高程曲面图的实现问题
问题解答
疑问1:是否需要将经纬度转换为x,y坐标,最优实现方式是什么?
- 是需要转换的。因为经纬度是球面坐标,直接作为平面xy轴绘图会因为纬度带来的长度形变导致曲面比例失真,尤其是业务数据范围较大时形变会更明显。
- 你当前使用的UTM投影转换就是最优方案之一,UTM是横轴墨卡托投影,在小范围(单个UTM带内)的形变误差可以忽略,完全满足高程剖面和3D曲面绘制的精度要求,你现有代码里调用
utm.from_latlon的逻辑是对的,如果业务数据范围跨UTM带,统一转到同一个投影带即可。
疑问2:是否需要将Z轴高程数据转换为二维数组?
- 是必须转换的。Plotly的
go.Surface要求入参的z是二维数组,x和y可以是一维数组(分别对应z的列、行坐标),你现在把x、y、z都存为一维列表直接传入的话,Surface图会渲染失败,无法生成正确的曲面。
修正后可直接运行的代码
先安装依赖的utm库:pip install utm
完整代码如下:
import plotly.graph_objs as go import utm import numpy as np elevation = {'data': [{'coordinate': {'latitude': -33.88676483475523, 'longitude': 150.84667222543544}, 'elevationInMeter': 59.76341}, {'coordinate': {'latitude': -33.88676483475523, 'longitude': 150.84689611369265}, 'elevationInMeter': 58.91294}, {'coordinate': {'latitude': -33.88676483475523, 'longitude': 150.8471200019499}, 'elevationInMeter': 58.2653}, {'coordinate': {'latitude': -33.88676483475523, 'longitude': 150.8473438902071}, 'elevationInMeter': 57.80102}, {'coordinate': {'latitude': -33.88657811224419, 'longitude': 150.84667222543544}, 'elevationInMeter': 60.25625}, {'coordinate': {'latitude': -33.88657811224419, 'longitude': 150.84689611369265}, 'elevationInMeter': 59.25375}, {'coordinate': {'latitude': -33.88657811224419, 'longitude': 150.8471200019499}, 'elevationInMeter': 58.59771}, {'coordinate': {'latitude': -33.88657811224419, 'longitude': 150.8473438902071}, 'elevationInMeter': 58.17687}, {'coordinate': {'latitude': -33.88639138973315, 'longitude': 150.84667222543544}, 'elevationInMeter': 60.63495}, {'coordinate': {'latitude': -33.88639138973315, 'longitude': 150.84689611369265}, 'elevationInMeter': 59.59782}, {'coordinate': {'latitude': -33.88639138973315, 'longitude': 150.8471200019499}, 'elevationInMeter': 58.97992}, {'coordinate': {'latitude': -33.88639138973315, 'longitude': 150.8473438902071}, 'elevationInMeter': 58.59934}, {'coordinate': {'latitude': -33.8862046672221, 'longitude': 150.84667222543544}, 'elevationInMeter': 61.03286}, {'coordinate': {'latitude': -33.8862046672221, 'longitude': 150.84689611369265}, 'elevationInMeter': 60.10513}, {'coordinate': {'latitude': -33.8862046672221, 'longitude': 150.8471200019499}, 'elevationInMeter': 59.54065}, {'coordinate': {'latitude': -33.8862046672221, 'longitude': 150.8473438902071}, 'elevationInMeter': 59.13883}]} val_x = [] val_y = [] val_z = [] for entry in elevation['data']: x, y, zone, ut = utm.from_latlon(entry['coordinate']['latitude'], entry['coordinate']['longitude']) val_x.append(x) val_y.append(y) val_z.append(entry['elevationInMeter']) # 转换为4x4的二维结构,示例数据为4行纬度×4列经度的网格 # 先取去重后的一维x、y坐标 x_unique = np.unique(val_x) y_unique = np.unique(val_y) # 构造二维z数组 z_2d = np.array(val_z).reshape(len(y_unique), len(x_unique)) fig = go.Figure(data=[go.Surface(x=x_unique, y=y_unique, z=z_2d)]) fig.update_traces(contours_z=dict( show=True, usecolormap=True, highlightcolor="limegreen", project_z=True)) # 可选:调整坐标轴命名更清晰 fig.update_layout( scene = dict( xaxis_title='UTM东向坐标 (m)', yaxis_title='UTM北向坐标 (m)', zaxis_title='高程 (m)' ) ) fig.show()
内容的提问来源于stack exchange,提问作者Rob Hess
相关产品推荐
相关产品推荐

