You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python如何反转netCDF数组解决高程数据上下颠倒问题

netCDF高程数据上下颠倒问题修正

高程数据上下颠倒问题示意图

问题说明

从netCDF格式高程文件中提取CSV坐标点对应高程值时,发现文件存储的高程数据南北方向上下颠倒,直接提取的结果位置完全错位。此前尝试将CSV读取的纬度值乘以-1的方案会篡改原始坐标,不符合最终输出的坐标准确性要求。

原有问题代码

import numpy as np
from netCDF4 import Dataset
import matplotlib.pyplot as plt
import pandas as pd
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Path, PathPatch

csv_data = np.loadtxt('CSV with target coordinates',skiprows=1,delimiter=',')
num_el = csv_data[:,0]
lat = csv_data[:,1]
lon = csv_data[:,2]
value = csv_data[:,3]

data = Dataset("elevation Data",'r')
lon_range = data.variables['x_range'][:]
lat_range = data.variables['y_range'][:]
topo_range = data.variables['z_range'][:]
spacing = data.variables['spacing'][:]
dimension = data.variables['dimension'][:]
z = data.variables['z'][:]
lon_num =  dimension[0]
lat_num =  dimension[1]

etopo_lon = np.linspace(lon_range[0],lon_range[1],dimension[0])
etopo_lat = np.linspace(lat_range[0],lat_range[1],dimension[1])
topo = np.reshape(z, (lat_num, lon_num))

height = np.empty_like(num_el)
desired_lat_idx = np.empty_like(num_el)
desired_lon_idx = np.empty_like(num_el)
for i in range(len(num_el)): 
    tmp_lat = np.abs(etopo_lat - lat[i]).argmin()
    tmp_lon = np.abs(etopo_lon - lon[i]).argmin()
    desired_lat_idx[i] = tmp_lat
    desired_lon_idx[i] = tmp_lon
    height[i] = topo[tmp_lat,tmp_lon]
height[height<-10]=0 

print(len(desired_lat_idx))
print(len(desired_lon_idx))
print(len(height))


dfl= pd.DataFrame({
    'Latitude' : lat.reshape(-1),
    'Longitude': lon.reshape(-1),
    'Altitude': height.reshape(-1)
});
print(dfl)

# 要求此处纬度值必须和原始CSV一致,不能修改
df =dfl
lat=np.array(df['Latitude'])
lon=np.array(df['Longitude'])
val=np.array(df['Altitude'])

m = Basemap(projection='robin', lon_0=0, lat_0=0, resolution='l',area_thresh=1000)
m.drawcoastlines(color = 'black')
x,y = m(lon,lat)
colormesh= m.contourf(x,y,val,100, tri=True,  cmap = 'terrain')
plt.colorbar(location='bottom',pad=0.04,fraction=0.06)
plt.show()

无效方案

直接反转原始CSV纬度值的方案会导致坐标准确性失效,不可用:

lat = csv_data[:,1]
lat= lat*(-1)

根因分析

绝大多数公开地形netCDF文件(比如ETOPO系列)的z数组存储顺序为纬度从北向南排列(即第一行对应最北边界,最后一行对应最南边界),但代码中用np.linspace生成的etopo_lat是按纬度值从小到大(从南向北)排列,两者顺序不匹配,导致按纬度索引取高程时取到了南北对称位置的错误值。

修正方法

不需要修改任何原始CSV的坐标值,只需要在reshape得到topo数组后,沿纬度轴(第0轴)上下翻转数组,让topo的行顺序和etopo_lat的纬度顺序一一对应即可。
找到代码中这一行:

topo = np.reshape(z, (lat_num, lon_num))

在它后面新增一行翻转操作:

topo = np.flipud(topo)

其余代码完全不需要改动,后续的索引匹配、DataFrame生成、绘图逻辑都可以正常运行,最终输出的纬度字段完全保留原始CSV的准确值,提取的高程值也会和坐标正确匹配。

验证提示:可以先选取已知高程的点位(如青藏高原点位高程应在4000m以上、沿海平原点位高程在0-100m区间)做校验,确认提取结果正确。

内容的提问来源于stack exchange,提问作者Weiss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 02:54:21