.Net方式对NetCDF格式文件读取

.Net的方式对NetCDF格式文件读取

释义

NetCDF(network Common Data Form)网络通用数据格式是由美国大学大气研究协会(University Corporation for Atmospheric Research,UCAR)的Unidata项目科学家针对科学数据的特点开发的,是一种面向数组型并适于网络共享的数据的描述和编码标准。

NetCDF数据结构

​ NetCDF数据集(文件名后缀为.nc) 的格式不是固定的,它是使用者根据需求 自己定义的。一个NetCDF数据集包含维(dimensions)、变量(variables)和属性(attributes)三种描述类型,每种类型都会被分配一个名字和一个ID,这些类型共同描述了一个数据集,NetCDF库可以同时访问多个数据集,用ID来识别不同数据集。变量存储实际数据,维给出了变量维度信息,属性则给出了变量或数据集本身的辅助信息属性,又可以分为适用于整个文件的全局属性和适用于特定变量的局部属性,全局属性则描述了数据集的基本属性以及数据集的来源。一个NetCDF文件的结构包括以下对象:

NetCDF name{
Dimensions:… //定义维数
Variables:… //定义变量
Attributes:… //属性
Data:…//数据
}

NetCDF解析

注意

程序启动时需要将netcdf的相关dll放到程序的生成路径下

基础类

public class DotNetCDF
    {
        public const int NC_GLOBAL = -1;

        public static int GetVarId(int ncid, string varName)
        {
            int res = -1;
            nc_inq_varid(ncid, varName, out res);
            return res;
        }

        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_open(string path, CreateModeEnum mode, out int ncidp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_create(string path, CreateModeEnum mode, out int ncidp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_close(int ncidp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_sync(int ncid);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_enddef(int ncid);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_redef(int ncid);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern string nc_strerror(int ncerror);

        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq(int ncid, out int ndims, out int nvars, out int ngatts, out int unlimdimid);

        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_def_var(int ncid, string name, NcTypeEnum xtype, int ndims, int[] dimids, out int varidp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_var(int ncid, int varid, StringBuilder name, out NcTypeEnum type, out int ndims, int[] dimids, out int natts);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_varids(int ncid, out int nvars, int[] varids);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_vartype(int ncid, int varid, out NcTypeEnum xtypep);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_varnatts(int ncid, int varid, out int nattsp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_varid(int ncid, string name, out int varidp);

        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_ndims(int ncid, out int ndims);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_nvars(int ncid, out int nvars);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_varname(int ncid, int varid, StringBuilder name);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_varndims(int ncid, int varid, out int ndims);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_vardimid(int ncid, int varid, int[] dimids);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_var_fill(int ncid, int varid, out int no_fill, out object fill_value);


        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_natts(int ncid, out int ngatts);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_unlimdim(int ncid, out int unlimdimid);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_format(int ncid, out int format);

        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_attname(int ncid, int varid, int attnum, StringBuilder name);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_atttype(int ncid, int varid, string name, out NcTypeEnum type);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_att(int ncid, int varid, string name, out NcTypeEnum type, out int length);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_att_text(int ncid, int varid, string name, StringBuilder value);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_att_schar(int ncid, int varid, string name, sbyte[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_att_short(int ncid, int varid, string name, short[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_att_int(int ncid, int varid, string name, int[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_att_float(int ncid, int varid, string name, float[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_att_double(int ncid, int varid, string name, double[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_att_longlong(int ncid, int varid, string name, long[] data);



        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_att_text(int ncid, int varid, string name, int len, string tp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_att_double(int ncid, int varid, string name, NcTypeEnum type, int len, double[] tp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_att_int(int ncid, int varid, string name, NcTypeEnum type, int len, int[] tp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_att_short(int ncid, int varid, string name, NcTypeEnum type, int len, short[] tp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_att_float(int ncid, int varid, string name, NcTypeEnum type, int len, float[] tp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_att_byte(int ncid, int varid, string name, NcTypeEnum type, int len, sbyte[] tp);

        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_def_dim(int ncid, string name, int len, out int dimidp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_dim(int ncid, int dimid, StringBuilder name, out int length);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_dimname(int ncid, int dimid, StringBuilder name);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_dimid(int ncid, string name, out int dimid);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_inq_dimlen(int ncid, int dimid, out int length);


        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_var_text(int ncid, int varid, byte[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_var_schar(int ncid, int varid, sbyte[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_var_short(int ncid, int varid, short[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_var_int(int ncid, int varid, int[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_var_long(int ncid, int varid, long[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_var_float(int ncid, int varid, float[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_var_double(int ncid, int varid, double[] data);

        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_vara_double(int ncid, int varid, int[] start, int[] count, double[] dp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_vara_float(int ncid, int varid, int[] start, int[] count, float[] fp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_vara_short(int ncid, int varid, int[] start, int[] count, short[] sp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_vara_int(int ncid, int varid, int[] start, int[] count, int[] ip);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_vara_long(int ncid, int varid, int[] start, int[] count, long[] lp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_vara_ubyte(int ncid, int varid, int[] start, int[] count, byte[] bp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_vara_schar(int ncid, int varid, int[] start, int[] count, sbyte[] cp);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_put_vara_string(int ncid, int varid, int[] start, int[] count, string[] sp);


        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_vara_text(int ncid, int varid, int[] start, int[] count, byte[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_vara_schar(int ncid, int varid, int[] start, int[] count, sbyte[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_vara_short(int ncid, int varid, int[] start, int[] count, short[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_vara_ubyte(int ncid, int varid, int[] start, int[] count, byte[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_vara_long(int ncid, int varid, int[] start, int[] count, long[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_vara_int(int ncid, int varid, int[] start, int[] count, int[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_vara_float(int ncid, int varid, int[] start, int[] count, float[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_vara_double(int ncid, int varid, int[] start, int[] count, double[] data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_vara_string(int ncid, int varid, int[] start, int[] count, string[] data);




        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_var1_double(int ncid, int varid, int[] count, out double data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_var1_float(int ncid, int varid, int[] count, out float data);
        [DllImport("netcdf.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int nc_get_var1_short(int ncid, int varid, int[] count, out short data);


    }
    public enum NcTypeEnum : int
    {
        /// <summary>signed 1 byte intege</summary>
        NC_BYTE = 1,
        /// <summary>ISO/ASCII character</summary>
        NC_CHAR = 2,
        /// <summary>signed 2 byte integer</summary>
        NC_SHORT = 3,
        /// <summary>signed 4 byte integer</summary>
        NC_INT = 4,
        /// <summary>single precision floating point number</summary>
        NC_FLOAT = 5,
        /// <summary>double precision floating point number</summary>
        NC_DOUBLE = 6,
        /// <summary>signed 8-byte int</summary>
        NC_INT64 = 10,
        /// <summary>string</summary>
        NC_STRING = 12	
    }
    public enum CreateModeEnum : int
    {
        NC_NOWRITE = 0,
        /// <summary>read & write</summary>
        NC_WRITE = 0x0001,
        NC_CLOBBER = 0,
        /// <summary>Don't destroy existing file on create</summary>
        NC_NOCLOBBER = 0x0004,
        /// <summary>argument to ncsetfill to clear NC_NOFILL</summary>
        NC_FILL = 0,
        /// <summary>Don't fill data section an records</summary>
        NC_NOFILL = 0x0100,
        /// <summary>Use locking if available</summary>
        NC_LOCK = 0x0400,
        /// <summary>Share updates, limit cacheing</summary>
        NC_SHARE = 0x0800,
        NC_64BIT_OFFSET = 0x0200,
        /// <summary>Enforce strict netcdf-3 rules</summary>
        NC_CLASSIC = 0x0100,
        /// <summary>causes netCDF to create a HDF5/NetCDF-4 file</summary>
        NC_NETCDF4 = 0x1000
    }

NetCDF文件模型

public class Dimension
    {
        /// <summary>
        /// 时间
        /// </summary>
        public int Time { get; set; }

        /// <summary>
        /// 纬度
        /// </summary>
        public int Latitude { get; set; }

        /// <summary>
        /// 经度
        /// </summary>
        public int Longitude { get; set; }

        /// <summary>
        /// 深度
        /// </summary>
        public int Depth { get; set; }
    }
    public class NetCDFFileInfo
    {
        public string FilePath { get; set; }

        public string FileName { get; set; }

        public int NcID { get; set; }

        public Dimension Dimension { get; set; }

        public Salinity SalinityVariable { get; set; }

        public Temperature TemperatureVariable { get; set; }
    }
    public class Salinity
    {
        /// <summary>
        /// 变量的名称
        /// </summary>
        public string VariableName { get; set; }

        /// <summary>
        /// 变量的唯一ID
        /// </summary>
        public int VarID { get; set; }

        /// <summary>
        /// 盐度的纬度个数
        /// </summary>
        public int Dimension { get; set; }

        /// <summary>
        /// 盐度单位
        /// </summary>
        public string Units { get; set; }

        /// <summary>
        /// 临界值(如果获取到的值等于这个临界值,那么此值当0处理)
        /// </summary>
        public short FillValue { get; set; }

        /// <summary>
        /// 偏移量
        /// </summary>
        public double AddOffset { get; set; }

        /// <summary>
        /// 比例因子
        /// </summary>
        public double ScaleFactor { get; set; }
    }
 public class Temperature
    {
        /// <summary>
        /// 变量的名称
        /// </summary>
        public string VariableName { get; set; }

        /// <summary>
        /// 变量的唯一ID
        /// </summary>
        public int VarID { get; set; }

        /// <summary>
        /// 盐度的纬度个数
        /// </summary>
        public int Dimension { get; set; }

        /// <summary>
        /// 盐度单位
        /// </summary>
        public string Units { get; set; }

        /// <summary>
        /// 临界值(如果获取到的值等于这个临界值,那么此值当0处理)
        /// </summary>
        public short FillValue { get; set; }

        /// <summary>
        /// 偏移量
        /// </summary>
        public double AddOffset { get; set; }

        /// <summary>
        /// 比例因子
        /// </summary>
        public double ScaleFactor { get; set; }
    }

NetCDFAPI

public class NetCDFAPI
    {
        public static string ncPath { get; set; }

        private static NetCDFFileInfo pCurrentCDFFileInfo = null;

        public static NetCDFFileInfo CurrentCDFFileInfo 
        {
            get 
            {
                if (pCurrentCDFFileInfo == null)
                {
                    pCurrentCDFFileInfo = InitCDFFileInfo();
                }
                return pCurrentCDFFileInfo;
            }
            set 
            {
                pCurrentCDFFileInfo = value;
            }
        }
        private static int ncid = 0;

        public static void SetNcPath(string path) 
        {
            ncPath = path;
        }

        /// <summary>
        /// 打开NetCDF文件并返回文件唯一ID
        /// </summary>
        /// <returns></returns>
        private static int OpenNetCDFFile() 
        {
            int num = DotNetCDF.nc_open(ncPath, CreateModeEnum.NC_NOWRITE, out ncid);
            return ncid;
        }

        /// <summary>
        /// 关闭NetCDF文件
        /// </summary>
        public static void CloseCDFFile() 
        {
            DotNetCDF.nc_close(ncid);
        }

        /// <summary>
        /// 通过维度名称获取维度的长度
        /// </summary>
        /// <param name="dimName"></param>
        /// <returns></returns>
        private static int DimLengthByDimName(string dimName) 
        {
            int dimid = 0;
            int dimLength;
            DotNetCDF.nc_inq_dimid(ncid, dimName, out dimid);
            DotNetCDF.nc_inq_dimlen(ncid, dimid, out dimLength);
            return dimLength;
        }

        /// <summary>
        /// 初始化NC文件的所有信息
        /// </summary>
        /// <returns></returns>
        private static NetCDFFileInfo InitCDFFileInfo() 
        {
            NetCDFFileInfo cdfFile = new NetCDFFileInfo();
            if (!string.IsNullOrEmpty(ncPath) && File.Exists(ncPath))
            {
                cdfFile.FilePath = ncPath;
                cdfFile.FileName = Path.GetFileNameWithoutExtension(ncPath);
                int ncid = OpenNetCDFFile();
                cdfFile.NcID = ncid;
                Dimension dimension = new Dimension();
                dimension.Time = DimLengthByDimName("time");
                dimension.Latitude = DimLengthByDimName("latitude");
                dimension.Longitude = DimLengthByDimName("longitude");
                dimension.Depth = DimLengthByDimName("depth");
                cdfFile.Dimension = dimension;
                cdfFile.SalinityVariable = (Salinity)InitVariableInfo(cdfFile, DataTypeEnum.Sality);
                cdfFile.TemperatureVariable = (Temperature)InitVariableInfo(cdfFile,DataTypeEnum.Temperature);
            }
            return cdfFile;
        }

        /// <summary>
        /// 初始化NC文件中Variable的信息
        /// </summary>
        /// <param name="cdfFile"></param>
        /// <param name="dataTypeEnum"></param>
        /// <returns></returns>
        private static object InitVariableInfo(NetCDFFileInfo cdfFile, DataTypeEnum dataTypeEnum) 
        {
            object obj = null;
            try
            {
                string variableName = "";//参数名称
                Salinity salinity = null;
                Temperature temperature = null;
                if (dataTypeEnum == DataTypeEnum.Sality)
                {
                    variableName = "so";
                }
                if (dataTypeEnum == DataTypeEnum.Temperature)
                {
                    variableName = "thetao";
                }
                int varid = DotNetCDF.GetVarId(ncid, variableName);
                int dimid = 0;
                DotNetCDF.nc_inq_varndims(ncid, varid, out dimid);//获取当前这个variable有几个维度
                int nattsp;
                DotNetCDF.nc_inq_varnatts(ncid, varid, out nattsp);
                short[] fileValueshortArray = null;
                double[] addOffsetDoubleArray = null;
                double[] scalefactorDoubleArray = null;
                StringBuilder sbValue = new StringBuilder();
                for (int i = 0; i < nattsp; i++)
                {
                    StringBuilder abc = new StringBuilder();
                    DotNetCDF.nc_inq_attname(ncid, varid, i, abc);//获取当前这个variable下面的参数的名称
                    if (abc.ToString() == "_FillValue")
                    {
                        fileValueshortArray = new short[cdfFile.Dimension.Time * cdfFile.Dimension.Depth * cdfFile.Dimension.Latitude * cdfFile.Dimension.Longitude];
                        DotNetCDF.nc_get_att_short(ncid, varid, abc.ToString(), fileValueshortArray);
                    }
                    if (abc.ToString() == "add_offset")
                    {
                        addOffsetDoubleArray = new double[cdfFile.Dimension.Time * cdfFile.Dimension.Depth * cdfFile.Dimension.Latitude * cdfFile.Dimension.Longitude];
                        DotNetCDF.nc_get_att_double(ncid, varid, abc.ToString(), addOffsetDoubleArray);
                    }
                    if (abc.ToString() == "scale_factor")
                    {
                        scalefactorDoubleArray = new double[cdfFile.Dimension.Time * cdfFile.Dimension.Depth * cdfFile.Dimension.Latitude * cdfFile.Dimension.Longitude];
                        DotNetCDF.nc_get_att_double(ncid, varid, abc.ToString(), scalefactorDoubleArray);
                    }
                    if (abc.ToString() == "units")
                    {
                        DotNetCDF.nc_get_att_text(ncid, varid, abc.ToString(), sbValue);
                    }
                }
                if (dataTypeEnum == DataTypeEnum.Sality)
                {
                    salinity = new Salinity();
                    salinity.VariableName = variableName;
                    salinity.VarID = varid;
                    salinity.Dimension = dimid;
                    salinity.Units = sbValue.ToString();
                    salinity.FillValue = fileValueshortArray[0];
                    salinity.AddOffset = addOffsetDoubleArray[0];
                    salinity.ScaleFactor = scalefactorDoubleArray[0];
                    obj = salinity;
                }
                if (dataTypeEnum == DataTypeEnum.Temperature)
                {
                    temperature = new Temperature();
                    temperature.VariableName = variableName;
                    temperature.VarID = varid;
                    temperature.Dimension = dimid;
                    temperature.Units = sbValue.ToString();
                    temperature.FillValue = fileValueshortArray[0];
                    temperature.AddOffset = addOffsetDoubleArray[0];
                    temperature.ScaleFactor = scalefactorDoubleArray[0];
                    obj = temperature;
                }
            }
            catch (Exception ex)
            {
                
            }
            return obj;
        }


        /// <summary>
        /// 读取NC文件的参数信息,通过坐标获取对应的值
        /// </summary>
        /// <param name="cdfFileInfo"></param>
        /// <param name="dataTypeEnum"></param>
        /// <param name="longitude"></param>
        /// <param name="latitude"></param>
        /// <returns></returns>
        public static double GetCoordinateVariableValue(DataTypeEnum dataTypeEnum,double longitude,double latitude) 
        {
            int variableDimension = 0;
            int varid = 0;
            short fileValue = 0;
            double addOffset = 0;
            double scaleFactor = 0;
            if (dataTypeEnum == DataTypeEnum.Sality)
            {
                variableDimension = CurrentCDFFileInfo.SalinityVariable.Dimension;
                varid = CurrentCDFFileInfo.SalinityVariable.VarID;
                fileValue = CurrentCDFFileInfo.SalinityVariable.FillValue;
                addOffset = CurrentCDFFileInfo.SalinityVariable.AddOffset;
                scaleFactor = CurrentCDFFileInfo.SalinityVariable.ScaleFactor;
            }
            if (dataTypeEnum == DataTypeEnum.Temperature)
            {
                variableDimension = CurrentCDFFileInfo.TemperatureVariable.Dimension;
                varid = CurrentCDFFileInfo.TemperatureVariable.VarID;
                fileValue = CurrentCDFFileInfo.TemperatureVariable.FillValue;
                addOffset = CurrentCDFFileInfo.TemperatureVariable.AddOffset;
                scaleFactor = CurrentCDFFileInfo.TemperatureVariable.ScaleFactor;
            }
            int[] dimSize = new int[variableDimension];
            short tempvalue = 0;
            dimSize[0] = 0;
            dimSize[1] = 0;
            dimSize[2] = Convert.ToInt32((latitude + 80) * CurrentCDFFileInfo.Dimension.Latitude / 170);
            dimSize[3] = Convert.ToInt32((longitude + 180) * CurrentCDFFileInfo.Dimension.Longitude / 359.916672);
            //if (latitude < 0)
            //{
            //    dimSize[2] = Convert.ToInt32((latitude + 80) * cdfFileInfo.Dimension.Latitude / 170);
            //}
            //else
            //{
            //    dimSize[2] = Convert.ToInt32(Math.Round(latitude,3) * cdfFileInfo.Dimension.Latitude / 170);
            //}
            //if (longitude < 0)
            //{
            //    dimSize[3] = Convert.ToInt32((longitude + 180) * cdfFileInfo.Dimension.Longitude / 359.916672);
            //}
            //else
            //{
            //    dimSize[3] = Convert.ToInt32(Math.Round(longitude, 3) * cdfFileInfo.Dimension.Longitude / 359.916672);
            //}

            DotNetCDF.nc_get_var1_short(CurrentCDFFileInfo.NcID, varid, dimSize, out tempvalue);
            double value = 0.0;
            if (tempvalue != fileValue)
            {
                value = Math.Round(tempvalue * scaleFactor+ addOffset, 2);
            }
            return value;
        }


        private double GetSalityAndTemperatureValueByCoordinate(DataTypeEnum dataTypeEnum, double longitude,double latitude) 
        {
            //string varname = "";
            //if (dataTypeEnum == DataTypeEnum.Sality)
            //{
            //    varname = "so";
            //}
            //if (dataTypeEnum == DataTypeEnum.Temperature)
            //{
            //    varname = "thetao";
            //}
            //int varid = DotNetCDF.GetVarId(ncid, varname);
            //int nattsp;
            //DotNetCDF.nc_inq_varnatts(ncid, varid, out nattsp);
            //short[] fileValueshortArray = null;
            //double[] addOffsetDoubleArray = null;
            //double[] scalefactorDoubleArray = null;
            //for (int i = 0; i < nattsp; i++)
            //{
            //    StringBuilder abc = new StringBuilder();
            //    DotNetCDF.nc_inq_attname(ncid, varid, i, abc);//获取当前这个variable下面的参数的名称
            //    if (abc.ToString() == "_FillValue")
            //    {
            //        fileValueshortArray = new short[time_length * dept_length * lat_length * lon_length];
            //        DotNetCDF.nc_get_att_short(ncid, varid, abc.ToString(), fileValueshortArray);
            //    }
            //    if (abc.ToString() == "add_offset")
            //    {
            //        addOffsetDoubleArray = new double[time_length * dept_length * lat_length * lon_length];
            //        DotNetCDF.nc_get_att_double(ncid, varid, abc.ToString(), addOffsetDoubleArray);
            //    }
            //    if (abc.ToString() == "scale_factor")
            //    {
            //        scalefactorDoubleArray = new double[time_length * dept_length * lat_length * lon_length];
            //        DotNetCDF.nc_get_att_double(ncid, varid, abc.ToString(), scalefactorDoubleArray);
            //    }
            //    #region 获取类型及值 暂时屏蔽
            //    //NcTypeEnum attType;
            //    //DotNetCDF.nc_inq_atttype(ncid, varid, abc.ToString(), out attType);//获取当前这个variable下面的参数的类型
            //    //switch (attType)
            //    //{
            //    //    case NcTypeEnum.NC_BYTE:
            //    //        DotNetCDF.nc_get_att_ubyte(ncid, varid, abc.ToString(), byteArray);
            //    //        break;
            //    //    case NcTypeEnum.NC_CHAR:
            //    //        DotNetCDF.nc_get_att_schar(ncid, varid, abc.ToString(), sbyteArray);
            //    //        //string str = Encoding.Default.GetString(sbyteArray);
            //    //        DotNetCDF.nc_get_att_text(ncid, varid, abc.ToString(), sb);
            //    //        break;
            //    //    case NcTypeEnum.NC_SHORT:
            //    //        DotNetCDF.nc_get_att_short(ncid, varid, abc.ToString(), shortArray);
            //    //        break;
            //    //    case NcTypeEnum.NC_INT:
            //    //        DotNetCDF.nc_get_att_int(ncid, varid, abc.ToString(), intArray);
            //    //        break;
            //    //    case NcTypeEnum.NC_FLOAT:
            //    //        DotNetCDF.nc_get_att_float(ncid, varid, abc.ToString(), floatArray);
            //    //        break;
            //    //    case NcTypeEnum.NC_DOUBLE:
            //    //        DotNetCDF.nc_get_att_double(ncid, varid, abc.ToString(), doubleArray);
            //    //        break;
            //    //    case NcTypeEnum.NC_INT64:
            //    //        DotNetCDF.nc_get_att_longlong(ncid, varid, abc.ToString(), longArray);
            //    //        break;
            //    //    case NcTypeEnum.NC_STRING:
            //    //        DotNetCDF.nc_get_att_text(ncid, varid, abc.ToString(), sb);
            //    //        break;
            //    //    default:
            //    //        break;
            //    #endregion
            //}
            //int[] dimSize = new int[4];
            //short tempvalue = 0;
            //dimSize[0] = 0;
            //dimSize[1] = 0;
            //if (latitude < 0)
            //{
            //    dimSize[2] = Convert.ToInt32((latitude + 80) * lat_length / 170);
            //}
            //else 
            //{
            //    dimSize[2] = Convert.ToInt32((latitude) * lat_length / 170);
            //}
            //if (longitude < 0)
            //{
            //    dimSize[3] = Convert.ToInt32((longitude + 180) * lon_length / 359.916672);
            //}
            //else 
            //{
            //    dimSize[3] = Convert.ToInt32((longitude) * lon_length / 359.916672);
            //}
            
            //DotNetCDF.nc_get_var1_short(ncid, varid, dimSize, out tempvalue);
            //double value = 0.0;
            //if (tempvalue != fileValueshortArray[0])
            //{
            //    value = Math.Round(tempvalue * scalefactorDoubleArray[0] + addOffsetDoubleArray[0], 2);
            //}
            //for (int i = 0; i < lat_length; i++)
            //{
            //    dimSize[2] = i;
            //    for (int j = 0; j < lon_length; j++)
            //    {
            //        dimSize[3] = j;
                    
            //        DotNetCDF.nc_get_var1_short(ncid,varid,dimSize,out value);
            //    }
            //}
            return 0;
        }


    }

Python的方式加载NC数据

# coding=utf-8
import sys

from netCDF4 import Dataset, num2date
#nc文件的路径
filename = r"{0}".format(sys.argv[1])

nc = Dataset(filename, 'r', Format='NETCDF4')

lats = nc.variables['latitude'][:]
lons = nc.variables['longitude'][:]
so = nc.variables['so'][:]
thetao = nc.variables['thetao'][:]
times = nc.variables['time'][:]
depth = nc.variables['depth'][:]

sotxt= open(sys.argv[2],'a+')#参数名称
thetaotxt = open(sys.argv[3],'a+')#参数名称
for lat_index, lat in enumerate(lats):
        for lon_index, lon in enumerate(lons):
            for time_index, time in enumerate(times): # for a date
                # pull out the data
                for dep_index,dep in enumerate(depth):
                    dataso = so[time_index, dep_index,lat_index, lon_index]
                    datatem = thetao[time_index, dep_index,lat_index, lon_index]
                    print("{0},{1},{2}".format(lat,lon,dataso),file=sotxt)
                    print("{0},{1},{2}".format(lat,lon,datatem), file=thetaotxt)
sotxt.close()
thetaotxt.close()

# close netcdf
nc.close()

Python的方式读取NC文件并形成图表

from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np
import netCDF4 as nc
import sys


file_path = r"{0}".format(sys.argv[1])#nc文件的路径
file = nc.Dataset(file_path, 'r', Format='NETCDF4')


map = Basemap(lon_0=0,lat_0 = 0)
map.drawmapboundary()
map.drawstates()
map.drawcoastlines()


map.drawparallels(np.arange(-80., 90., 34.),labels = [1,0,0,0],fontsize = 12)
map.drawmeridians(np.arange(-180., 180., 72.),labels = [0,0,0,1],fontsize = 12)
plt.title("{0}".format(sys.argv[2]))


time = (file.variables['time'][:])
lat = (file.variables['latitude'][:])
lon = (file.variables['longitude'][:])
depth = (file.variables['depth'][:])
so = file.variables['{0}'.format(sys.argv[3])][:]

data_lon = np.array(lon)
data_lat = np.array(lat)
data_time = np.array(time)
data_depth = np.array(depth)
data_so = np.array(so)
data_plt_sla = data_so[0,0,:,:]

x,y = np.meshgrid(data_lon,data_lat)
curve = map.contour(x,y,data_plt_sla)
cmap_color = plt.cm.get_cmap("rainbow")
#绘制海岸线
map.drawcoastlines()
shade = map.contourf(x,y,data_plt_sla ,cmap = cmap_color)
cbar = map.colorbar()
cbar.ax.tick_params(direction='out',labelsize = 12)
#plt.savefig("u-shade.png")
plt.show()
file.close()

备注

dll 需要加q:656012678

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值