李 康,唐厚炳,周 燕
(凱里學(xué)院,貴州 黔東南苗族侗族自治州 556011)
現(xiàn)階段在喀斯特巖溶環(huán)境下研究地下水分布的數(shù)據(jù)模型較少[1],究其原因,主要是當(dāng)前在喀斯特巖溶洞穴環(huán)境下的采樣設(shè)備裝置較為缺乏,研究人員對(duì)水樣目標(biāo)信息研究各有不同,研究的深度也是參差不齊,對(duì)接云南省地理研究所目前在此方面的需求后,存在當(dāng)前設(shè)備采集的數(shù)據(jù)無法有效提取、數(shù)據(jù)存儲(chǔ)在傳統(tǒng)的傳輸介質(zhì)中而無法與計(jì)算機(jī)進(jìn)行直接數(shù)據(jù)交互、編碼方式煩瑣無法準(zhǔn)確解析等問題,一個(gè)性能良好的數(shù)據(jù)解析與可視化平臺(tái)軟件是目前云南地理研究所對(duì)數(shù)據(jù)分析的迫切需求。
針對(duì)喀斯特巖溶洞穴環(huán)境下記錄的樣本數(shù)據(jù),其關(guān)鍵信息為樣品瓶的編號(hào)、取樣模式、起始時(shí)間、結(jié)束時(shí)間、降雨量等,不同模式下,不同觀測(cè)點(diǎn)水樣降落的速度(在此稱為滴速),在數(shù)據(jù)分析中占據(jù)一個(gè)重要的指標(biāo),下面將對(duì)樣本數(shù)據(jù)進(jìn)行詳細(xì)分析。
因取樣設(shè)備采用的是32位嵌入式微控制器對(duì)數(shù)據(jù)進(jìn)行預(yù)存儲(chǔ),并且微控制MCU只能處理十六進(jìn)制數(shù)據(jù)[2],原始數(shù)據(jù)沒有任何規(guī)律,缺乏可讀性,具體如表1所示,因此,在程序編寫需求階段,對(duì)每個(gè)字段都進(jìn)行定義,此代碼為一段機(jī)器代碼,完全依賴于微控制的硬件。要對(duì)原始數(shù)據(jù)進(jìn)行分析就得預(yù)知關(guān)鍵數(shù)據(jù)的編碼方式、每個(gè)字段在控制器內(nèi)存當(dāng)中的存儲(chǔ)特征,解析成研究人員能夠閱讀的文本格式。
表1 (續(xù))
表1 SD卡存儲(chǔ)的原始數(shù)據(jù)
獲取關(guān)鍵字段的解碼方式后,對(duì)原始數(shù)據(jù)進(jìn)行解析,可以很容易地將原始數(shù)據(jù)轉(zhuǎn)換成可閱讀的文本格式,具體如表2所示。
表2 解析后的數(shù)據(jù)
從表2中可知,滴速關(guān)鍵值無法直觀體現(xiàn),需要進(jìn)行二次處理,在軟件設(shè)計(jì)中,初步考慮將起始時(shí)間與結(jié)束時(shí)間換算成時(shí)間戳,然后用降雨量除以2個(gè)時(shí)間戳差值[3],計(jì)算平均滴速關(guān)鍵參考值,將滴速變量設(shè)為V,起始時(shí)間的時(shí)間戳設(shè)為S,結(jié)束時(shí)間的時(shí)間戳設(shè)為E,降雨量設(shè)為M,很容易得到樣本的關(guān)鍵數(shù)據(jù)解析成txt格式后,增強(qiáng)了可讀性,但是在數(shù)據(jù)量劇增時(shí),這些變量參考值之間的相互聯(lián)系與變化趨勢(shì)仍然無法直觀體現(xiàn),云南省地理研究所目前采用的是將解析的文本格式信息二次錄入Excel表格進(jìn)行存儲(chǔ),數(shù)據(jù)量較小時(shí)在一定程度上可以基本體現(xiàn)其變化趨勢(shì),數(shù)據(jù)的處理操作也較為方便。但面對(duì)龐大數(shù)據(jù)的時(shí)候,在存儲(chǔ)上Excel是有局限的,會(huì)占用較多內(nèi)存資源,變化趨勢(shì)只能用單調(diào)的折線圖呈現(xiàn),本身屬性值需要查閱檢索才能獲取[4]。
對(duì)樣本數(shù)據(jù)的解析及需求的分析,為了更好直觀地展現(xiàn)特定關(guān)鍵參數(shù)的變化規(guī)律和趨勢(shì),引入直角坐標(biāo)系,如圖1所示,橫坐標(biāo)為時(shí)間參數(shù)刻度軸,主要反映樣本數(shù)據(jù)采集的時(shí)間節(jié)點(diǎn),縱坐標(biāo)反映的是樣本的滴速,樣本則以柱狀圖的高低變化趨勢(shì)反映滴速的變化,柱狀圖本身附帶固有屬性,在這里主要是指取樣模式和樣本編號(hào)。數(shù)據(jù)的展現(xiàn)顯示為最新的數(shù)據(jù)覆蓋前面的數(shù)據(jù),如果某一次數(shù)據(jù)量較大時(shí),在一個(gè)展現(xiàn)頁面無法完整呈現(xiàn),則采用刷新按鈕手動(dòng)觸發(fā)刷新,展示時(shí)間可以通過程序設(shè)定。
圖1 數(shù)據(jù)分析軟件界面設(shè)計(jì)
對(duì)數(shù)據(jù)的可視化展現(xiàn),目前使用較多的是基于Python編程語言和Pyecharts的開源數(shù)據(jù)包結(jié)合的方式[5],在web頁面動(dòng)態(tài)展示有較好的效果,由于樣本數(shù)據(jù)目前在內(nèi)部使用測(cè)試,無需嵌入web頁面,無需對(duì)外公開發(fā)布,本次在開發(fā)軟件上選擇現(xiàn)在比較成熟的C++框架開發(fā)平臺(tái)Qt,因?yàn)橐淮尉幾g,跨平臺(tái)使用的特點(diǎn)被廣泛使用在Widows、Linux等主流操作系統(tǒng)平臺(tái)[6],C++語言更接近底層硬件語言,容易移植在各個(gè)微控制器嵌入式平臺(tái)上,并且運(yùn)行更加穩(wěn)定流暢。
在軟件設(shè)計(jì)中通過坐標(biāo)及直方圖來展現(xiàn)其變化規(guī)律,Qt平臺(tái)自身不具備坐標(biāo)系,需要引入第三方庫qwt[7],使用Qt Creator編譯,將編譯產(chǎn)生的文件qwt.dll、libqwt.a,qwtd.dll、libqwtd.a分別放入Qt安裝目錄bin文件夾和Qt安裝目錄lib文件夾,最后在sample_01.pro做如下配置:
TARGET=Sample_01
TEMPLATE=app
LⅠBS+=-L"c:/Qt/2022.05/qt/lib"-lqwt
ⅠNCLUDEPATH+="c:/Qt/2022.05/qt/include/qwt"
include(E:qwtqwt.prf)
RC_FⅠLE=SAMPLE.rc
SOURCES += main.cppmainwindow.cpp archart.cpp
HEADERS +=mainwindow.harchar.hcommon.h
OTHER_FⅠLES+=SAMPLE.rcSAMPLE.ico
工程項(xiàng)目文件中ⅠNCLUDEPATH+="c:/Qt/2022.05/qt/include/qwt"包含第三方庫文件的編譯路徑,barchar.h為直方圖編譯所依賴的的頭文件,SAMPLE.ico是軟件設(shè)計(jì)的圖標(biāo)文件。
在本設(shè)計(jì)中最重要的是要將采樣時(shí)間進(jìn)行轉(zhuǎn)化,首先對(duì)文本進(jìn)行解析得到年、月、日,文本之間的用逗號(hào)分割,時(shí)間年、月、日之間用短破折號(hào)分割,具體代碼如下。
lineStr=in.readLine();strList=lineStr.split(",");{yearStrList=strList[0].split(":");yearⅠnfoStrList=yearStrList[1].split("-");year=yearⅠnfoStrList[0].toⅠnt();month=yearⅠnfoStrList[1].toⅠnt();day=yearⅠnfoStrList[2].toⅠnt();}{hourSpeedStrList=strList[1].split(":");hour=hourSpeedStrList[0].toⅠnt();minute=hourSpeedStrList[1].toⅠnt();second = hourSpeedStrList[2].mid(0,7).toFloat();if(hourSpeedStrList[3]==""){qDebug()<<"@@@@@@@@@@@@@@@@@";speed = hourSpeedStrList[7].mid(0,7).toFloat();}else{speed = hourSpeedStrList[6].mid(0,7).toFloat();}}
所有時(shí)間數(shù)據(jù)處理完成后,使用函數(shù)ⅠnsetDataToDataBase(year,moth,day,hour,Minute,second,speed)載入SQLⅠTE數(shù)據(jù)庫。所有的樣本數(shù)據(jù)均拷貝至大容量UsbDisk,軟件通過Event-Driver的方式檢測(cè)[8]。系統(tǒng)會(huì)向窗體發(fā)送WM_DEVⅠCECHANGE,當(dāng)有外部設(shè)備插入或撥出時(shí)通過判斷獲取wParam變量的值,wParam=DBT_DEVⅠCEARRⅠVAL在這里表示UsbDisk已被插入,wParam=DBT_DEVⅠCEREMOVECOMPLETE表示UsbDisk被移除[9]。
主線程是程序運(yùn)行的軸線,main()即為程序的入口地址,不同于子線程代碼獨(dú)立,各個(gè)功能的子線程需要依附主線程才能夠得以運(yùn)行[10],Qt是集成的開發(fā)框架,各個(gè)類型的對(duì)象窗體完全采用繼承與封裝的機(jī)制,主線程主要是調(diào)用應(yīng)用程序的圖形界面,配置軟件在使用過程需要用到的文本編碼格式,給應(yīng)用程序載入一個(gè)軟件圖標(biāo),具體代碼如下。
int main(int argc,char*argv[]){QApplication a(argc,argv);QTextCodec::setCodecForTr(QTextCodec::codecForNa me("system"));QTextCodec::setCodecForLocale(QTextCodec::codecFo rName("system"));QTextCodec::setCodecForCStrings(QTextCodec::codec ForName("system"));MainWindow w;