劉勝國, 高景春, 李永慶, 張從珍
(河北省地震局,石家莊 050021)
地震預(yù)警信息接收PC客戶端的設(shè)計(jì)及實(shí)現(xiàn)
劉勝國, 高景春, 李永慶, 張從珍
(河北省地震局,石家莊 050021)
介紹了地震預(yù)警示范系統(tǒng)中預(yù)警客戶端的消息定義與傳輸協(xié)議、軟件流程和技術(shù)實(shí)現(xiàn)方式等內(nèi)容,以及各部分的主體技術(shù)方法、原理等細(xì)節(jié),并給出了相關(guān)模塊的源代碼。對這些軟件相關(guān)內(nèi)容的介紹,旨在為地震預(yù)警系統(tǒng)的運(yùn)行完善提供幫助,也為維護(hù)和有特殊研發(fā)需求的臺網(wǎng)提供借鑒。
地震預(yù)警;客戶端;地震烈度;消息
地震預(yù)警是在地震發(fā)生后,對即將到來的破壞性地震動進(jìn)行預(yù)測和警報(bào)[1]。其利用地震波傳播速度小于電磁波傳播速度的特點(diǎn),提前對地震波尚未到達(dá)的地方進(jìn)行預(yù)警,利用實(shí)時(shí)監(jiān)測臺網(wǎng)獲取的地震信息,以及對地震可能的破壞范圍和程度做快速評估,在破壞性地震波到達(dá)之前的短暫時(shí)間發(fā)出預(yù)警,減少人員傷亡和經(jīng)濟(jì)損失。
繼“十一五”國家科技支撐項(xiàng)目“地震預(yù)警與烈度速報(bào)系統(tǒng)的研究與示范應(yīng)用”以后,在北京和蘭州部署安裝了“預(yù)警臺網(wǎng)信息實(shí)時(shí)分析和地震報(bào)警及信息發(fā)布軟件”。地震預(yù)警PC桌面客戶端和其它預(yù)警接收軟件一樣,處在預(yù)警系統(tǒng)的末端,直接面向用戶,是地震預(yù)警軟件系統(tǒng)的重要組成部分;其可靠運(yùn)行將為指揮決策服務(wù),為用戶在災(zāi)難面前贏取寶貴的時(shí)間,減輕地震次生災(zāi)害、人員傷亡以及經(jīng)濟(jì)損失。在此,我們對地震預(yù)警客戶端的消息協(xié)議、實(shí)現(xiàn)方式和技術(shù)原理等關(guān)鍵環(huán)節(jié)進(jìn)行分析介紹。
1.1 傳輸協(xié)議
預(yù)警發(fā)布服務(wù)器發(fā)布的預(yù)警消息采用ActiveMQ的服務(wù)接口、遵循其消息包裝方式(ActiveMQ是由Apache出品,能力強(qiáng)勁的開源消息總線),使用BytesMessage消息進(jìn)行通訊,從EW.XX主題接收預(yù)警消息(XX代表臺網(wǎng)代碼)。
對預(yù)警消息的封裝主要由消息屬性和消息體組成。對于最基本的標(biāo)志性信息需要從屬性中讀取,有了這些標(biāo)志性信息,我們就可以做到篩選自己感興趣的內(nèi)容。比如通過讀消息屬性,我們可以做到僅接收某一臺網(wǎng)發(fā)布的預(yù)警消息(有可能連接主題上還包含其它消息)。
地震預(yù)警消息的屬性、消息主體按如下定義封裝:
1.2 預(yù)警消息屬性
消息屬性的封裝如下(表1)。
表1 預(yù)警消息屬性表
1.3 預(yù)警消息體
對消息體的封裝遵循W3C發(fā)布的可擴(kuò)展標(biāo)記語言XML1.0規(guī)范,編碼方式為UTF-8。定義如下:
消息體的具體定義如下:
1) 根節(jié)點(diǎn)為EarlyWarning,其屬性包括:
Net_code:臺網(wǎng)代碼
Event_id:事件ID
Catalog_id:目錄ID
Promul_no:第幾次發(fā)布
Promul_time:發(fā)布時(shí)間
Ew_reliability:預(yù)警可靠度(1.0為最高可靠度值,0為最低可靠度值)
Intensity_value:震中烈度值
2)地震目錄節(jié)點(diǎn)Catalog,其屬性包含了地震目錄參數(shù)
Net_code:臺網(wǎng)代碼
O_time:發(fā)震時(shí)刻中的年月日時(shí)分秒,其中秒為整數(shù)
O_time_frac:發(fā)震時(shí)刻(1/10 000)s,即秒的小數(shù)部分
Epi_lat:震中緯度
Epi_lon:震中經(jīng)度
Epi_depth:深度,單位為公里(km)
M:震級
M_source:發(fā)布震級來源
Loc_stn:定位臺站數(shù)
Location_cname:震中參考地名
3)預(yù)警對象節(jié)點(diǎn)Ew_object,其下包含一個或一個以上的預(yù)警對象Object。
4)單個預(yù)警對象節(jié)點(diǎn)Object(對多個城市點(diǎn)做預(yù)警時(shí),重復(fù)此節(jié)點(diǎn)),其屬性如下:
Object_name:預(yù)警目標(biāo)名稱(比如:某一城市)
Object_lon:預(yù)警目標(biāo)經(jīng)度
Object_lat:預(yù)警目標(biāo)緯度
Predict_intensity:預(yù)測烈度
Warning_time:預(yù)警時(shí)間,以s為單位
S_arrive:S波預(yù)計(jì)到達(dá)時(shí)間
S_arrive_frac:S波預(yù)計(jì)到達(dá)時(shí)間(1/10 000)s
2.1 實(shí)現(xiàn)流程
軟件啟動時(shí)讀入?yún)?shù)文件,初始化工作環(huán)境。由預(yù)警接收線程實(shí)時(shí)監(jiān)聽地震預(yù)警發(fā)布服務(wù)器上的預(yù)警消息,當(dāng)有新消息到來后根據(jù)地震消息參數(shù)計(jì)算震中距和本地烈度,以震中位置為中心動態(tài)顯示預(yù)警時(shí)間和當(dāng)前位置地震烈度等關(guān)鍵信息(圖1):
圖1 軟件工作流程
2.2 監(jiān)聽預(yù)警消息實(shí)現(xiàn)方法
通過與ActiveMQ消息總線相連,從預(yù)警發(fā)布主題接收預(yù)警消息,其連接遵循ActiveMQ的CMS接口規(guī)范。按如下步驟進(jìn)行:
(1)創(chuàng)建連接類廠
std::auto_ptr
(2)創(chuàng)建連接
std::auto_ptr
(3)創(chuàng)建會話
std::auto_ptr
(4)創(chuàng)建接收主題
std::auto_ptr
(5)創(chuàng)建消費(fèi)者
std::auto_ptr
session->createConsumer(myTopic ) );
(6)接收預(yù)警消息
while(!done ) {
std::auto_ptr
...處理預(yù)警消息...
}
接收到消息后,按上面接收的“消息定義”解析地震預(yù)警的信息內(nèi)容。
2.3 計(jì)算本地烈度方法
按烈度的衰減公式[2]計(jì)算接收者所在地的本地烈度,公式如下:
I=A+B×M+C×log10(R+R0)
(1)
式中:M為震級,R為震中距(用戶所在地到震中的距離)??紤]到烈度衰減的復(fù)雜,把全國版圖分區(qū),不同地區(qū)選用不同的參數(shù)(表2)。
表2 烈度計(jì)算分區(qū)表
按下表選取公式所用的參數(shù)(表3)。
表3 烈度公式所用參數(shù)表
程序?qū)崿F(xiàn)代碼如下:
double CEWClinetView::cal_LocalIntensity(double lon, double lat, double mag, double delta)
{
const double a[4] = { 5.387, 5.455, 2.751, 6.420 };
const double b[4] = { 1.446, 1.252, 1.459, 1.106 };
const double c[4] = {-4.584,-4.120,-3.409,-4.060 };
const double d[4] = { 21.0, 18.0, 10.0, 18.0 };
if ( lon <= 104.0 && lat >= 36.0 )
return a[0] + b[0]*mag + c[0]*log10(delta+d[0]);
else if( lon <= 104.0 && lat < 36.0 )
return a[1] + b[1]*mag + c[1]*log10(delta+d[1]);
else if( lon > 104.0 && lat > 32.0 && lat < 42.0 )
return a[2] + b[2]*mag + c[2]*log10(delta+d[2]);
return a[3] + b[3]*mag + c[3]*log10(delta+d[3]);
}
2.4 計(jì)算預(yù)警時(shí)間
從預(yù)警發(fā)布服務(wù)器接收地震預(yù)警消息,根據(jù)消息中地震目錄給出的發(fā)震時(shí)刻,動態(tài)計(jì)算預(yù)警時(shí)間。計(jì)算公式如下:
(2)
式中:Rt為預(yù)警時(shí)間,Δ為震中距,VS為S波速度,Ct為當(dāng)前時(shí)間,T0為發(fā)震時(shí)刻。
程序?qū)崿F(xiàn)代碼如下:
voidCEWClinetView::DrawEWTime(CDC*pDC,unsignedintlapse)
{
CEWClinetDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
if(!pDoc)return;
intremain_seconds=static_cast
if(remain_seconds< 0 )return;
usingnamespaceGdiplus;
Graphicsgraphics(pDC->m_hDC);
intposx=viewWidth- 748;
intposy=viewHight-110;
intwidth= 728;
inthigh= 80;
// 區(qū)域
DrawRoundRect(&graphics,posx,posy,width,high,40,Color(255, 255, 255, 110));
GraphicsPathpath;
path.StartFigure();
intspace= 20;
Rectr(posx+space,posy+space,width-space-space,high-space-space);
path.AddRectangle(r);
path.CloseFigure();
Regionregion(&path);
graphics.SetClip(®ion);
FontFamilyfontfamily(L"黑體");
Gdiplus::Fontfont(&fontfamily, 40,FontStyleBold,UnitPixel);
SolidBrushbrush(Color(255, 255, 0, 0));
Gdiplus::REALxP=posx+space;
Gdiplus::REALyP=posy+space;
wchar_tsm[256] = {0};
if(remain_seconds> 0 )
swprintf(sm,L"估計(jì) %d秒后橫波到達(dá)您現(xiàn)在位置",remain_seconds);
else
{
swprintf(sm,L" 橫波已經(jīng)到達(dá)您現(xiàn)在位置 ",remain_seconds);
CEWClinetApp*pApp= (CEWClinetApp*)AfxGetApp();
pApp->EndAlarm();
}
graphics.DrawString(sm,wcslen(sm), &font,PointF(xP,yP), &brush);
}
程序運(yùn)行界面的右上方顯示“本次地震的參數(shù)”和“預(yù)測用戶所在地的烈度”,在右下方動態(tài)顯示預(yù)警時(shí)間。動態(tài)擴(kuò)大的實(shí)心圓代表S波的到達(dá)區(qū)域,外圍的大圓是P波到達(dá)的區(qū)域(圖2):
圖2 軟件界面
3.1 實(shí)現(xiàn)的核心部分
接收到新的預(yù)警消息以后,在地圖上標(biāo)注震中位置,顯示地震參數(shù)、本地烈度、S波到達(dá)時(shí)間[3]。程序?qū)崿F(xiàn)的關(guān)鍵代碼如下:
void CEWClinetView::OneEWMessage()// 處理新收到的預(yù)警消息
{
CEWClinetDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
if( !CheckData() ) return;
// 震中位置
setEQposition(pDoc->m_catalog.Epi_lat, pDoc->m_catalog.Epi_lon);
// 發(fā)震時(shí)刻
m_eqtime = CTime(pDoc->m_catalog.timeS.year, pDoc->m_catalog.timeS.month, pDoc->m_catalog.timeS.day,
pDoc->m_catalog.timeS.hour, pDoc->m_catalog.timeS.minute, (int)(pDoc->m_catalog.timeS.fsec + 0.5) );
// 震中距
m_delta = ApproxDistance(pDoc->m_catalog.Epi_lat, pDoc->m_catalog.Epi_lon, g_latitude, g_longitude);
// 計(jì)算本地烈度
pDoc->m_localintensity = cal_LocalIntensity(pDoc->m_catalog.Epi_lon, pDoc->m_catalog.Epi_lat, pDoc->m_catalog.M, m_delta);
CEWClinetApp* pApp = (CEWClinetApp*)AfxGetApp();
if(pDoc->m_localintensity > g_AlarmIntensity)
{
pApp->StartAlarm();
}
m_pMemDC->BitBlt(0, 0, viewWidth, viewHight, NULL, 0, 0, WHITENESS);//清空BITMAP
/**
視區(qū)經(jīng)緯度中心點(diǎn)
*/
blat0 = (eq_lat + pDoc->m_catalog.Epi_lat)/2;
blon0 = (eq_lon + pDoc->m_catalog.Epi_lon)/2;
bx0 = viewWidth*2/5; // 不在“X”軸的中點(diǎn),設(shè)置在2/5的位置
by0 = viewHight/2;
DrawMap(m_pMemDC);//重繪
m_ETflag = true;
SetTimer(WM_SECONDCHANGE,1000,NULL);
Invalidate(); //更新顯示
}
3.2 shp文件讀取
shp地圖格式是ESRI提供的一種矢量數(shù)據(jù)格式,它沒有拓?fù)湫畔ⅲ饕勺鴺?biāo)文件(.shp)、索引文件(.shx)和屬性文件(.dbf)組成。由于自己寫代碼讀取相對復(fù)雜,我們采用了GIS開源庫shplib去實(shí)現(xiàn)。
程序調(diào)用shp文件的相關(guān)代碼如下:
CMapLayer::CMapLayer(const char *filename)
{
CString str, str1;
CMapObject* object;
SHPHandle hSHP = SHPOpen( filename, "rb" );
if( hSHP == NULL )
{
CString slog;
slog.Format( "打開文件 %s 錯誤。", filename );
AfxMessageBox(slog);
return;
}
double adfMinBound[4], adfMaxBound[4];
intnShapeType, nEntities;
SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound );
m_fMinX = adfMinBound[0];
m_fMinY = adfMinBound[1];
m_fMaxX = adfMaxBound[0];
m_fMaxY = adfMaxBound[1];
// open dbf file
CString dbfname(filename);
dbfname = dbfname.Left( dbfname.GetLength()-3 );
dbfname += "dbf";
DBFHandlehDBF = DBFOpen( (LPCTSTR)dbfname, "rb" );
if( hDBF == NULL )
{
SHPClose( hSHP );
CString slog("打開文件 ");
slog += dbfname;
slog += " 錯誤。";
AfxMessageBox(slog);
return;
}
int reclen = DBFGetRecordCount(hDBF);
if( reclen != nEntities )
{
DBFClose( hDBF );
SHPClose( hSHP );
AfxMessageBox("shp 和 dbf 文件條目不等。");
return;
}
if( nShapeType == SHPT_POLYGON )// 多邊形區(qū)域
{
for(int i=0;i< nEntities ;i++)
{
SHPObject*psShape;
psShape = SHPReadObject( hSHP, i );// 讀一個實(shí)體類型結(jié)構(gòu)
if( psShape == NULL ) continue;
CString name_ = DBFReadStringAttribute( hDBF, i, 2 );
COLORREF col = RGB(164,240,190);
object = new CMapRegion(psShape, name_, col);
m_aObject.Add(object);
}
}
else if( nShapeType == SHPT_MULTIPOINT || nShapeType == SHPT_POINT )
{
for(int i=0;i< nEntities ;i++)// 點(diǎn)個數(shù)
{
SHPObject*psShape;
psShape = SHPReadObject( hSHP, i );// 讀一個實(shí)體類型結(jié)構(gòu)
if( psShape == NULL ) continue;
CString name_ = DBFReadStringAttribute( hDBF, i, 0 );
COLORREF col = RGB(128,0,0);
object = new CMapDot(psShape, name_, col);
m_aObject.Add(object);
}
}
DBFClose( hDBF );
SHPClose( hSHP );
}
3.3 設(shè)置投影參數(shù)
畫地圖界面繞不開從球面到平面的投影,為使中國版圖的變形最小,地震預(yù)警界面地圖采用lambert投影。在此,僅對使用lambert投影的工作參數(shù)進(jìn)行介紹。
按如下參數(shù)和方法初始化lambert投影,代碼如下:
void CEWClinetView::InitLambertPara()
{
double temflat,temflon;
double x = 0;
double y = ( by0 - viewHight ) * bscale;
xy2ll(x,y,blon0,blat0,&temflon,&temflat);
double bottom = temflat;
x = 0;
y = by0 * bscale;
xy2ll(x,y,blon0,blat0,&temflon,&temflat);
double top = temflat;
lambert.Set_Lambert_Parameters(6378137.0 , 1 / 298.257223563, blat0 ,
blon0 ,
bottom ,
top ,
0,
0);
}
地震預(yù)警系統(tǒng)在我國尚在發(fā)展階段,許多技術(shù)問題有待進(jìn)一步的提高和完善。地震預(yù)警PC桌面客戶端是地震預(yù)警軟件系統(tǒng)的重要組成部分,通過了國家相關(guān)機(jī)構(gòu)組織的驗(yàn)收,目前在首都圈中心和蘭州中心均進(jìn)行了部署,作為地震預(yù)警的基礎(chǔ)軟件24 小時(shí)/天在線運(yùn)行。希望此文的介紹能為地震預(yù)警系統(tǒng)的運(yùn)行和開發(fā)完善提供幫助,也為維護(hù)和有特殊研發(fā)需求的臺網(wǎng)提供借鑒。
[1] DB/T 60-2015, 地震臺站建設(shè)規(guī)范 地震烈度速報(bào)與預(yù)警臺站[S].北京: 地震出版社, 2015.
[2] 肖亮, 俞言祥.應(yīng)用兩步法使用圓模型擬合華北地區(qū)地震烈度衰減關(guān)系[C]//中國地球物理學(xué)會第二十六屆年會暨中國地震學(xué)會第十三次學(xué)術(shù)大會論文集.寧波: 中國地球物理學(xué)會, 2010: 314.
[3] 張臣, 楊剛, 王海濱. 基于GIS的城市地震預(yù)警系統(tǒng)[J].山西建筑 2007, 33(11): 9-10.
Design and Implementation of the PC Receiving Client for Earthquake Early Warning Information
LIU Sheng-guo, GAO Jing-chun, LI Yong-qing, ZHANG Cong-zhen
(Earthquake Administration of Hebei Province, Shijiazhuang 050021, China)
The PC client of the earthquake early warning demonstration system is introduced including its message definition, transport protocol, software process, and technique implementation. The main technical methods, principle of each part and other details of the PC client are also introduced and the source code of the related modules is provided. The introducing may improve the operation of the earthquake early warning system, offer reference for the maintenance and special research and development of other networks.
earthquake early warning; client; seismic intensity; message
2016-11-21
地震科研專項(xiàng):自動速報(bào)震級測定方法研究與實(shí)時(shí)運(yùn)行監(jiān)控軟件研制(201508012)
劉勝國(1974—),男,河北行唐人,高級工程師,主要從事地震臺網(wǎng)監(jiān)測研究工作.E-mail:shengguo@sina.com
P315-391
A
1003-1375(2017)02-0054-07
10.3969/j.issn.1003-1375.2017.02.009
劉勝國,高景春,李永慶,等. 地震預(yù)警信息接收PC客戶端的設(shè)計(jì)及實(shí)現(xiàn)[J].華北地震科學(xué),2017,35(2):54-60.