周長(zhǎng)志 茅海祥 晏理華 陳方遠(yuǎn)
(貴州省銅仁市氣象局, 銅仁 554300)
?
利用VB編程實(shí)現(xiàn)氣象數(shù)據(jù)可視化
周長(zhǎng)志 茅海祥 晏理華 陳方遠(yuǎn)
(貴州省銅仁市氣象局, 銅仁 554300)
為使氣象數(shù)據(jù)能夠以直觀可視的圖形方式進(jìn)行顯示,利用VB可視化編程方法進(jìn)行程序設(shè)計(jì),實(shí)現(xiàn)了地圖繪制、氣象數(shù)據(jù)顯示、圖形縮放及漫游等功能。
VB編程語(yǔ)言;氣象數(shù)據(jù);可視化
在氣象工作中,經(jīng)常用到以地圖為背景實(shí)現(xiàn)降水、氣溫等氣象要素的可視化分析方法。常見(jiàn)的方法是基于地理信息系統(tǒng)(GIS,Geographic Information System)環(huán)境進(jìn)行可視化編程,實(shí)現(xiàn)數(shù)據(jù)與地圖的有效結(jié)合。運(yùn)用VB和Surfer聯(lián)合編程技術(shù)也可以實(shí)現(xiàn)雨量等氣象資料的圖形可視化。李強(qiáng)等人研究開(kāi)發(fā)了基于GIS的小區(qū)域氣象災(zāi)害精細(xì)化預(yù)警系統(tǒng)[1]。 柳錦寶等人運(yùn)用WebGIS技術(shù)開(kāi)發(fā)了四川省氣象服務(wù)信息系統(tǒng)[2]。林伙海運(yùn)用VB6.0語(yǔ)言并結(jié)合Surfer 8.0實(shí)現(xiàn)了雨量圖形可視化[3]。但他們均是運(yùn)用相關(guān)編程軟件聯(lián)合第三方平臺(tái)的地圖功能來(lái)實(shí)現(xiàn)氣象信息的可視化,需要軟件開(kāi)發(fā)者熟練掌握第三方。本次研究運(yùn)用VB6.0語(yǔ)言開(kāi)發(fā)一套矢量地圖繪制程序,將銅仁市區(qū)域內(nèi)氣象站的要素資料(雨量、溫度等)實(shí)時(shí)地顯示在地圖上,實(shí)現(xiàn)氣象要素隨矢量地圖縮放、漫游等功能。
1.1 地圖數(shù)據(jù)的采集
處理地圖矢量數(shù)據(jù)時(shí),一般應(yīng)用矢量化處理軟件(如MapInfo)將紙質(zhì)地圖的柵格數(shù)據(jù)轉(zhuǎn)換成矢量數(shù)據(jù),也可以利用MICAPS系統(tǒng)獲取縣級(jí)以上邊界地圖數(shù)據(jù)。但對(duì)于質(zhì)量要求不高的示意類(lèi)地圖可以采用人工的方式進(jìn)行讀?。涸诘貓D邊界上先任意取一個(gè)起點(diǎn),沿邊界按順時(shí)針或逆時(shí)針?lè)较?,每?.1個(gè)緯距或經(jīng)距,讀出相應(yīng)的坐標(biāo)值(即經(jīng)度和緯度值),直到回到終點(diǎn)。按照該方法讀出河流、公路、城市站點(diǎn)等數(shù)據(jù)。
1.2 地圖矢量數(shù)據(jù)的存儲(chǔ)
將采集到的地圖數(shù)據(jù)存儲(chǔ)到Access數(shù)據(jù)庫(kù)中,根據(jù)實(shí)際情況建立相關(guān)數(shù)據(jù)表,如縣邊界、鄉(xiāng)鎮(zhèn)邊界、河流、公路、城市站點(diǎn)等不同的數(shù)據(jù)表,在數(shù)據(jù)庫(kù)表中第1列為經(jīng)度數(shù)據(jù)、第2列為緯度數(shù)據(jù)。
1.3 氣象資料的獲取
銅仁市區(qū)域氣象站的要素資料(雨量、溫度等)主要通過(guò)內(nèi)網(wǎng)專(zhuān)線或VPN 連接到銅仁市氣象局區(qū)域站SQL服務(wù)器。應(yīng)用VB6.0中的ADO對(duì)象模型,通過(guò)定義對(duì)象和編寫(xiě)相關(guān)代碼來(lái)實(shí)現(xiàn)對(duì)SQL數(shù)據(jù)庫(kù)的訪問(wèn)和查詢(xún)。
2.1 地圖繪制方法
地圖邊界曲線實(shí)際上是由無(wú)數(shù)條線段首尾相連組合而成,在VB6.0中實(shí)現(xiàn)曲線的繪制需要利用PictureBox(圖片框)控件和畫(huà)線函數(shù)line(x1,y1)-(x2,y2)。在Form設(shè)計(jì)時(shí),加入一個(gè)PictureBox控件,該控件作為OLE容器,繪圖區(qū)域的大小及比例可通過(guò)圖片框的Scale方法設(shè)定,再利用line方法可以將地圖邊界的點(diǎn)依次連接起來(lái),從而構(gòu)成一條地圖邊界線。另外在地圖數(shù)據(jù)中,其邊界點(diǎn)的坐標(biāo)為經(jīng)緯度值,需要將其轉(zhuǎn)換為圖片框上的坐標(biāo),轉(zhuǎn)換公式為:
x=(tempx-xmin)*kx
y=(ymax-tempy)*kx
式中:x、y分別為PictureBox圖片框上點(diǎn)的橫、縱坐標(biāo);tempx、tempy分別為地圖上邊界點(diǎn)的經(jīng)度、緯度;kx為ScaleWidth(xmax-xmin)和ScaleHeight(ymax-ymin)兩者中的最小值;xmin、xmax、ymin、ymax分別是所有地圖邊界點(diǎn)中最小經(jīng)度值、最大經(jīng)度值、最小緯度值、最大緯度值。
繪制地圖邊界的函數(shù)為:Function drawmap(drawpic as PictureBox, lcolor as Single,zoom as Single, xmove as Single,ymove as Single, manyou as Boolean)。其中:drawmap為所繪制地圖邊界的函數(shù);drawpic為繪圖的圖片框;lcolor為線條的顏色;zoom為放大倍數(shù);xmove、ymove分別為拖動(dòng)漫游x和y方向的位移;manyou為漫游標(biāo)志。
2.1.1 轉(zhuǎn)換地圖坐標(biāo)為圖片框上點(diǎn)的坐標(biāo)
代碼如下:
fxwidth = xmax - xmin
fyheight = ymax - ymin
if kx < ky then
ky = kx
else
kx = ky
end if
rsmap.open "select fx,fy,ftype from mapdata ",connmap,adOpenForwardOnly,adLockReadOnly
i = 1
with rsmap
do while i < 504 ′在本實(shí)例中共504個(gè)坐標(biāo)點(diǎn)
tmpy = .fields("fy")
redim preserve gridx(UBound(gridx) + 1) ′重新定義數(shù)組維數(shù)
redim preserve gridy(UBound(gridy) + 1)
gridx(i) = zoom * ((tempx - xmin) * kx)
gridy(i) = zoom * ((ymax - tempy) * ky)
i = i + 1
.movenext
loop
end with
rsmap.close
else
2.1.2 繪制地圖邊界
代碼如下:
drawpic.cls
drawpic.DrawWidth = 3
for j = 1 To i - 2
drawpic.Line (gridx(j), gridy(j))-(gridx(j + 1), gridy(j + 1)), lcolor
next
private sub cmdshowmap_Click()′顯示地圖
call drawmap(picdrawmap, RGB(255, 255, 0), 1, 0, 0, False)
end sub
2.1.3 實(shí)現(xiàn)地圖放大與縮小
有時(shí)候在地圖中因氣象站點(diǎn)資料較密集,難以看清具體數(shù)值,此時(shí)需要對(duì)圖形進(jìn)行放大和縮小,如在圖形上左鍵雙擊放大地圖、右鍵雙擊縮小地圖。實(shí)現(xiàn)此功能的代碼如下:
private sub picdrawmap_dblClick()
if lastbutton = 1 then
call drawmap(picdrawmap, mcolor, mzoom * 1.5, 0, 0, False)′鼠標(biāo)左鍵雙擊,每次放大0.5 倍
end if
if lastbutton = 2 then
call drawmap(picdrawmap, mcolor, mzoom * 0.5, 0, 0, false)′鼠標(biāo)右鍵雙擊,每次縮小0.5倍
end if
end sub
2.1.4 設(shè)計(jì)地圖的漫游功能
將地圖放大或縮小后,因顯示器屏幕的局限性,地圖及相關(guān)資料可能在屏幕上僅顯示部分內(nèi)容,或者位置有所偏移,此時(shí)需要對(duì)地圖進(jìn)行拖動(dòng),移到適合的位置。即按住鼠標(biāo)鍵并移動(dòng)鼠標(biāo)時(shí),地圖將沿鼠標(biāo)移動(dòng)方向進(jìn)行移動(dòng),實(shí)現(xiàn)地圖的漫游功能。其代碼如下:
private sub picdrawmap_mousedown(button as integer, shift as integer, x as single, y as single)
startx = x
starty = y
end sub
private sub picdrawmap_MouseUp(button as integer, shift as integer, x as single, y as single)
nxmove = nzoom * (x - startx)
nymove = nzoom * (y - starty)
call drawmap(Picdrawmap, ncolor, nzoom, nxmove, nymove, true)
startx = x
starty = y
end sub
2.2 氣象資料在地圖上顯示方法
為實(shí)現(xiàn)氣象資料在地圖上的正確顯示,在手動(dòng)操縱鼠標(biāo)實(shí)現(xiàn)地圖放大、縮小、漫游時(shí),氣象資料能實(shí)時(shí)跟隨地圖進(jìn)行相應(yīng)的變化和移動(dòng)。如在本實(shí)例中,通過(guò)select語(yǔ)句查詢(xún)時(shí)間段內(nèi)的小時(shí)雨量數(shù)據(jù),并在地圖上進(jìn)行可視化操作。其關(guān)鍵代碼如下:
txtSQL = "select trlysz.StationID,trlysz.jd,trlysz.wd,tabHourData,R1H,tabHourData,tabHourData.ObservTime from trlysz,tabHourData where trlysz.StationID = tabHourData.StationID and ObservTime= '" + datetime1 + "'" '根據(jù)設(shè)定時(shí)間對(duì)區(qū)域站數(shù)據(jù)庫(kù)中的小時(shí)雨量資料進(jìn)行查詢(xún)
rszdzdata.CursorLocation = adUseClient
rszdzdata.Open txtSQL, connzdzdata, adOpenDynamic, adLockBatchOptimistic
if rszdzdata.RecordCount > 0 then′判斷是否有數(shù)據(jù)記錄
i= 1
with rszdzdata
do while i < jls′ jls為滿足查詢(xún)條件的記錄數(shù)
tempx1= .fields("jd")′獲取站點(diǎn)經(jīng)度數(shù)據(jù)
tempy1= .fields("wd")′獲取站點(diǎn)緯度數(shù)據(jù)
tepR1H = .fields("R1H")′獲取小時(shí)雨量數(shù)據(jù)
tepObservTime = .fields("ObservTime")′獲取所查詢(xún)的時(shí)間
redim preserve gridx1(UBound(gridx1) + 1)′重新定義數(shù)組維數(shù)
redim preserve gridy1(UBound(gridy1) + 1)
redim preserve R1H(UBound(R1H) + 1)
redim preserve ObservTime(UBound(ObservTime) + 1)
gridx1(i) = zoom * ((tempx1 - xmin) * kx)′站點(diǎn)氣象資料隨地圖漫游
gridy1(i) = zoom * ((ymax - tempy1) *ky)
R1H(i) = tepR1H
if R1H(i) = 0 then R1H(i) = ""
if R1H(i) = "" then R1H(i) = ""else R1H(i) = Format(R1H(i)10, "0.0")
ObservTime(i) = tepObservTime
i = i + 1
.MoveNext
loop
end with
rszdzdata.close
for j = 1 To i - 1
picdrawmap.print R1H(j)
next
基于以上編程方法,可以根據(jù)不同的業(yè)務(wù)需求增加其他功能,如實(shí)時(shí)動(dòng)態(tài)顯示最高氣溫、最低氣溫、不同時(shí)段累計(jì)降水量等。運(yùn)用VB編程開(kāi)發(fā)的銅仁市防汛氣象服務(wù)平臺(tái),運(yùn)用上述方法嵌入了區(qū)域自動(dòng)站雨量、溫度的地圖化顯示,通過(guò)人機(jī)對(duì)話實(shí)現(xiàn)放大、縮小、漫游、刷新等功能,同時(shí)能夠?qū)A(chǔ)地理信息(縣界、縣名、鄉(xiāng)鎮(zhèn)名)進(jìn)行顯示和消隱,并實(shí)現(xiàn)了統(tǒng)計(jì)查詢(xún)、語(yǔ)音報(bào)警等功能。圖1所示為銅仁市防汛氣象服務(wù)平臺(tái)界面。
圖1 銅仁市防汛氣象服務(wù)平臺(tái)界面
運(yùn)用VB語(yǔ)言,結(jié)合地圖資料及區(qū)域自動(dòng)氣象站數(shù)據(jù)庫(kù)編程,實(shí)現(xiàn)氣象數(shù)據(jù)的可視化。充分發(fā)揮VB人機(jī)交互界面及可編譯功能的優(yōu)勢(shì),實(shí)現(xiàn)了氣象資料在地圖上的自動(dòng)標(biāo)注和填充,并具有圖形縮放、漫游功能,基本實(shí)現(xiàn)了氣象信息的可視化、形象化和實(shí)時(shí)化。單獨(dú)應(yīng)用VB編程實(shí)現(xiàn)氣象要素在地圖上的可視化顯示是可行的,這為今后開(kāi)發(fā)具有繪圖功能的業(yè)務(wù)系統(tǒng)提供了新的思路。
[1] 李強(qiáng),何遂,吉莉,等.基于GIS的小區(qū)域氣象災(zāi)害精細(xì)化預(yù)警系統(tǒng)[J].氣象科技,2014,42(1):89-93.
[2] 柳錦寶,何政偉,王增武,等. 四川省氣象服務(wù)信息系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)[J].氣象科技,2010,38(4):484-487.
[3] 林伙海,吳陳鋒.基于Surfer8.0實(shí)現(xiàn)雨量圖形可視化[J].氣象,2006,32(7):115-118.
[4] 葛小東.VB編程實(shí)例與技巧集粹[M].北京:中國(guó)科學(xué)技術(shù)出版社,2003:20-21.
Meteorological Data Visualization by Based on VB Program
ZHOUChangzhiMAOHaixiangYANLihuaCHENFangyuan
(Meteorological Bureau of Tongren City, Guizhou Province, Tongren Guizhou 554300, China)
In order to display the meteorological data more intuitively and visually, this paper introduces a design by visual programming method of VB to realize techniques and methods of mapping, meteorological data display, graphics zoom and roaming.
VB programming language; meteorological data; visualization
2016-09-30
貴州省氣象局氣象科技開(kāi)放研究基金項(xiàng)目“銅仁市氣象信息共享及氣象災(zāi)害聯(lián)動(dòng)防御決策指揮系統(tǒng)研究”(黔氣科合KF〔2014〕01號(hào));銅仁市氣象局氣象科技基金項(xiàng)目“銅仁市氣象臺(tái)預(yù)報(bào)業(yè)務(wù)服務(wù)平臺(tái)升級(jí)改造”(銅氣科合〔2015〕05號(hào))
周長(zhǎng)志(1982 — ),男,工程師,研究方向?yàn)槎唐谔鞖忸A(yù)報(bào)及系統(tǒng)開(kāi)發(fā)。
TP319
A
1673-1980(2017)02-0088-04