用Python实现ASCII类型栅格数据转NC文件


Hello!Hello!大家好!
今天给大家带来的主要是如何利用Python读取ASCII码形式的数据,并将其转化为NC文件
预告:下一期将给大家带来ASCII码形式数据转TIF(有地理信息坐标的哦!)

数据准备

如果无需复现程序,可以直接跳过这一部分的内容,从下一节开始啦 \color{red}{如果无需复现程序,可以直接跳过这一部分的内容,从下一节开始啦} 如果无需复现程序,可以直接跳过这一部分的内容,从下一节开始啦

为了方便本次教程的开展,我还是使用NCEP的多气压层气温数据,只是我这里为方便大家复现整个流程,现将其转为ASCII形式再用Python对其进行处理,下载网址在这里:点我,点我,快点我

预处理

ArcGIS打开NC
在这里插入图片描述
接下来使用这个工具就行将TIF转为ASCII
在这里插入图片描述

示例数据展示

如果大家需要处理的数据是这个类型的,或者和这样子很像的文本数据(知道坐标网格的)其实处理起来的本质是一样的,那么接下里就开始本次教程把!
在这里插入图片描述

代码讲解

库函数准备

想要完成这个流程需要的库函数其实并不多,就下面这几个。

import xarray as xr
import numpy as np

文件读取

很简单,

def read_ASCII(file):
    """
    读取ASCII文件
    :param file: 输入是f.readlines(),一个列表文件
    :return: 还是一个列表文件   
    :功能:防止文件中间或者末尾有空行
    """

    file_tep = []
    for j in range(len(file)):
        if len(file[j].split()) != 0:
            file_tep.append(file[j])
    file = file_tep
f = open(r'D:\优快云/ascii示例数据.txt')
file = read_ASCII(f.readlines())

经纬度生成

根据ASCII文件的格式类型,我们发现前六行都是网格信息,那么我们第一步就是先要将网格信息读取出来。

for num,value in enumerate(file):
        value = value.split()
        if len(value) != 0:
            if num == 0:
                cols = int(value[-1]) #列数
            elif num == 1:
                rows = int(value[-1]) #行数
            elif num == 2:
                s_lon = float(value[-1]) #左上角经度
            elif num == 3:
                s_lat = float(value[-1]) #左上角纬度
            elif num == 4:
                cell_size = float(value[-1]) #单元格大小
            elif num == 5:
                mask_value = float(value[-1]) #掩膜数值
print(cols,rows,s_lon,s_lat,cell_size,mask_value)
lat = np.arange(-90,90+0.1,2.5)[::-1]
lon = np.arange(0,360,2.5)
print(len(lat),len(lon))
print(lat,lon)

输出结果
在这里插入图片描述结果显示的是起始经纬度分别是 − 1.25 和 − 91.25 \color{red}{-1.25和-91.25} 1.2591.25,而我在上边使用的 0 和 − 90 \color{red}{0和-90} 090,这个起始是ArcGIS本身储存网格数据的机制造成的,我们在处理的时候一般是指网格中心经纬度,而ArcGIS是网格边缘经纬度,所以就造成了相差1.25(刚好是一半的单元格大小哦!),这个不是很重要的。

数组生成

values_array = np.zeros((rows,cols)) #创建一个空矩阵
f.seek(0) # 将文件指针重新定位到文件开头
n = 0
for num,value in enumerate(file):
        value = value.split()
        if len(value) != 0: # 如果文件中有空行,则不进行读取
            if num > 5:
                for j in range(len(value)):
                    if float(value[j]) == mask_value:
                        value[j] = np.nan # 根据mask_value将mask_value设置为nan
                    else:
                        value[j] = float(value[j])
                values_array[n,:] = value
                n = n+1
    
f.close()
print(values_array)

保存为NC文件

from metpy.units import units
ds = xr.Dataset()
# *units.degC 是给气温赋单位,有没有单位都可以,锦上添花的东西
ds['1000hPa气温'] = (('lat','lon'),values_array*units.degC)
ds.coords['lat'] = ('lat',lat)
ds.coords['lon'] = ('lon',lon)
ds.to_netcdf(r'D:\优快云/ascii示例数据.nc')

完整代码奉上

import xarray as xr
import numpy as np
from metpy.units import units

def read_ASCII(file):
    """
    读取ASCII文件
    :param file: 输入是f.readlines(),一个列表文件
    :return: 还是一个列表文件   
    :功能:防止文件中间或者末尾有空行
    """

    file_tep = []
    for j in range(len(file)):
        if len(file[j].split()) != 0:
            file_tep.append(file[j])
    file = file_tep
    return file
f = open(r'D:\优快云/ascii示例数据.txt')
file = read_ASCII(f.readlines())

for num,value in enumerate(file):
        value = value.split()
        if len(value) != 0:
            if num == 0:
                cols = int(value[-1])
            elif num == 1:
                rows = int(value[-1])
            elif num == 2:
                s_lon = float(value[-1])
            elif num == 3:
                s_lat = float(value[-1])
            elif num == 4:
                cell_size = float(value[-1])
            elif num == 5:
                mask_value = float(value[-1])
print(cols,rows,s_lon,s_lat,cell_size,mask_value)
lat = np.arange(-90,90+0.1,2.5)[::-1]
lon = np.arange(0,360,2.5)
print(len(lat),len(lon))
print(lat,lon)

values_array = np.zeros((rows,cols)) #创建一个空矩阵
f.seek(0) # 将文件指针重新定位到文件开头
n = 0
for num,value in enumerate(file):
        value = value.split()
        if len(value) != 0: # 如果文件中有空行,则不进行读取
            if num > 5:
                for j in range(len(value)):
                    if float(value[j]) == mask_value:
                        value[j] = np.nan # 根据mask_value将mask_value设置为nan
                    else:
                        value[j] = float(value[j])
                values_array[n,:] = value
                n = n+1
    
f.close()
print(values_array)

ds = xr.Dataset()
# *units.degC 是给气温赋单位,有没有单位都可以,锦上添花的东西
ds['1000hPa气温'] = (('lat','lon'),values_array*units.degC)
ds.coords['lat'] = ('lat',lat)
ds.coords['lon'] = ('lon',lon)
ds.to_netcdf(r'D:\优快云/ascii示例数据.nc')

预告

下一期打算做一下如何直接使用ASCII文件生成TIF文件

### GEBCO DEM 数据概述 GEBCO (General Bathymetric Chart of the Oceans) 提供全球海洋地形模型,旨在提供尽可能最全面的海底地形描述。该数据集广泛应用于科学研究、资源管理以及环境监测等领域。 #### 下载方式 GEBCO 数据可通过官方网站获取。用户可以根据需求选择不同版本的数据产品: - **GEBCO Grid**: 全球网格化 bathymetry 数据,分辨率为 30 arc-second (~900 m at equator)[^2]。 - **GEBCO One Minute Grid**: 较低分辨率版本,适用于大范围研究区域快速浏览。 - **GEBCO_2022 Global gridded data set**: 最新版全局栅格数据集合,提供了更高精度的选择。 访问 [GEBCO 官方网站](https://www.gebco.net/) 后,在页面顶部导航栏找到 “Data & Products”,点击进入可以查看并下载所需的产品文件。 #### 文件格式说明 GEBCO 发布的主要数据格式包括 NetCDF 和 ESRI ASCII Grid: - **NetCDF (.nc)**: 推荐使用的二进制存储格式,支持多维数组结构,便于高效读取大规模数据集。此格式兼容多种主流 GIS 软件平台如 QGIS 或 ArcGIS Pro。 - **ESRI ASCII Grid (.asc)**: 文本形式的空间栅格数据表示法,易于解析但体积较大。适合用于编程语言处理(例如 Python 的 `numpy` 库加载),也容易与其他开源工具集成。 对于希望进一步了解具体编码细节的情况,可查阅官方文档中的元数据部分来获得更详尽的技术参数。 #### 使用方法示例 为了方便开发者和研究人员利用这些宝贵的数据源,下面给出一段简单的 Python 代码片段展示如何加载并可视化 GEBCO NetCDF 格式的高程数据: ```python import netCDF4 as nc import matplotlib.pyplot as plt from mpl_toolkits.basemap import Basemap # 打开 NETCDF 文件 dataset = nc.Dataset('gebco_data.nc') # 获取变量信息 lon = dataset.variables['lon'][:] lat = dataset.variables['lat'][:] elevation = dataset.variables['elevation'][:] # 绘制地图背景 plt.figure(figsize=(10, 8)) m = Basemap(projection='cyl', resolution='l', llcrnrlat=min(lat), urcrnrlat=max(lat), llcrnrlon=min(lon), urcrnrlon=max(lon)) m.drawmapboundary(fill_color='#A6CAE0') m.fillcontinents(color='grey', lake_color='#A6CAE0') m.drawcountries() # 添加等深线图层 cs = m.contourf(*m.makegrid(lon, lat), elevation, cmap=plt.cm.jet) cb = m.colorbar(cs, "right", size="5%", pad='2%') cb.set_label('Depth (meters below sea level)') plt.title('GEBCO Elevation Data Visualization') plt.show() ``` 这段脚本实现了从本地磁盘读入指定路径下的 `.nc` 文件,并通过 Matplotlib 及其扩展包 Basemap 来呈现彩色填充轮廓的地图视图,直观展现了水下地貌特征。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷心没有菜

你若晌饭便是义父!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值