利用PYTHON将netcdf(.nc)格式数据转换成JSON GeoJSON_nc文件转json_水成文 鸿长飞的博客-程序员秘密

技术标签: python  node.js  javascript  

PYTHON netcdf(.nc)格式数据转JSON GeoJSON

代码

废话不多,直接上代码

#%%
import xarray as xr
import json
from datetime import datetime,timedelta
import numpy as np
from glob import glob

# %%
def gen_data_dict(data_array, reftime, parameterNumber, parameterNumberName):
    """
        data_array: an xarray data with two dimensions;
        parameterNumber: the number the same as example data;
        parameterNumberName: the same as example data.
            
    """
    numberPoints = np.size(data_array)
    nx, ny = data_array.shape[:]
    parameterNumberName = 'U_component_of_current'
    parameterNumber = 2
    lo1 = data_array['lon_uv'].min()
    la1 = data_array['lat_uv'].max()
    lo2 = data_array['lon_uv'].max()
    la2 = data_array['lat_uv'].min()
    dx = np.gradient(data_array['lon_uv']).mean()
    dy = np.gradient(data_array['lat_uv']).mean()
    header_dict = {
    
        'discipline': 10,
        'disciplineName': 'Oceanographic_products',
        'center': 0,
        'centerName': 'Ocean Modeling and Observation Laboratory',
        'refTime': reftime,
        'significanceOfRT': 0,
        'significanceOfRTName': 'Analysis',
        'parameterCategory': 1,
        'parameterCategoryName': 'Currents',
        'parameterNumber': parameterNumber,
        'parameterNumberName': parameterNumberName,
        'parameterUnit': 'm.s-1',
        'forecastTime': 0,
        'surface1Type': 160,
        'surface1TypeName': 'Depth below sea level',
        'surface1Value': 15,
        'numberPoints': numberPoints,
        'shape': 0,
        'shapeName': 'Earth spherical with radius = 6,367,470 m',
        'scanMode': 0,
        'nx': nx,
        'ny': ny,
        'lo1': float(lo1),
        'la1': float(la1),
        'lo2': float(lo2),
        'la2': float(la2),
        'dx': dx,
        'dy': dy
    }
    nan_to_none = np.fliplr(np.where(np.isnan(data_array), None, data_array))
    data_list = list(nan_to_none.ravel('F'))
    return {
    'header':header_dict,'data':data_list}

#%% 
if __name__ == '__main__':
    file_path = '20090101-20090103\*.nc'
    file_list = glob(file_path)
    file_list.sort()
    for file_name in file_list:
        ds = xr.open_dataset(file_name,decode_times=False)
        #%% -----------------covert time --------------
        matlab_datenum = ds['time'].values[0]
        # file_time = datetime.fromordinal(int(matlab_datenum)) + timedelta(days=matlab_datenum%1) - timedelta(days = 366)
        file_time = datetime.fromordinal(int(matlab_datenum)) - timedelta(days = 366)
        print(file_time)
        # ds['time'] = file_time
        reftime = file_time.strftime('%Y-%m-%dT00:00:00.000Z')
        # step = 10
        depth_layer = 14
        u = np.squeeze(ds['u'][depth_layer])
        parameterNumberName = 'U_component_of_current'
        parameterNumber = 2
        json_u = gen_data_dict(u, reftime,parameterNumber, parameterNumberName)
        v = np.squeeze(ds['v'][depth_layer])
        parameterNumberName = 'V_component_of_current'
        parameterNumber = 3
        json_v = gen_data_dict(v, reftime,parameterNumber, parameterNumberName)
        json_list = [json_u, json_v]
        date_str = file_time.strftime('%Y%m%d')
        if depth_layer==0:
            surface = 'surface'
        else:
            # surface = f'{depth_layer}m'
            surface = '100m'
        #%% ------------------output-------------------
        with open(f'public\data\oscar\{
      date_str}-{
      surface}-currents-oscar-0.33.json', 'w') as fp:
            json.dump(json_list, fp)
        # ds2 = xr.combine_by_coords([u,v])
        # ds2.to_netcdf(f'20090101-20090103\ROMS_0_{date_str}.nc')
    print('Done')

代码解释

首先是定义了一个函数,要求输入的第一个参数为一个二维的矩阵,实际上是个xarray的dataarray,对xarray不熟悉的可以参阅 官方文档 ,第二和第三个参数是按照给的geojson例子设定的,在本例子中u v方向分量的number分别是2和3,第三个参数是变量描述名。函数的功能是计算nx, ny, dx, dy和转换数据等功能,注意使用ravel转换成一维数据时要使用参数’F’, 才是符合JS读取的顺序的。

在实际运行中,利用xarray把数据从文件夹里挨个读取出来,然后把nc数据的时间转换一下,如果读取的时间是cftime的格式则不需要转换,可以直接读取得到datetime格式的数据,然后提取某一深度的进行转换,代码中给的是第14层,也可以加多一个对深度的循环进行循环读取,随后调用函数即可。单个JSON数据的格式其实是:

{
    'header':header_dict,'data':data_list}

但因为要把u v分量同时写进一个JSON中,所以则需要两个字典组成一个列表,因此使用了

json_u = gen_data_dict(u, reftime,parameterNumber, parameterNumberName)
json_v = gen_data_dict(v, reftime,parameterNumber, parameterNumberName)
json_list = [json_u, json_v]

最后利用json.dump的方式写入文件就完成了转换。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43876852/article/details/124359639

智能推荐

选择性粘贴更改html格式,选择性粘贴这二个逆天的技巧你肯定不知道!_weixin_39635373的博客-程序员秘密

选择性粘贴-公式功能选择此选项时仅粘贴源单元格中的公式。当粘贴公式时,引用的单元格将根据所用的引用类型而变化。如要使引用的单元格地址固定不变,请使用绝对引用。常规应用当需要从其他单元格复制公式到目标单元格,而又不覆盖目标单元格的格式时,选用此选项。应用技巧逆天应用1:将数值粘贴到合并单元格,保留合并格式在《“偷懒”的技术:打造财务Excel达人》中说过,使用合并单元格很多弊端,所以在清单式表格中不...

第四届蓝桥杯省赛C++A组 大臣的旅费_ryo_218的博客-程序员秘密

标题:大臣的旅费很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个...

epoll 使用实例_diche7031的博客-程序员秘密

原文:http://blog.csdn.net/force_eagle/article/details/4348017epoll网上g一大把, 就不详细叙述了.推荐几篇好文章:epoll精髓 epoll相关资料整理 epoll LT VS ET epoll(7) - Linux man pageEPOLL为我们带来了什么[cpp] view...

创建一个JavaBean(普通方式)_Java是最好喝的咖啡的博客-程序员秘密

JavaBean通常在Jsp页面中使用,在Jsp页面中使用JavaBean的方法有两种。一是像使用普通Java类一样创建JavaBean实例,可以使用New关键字,后面使用构造方法,来实例化一个JavaBean实例。首先创建一个Web项目,因为JavaBean是一个Java类,创建的方式也和普通Java类一样。在src目录下创建一个包,并在包中创建一个class类。...

解决BottomNavigationView长按显示Toast_Target1314的博客-程序员秘密

//Tab idsprivate var ids = mutableListOf(R.id.home, R.id.offers, R.id.move_money, R.id.setting).toMutableList()/* * 清除长按时的toast * @param bottomNavigationView 当前BottomNavigationView * @param ids 与配置文件中对应的所有id */private fun cle...

随便推点

usb2-键盘里的hid_xie0812的博客-程序员秘密

键盘设备和主机的hid规范[cpp] view plain copy       /*键盘发送给PC的数据每次8个字节       data0 data1 data2 data3 data4 data5 data6 data7        定义分别是:       data0 --       |--bit0: Left Control是否按下,按下为1     

机器学习实验一:Python学习(0基础)_蓝多多的小仓库的博客-程序员秘密

机器学习实验一:Python学习仅供参考,如有错误或不规范请留言指正。import datetime as dtimport time as tm1、输出一段字符串"Hello,World",并使用单行注释#输出一段字符串"Hello,World",并使用单行注释print("Hello,World")2、表达式isinstance(‘Hello world’, str)的值为print(isinstance('Hello world', str))3、定义字符串对象y = “Hel

解决方案:Windows下Mysql提示Access denied for user ''@'localhost' to database '数据库名'_Cg心的博客-程序员秘密

问题描述新建了一个blog的账户,并且设置了密码,但是发现使用 “Mysql -ublog -p” 登陆会报错,即使密码正确也不能登录,最后发现,不用输入密码,直接回车就登录进去了。解决方案后来,查询了资料原因是 数据库里面有空用户,通过 下面SQL语句查询是否有空用户,select * from mysql.user where user='';如果查询到数据,然后通过 下面SQL...

Java版gRPC的使用之一:简单的gRPC搭建_java grpc_CJ_simple的博客-程序员秘密

一、环境准备安装protocbuf下载地址选择对应的版本下载安装,这里我选择3.17.2选择对应的压缩包解压配置环境变量变量名 :PROTOCBUF_HOME变量值:D:\protoc-3.19.1-win64找到系统变量中的path变量,选中后点击编辑,新增:%PROTOBUF_HOME%\bin安装protocbuf插件从idea官网下载插件二、gRPC项目构建项目结构创建maven父工程spring-boot-grpc完整pom.xml<?xml versi

iconfont 设置line-height仍垂直不局中问题_xfxTab的博客-程序员秘密

问题:方法:给标签设置vertical-align: middle;效果图:

(Python)从零开始,简单快速学机器仿人视觉Opencv---第九节:颜色空间转换_Eragonl的博客-程序员秘密

事先准备使用工具Python3.5使用包cv2,numpy涉及函数cv2.cvtColor()cv2.inRange()任务1:转换颜色空间  在 OpenCV 中有 超过150 种进行颜色空间转换的方法。但是你以后就会发现我们经常用到的也就两种:BGRGray 和 BGRHSV。我们用到的函数是:cv2.cvtColor(input_image,flag),其中flag就是转换...

推荐文章

热门文章

相关标签