NetCDF 介紹


Java代碼   收藏代碼
  1. NetCDF  
  2. 1 NetCDF  
  3. 1.1概述(Overview)  
  4. NetCDF (network Common Data Form) is a set of software libraries and machine-independent data formats that support the creation, access, and sharing of array-oriented scientific data. Distributions are provided for Java and C/C++/Fortran. See the netCDF web site for more information.  
  5. NetCDF全稱為network Common Data Format( “網絡通用數據格式”),是一個軟件庫與機器無關的數據格式,支持創建,訪問基於數組的科研數據。分別提供了對Java和C / C++ / Fortran語言。  
  6. 對程序員來說,它和zip、jpeg、bmp文件格式類似,都是一種文件格式的標准。netcdf文件開始的目的是用於存儲氣象科學中的數據,現在已經成為許多數據采集軟件的生成文件的格式。  
  7.    從數學上來說,netcdf存儲的數據就是一個多自變量的單值函數。用公式來說就是f(x,y,z,...)=value, 函數的自變量x,y,z等在netcdf中叫做維(dimension)或坐標軸(axix),函數值value在netcdf中叫做變量(Variables)。而自變量和函數值在物理學上的一些性質,比如計量單位(量綱)、物理學名稱在netcdf中就叫屬性(Attributes)。  
  8. 1.2 數組理解  
  9. NetCDF是以數組為基礎來對數據讀寫操作的,所以需要對數組理解明白,我們接觸的二維數組比較容易理解,如果是三維、四維等多維數組的理解:  
  10. 基礎:  
  11.     //靜態初始化  
  12.     int a[][] = {{1,2},{2,3}};  
  13.     //動態初始化  
  14.     int c[][] = new int[2][];  
  15.     int d[][] = new int[2][3];  
  16.     /*********多維數組聲明和初始化是從高維到低維 以下都是語法錯誤的: 
  17.      *int b[2][] = {{1,2},{2,3}}; 
  18.      *int c[][] = new int[][]; 
  19.      *int c[][] = new int[][4]; 
  20.      *********多維數組可以看成以高維數組作為元素的數組*/  
  21. 如:int c[][] = new int[2][];  
  22.     c[0] = new int[3];  
  23.     c[1] = new int[3];  
  24. 在內存中如下存放:  
  25.    
  26. 2 參考網站  
  27. http://www.unidata.ucar.edu/  
  28. 2.1 Unidata  
  29. 2.2.1 About   
  30. Unidata is a diverse community of over 160 institutions vested in the common goal of sharing data, and tools to access and visualize that data. For 20 years Unidata has been providing data, tools, and support to enhance earth-system education and research. In an era of increasing data complexity, accessibility, and multidisciplinary integration, Unidata provides a rich set of services and tools.  
  31. Unidatay是一個多樣化的社區。對通用數據共享,處理工具,數據訪問,可視化等處理,近20年來Unidata已提供數據,工具和支持,以加強地球系統教育和研究。在一個日益復雜的數據,交通方便,和多學科融合的時代,Unidata提供的服務和豐富的工具集。  
  32. 2.2.2 DATA  
  33. The Unidata Program helps researchers and educators acquire and use earth-related data. Most of the data are provided in "real time" or "near-real time" — that is, the data are sent to participants almost as soon as the observations are made. Unidata is a data facilitator, not a data archive center. We provide a mechanism whereby educators and researchers, by participating in our Internet Data Distribution (IDD) system, may subscribe to streams of current data that interest them.  
  34. Unidata項目幫助研究人員和教育工作者獲得和使用地球相關的數據。大部分數據為實時數據或者臨近數據,將數據發送到需要參與的對象。 Unidata是數據處理,而不是數據存儲中心。  
  35. Available Data Types:(現有數據類型)  
  36. Forecast Model Output:出型預報  
  37. Satellite Data:衛星數據  
  38. Radar Data:雷達數據  
  39. Lightning Data:閃電數據  
  40. Wind Profiler Data:風分析的數據  
  41. Aircraft-Borne (ACARS):航空傳播數據  
  42. GPS Meteo. (SuomiNet):GPS數據  
  43. …………  
  44. 3 NetCDF文件結構  
  45. 3.1 變量(Variables)  
  46. 變量對應着真實的物理數據。比如我們家里的電表,每個時刻顯示的讀數表示用戶的到該時刻的耗電量。這個讀數值就可以用netcdf里的變量來表示。它是一個以時間為自變量(或者說自變量個數為一維)的單值函數。再比如在氣象學中要作出一個氣壓圖,就是“東經xx度,北緯yy度的點的大氣壓值為多少帕”,這是一個二維單值函數,兩維分別是經度和緯度。函數值為大氣壓。  
  47. 從上面的例子可以看出,netcdf中的變量就是一個N維數組,數組的維數就是實際問題中的自變量個數,數組的值就是觀測得到的物理值。變量(數組值)在netcdf中的存儲類型有六種,ascii字符(char) ,字節(byte), 短整型(short), 整型(int), 浮點(float), 雙精度(double)。  
  48. 3.2 維(dimension)  
  49. 一個維對應着函數中的某個自變量,或者說函數圖象中的一個坐標軸,在線性代數中就是一個N維向量的一個分量(這也是維這個名稱的由來)。在netcdf中,一個維具有一個名字和范圍(或者說長度,也就是數學上所說的定義域,可以是離散的點集合或者連續的區間)。在netcdf中,維的長度基本都是有限的,最多只能有一個具有無限長度的維。  
  50. 3.3 屬性(Attribute)  
  51. 屬性對變量值和維的具體物理含義的注釋或者說解釋。因為變量和維在netcdf中都只是無量綱的數字,要想讓人們明白這些數字的具體含義,就得靠屬性這個對象了。在netcdf中,屬性由一個屬性名和一個屬性值(一般為字符串)組成。比如,在某個cdl文件(cdl文件的具體格式在下一節中講述)中有這樣的代碼段:  
  52. temperature:units = "celsius" ;  
  53. 前面的temperature是一個已經定義好的變量(Variable),即溫度,冒號后面的units就是屬性名,表示物理單位,=后面的就是units這個屬性的值,為“celsius” ,即攝氏度,整個一行代碼的意思就是溫度這個物理量的單位為celsius。  
  54. 3.4 表現形式(Representations)  
  55. Representations of netCDF CF(Climate and Forecast) Dimension and Variable Information:  
  56. CDL text, ncML, ncML with coordinate system extensions, and ncML-GML  
  57. 3.4.1 CDL  
  58. 網址:http://mailman.unidata.ucar.edu/software/netcdf/docs/netcdf/CDL-Syntax.html#CDL-Syntax  
  59.      netcdf example_1plus  {  // CDL with CF addions       
  60.      dimensions:         // dimension names and lengths are declared first  
  61.              lat = 5, lon = 10, level = 4, time = unlimited;  
  62.      
  63.      variables:          // variable types, names, shapes, attributes  
  64.              short   time(time);  
  65.                          time:standard_name  = "time";  
  66.                          time:units      = "hours since 1996-1-1";  
  67.              int     lat(lat), lon(lon), level(level);  
  68.                          lat:units       = "degrees_north";  
  69.                          lat:standard_name = "latitude";  
  70.                          lon:units       = "degrees_east";  
  71.                          lon:long_name = "longitude";  
  72.                          level:standard_name     = "air_pressure";  
  73.                          level:units     = "millibars";  
  74.              float   temp(time,level,lat,lon);  
  75.                          temp:long_name     = "temperature";  
  76.                          temp:standard_name     = "air_temperature";  
  77.                          temp:units         = "celsius";  
  78.              float   rh(time,lat,lon);  
  79.                          rh:long_name = "relative humidity";  
  80.                          rh:valid_range = 0.01.0;      // min and max  
  81.   
  82.              // global attributes  
  83.                          :source = "Fictional Model Output";  
  84.                          :Conventions = "CF-1.0";  
  85.        
  86.      data:                // optional data assignments  
  87.              level   = 1000850700500;  
  88.              lat     = 2030405060;  
  89.              lon     = -160,-140,-118,-96,-84,-52,-45,-35,-25,-15;  
  90.              time    = 12;  
  91.              rh      =.5,.2,.4,.2,.3,.2,.4,.5,.6,.7,  
  92.                       .1,.3,.1,.1,.1,.1,.5,.7,.8,.8,  
  93.                       .1,.2,.2,.2,.2,.5,.7,.8,.9,.9,  
  94.                       .1,.2,.3,.3,.3,.3,.7,.8,.9,.9,  
  95.                        0,.1,.2,.4,.4,.4,.4,.7,.9,.9;  
  96.      }   
  97. 如上:0.5表示time為12,lon為-160,lat為20的三維數據  
  98.       0.2表示time為12,lon為-140,lat為20的三維數據  
  99.       0  time為12,表示lon為-160,lat為60的三維數據  
  100. ………………….  
  101. 3.4.2 NCML  
  102. 參考網址:http://www.unidata.ucar.edu/software/netcdf/ncml/v2.2/Tutorial.html  
  103. <?xml version="1.0" encoding="UTF-8"?>  
  104. <netcdf xmlns="http://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2" location="T:/GALEON/SimpleSamples/SampleNetCDFbens.nc">  
  105.   <dimension name="lat" length="5" />  
  106.   <dimension name="lon" length="10" />  
  107.   <dimension name="level" length="4" />  
  108.   <dimension name="time" length="1" isUnlimited="true" />  
  109.   <attribute name="source" type="String" value="Fictional Model Output" />  
  110.   <attribute name="Conventions" type="String" value="CF-1.0" />  
  111.   <variable name="time" shape="time" type="short">  
  112.     <attribute name="standard_name" type="String" value="time" />  
  113.     <attribute name="units" type="String" value="hours since 1996-1-1" />  
  114.   </variable>  
  115.   <variable name="lat" shape="lat" type="int">  
  116.     <attribute name="units" type="String" value="degrees_north" />  
  117.     <attribute name="standard_name" type="String" value="latitude" />  
  118.   </variable>  
  119.   <variable name="lon" shape="lon" type="int">  
  120.     <attribute name="units" type="String" value="degrees_east" />  
  121.     <attribute name="long_name" type="String" value="longitude" />  
  122.   </variable>  
  123.   <variable name="level" shape="level" type="int">  
  124.     <attribute name="standard_name" type="String" value="air_pressure" />  
  125.     <attribute name="units" type="String" value="millibars" />  
  126.   </variable>  
  127.   <variable name="temp" shape="time level lat lon" type="float">  
  128.     <attribute name="long_name" type="String" value="temperature" />  
  129.     <attribute name="standard_name" type="String" value="air_temperature" />  
  130.     <attribute name="units" type="String" value="celsius" />  
  131.   </variable>  
  132.   <variable name="rh" shape="time lat lon" type="float">  
  133.     <attribute name="long_name" type="String" value="relative humidity" />  
  134.     <attribute name="valid_range" type="double" value="0.0 1.0" />  
  135.   </variable>  
  136. </netcdf>  
  137. 3.4.3 NCML-CS  
  138. 參考網址:http://www.unidata.ucar.edu/projects/THREDDS/GALEON/NetCDFandStandards.htm  
  139. <?xml version="1.0" encoding="UTF-8"?>  
  140. <netcdf xmlns="http://www.ucar.edu/schemas/netcdf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ucar.edu/schemas/netcdf http://www.unidata.ucar.edu/schemas/netcdf-cs.xsd" uri="T:/GALEON/SimpleSamples/SampleNetCDFbens.nc">  
  141.   <dimension name="lat" length="5" />  
  142.   <dimension name="lon" length="10" />  
  143.   <dimension name="level" length="4" />  
  144.   <dimension name="time" length="1" isUnlimited="true" />  
  145.   <attribute name="source" type="String" value="Fictional Model Output" />  
  146.   <attribute name="Conventions" type="String" value="CF-1.0" />  
  147.   <coordinateAxis name="time" shape="time" type="short" units="hours since 1996-1-1" axisType="Time">  
  148.     <attribute name="standard_name" type="String" value="time" />  
  149.     <attribute name="units" type="String" value="hours since 1996-1-1" />  
  150.     <attribute name="_CoordinateAxisType" type="String" value="Time" />  
  151.   </coordinateAxis>  
  152.   <coordinateAxis name="lat" shape="lat" type="int" units="degrees_north" axisType="Lat">  
  153.     <attribute name="units" type="String" value="degrees_north" />  
  154.     <attribute name="standard_name" type="String" value="latitude" />  
  155.     <attribute name="_CoordinateAxisType" type="String" value="Lat" />  
  156.   </coordinateAxis>  
  157.   <coordinateAxis name="lon" shape="lon" type="int" units="degrees_east" axisType="Lon">  
  158.     <attribute name="units" type="String" value="degrees_east" />  
  159.     <attribute name="long_name" type="String" value="longitude" />  
  160.     <attribute name="_CoordinateAxisType" type="String" value="Lon" />  
  161.   </coordinateAxis>  
  162.   <coordinateAxis name="level" shape="level" type="int" units="millibars" axisType="Pressure">  
  163.     <attribute name="standard_name" type="String" value="air_pressure" />  
  164.     <attribute name="units" type="String" value="millibars" />  
  165.     <attribute name="_CoordinateAxisType" type="String" value="Pressure" />  
  166.   </coordinateAxis>  
  167.   <variable name="temp" shape="time level lat lon" type="float" coordinateSystems="time-level-lat-lon">  
  168.     <attribute name="long_name" type="String" value="temperature" />  
  169.     <attribute name="standard_name" type="String" value="air_temperature" />  
  170.     <attribute name="units" type="String" value="celsius" />  
  171.   </variable>  
  172.   <variable name="rh" shape="time lat lon" type="float" coordinateSystems="time-lat-lon">  
  173.     <attribute name="long_name" type="String" value="relative humidity" />  
  174.     <attribute name="valid_range" type="double" value="0.0 1.0" />  
  175.   </variable>  
  176.   <coordinateSystem name="time-level-lat-lon">  
  177.     <coordinateAxisRef ref="time" />  
  178.     <coordinateAxisRef ref="level" />  
  179.     <coordinateAxisRef ref="lat" />  
  180.     <coordinateAxisRef ref="lon" />  
  181.   </coordinateSystem>  
  182.   <coordinateSystem name="time-lat-lon">  
  183.     <coordinateAxisRef ref="time" />  
  184.     <coordinateAxisRef ref="lat" />  
  185.     <coordinateAxisRef ref="lon" />  
  186.   </coordinateSystem>  
  187. </netcdf>  
  1. 附件文檔:  
  2.   
  3. 4 NetCDF Java  
  4. 4.1 概述(Overview)  
  5. 參考網址:http://www.unidata.ucar.edu/software/netcdf-java/documentation.htm  
  6. The NetCDF-Java library implements a Common Data Model (CDM), a generalization of the NetCDF, OpenDAP and HDF5 data models. The library is a prototype for the NetCDF-4 project, which provides a C language API for the "data access layer" of the CDM, on top of the HDF5 file format. The NetCDF-Java library is a 100% Java framework for reading netCDF and other file formats into the CDM, as well as writing to the netCDF-3 file format. The NetCDF-Java library also implements NcML, which allows you to add metadata to CDM datasets, as well as to create virtual datasets through aggregation.  
  7.   
  8. NetCDF-Java庫實現了CDM(通用數據模型),CDM包括NetCDF,OpenDAP,HDF5數據模型,它是NetCDF-4項目的一個原型,NetCDF-4項目是緊跟HDF5文件格式后采用C語言作為CDM的的數據訪問層API。在CDM中NetCDF-Java包是完全用Java架構來讀取NetCDF和其他格式文件,和寫netCDF-3格式文件一樣。它還實現了NCML,允許你為CDM數據集添加元數據,和通過運算生成實際數據一樣。  
  9. 4.2 CDM(通用數據模型)  
  10. 參考網址:http://www.unidata.ucar.edu/software/netcdf-java/CDM/index.html  
  11. Unidata’s Common Data Model (CDM) is an abstract data model for scientific datasets. It merges the netCDF, OPeNDAP, and HDF5 data models to create a common API for many types of scientific data. The NetCDF Java library is an implementation of the CDM which can read many file formats besides netCDF. We call these CDM files, a shorthand for files that can be read by the NetCDF Java library and accessed through the CDM data model.   
  12.   
  13. Unidata社區的CDM(通用數據模型)是一個科學數據的抽象數據模型,它包括了NetCDF, OPeNDAP, HDF5數據模型並為不同類型的科學數據創建了一個通用的API。NetCDF Java庫實現了CDM,CDM除了能讀取NetCDF格式外還有其他類型文件,我們把這些CDM文件作為那些能被NetCDF Java庫讀取和訪問的的文件的簡稱。  
  14.   
  15. 4.3 NetCDF-Java/CDM  Architecture  
  16.    
  17. 4.4 CDM-FILES  
  18. General: NetCDF, OPeNDAP, HDF5, NetCDF4, HDF4, HDF-EOS  
  19. Gridded: GRIB-1, GRIB-2, GEMPAK  
  20. Radar: NEXRAD 2&3, DORADE, CINRAD, Universal Format, TDWR  
  21. Point: BUFR, ASCII  
  22. Satellite: DMSP, GINI, McIDAS AREA  
  23. Misc: GTOPO, Lightning, etc  
  24. Others in development (partial):   
  25. AVHRR, GPCP, GACP, SRB, SSMI, HIRS (NCDC)  
  26. 4.5 Data Access Layer Object Model  
  27.    
  28. 4.6 NetCDF舉例  
  29. 4.6.1 下載  
  30. 下載地址: http://www.unidata.ucar.edu/software/netcdf-java/documentation.htm  
  31. 在線API: http://www.unidata.ucar.edu/software/netcdf-java/v4.2/javadoc/index.html  
  32. 目前最新版本為4.2.20  
  33. 最新版本需要JDK6  
  34. 4.6.2  生成NC文件  
  35. package my.demo;  
  36.   
  37. import java.io.IOException;  
  38. import java.util.ArrayList;  
  39.   
  40. import ucar.ma2.Array;  
  41. import ucar.ma2.DataType;  
  42. import ucar.nc2.Dimension;  
  43. import ucar.nc2.NetcdfFileWriteable;  
  44.   
  45. public class CreateNetcdf {  
  46.     @SuppressWarnings("unchecked")  
  47.     public static void main(String[] args) throws Exception {  
  48.         String filename = "testWrite.nc";  
  49.         NetcdfFileWriteable ncfile = NetcdfFileWriteable.createNew(filename,true); // add  
  50.         // dimensions  
  51.         Dimension latDim = ncfile.addDimension("lat"3);  
  52.         Dimension lonDim = ncfile.addDimension("lon"3); // define  
  53.         // Variable  
  54.         ArrayList dims = new ArrayList();  
  55.         dims.add(latDim);  
  56.         dims.add(lonDim);  
  57.         ncfile.addVariable("temperature", DataType.DOUBLE, dims);  
  58.         ncfile.addVariableAttribute("temperature""units""K"); // add a  
  59.         // 1D  
  60.         // attribute  
  61.         // of  
  62.         // length  
  63.         // 3  
  64.         Array data = Array.factory(int.classnew int[] { 3 }, new int[] { 1,2,3 });  
  65.         ncfile.addVariableAttribute("temperature""scale", data);  
  66.         // add a string-valued variable: char svar(80)  
  67.         Dimension svar_len = ncfile.addDimension("svar_len"80);  
  68.         dims = new ArrayList();  
  69.         dims.add(svar_len);  
  70.         ncfile.addVariable("svar", DataType.CHAR, dims);  
  71.         // string array: char names(3, 80)  
  72.         Dimension names = ncfile.addDimension("names"3);  
  73.         ArrayList dima = new ArrayList();  
  74.         dima.add(names);  
  75.         dima.add(svar_len);  
  76.         ncfile.addVariable("names", DataType.CHAR, dima);  
  77.         // how about a scalar variable?  
  78.         ncfile.addVariable("scalar", DataType.DOUBLE, new ArrayList()); // add  
  79.         // global  
  80.         // attributes  
  81.         ncfile.addGlobalAttribute("yo""face");  
  82.         ncfile.addGlobalAttribute("versionD"new Double(1.2));  
  83.         ncfile.addGlobalAttribute("versionF"new Float(1.2));  
  84.         ncfile.addGlobalAttribute("versionI"new Integer(1));  
  85.         ncfile.addGlobalAttribute("versionS"new Short((short2));  
  86.         ncfile.addGlobalAttribute("versionB"new Byte((byte3)); // create  
  87.         // the  
  88.         // file  
  89.         try {  
  90.             ncfile.create();  
  91.         } catch (IOException e) {  
  92.             System.err.println("ERROR creating file " + ncfile.getLocation()+ "\n" + e);  
  93.         }  
  94.     }  
  95. }  
  96. 會生成一個testWrite.nc文件,該文件不能直接打開,可以通過下載的包中netcdfUI-4.2.jar打開:  
  97.    
  98. 4.6.3 讀取NC文件  
  99. package my.demo;  
  100.   
  101. import java.io.IOException;  
  102. import java.util.List;  
  103.   
  104. import ucar.nc2.Dimension;  
  105. import ucar.nc2.NetcdfFile;  
  106. import ucar.nc2.Variable;  
  107.   
  108. public class ReadNetcdf {  
  109.     public static void main(String[] args) {  
  110.         String filename = "D:\\work\\netcdf\\testWrite.nc";  
  111.         NetcdfFile ncfile = null;  
  112.         try {  
  113.             ncfile = NetcdfFile.open(filename);  
  114.               
  115.             //read dimensions  
  116.             List<Dimension> list =  ncfile.getDimensions();  
  117.             for(Dimension d : list){  
  118.                 System.out.println("name="+d.getName()+" length="+d.getLength());  
  119.             }  
  120.             //read variables  
  121.             List<Variable> variables = ncfile.getVariables();  
  122.             System.out.println();  
  123.             for(Variable v : variables){  
  124.                 System.out.println("name="+v.getName()+" NameAndDimension="+v.getNameAndDimensions()+" ElementSize="+v.getElementSize());  
  125.             }  
  126.               
  127.         } catch (IOException ioe) {  
  128.         } finally {  
  129.             if (null != ncfile)  
  130.                 try {  
  131.                     ncfile.close();  
  132.                 } catch (IOException ioe) {  
  133.                 }  
  134.         }  
  135.     }  
  136. }  
  137. 運行打印如下:  
  138. name=lat length=3  
  139. name=lon length=3  
  140. name=svar_len length=80  
  141. name=names length=3  
  142.   
  143. name=temperature NameAndDimension=temperature(lat=3, lon=3) ElementSize=8  
  144. name=svar NameAndDimension=svar(svar_len=80) ElementSize=1  
  145. name=names NameAndDimension=names(names=3, svar_len=80) ElementSize=1  
  146. name=scalar NameAndDimension=scalar ElementSize=8  
  147. 4.6.4 讀寫文件  
  148. package my.demo;  
  149.   
  150. import java.io.IOException;  
  151.   
  152. import ucar.ma2.ArrayDouble;  
  153. import ucar.ma2.Index;  
  154. import ucar.ma2.InvalidRangeException;  
  155. import ucar.nc2.Dimension;  
  156. import ucar.nc2.NetcdfFileWriteable;  
  157.   
  158. public class WriteDataToNetcdf {  
  159.   
  160.     /** 
  161.      * @param args 
  162.      * @throws IOException 
  163.      */  
  164.     public static void main(String[] args) throws IOException {  
  165.         NetcdfFileWriteable ncfile = NetcdfFileWriteable.openExisting("D:\\work\\netcdf\\testWrite.nc"true);  
  166.         Dimension latDim = ncfile.getDimensions().get(0);  
  167.         Dimension lonDim = ncfile.getDimensions().get(1);  
  168.         ArrayDouble A = new ArrayDouble.D2(latDim.getLength(), lonDim.getLength());  
  169.         int i, j;  
  170.         Index ima = A.getIndex();  
  171.         for (i = 0; i < latDim.getLength(); i++) {  
  172.             for (j = 0; j < lonDim.getLength(); j++) {  
  173.                 A.setDouble(ima.set(i, j), (double) (2));  
  174.             }  
  175.         }  
  176.         int[] origin = new int[2];  
  177.         try {  
  178.             ncfile.write("temperature", origin, A);  
  179.             ncfile.close();  
  180.         } catch (IOException e) {  
  181.             System.err.println("ERROR writing file");  
  182.         } catch (InvalidRangeException e) {  
  183.             e.printStackTrace();  
  184.         }  
  185.     }  
  186. }  
  187. 該方法為Variable temperature進行賦值,可以將修改后的testWrite.nc在netcdfUI-4.2.jar中查看:  
  188.    double temperature(lat=3, lon=3);  
  189.      :units = "K";  
  190.      :scale = 123// int  
  191.  data:  
  192.   {  
  193.     {2.02.02.0},  
  194.     {2.02.02.0},  
  195.     {2.02.02.0}  
  196.   }  
  197. 4.6.5 讀取二維數據  
  198. 通過v.read()可以讀取數據:  
  199.  Variable v = ncfile.findVariable(varName);  
  200. Variable v = ncfile.findVariable(varName);  
  201.  Array data = v.read("0:2:1, 0:19:1");  
  202. package my.demo;  
  203.   
  204. import java.io.IOException;  
  205.   
  206. import ucar.ma2.Array;  
  207. import ucar.nc2.NCdumpW;  
  208. import ucar.nc2.NetcdfFile;  
  209. import ucar.nc2.Variable;  
  210.   
  211. public class ReadData {  
  212.     public static void main(String[] args) {  
  213.         String filename = "D:\\work\\netcdf\\testWrite.nc";  
  214.         NetcdfFile ncfile = null;  
  215.         try {  
  216.             ncfile = NetcdfFile.open(filename);  
  217.             //find variable  
  218.             String variable = "temperature";  
  219.             Variable varBean = ncfile.findVariable(variable);  
  220.             //Reading data from a Variable   
  221.             if(null != varBean) {  
  222.                 Array all = varBean.read();  
  223.                 Array data = varBean.read("0:2:1, 0:2:1");  
  224.                 Array data1 = varBean.read("0:2:2, 0:2:2");  
  225.                 System.out.println("讀取所有:\n"+NCdumpW.printArray(all, variable, null));  
  226.                 System.out.println("x軸從0到2 跨度為1 y軸從0到2 跨度為1:\n"+NCdumpW.printArray(data, variable, null));  
  227.                 System.out.println("x軸從0到2 跨度為2 y軸從0到2 跨度為2:\n"+NCdumpW.printArray(data1, variable, null));  
  228.             }  
  229.               
  230.             if(null != varBean) {  
  231.                 int[] origin = new int[] { 0 , 0};  
  232.                 int[] size = new int[] { 3,3};  
  233.                 Array data2D = varBean.read(origin, size);  
  234.                 System.out.println("讀取所有:\n"+NCdumpW.printArray(data2D, variable, null));  
  235.             }  
  236.               
  237.             if(null != varBean) {  
  238.                 int[] origin = new int[] { 1 , 1};  
  239.                 int[] size = new int[] { 2,1};  
  240.                 Array data2D = varBean.read(origin, size);  
  241.                 System.out.println("讀取從第二行第二列開始為起點x數量為1,y數量為2:\n"+NCdumpW.printArray(data2D, variable, null));  
  242.             }  
  243.             System.out.println("由此可得結論:維上的起點都以數組0開始,且陣列順序在坐標中是從右至左\n如:int[] size = new int[] { 2,1},1代表x軸,2代表的是y軸....");  
  244.         } catch (Exception ioe) {  
  245.             ioe.printStackTrace();  
  246.         } finally {  
  247.             if (null != ncfile)  
  248.                 try {  
  249.                     ncfile.close();  
  250.                 } catch (IOException ioe) {  
  251.                 }  
  252.         }  
  253.     }  
  254. }  
  255.   
  256. 打印結果如下:根據結果可以知道read("0:2:2, 0:2:2")和read(origin, size)的差別  
  257. 讀取所有:  
  258. temperature =  
  259.   {  
  260.     {0.01.02.0},  
  261.     {1.02.03.0},  
  262.     {2.03.04.0}  
  263.   }  
  264.   
  265. x軸從02 跨度為1 y軸從02 跨度為1:  
  266. temperature =  
  267.   {  
  268.     {0.01.02.0},  
  269.     {1.02.03.0},  
  270.     {2.03.04.0}  
  271.   }  
  272.   
  273. x軸從02 跨度為2 y軸從02 跨度為2:  
  274. temperature =  
  275.   {  
  276.     {0.02.0},  
  277.     {2.04.0}  
  278.   }  
  279.   
  280. 讀取所有:  
  281. temperature =  
  282.   {  
  283.     {0.01.02.0},  
  284.     {1.02.03.0},  
  285.     {2.03.04.0}  
  286.   }  
  287.   
  288. 讀取從第二行第二列開始為起點x數量為1,y數量為2:  
  289. temperature =  
  290.   {  
  291.     {2.0},  
  292.     {3.0}  
  293.   }  
  294.   
  295. 由此可得結論:維上的起點都以數組0開始,且陣列順序在坐標中是從右至左  
  296. 如:int[] size = new int[] { 2,1},1代表x軸,2代表的是y軸....  
  297. 4.6.6 多維NetCDF(三維)  
  298. 4.6.6.1 創建  
  299. 創建三維NetCDF文件:  
  300. package my.demo;  
  301. import java.io.IOException;  
  302. import java.util.ArrayList;  
  303. import ucar.ma2.Array;  
  304. import ucar.ma2.DataType;  
  305. import ucar.nc2.Dimension;  
  306. import ucar.nc2.NetcdfFileWriteable;  
  307. public class Create3DNetCDF {  
  308.     @SuppressWarnings("unchecked")  
  309.     public static void main(String[] args) throws Exception {  
  310.         String filename = "test3D.nc";  
  311.         NetcdfFileWriteable ncfile = NetcdfFileWriteable.createNew(filename,true); // add  
  312.         Dimension timeDim = ncfile.addDimension("time",2);  
  313.         Dimension latDim = ncfile.addDimension("lat"3);  
  314.         Dimension lonDim = ncfile.addDimension("lon"3); // define  
  315.         ArrayList dims = new ArrayList();  
  316.         dims.add(timeDim);  
  317.         dims.add(latDim);  
  318.         dims.add(lonDim);  
  319.         ncfile.addVariable("temperature", DataType.DOUBLE, dims);  
  320.         ncfile.addVariableAttribute("temperature""units""K"); // add a  
  321.         Array data = Array.factory(int.classnew int[] { 3 }, new int[] { 1,2,3 });  
  322.         ncfile.addVariableAttribute("temperature""scale", data);  
  323.         try {  
  324.             ncfile.create();  
  325.         } catch (IOException e) {  
  326.             System.err.println("ERROR creating file " + ncfile.getLocation()+ "\n" + e);  
  327.         }  
  328.     }  
  329. }  
  330. 4.6.6.2 寫數據  
  331. package my.demo;  
  332. import java.io.IOException;  
  333. import ucar.ma2.ArrayDouble;  
  334. import ucar.ma2.Index;  
  335. import ucar.ma2.InvalidRangeException;  
  336. import ucar.nc2.Dimension;  
  337. import ucar.nc2.NetcdfFileWriteable;  
  338. public class Write3DNetCDF {  
  339.     public static void main(String[] args) throws IOException {  
  340.         NetcdfFileWriteable ncfile = NetcdfFileWriteable.openExisting("D:\\work\\netcdf\\test3D.nc"true);  
  341.         Dimension timeDim = ncfile.getDimensions().get(0);  
  342.         Dimension latDim = ncfile.getDimensions().get(1);  
  343.         Dimension lonDim = ncfile.getDimensions().get(2);  
  344.         ArrayDouble A = new ArrayDouble.D3(timeDim.getLength(),latDim.getLength(), lonDim.getLength());  
  345.         int k,i, j;  
  346.         Index ima = A.getIndex();  
  347.         for(k = 0; k < timeDim.getLength(); k++){  
  348.             for (i = 0; i < latDim.getLength(); i++) {  
  349.                 for (j = 0; j < lonDim.getLength(); j++) {  
  350.                     A.setDouble(ima.set(k,i,j), (double) (k+i+j));  
  351.                 }  
  352.             }  
  353.         }  
  354.         int[] origin = new int[3];  
  355.         try {  
  356.             ncfile.write("temperature", origin, A);  
  357.             ncfile.close();  
  358.         } catch (IOException e) {  
  359.             System.err.println("ERROR writing file");  
  360.         } catch (InvalidRangeException e) {  
  361.             e.printStackTrace();  
  362.         }  
  363.     }  
  364. }  
  365.   
  366. 對應的CDL格式如下:  
  367.    double temperature(time=2, lat=3, lon=3);  
  368.      :units = "K";  
  369.      :scale = 123// int  
  370.  data:  
  371.   {  
  372.     {  
  373.       {0.01.02.0},  
  374.       {1.02.03.0},  
  375.       {2.03.04.0}  
  376.     },  
  377.     {  
  378.       {1.02.03.0},  
  379.       {2.03.04.0},  
  380.       {3.04.05.0}  
  381.     }  
  382.   }  
  383. 4.6.6.3 讀數據  
  384. package my.demo;  
  385. import java.io.IOException;  
  386. import ucar.ma2.Array;  
  387. import ucar.nc2.NCdumpW;  
  388. import ucar.nc2.NetcdfFile;  
  389. import ucar.nc2.Variable;  
  390. public class Read3DNetCDF {  
  391.     public static void main(String[] args) {  
  392.         String filename = "D:\\work\\netcdf\\test3D.nc";  
  393.         NetcdfFile ncfile = null;  
  394.         try {  
  395.             ncfile = NetcdfFile.open(filename);  
  396.             String variable = "temperature";  
  397.             Variable varBean = ncfile.findVariable(variable);  
  398.             //read all data  
  399.             if(null != varBean) {  
  400.                 Array all = varBean.read();  
  401.                 System.out.println("讀取所有:\n"+NCdumpW.printArray(all, variable, null));  
  402.             }  
  403.             if(null != varBean) {  
  404.                 int[] origin = new int[] { 0,1,1};  
  405.                 int[] size = new int[] { 2,2,2};  
  406.                 Array data2D = varBean.read(origin, size);  
  407.                 System.out.println("讀取從第一維的0開始,第二維從1開始,第三維從1開始,數量分別為2,2,2:\n"+NCdumpW.printArray(data2D, variable, null));  
  408.             }             
  409.             // invoke reduce trans 3D to 2D  
  410.             if(null != varBean) {  
  411.                 int[] origin = new int[] { 0,1,1};  
  412.                 int[] size = new int[] { 1,2,2};  
  413.                 Array data2D = varBean.read(origin, size).reduce().reduce();  
  414.                 System.out.println("讀取從第一維的0開始,第二維從1開始,第三維從1開始,數量分別為1,2,2並轉為二維:\n"+NCdumpW.printArray(data2D, variable, null));  
  415.             }  
  416.         } catch (Exception ioe) {  
  417.             ioe.printStackTrace();  
  418.         } finally {  
  419.             if (null != ncfile)  
  420.                 try {  
  421.                     ncfile.close();  
  422.                 } catch (IOException ioe) {  
  423.                 }  
  424.         }  
  425.     }  
  426. }  
  427. 打印:  
  428. 讀取所有:  
  429. temperature =  
  430.   {  
  431.     {  
  432.       {0.01.02.0},  
  433.       {1.02.03.0},  
  434.       {2.03.04.0}  
  435.     },  
  436.     {  
  437.       {1.02.03.0},  
  438.       {2.03.04.0},  
  439.       {3.04.05.0}  
  440.     }  
  441.   }  
  442. 讀取從第一維的0開始,第二維從1開始,第三維從1開始,數量分別為2,2,2:  
  443. temperature =  
  444.   {  
  445.     {  
  446.       {2.03.0},  
  447.       {3.04.0}  
  448.     },  
  449.     {  
  450.       {3.04.0},  
  451.       {4.05.0}  
  452.     }  
  453.   }  
  454.   
  455. 讀取從第一維的0開始,第二維從1開始,第三維從1開始,數量分別為1,2,2並轉為二維:  
  456. temperature =  
  457.   {  
  458.     {2.03.0},  
  459.     {3.04.0}  
  460.   }  
  461. 4.7 NetCDF-NCML(Modifying existing files)  
  462. 通過NCML標記語言可以對NetCDF文件修改  
  463. 參考網址:http://www.unidata.ucar.edu/software/netcdf/ncml/v2.2/Tutorial.html  
  464. 4.8 NCML- Aggregation  
  465. 通過NCML合並存在的多個NetCDF文件  
  466. 參考網站:http://www.unidata.ucar.edu/software/netcdf/ncml/v2.2/Aggregation.html  
  467. 4.9 NetCDF-IOSP(I/O Service Provide)  
  468. 參考網址:http://www.unidata.ucar.edu/software/netcdf-java/tutorial/IOSPoverview.html  
  469. 4.9.1 Overview  
  470. A client uses the NetcdfFile, NetcdfDataset, or one of the Scientific Feature Type APIs to read data from a CDM file. These provide a rich and sometimes complicated API to the client. Behind the scenes, when any of these APIs actually read from a dataset, however, they use a very much simpler interface, the I/O Service Provider or IOSP for short. The Netcdf Java library has many implementations of this interface, one for each different file format that it knows how to read. This design pattern is called a Service Provider.  
  471.   
  472. IOSPs are managed by the NetcdfFile class. When a client requests a dataset (by calling NetcdfFile.open), the file is opened as a ucar.unidata.io.RandomAccessFile (an improved version of java.io.RandomAccessFile). Each registered IOSP is then asked "is this your file?" by calling isValidFile( ucar.unidata.io.RandomAccessFile). The first one that returns true claims it. When you implement isValidFile() in your IOSP, it must be very fast and accurate.  
  473. 4.9.2 IOServiceProvider  
  474. package ucar.nc2.iosp;  
  475. import ucar.ma2.Section;  
  476. import ucar.ma2.InvalidRangeException;  
  477. import ucar.ma2.StructureDataIterator;  
  478. import ucar.nc2.ParsedSectionSpec;  
  479. import ucar.nc2.Structure;  
  480. import java.io.IOException;  
  481. import java.nio.channels.WritableByteChannel;  
  482. /** 
  483.  * This is the service provider interface for the low-level I/O access classes (read only). 
  484.  * This is only used by service implementors. 
  485.  * 
  486.  * The NetcdfFile class manages all registered IOServiceProvider classes. 
  487.  * When NetcdfFile.open() is called: 
  488.  * <ol> 
  489.  * <li> the file is opened as a ucar.unidata.io.RandomAccessFile;</li> 
  490.  * <li> the file is handed to the isValidFile() method of each registered 
  491.  * IOServiceProvider class (until one returns true, which means it can read the file).</li> 
  492.  * <li> the open() method on the resulting IOServiceProvider class is handed the file.</li> 
  493.  * 
  494.  * @see ucar.nc2.NetcdfFile#registerIOProvider(Class) ; 
  495.  * 
  496.  * @author caron 
  497.  */  
  498. public interface IOServiceProvider {  
  499.   
  500.    /** 
  501.     * Check if this is a valid file for this IOServiceProvider. 
  502.     * You must make this method thread safe, ie dont keep any state. 
  503.     *  
  504.     * @param raf RandomAccessFile 
  505.     * @return true if valid. 
  506.     * @throws java.io.IOException if read error 
  507.     */  
  508.   public boolean isValidFile( ucar.unidata.io.RandomAccessFile raf) throws IOException;  
  509. }  
  510. 其他方法見官網介紹或API文檔。  
  511. 4.9.3 AbstractIOServiceProvider  
  512. Your implementataion class should extend ucar.nc2.iosp.AbstractIOServiceProvider. This provides default implementation of some of the methods, so minimally, you only have to implement 4 methods:  
  513. public class MyIosp extends ucar.nc2.iosp.AbstractIOServiceProvider {  
  514.  1)  public boolean isValidFile(RandomAccessFile raf) throws IOException {}  
  515.  2)  public void open(RandomAccessFile raf, NetcdfFile ncfile, CancelTask cancelTask) throws IOException {}  
  516.  3)  public Array readData(Variable v2, Section wantSection) throws IOException, InvalidRangeException {}  
  517.  4)  public void close() throws IOException {}  
  518.   
  519.  5)  public String getFileTypeId() {}  
  520.  5)  public String getFileTypeVersion() {}  
  521.  5)  public String getFileTypeDescription();  
  522. }  
  523. 4.9.4 IOSP-Example  
  524. 通過IOSP對數據處理生成NetCDF文件已經讀取NetCDF數據例子:  
  525. 參考網址:  
  526. http://www.unidata.ucar.edu/software/netcdf-java/tutorial/index.html  
  527.    
  528. 圖中的例子為雷電數據,衛星數據,雷達數據相關


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM