利用VB编程实现气象数据可视化
2017-05-09周长志茅海祥晏理华陈方远
周长志 茅海祥 晏理华 陈方远
(贵州省铜仁市气象局, 铜仁 554300)
利用VB编程实现气象数据可视化
周长志 茅海祥 晏理华 陈方远
(贵州省铜仁市气象局, 铜仁 554300)
为使气象数据能够以直观可视的图形方式进行显示,利用VB可视化编程方法进行程序设计,实现了地图绘制、气象数据显示、图形缩放及漫游等功能。
VB编程语言;气象数据;可视化
在气象工作中,经常用到以地图为背景实现降水、气温等气象要素的可视化分析方法。常见的方法是基于地理信息系统(GIS,Geographic Information System)环境进行可视化编程,实现数据与地图的有效结合。运用VB和Surfer联合编程技术也可以实现雨量等气象资料的图形可视化。李强等人研究开发了基于GIS的小区域气象灾害精细化预警系统[1]。 柳锦宝等人运用WebGIS技术开发了四川省气象服务信息系统[2]。林伙海运用VB6.0语言并结合Surfer 8.0实现了雨量图形可视化[3]。但他们均是运用相关编程软件联合第三方平台的地图功能来实现气象信息的可视化,需要软件开发者熟练掌握第三方。本次研究运用VB6.0语言开发一套矢量地图绘制程序,将铜仁市区域内气象站的要素资料(雨量、温度等)实时地显示在地图上,实现气象要素随矢量地图缩放、漫游等功能。
1 资料来源及处理
1.1 地图数据的采集
处理地图矢量数据时,一般应用矢量化处理软件(如MapInfo)将纸质地图的栅格数据转换成矢量数据,也可以利用MICAPS系统获取县级以上边界地图数据。但对于质量要求不高的示意类地图可以采用人工的方式进行读取:在地图边界上先任意取一个起点,沿边界按顺时针或逆时针方向,每隔0.1个纬距或经距,读出相应的坐标值(即经度和纬度值),直到回到终点。按照该方法读出河流、公路、城市站点等数据。
1.2 地图矢量数据的存储
将采集到的地图数据存储到Access数据库中,根据实际情况建立相关数据表,如县边界、乡镇边界、河流、公路、城市站点等不同的数据表,在数据库表中第1列为经度数据、第2列为纬度数据。
1.3 气象资料的获取
铜仁市区域气象站的要素资料(雨量、温度等)主要通过内网专线或VPN 连接到铜仁市气象局区域站SQL服务器。应用VB6.0中的ADO对象模型,通过定义对象和编写相关代码来实现对SQL数据库的访问和查询。
2 实现技术和方法
2.1 地图绘制方法
地图边界曲线实际上是由无数条线段首尾相连组合而成,在VB6.0中实现曲线的绘制需要利用PictureBox(图片框)控件和画线函数line(x1,y1)-(x2,y2)。在Form设计时,加入一个PictureBox控件,该控件作为OLE容器,绘图区域的大小及比例可通过图片框的Scale方法设定,再利用line方法可以将地图边界的点依次连接起来,从而构成一条地图边界线。另外在地图数据中,其边界点的坐标为经纬度值,需要将其转换为图片框上的坐标,转换公式为:
x=(tempx-xmin)*kx
y=(ymax-tempy)*kx
式中:x、y分别为PictureBox图片框上点的横、纵坐标;tempx、tempy分别为地图上边界点的经度、纬度;kx为ScaleWidth(xmax-xmin)和ScaleHeight(ymax-ymin)两者中的最小值;xmin、xmax、ymin、ymax分别是所有地图边界点中最小经度值、最大经度值、最小纬度值、最大纬度值。
绘制地图边界的函数为:Function drawmap(drawpic as PictureBox, lcolor as Single,zoom as Single, xmove as Single,ymove as Single, manyou as Boolean)。其中:drawmap为所绘制地图边界的函数;drawpic为绘图的图片框;lcolor为线条的颜色;zoom为放大倍数;xmove、ymove分别为拖动漫游x和y方向的位移;manyou为漫游标志。
2.1.1 转换地图坐标为图片框上点的坐标
代码如下:
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 ′在本实例中共504个坐标点
tmpy = .fields("fy")
redim preserve gridx(UBound(gridx) + 1) ′重新定义数组维数
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 实现地图放大与缩小
有时候在地图中因气象站点资料较密集,难以看清具体数值,此时需要对图形进行放大和缩小,如在图形上左键双击放大地图、右键双击缩小地图。实现此功能的代码如下:
private sub picdrawmap_dblClick()
if lastbutton = 1 then
call drawmap(picdrawmap, mcolor, mzoom * 1.5, 0, 0, False)′鼠标左键双击,每次放大0.5 倍
end if
if lastbutton = 2 then
call drawmap(picdrawmap, mcolor, mzoom * 0.5, 0, 0, false)′鼠标右键双击,每次缩小0.5倍
end if
end sub
2.1.4 设计地图的漫游功能
将地图放大或缩小后,因显示器屏幕的局限性,地图及相关资料可能在屏幕上仅显示部分内容,或者位置有所偏移,此时需要对地图进行拖动,移到适合的位置。即按住鼠标键并移动鼠标时,地图将沿鼠标移动方向进行移动,实现地图的漫游功能。其代码如下:
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 气象资料在地图上显示方法
为实现气象资料在地图上的正确显示,在手动操纵鼠标实现地图放大、缩小、漫游时,气象资料能实时跟随地图进行相应的变化和移动。如在本实例中,通过select语句查询时间段内的小时雨量数据,并在地图上进行可视化操作。其关键代码如下:
txtSQL = "select trlysz.StationID,trlysz.jd,trlysz.wd,tabHourData,R1H,tabHourData,tabHourData.ObservTime from trlysz,tabHourData where trlysz.StationID = tabHourData.StationID and ObservTime= '" + datetime1 + "'" '根据设定时间对区域站数据库中的小时雨量资料进行查询
rszdzdata.CursorLocation = adUseClient
rszdzdata.Open txtSQL, connzdzdata, adOpenDynamic, adLockBatchOptimistic
if rszdzdata.RecordCount > 0 then′判断是否有数据记录
i= 1
with rszdzdata
do while i < jls′ jls为满足查询条件的记录数
tempx1= .fields("jd")′获取站点经度数据
tempy1= .fields("wd")′获取站点纬度数据
tepR1H = .fields("R1H")′获取小时雨量数据
tepObservTime = .fields("ObservTime")′获取所查询的时间
redim preserve gridx1(UBound(gridx1) + 1)′重新定义数组维数
redim preserve gridy1(UBound(gridy1) + 1)
redim preserve R1H(UBound(R1H) + 1)
redim preserve ObservTime(UBound(ObservTime) + 1)
gridx1(i) = zoom * ((tempx1 - xmin) * kx)′站点气象资料随地图漫游
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
基于以上编程方法,可以根据不同的业务需求增加其他功能,如实时动态显示最高气温、最低气温、不同时段累计降水量等。运用VB编程开发的铜仁市防汛气象服务平台,运用上述方法嵌入了区域自动站雨量、温度的地图化显示,通过人机对话实现放大、缩小、漫游、刷新等功能,同时能够对基础地理信息(县界、县名、乡镇名)进行显示和消隐,并实现了统计查询、语音报警等功能。图1所示为铜仁市防汛气象服务平台界面。
图1 铜仁市防汛气象服务平台界面
3 结 语
运用VB语言,结合地图资料及区域自动气象站数据库编程,实现气象数据的可视化。充分发挥VB人机交互界面及可编译功能的优势,实现了气象资料在地图上的自动标注和填充,并具有图形缩放、漫游功能,基本实现了气象信息的可视化、形象化和实时化。单独应用VB编程实现气象要素在地图上的可视化显示是可行的,这为今后开发具有绘图功能的业务系统提供了新的思路。
[1] 李强,何遂,吉莉,等.基于GIS的小区域气象灾害精细化预警系统[J].气象科技,2014,42(1):89-93.
[2] 柳锦宝,何政伟,王增武,等. 四川省气象服务信息系统的设计与实现[J].气象科技,2010,38(4):484-487.
[3] 林伙海,吴陈锋.基于Surfer8.0实现雨量图形可视化[J].气象,2006,32(7):115-118.
[4] 葛小东.VB编程实例与技巧集粹[M].北京:中国科学技术出版社,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
贵州省气象局气象科技开放研究基金项目“铜仁市气象信息共享及气象灾害联动防御决策指挥系统研究”(黔气科合KF〔2014〕01号);铜仁市气象局气象科技基金项目“铜仁市气象台预报业务服务平台升级改造”(铜气科合〔2015〕05号)
周长志(1982 — ),男,工程师,研究方向为短期天气预报及系统开发。
TP319
A
1673-1980(2017)02-0088-04