地震预警信息接收PC客户端的设计及实现

2017-06-01 11:29刘胜国高景春李永庆张从珍
华北地震科学 2017年2期
关键词:烈度台网代码

刘胜国, 高景春, 李永庆, 张从珍

(河北省地震局,石家庄 050021)

地震预警信息接收PC客户端的设计及实现

刘胜国, 高景春, 李永庆, 张从珍

(河北省地震局,石家庄 050021)

介绍了地震预警示范系统中预警客户端的消息定义与传输协议、软件流程和技术实现方式等内容,以及各部分的主体技术方法、原理等细节,并给出了相关模块的源代码。对这些软件相关内容的介绍,旨在为地震预警系统的运行完善提供帮助,也为维护和有特殊研发需求的台网提供借鉴。

地震预警;客户端;地震烈度;消息

0 引言

地震预警是在地震发生后,对即将到来的破坏性地震动进行预测和警报[1]。其利用地震波传播速度小于电磁波传播速度的特点,提前对地震波尚未到达的地方进行预警,利用实时监测台网获取的地震信息,以及对地震可能的破坏范围和程度做快速评估,在破坏性地震波到达之前的短暂时间发出预警,减少人员伤亡和经济损失。

继“十一五”国家科技支撑项目“地震预警与烈度速报系统的研究与示范应用”以后,在北京和兰州部署安装了“预警台网信息实时分析和地震报警及信息发布软件”。地震预警PC桌面客户端和其它预警接收软件一样,处在预警系统的末端,直接面向用户,是地震预警软件系统的重要组成部分;其可靠运行将为指挥决策服务,为用户在灾难面前赢取宝贵的时间,减轻地震次生灾害、人员伤亡以及经济损失。在此,我们对地震预警客户端的消息协议、实现方式和技术原理等关键环节进行分析介绍。

1 预警消息传输协议与定义

1.1 传输协议

预警发布服务器发布的预警消息采用ActiveMQ的服务接口、遵循其消息包装方式(ActiveMQ是由Apache出品,能力强劲的开源消息总线),使用BytesMessage消息进行通讯,从EW.XX主题接收预警消息(XX代表台网代码)。

对预警消息的封装主要由消息属性和消息体组成。对于最基本的标志性信息需要从属性中读取,有了这些标志性信息,我们就可以做到筛选自己感兴趣的内容。比如通过读消息属性,我们可以做到仅接收某一台网发布的预警消息(有可能连接主题上还包含其它消息)。

地震预警消息的属性、消息主体按如下定义封装:

1.2 预警消息属性

消息属性的封装如下(表1)。

表1 预警消息属性表

1.3 预警消息体

对消息体的封装遵循W3C发布的可扩展标记语言XML1.0规范,编码方式为UTF-8。定义如下:

消息体的具体定义如下:

1) 根节点为EarlyWarning,其属性包括:

Net_code:台网代码

Event_id:事件ID

Catalog_id:目录ID

Promul_no:第几次发布

Promul_time:发布时间

Ew_reliability:预警可靠度(1.0为最高可靠度值,0为最低可靠度值)

Intensity_value:震中烈度值

2)地震目录节点Catalog,其属性包含了地震目录参数

Net_code:台网代码

O_time:发震时刻中的年月日时分秒,其中秒为整数

O_time_frac:发震时刻(1/10 000)s,即秒的小数部分

Epi_lat:震中纬度

Epi_lon:震中经度

Epi_depth:深度,单位为公里(km)

M:震级

M_source:发布震级来源

Loc_stn:定位台站数

Location_cname:震中参考地名

3)预警对象节点Ew_object,其下包含一个或一个以上的预警对象Object。

4)单个预警对象节点Object(对多个城市点做预警时,重复此节点),其属性如下:

Object_name:预警目标名称(比如:某一城市)

Object_lon:预警目标经度

Object_lat:预警目标纬度

Predict_intensity:预测烈度

Warning_time:预警时间,以s为单位

S_arrive:S波预计到达时间

S_arrive_frac:S波预计到达时间(1/10 000)s

2 预警客户端实现流程和技术

2.1 实现流程

软件启动时读入参数文件,初始化工作环境。由预警接收线程实时监听地震预警发布服务器上的预警消息,当有新消息到来后根据地震消息参数计算震中距和本地烈度,以震中位置为中心动态显示预警时间和当前位置地震烈度等关键信息(图1):

图1 软件工作流程

2.2 监听预警消息实现方法

通过与ActiveMQ消息总线相连,从预警发布主题接收预警消息,其连接遵循ActiveMQ的CMS接口规范。按如下步骤进行:

(1)创建连接类厂

std::auto_ptr connectionFactory( cms::ConnectionFactory::createCMSConnectionFactory(URI) );

(2)创建连接

std::auto_ptr connection(connectionFactory->createConnection() );

(3)创建会话

std::auto_ptr session(connection->createSession() );

(4)创建接收主题

std::auto_ptr myTopic(session->createTopic( "EW.XX" ) );

(5)创建消费者

std::auto_ptr myConsumer(

session->createConsumer(myTopic ) );

(6)接收预警消息

while(!done ) {

std::auto_ptr message(myConsumer->receive() );

...处理预警消息...

}

接收到消息后,按上面接收的“消息定义”解析地震预警的信息内容。

2.3 计算本地烈度方法

按烈度的衰减公式[2]计算接收者所在地的本地烈度,公式如下:

I=A+B×M+C×log10(R+R0)

(1)

式中:M为震级,R为震中距(用户所在地到震中的距离)。考虑到烈度衰减的复杂,把全国版图分区,不同地区选用不同的参数(表2)。

表2 烈度计算分区表

按下表选取公式所用的参数(表3)。

表3 烈度公式所用参数表

程序实现代码如下:

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 计算预警时间

从预警发布服务器接收地震预警消息,根据消息中地震目录给出的发震时刻,动态计算预警时间。计算公式如下:

(2)

式中:Rt为预警时间,Δ为震中距,VS为S波速度,Ct为当前时间,T0为发震时刻。

程序实现代码如下:

voidCEWClinetView::DrawEWTime(CDC*pDC,unsignedintlapse)

{

CEWClinetDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

if(!pDoc)return;

intremain_seconds=static_cast(m_delta/g_S_velocity) -lapse; // 到达本地的剩余秒数

if(remain_seconds< 0 )return;

usingnamespaceGdiplus;

Graphicsgraphics(pDC->m_hDC);

intposx=viewWidth- 748;

intposy=viewHight-110;

intwidth= 728;

inthigh= 80;

// 区域

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"估计 %d秒后横波到达您现在位置",remain_seconds);

else

{

swprintf(sm,L" 横波已经到达您现在位置 ",remain_seconds);

CEWClinetApp*pApp= (CEWClinetApp*)AfxGetApp();

pApp->EndAlarm();

}

graphics.DrawString(sm,wcslen(sm), &font,PointF(xP,yP), &brush);

}

3 显示界面实现

程序运行界面的右上方显示“本次地震的参数”和“预测用户所在地的烈度”,在右下方动态显示预警时间。动态扩大的实心圆代表S波的到达区域,外围的大圆是P波到达的区域(图2):

图2 软件界面

3.1 实现的核心部分

接收到新的预警消息以后,在地图上标注震中位置,显示地震参数、本地烈度、S波到达时间[3]。程序实现的关键代码如下:

void CEWClinetView::OneEWMessage()// 处理新收到的预警消息

{

CEWClinetDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

if (!pDoc)

return;

if( !CheckData() ) return;

// 震中位置

setEQposition(pDoc->m_catalog.Epi_lat, pDoc->m_catalog.Epi_lon);

// 发震时刻

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);

// 计算本地烈度

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

/**

视区经纬度中心点

*/

blat0 = (eq_lat + pDoc->m_catalog.Epi_lat)/2;

blon0 = (eq_lon + pDoc->m_catalog.Epi_lon)/2;

bx0 = viewWidth*2/5; // 不在“X”轴的中点,设置在2/5的位置

by0 = viewHight/2;

DrawMap(m_pMemDC);//重绘

m_ETflag = true;

SetTimer(WM_SECONDCHANGE,1000,NULL);

Invalidate(); //更新显示

}

3.2 shp文件读取

shp地图格式是ESRI提供的一种矢量数据格式,它没有拓扑信息,主要由坐标文件(.shp)、索引文件(.shx)和属性文件(.dbf)组成。由于自己写代码读取相对复杂,我们采用了GIS开源库shplib去实现。

程序调用shp文件的相关代码如下:

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 )// 多边形区域

{

for(int i=0;i< nEntities ;i++)

{

SHPObject*psShape;

psShape = SHPReadObject( hSHP, i );// 读一个实体类型结构

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++)// 点个数

{

SHPObject*psShape;

psShape = SHPReadObject( hSHP, i );// 读一个实体类型结构

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 设置投影参数

画地图界面绕不开从球面到平面的投影,为使中国版图的变形最小,地震预警界面地图采用lambert投影。在此,仅对使用lambert投影的工作参数进行介绍。

按如下参数和方法初始化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);

}

4 结语

地震预警系统在我国尚在发展阶段,许多技术问题有待进一步的提高和完善。地震预警PC桌面客户端是地震预警软件系统的重要组成部分,通过了国家相关机构组织的验收,目前在首都圈中心和兰州中心均进行了部署,作为地震预警的基础软件24 小时/天在线运行。希望此文的介绍能为地震预警系统的运行和开发完善提供帮助,也为维护和有特殊研发需求的台网提供借鉴。

[1] DB/T 60-2015, 地震台站建设规范 地震烈度速报与预警台站[S].北京: 地震出版社, 2015.

[2] 肖亮, 俞言祥.应用两步法使用圆模型拟合华北地区地震烈度衰减关系[C]//中国地球物理学会第二十六届年会暨中国地震学会第十三次学术大会论文集.宁波: 中国地球物理学会, 2010: 314.

[3] 张臣, 杨刚, 王海滨. 基于GIS的城市地震预警系统[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

地震科研专项:自动速报震级测定方法研究与实时运行监控软件研制(201508012)

刘胜国(1974—),男,河北行唐人,高级工程师,主要从事地震台网监测研究工作.E-mail:shengguo@sina.com

P315-391

A

1003-1375(2017)02-0054-07

10.3969/j.issn.1003-1375.2017.02.009

刘胜国,高景春,李永庆,等. 地震预警信息接收PC客户端的设计及实现[J].华北地震科学,2017,35(2):54-60.

猜你喜欢
烈度台网代码
高烈度区域深基坑基坑支护设计
高烈度区高层住宅建筑的结构抗震设计策略
地球物理台网仪器维修信息管理的研究与实现
高烈度地震区非规则多跨长联连续梁抗震分析
推进报台网深度融合 做强区级融媒体中心
创世代码
创世代码
创世代码
创世代码
西藏地震应急流动台网浅析