技术资讯
利用VBA在EXCEL中对雨衰计算相关数据取值 发布时间:2020/12/30 14:06:00
卫星通信链路设计中,尤其是对Ku及以上频率的链路进行设计时,对降雨所带来的信号强度及噪声方面的影响进行合理的估算,几乎决定了卫星链路成败的关键因素。因此,国内外对降雨衰减的研究也是一直持续不断进行的,相关计算模型与方法也是不断在改进完善。
我国原有的计算标准为YD/T984-1998,对降雨主要采用雨区估算法,参考的是ITU发布的ITU-R P.618-5(199705)及ITU-R P.837-1(199408)的建议。随着近年来科学技术的进步及相关数据的不断积累,降雨率计算模型已经日臻完善,对地点的定位及雨率的计算也更加准确了。为适应我国卫星通信的发展,进一步与国际接轨,统一卫星通信行业标准,工信部组织相关单位共同对原标准进行了修订,并正式推出了YD/T984-2020《卫星通信链路大气和降雨衰减计算方法》,并自2020年10月1日起正式实施。在降雨衰减计算方面,YD/T984-2020参考了国际最新标准及计算方法,对原标准中诸多方面进行了修订,其中主要的修订在降雨特性、降雨高度等方面,由过去粗糙的雨区估算变为更加准确的按地点取值,同时给出了相关取值原则与方法:如果可以获得卫星站由当地相关机构提供的直接相关数据,如海拔、降雨高度和降雨率等,尽可能采用这些数据,以获得更加准确的计算结果。如没有直接数据,可通过ITU-R的相关技术书中的数据文件获得。在ITU P.1511所附带的数据文件TOPO.dat中包含有海拔数据,数据按2164行,4324列排列组成,行对应纬度值,列对应经度值,间隔均为1/12°(约0.083333°),为满足双三次插值计算条件(条件点周边需有16个数据),在实际有效数据外,分别在行的顶和底分别增加了两行数据,在首列和最后一列分别增加了两列数据。在ITU P.839.4所附带的数据文件h0.txt中包含有高于平均海平面的年平均0°C等温线数据。数据的提供范围为经度0°至360°及纬度+90°至–90°,按1.5°间隔成网格状分布,对不同于网格点的位置而言,在所需位置,高于平均海平面的年平均0°C等温线高度可通过对最近的四个网格点进行双线性插值获得。
在ITU P.837.7 所附带的数据文件R001.TXT中包含有超过年平均降雨率0.01%的年降雨率数据。其纬度网格从−90°N到+90°N ,每格0.125°;经度网格从−180°E到+180°E,每格0.125°。与处理ITU P.839.4数据一样,对不同于网格点的位置而言,在所需位置,可通过对最近的四个网格点进行双线性插值获得。以上数据文件均可通过访问ITU网站下载获得,但需指出的是,ITU的技术与数据文件也是在不断更新并重新编排的,一般只在最新版本中保留相关数据文件,如降雨率数据只在ITU P.837.7的附件中保存,之前版本的文件中只包含技术文件或相应的程序以及算法附件供研究对比使用。对于特定地点,采用人工在相关数据文件中查找选取相关数值并进行计算是十分费时费力,几乎不可取,且其他部分,如计算方法和过程等变化不大,因此编制一个程序将所需数值自动加入原有计算软件即可完成升级改造。
鉴于目前很多链路计算软件都是基与EXCEL现实的,本文提出了一种利用EXCEL自带VBA实现根据特定地点经纬度自动查找选取相关数值并计算的方法。EXCEL自带的VBA可支持对外部特定格式的文件进行打开、读取、写入与关闭等操作,其读取功能可对采用空格、逗号等格式的数据文件进行精确定位读取。借助于这些功能,本文提供了相关的示范程序源程序如下,供参考使用。
程序运行前需完成如下准备工作:
1、下载原始数据文件,并将解压出相应的数据文件:
h0.txt、R001.TXT和TOPO.dat;
2、本示范程序默认数据文件读取路径为C盘根目录,因此需要将数据文件按原文件名直接拷贝至C盘根目录下,效果截图如下:
其中:
h0.txt:ITU P.839.4 所附带的数据文件,包含有高于平均海平面的年平均0°C等温线数据。R001.TXT:ITUP.837.7 所附带的数据文件,包含有超过年平均降雨率0.01%的年降雨率数据。TOPO.dat:ITUP.1511 所附带的数据文件,包含有海拔数据,完成上述工作后,打开EXCEL文件,输入经纬度后,点击获取数据即可。注:程序主要示范精确取值功能,因此对所有非网格点数据均采用双插值四点法取值推算,ITU P.1511建议处理海拔数据采用双三插值16点法取值推算。程序运行效果如下:
Public Bilinear_value As DoublePublic Function Bilinear(Row_int,Column_int, Row_frac, Column_frac, Step_1, File_name_1)Dim Data(2,2) As DoubleDim Diff_row, Diff_col As DoubleDiff_row=Row_int-Row fracDiff col=Column int-Column fracOn Error GoTo bOpen File_name_1 For Input As #1'
第一种情况,纬度和经度符合数据库间距,可定位至一个点,直接取该点的值If Diff_row=0 And Dif Col=0 Then For i=1 To Row_int-1 Line Input #1, test Next For i=1 To Column_int-1 Input #1, test Next Input #1, test Bilinear_value=Val(test) Close #1 Exit Function End If'
第二种情况,纬度符合数据库间距,可定位至两个点,取值并计算If Diff_row=0 Then For i=1 To Row_int -1 Line Input #1, test Next For i=1 To Column_int-1 Input #1, test Next Input #1, test Data(1,1)=Val(test) Input #1, test Data(1,2)=Val(test) Bilinear_value = Data(1,1) * (Diff_col+1)+Data(1,2)*(-Diff_col) Close #1 Exit Function End If'
第三种情况,经度符合数据库间距,可定位至两个点,取值并计算If Diff_col=0 Then For i=1 To Row_int-1 Line Input #1, test Next For i=1 To Column_int-1 Input #1, test Next Input #1, test Data(1,1)=Val(test) Line Input #1, test For i=1 To Column_int-1 Input #1, test Next Input #1, test Data(2,1)=Val(test) Bilinear_value=Data(1,1) * (Diff_row+1)+Data(2,1)*(-Diff_row) Close #1 Exit Function End If'
第四种情况,都不符合数据库间距,定位至四个点,取值并计算For i=1 To Row_int-1 Line Input #1, test Next For i=1 To Column_int-1 Input #1, test Next Input #1, test Data(2,1)=test Input #1, test Data(2,2)=test Line Input #1, test For i=1 To Column_int-1 Input #1, test Next Input #1, test Data(1,1)=test Input #1, test Data(1,2)=test Bilinear_value=Data(1,1)*(Diff_row+1)*(Diff_col+1)+Data(2,1)*(-Diff_row)*(Diff_col+1)+Data(1,2)*(1+Diff_row)*(-Diff_col)+Data(2,2)*(-Diff_row)*(-Diff_col) Close #1 Exit Functionb: MsgBox" 相关文件不存在!"Bilinear_value=-100End Function'-----------'----修改编辑完成后将下列行替Sub数字地图取值()并将文件另存为新文件名如数字地图取值1.0'Private Sub Auto open()Sub数字地图取值() Load UserForm1 UserForm1. ShowEnd Sub Private Sub CommandButton1_Click()Dim Row_int_index, Column_int_index, Row_frac_index, Column_frac_index, Lat, Lon, Lat_trans, Lon_trans, Step AsDoubleDim File_name As StringLat=Val(纬度.Value)Lon=Val(经度.Value)If Lat > 90 Or Lat <-90 Then MsgBox "请检查相关数据!" Exit SubElseIf Lon> 180 Or Lon <-180 Then MsgBox "请检查相关数据!" Exit SubEnd If'839-降雨高度Step=1.5Lat_trans=LatRow_frac_index=(90-Lat_trans)/Step+1Row_int_index=Fix((90-Lat_trans)/Step)+1If Lon>0 Then Lon_trans=LonElse Lon_trans=Lon+360End If Column_frac_index=Lon_trans/Step+1Column_int_index=Fix(Lon_trans/Step)+1File_name="C:\h0.txt"Call Bilinear(Row_int_index,Column_int_index, Row_frac_index, Column_frac_index, Step, File_name)降雨高度. Value=Int(Bilinear_value*1000)/1000If Bilinear_value=-100 Then Bilinear_value= " " Exit SubEnd If'837-降雨量Step=0.125Lat_trans=LatRow_frac_index=(90+Lat_trans)/Step+1Row_int_index=Fix((90+Lat_trans)/Step)+1Lon_trans=Lon+180Column_frac_index=Lon_trans/Step+1Column_int_index=Fix(Lon_trans/Step)+1File_name="C:\R001.txt"Call Bilinear(Row_int_index,Column_int_index, Row_frac_index, Column_frac_index, Step, File_name)降雨量. Value=Int(Bilinear_value*1000)/1000If Bilinear_value=-100 Then Bilinear_value=" " Exit SubEnd If'1511海拔高度Step=1/12Lat_trans=Lat+0.125Row_frac_index=(90-Lat_trans)/Step+3Row_int_index=Fix((90-Lat_trans)/Step)+3Lon_trans=Lon-0.04166+180Column_frac_index=Lon_trans/Step+3Column_int_index=Fix(Lon_trans/Step)+3File_name="C:\TOPO.dat"Call Bilinear(Row_int_index, Column_int_index, Row_frac_index, Column_frac_index, Step, File_name)海拔高度. Value=Int(Bilinear_value)/1000End Sub
如果大家有问题或者是有不懂得方面欢迎私信一起讨论~