最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++讀取NC數(shù)據(jù)的結(jié)果與真實(shí)數(shù)值不一致的解決方法

 更新時(shí)間:2024年03月08日 10:09:08   作者:瘋狂學(xué)習(xí)GIS  
本文介紹基于C++ 語(yǔ)言的netCDF庫(kù)讀取.nc格式的柵格文件時(shí),代碼讀取到的數(shù)據(jù)與柵格文件的實(shí)際數(shù)據(jù)不一致的解決方法,文中通過代碼示例和圖文講解的非常詳細(xì),需要的朋友可以參考下

最近,由于需要讀取ERA5氣象數(shù)據(jù),因此使用C++ 語(yǔ)言中的netCDF庫(kù)讀取.nc格式文件。其中,偶然發(fā)現(xiàn)在Visual Studio的代碼中讀取到的.nc文件的數(shù)據(jù),和其實(shí)際的數(shù)據(jù)(ArcMap等軟件打開所顯示的數(shù)據(jù))不一致;這里就介紹一種可能導(dǎo)致上述情況的原因,以及對(duì)應(yīng)的解決方法。

首先,在C++ 語(yǔ)言的代碼讀取.nc格式文件時(shí),出現(xiàn)了如下圖所示的情況,可以看到這些值都是負(fù)值;而實(shí)際上我這里的這個(gè).nc格式文件肯定不應(yīng)該如此。

正常情況下,在ArcMap軟件中打開上述這個(gè).nc格式的文件,其數(shù)值正常范圍的區(qū)間應(yīng)該是如下圖所示,肯定都是在大于0的區(qū)間內(nèi);當(dāng)然,數(shù)據(jù)中確實(shí)可能會(huì)有NoData值,但盡管如此,這個(gè).nc格式文件也不可能像上圖那樣,出現(xiàn)這么多不同的負(fù)數(shù)值。

那么,如果出現(xiàn)類似上述這樣的情況,大家就可以多多注意,很可能是由于存在scaleoffset導(dǎo)致的問題了。

首先,什么是scaleoffset呢?簡(jiǎn)單來(lái)說,為了存儲(chǔ)方便,.nc格式文件在保存數(shù)據(jù)的時(shí)候,可能會(huì)讓原本的真實(shí)數(shù)據(jù)先乘以某個(gè)數(shù),然后再加上某個(gè)數(shù)(很多.tif格式的遙感影像也是這么存儲(chǔ)的,也就是常說的縮放系數(shù))。例如,假設(shè)一個(gè).nc格式文件原本的數(shù)值都是大于0、小于1的數(shù)值(例如反射率數(shù)據(jù),都是0.X的數(shù)據(jù)),那么直接存儲(chǔ)小數(shù)就需要占用大量的存儲(chǔ)空間(因?yàn)樾枰?code>float格式或者double格式);而如果讓這些數(shù)據(jù)都乘上1000或者10000,也就是盡可能讓小數(shù)部分消除,那么就可以用int格式來(lái)存儲(chǔ)數(shù)據(jù),從而降低了對(duì)存儲(chǔ)空間的占用。

因此,如果我們待讀取的.nc格式文件含有這個(gè)scaleoffset,那么在使用C++ 語(yǔ)言中的netCDF庫(kù)讀取.nc格式文件時(shí),讀到的數(shù)據(jù)就是經(jīng)過縮放處理后的數(shù)據(jù);對(duì)此,我們需要手動(dòng)將這個(gè)縮放后的數(shù)據(jù),先乘上scale,再加上offset,從而得到最終的真實(shí)結(jié)果數(shù)據(jù)。這一個(gè)步驟,在Python語(yǔ)言的netCDF庫(kù)中,應(yīng)該是會(huì)自動(dòng)幫我們處理(好像是這樣的,因?yàn)橹坝?strong>Python語(yǔ)言讀取.nc格式文件的時(shí)候,都沒有注意到過這個(gè)scaleoffset);而在C++ 語(yǔ)言的netCDF庫(kù)中,就需要我們自行手動(dòng)處理了。

netCDF庫(kù)的官方網(wǎng)站中,也有關(guān)于這個(gè)scaleoffset的說明——如下圖所示,二者在其中分別寫作scale_factoradd_offset;在官方網(wǎng)站中提到,只要在.nc格式文件中看到這2個(gè)參數(shù),都需要在讀取數(shù)據(jù)后,自行手動(dòng)將其乘以或添加到原數(shù)據(jù)中。

因此,在用C++ 語(yǔ)言netCDF庫(kù)讀取.nc格式的柵格文件時(shí),如果我們是第一次讀取它,那么可以通過如下的代碼,獲取其變量的屬性。

	NcFile file(path, NcFile::read);
	NcVar var = file.getVar(type);
	map<string, NcVarAtt> attributes_map = var.getAtts();

其中,NcFile file(path, NcFile::read);含義為創(chuàng)建一個(gè)NcFile對(duì)象,path是要打開的.nc格式的柵格文件的路徑,NcFile::read表示以只讀模式打開文件;隨后,NcVar var = file.getVar(type);表示調(diào)用file對(duì)象的getVar()方法,獲取了指定變量名type(也就是我們需要讀取的變量)的NcVar對(duì)象;最后,map<string, NcVarAtt> attributes_map = var.getAtts();調(diào)用var對(duì)象的getAtts()方法,獲取了變量的所有屬性,并將它們存儲(chǔ)在一個(gè)map<string, NcVarAtt>對(duì)象中。在這個(gè)map中,屬性的名稱是鍵,對(duì)應(yīng)的NcVarAtt對(duì)象是值。

其中,這個(gè)attributes_map如下圖所示;可以看到,其中是具有scale_factoradd_offset的。

但是,如果此時(shí)我們直接查看這個(gè)attributes_map,是看不到scale_factoradd_offset具體的值的,因?yàn)樗闹颠€是一個(gè)NcAtt對(duì)象;如下圖所示。

我們需要通過如下的代碼,首先通過.getAtt()方法獲取這個(gè)屬性,然后用.getValues()方法獲取這個(gè)屬性的具體數(shù)值。

	NcVarAtt attribute_offset = var.getAtt("add_offset");
	NcVarAtt attribute_scale = var.getAtt("scale_factor");
	double offset, scale;
	attribute_offset.getValues(&offset);
	attribute_scale.getValues(&scale);

其中,對(duì)于上述代碼,如果大家對(duì)變量值的精度有較高要求,記得要選擇double類型的變量來(lái)存儲(chǔ)scale_factoradd_offset——如果選擇的是float,可能會(huì)丟失一些精度。

運(yùn)行上述代碼,我們將得到如下圖所示的結(jié)果。

可以看到,scale_factoradd_offset的值都已經(jīng)顯示出來(lái)了。

那么,我們就可以將這個(gè)scale_factoradd_offset,分別作用到我們讀取得到的原始數(shù)據(jù)上(因?yàn)槲疫@里.nc格式數(shù)據(jù)的數(shù)據(jù)量非常大,所以我們就只處理前100個(gè)),來(lái)看看其數(shù)值是否正確;具體代碼如下。

	vector<double> var_array(time_size * latitude_size * longitude_size);
	var.getVar(var_array.data());
	for (int i = 0; i < 100; ++i) {
		var_array[i] *= scale;
		var_array[i] += offset;
	}

可以看到,此時(shí)得到的結(jié)果,就符合實(shí)際了;如下圖所示。

此外,我們可以在ArcGIS軟件中打開這個(gè).nc格式的數(shù)據(jù),找到其左上角的像元,獲取一下這個(gè)像元的數(shù)值,如下圖所示。

可以看到,此時(shí)上圖中所顯示的數(shù)據(jù),就和上上圖中,我們?cè)?strong>Visual Studio的代碼中讀取到的.nc文件的數(shù)據(jù)是一致的了。

當(dāng)然,這里也需要注意,有些.nc格式的數(shù)據(jù),其變量也可能不含有scale_factoradd_offset這兩個(gè)屬性的,如下圖所示;所以我們都可以用本文前述的代碼,先獲取其屬性,看看到底有沒有scale_factoradd_offset;如果有的話,在執(zhí)行對(duì)應(yīng)的數(shù)據(jù)恢復(fù)操作即可。

至此,大功告成。

以上就是C++讀取NC數(shù)據(jù)的結(jié)果與真實(shí)數(shù)值不一致的解決方法的詳細(xì)內(nèi)容,更多關(guān)于C++讀取NC數(shù)據(jù)結(jié)果不一致的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++ IO流詳解之標(biāo)準(zhǔn)IO、文件IO與字符串IO實(shí)戰(zhàn)

    C++ IO流詳解之標(biāo)準(zhǔn)IO、文件IO與字符串IO實(shí)戰(zhàn)

    本文詳細(xì)介紹了C++中的IO流,包括標(biāo)準(zhǔn)IO流、文件IO流和字符串IO流,文章介紹了如何重載運(yùn)算符以支持自定義類型的IO流操作,并提供了一些實(shí)戰(zhàn)案例來(lái)說明如何使用IO流解決實(shí)際問題,感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)數(shù)據(jù)圖文混排

    Qt數(shù)據(jù)庫(kù)應(yīng)用之實(shí)現(xiàn)數(shù)據(jù)圖文混排

    除了能夠打印基本的文字信息數(shù)據(jù)到pdf和紙張,越來(lái)越多的應(yīng)用需求還要求能夠?qū)С鰣D片,并且要支持圖文混排。本文將通過Qt實(shí)現(xiàn)這一功能,需要的可以參考一下
    2022-01-01
  • 用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷游戲

    用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C語(yǔ)言實(shí)現(xiàn)猜數(shù)游戲

    C語(yǔ)言實(shí)現(xiàn)猜數(shù)游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)猜數(shù)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • 深入淺析C語(yǔ)言與C++的區(qū)別與聯(lián)系

    深入淺析C語(yǔ)言與C++的區(qū)別與聯(lián)系

    這篇文章主要為大家介紹了深入的分析了C語(yǔ)言與C++的區(qū)別與聯(lián)系,文中通過詳細(xì)的示例進(jìn)行了對(duì)比,以便大家更容易的看懂理解,有需要的朋友可以借鑒參考下
    2021-11-11
  • C++程序簡(jiǎn)單示例

    C++程序簡(jiǎn)單示例

    這篇文章主要給大家分享的是C++程序簡(jiǎn)單示例,下面文章將圍繞C++程序的相關(guān)資料展開內(nèi)容,需要的朋友可以參考一下,希望對(duì)你有所幫助
    2021-11-11
  • 在C語(yǔ)言中調(diào)用C++做的動(dòng)態(tài)鏈接庫(kù)

    在C語(yǔ)言中調(diào)用C++做的動(dòng)態(tài)鏈接庫(kù)

    如果你有一個(gè)c++做的動(dòng)態(tài)鏈接庫(kù).so文件,而你只有一些相關(guān)類的聲明,那么你如何用c調(diào)用呢,別著急,本文通過一個(gè)小小的例子,讓你能夠很爽的搞定.
    2016-05-05
  • C++中Boost.Chrono時(shí)間庫(kù)的使用方法

    C++中Boost.Chrono時(shí)間庫(kù)的使用方法

    chrono是一個(gè)time library, 源于boost,現(xiàn)在已經(jīng)是C++11標(biāo)準(zhǔn)了,下面這篇文章主要給大家介紹了關(guān)于C++中Boost.Chrono時(shí)間庫(kù)的使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • Opencv實(shí)現(xiàn)綠幕視頻背景替換功能

    Opencv實(shí)現(xiàn)綠幕視頻背景替換功能

    這篇文章主要為大家詳細(xì)介紹了Opencv實(shí)現(xiàn)綠幕視頻背景替換功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • C++和python實(shí)現(xiàn)單鏈表及其原理

    C++和python實(shí)現(xiàn)單鏈表及其原理

    這篇文章主要介紹了C++和python實(shí)現(xiàn)單鏈表及其原理,單鏈表是鏈表家族中的一員,每個(gè)節(jié)點(diǎn)依舊由數(shù)據(jù)域(data)和指針域(next)組成,鏈表的具體概念下面文章將詳細(xì)介紹,需要的小伙伴可以參考一下
    2022-03-03

最新評(píng)論

明溪县| 阳东县| 密云县| 南城县| 和静县| 阿尔山市| 庆元县| 海盐县| 通榆县| 安溪县| 上思县| 汤原县| 金沙县| 靖宇县| 中牟县| 寿阳县| 北碚区| 聂荣县| 阿勒泰市| 夏河县| 馆陶县| 云霄县| 祁东县| 泸西县| 高雄县| 香河县| 镇坪县| 嘉义市| 揭阳市| 永平县| 富源县| 永胜县| 田阳县| 莲花县| 鲜城| 哈尔滨市| 东宁县| 资源县| 宁波市| 马山县| 湾仔区|