气象信息与网络技术课程设计题目地面/探空电码译码系统
学生姓名刘星宇
学号20121334054
学院电子与信息工程学院
专业通信工程
设计时间16周
二O一三年十二月三十日
地面/探空电码译码系统
刘星宇
南京信息工程大学通信工程专业,南京 210044
摘要:随着经济发展和人们生活水平的不断提高,气象对人类生活的影响程度也越来越大。
对事关防灾减灾和应对气候变化能力建设的气象服务需求日益增加。气象电码蕴含了丰富的原始
气象观测资料,气象电码的质量关系到天气预报准确度,关系到整个气象事业和人们的生活。科
学准确的气象信息可以提高防灾减灾服务的质量,促进和谐社会的发展,提高应对气候变化能力
积极推进社会的科学发展。而这些都要求我们有一个稳定、高效的气象电码译码系统,以适应发
展的要求。本文的目的是致力于设计一个小的气象地面/探空电码译码系统的研究与实现。本文
通过流程图设计和c语言编程的方法,阐述了如何利用c语言设计一个小的气象地面/探空电码
译码系统及其内部各要素的电码译码。最后得出了结论:此电码译码系统可以较准确的实现气象
地面/探空电码的译码及输出。
关键词:气象;信息;安全;译码
一、前言
气象地面报文电码具有地面各种气象要素和天气现象,如气温、湿度、风向、风速、海平面气压和雨、雪、雾,还具有记录云高、云状、天气演变如三小时变压、气压倾向等。近年来,随着计算机技术的快速发展以及卫星通信技术的研究深度的加深,地面气象报文系统的发展日益完善,报文电码的发展与计算机技术相关度越来越大,二者相结合为人类的日常生活产生了日益深远的影响。
我国是自然灾害频发的国家,而气象灾害又是在自然灾害中损毁程度最严重的。如我国最近几年发生几次大的寒潮,以及每年夏天发生的台风等同时每次自然灾害给人民的生产生活都带来了极大的不便甚至对一个地区的生产秩序起到破坏性的作用,因此国际国内对天气系统的变化情况越来越关注,而在气象领域对卫星观测资料的依赖度越来越大,天气资料在天气预报系统中占据越来越重要的作用,气象报文信息发挥了比以往更关键的角色,气象台根据气象信息预报寒潮、台风、暴雨等自然灾害出现的位置和强度,就可以直接为工农业生产和群众生活服务,通过应急准备及人员疏散等可以讲自然灾害带来的损害讲到最低。气象信息就成为现代社会不可缺少的重要信息。同时,气象信息的作用与气象代码翻译工作是分不开的,通过现代化的手段以及先进的通讯工具,气象电码的翻译工作效率大大提高,气象信息一经翻译,依赖于先进的通讯工具就能够及时地发布出去,具有很强的实时性,因而此代码翻译系统是具有重要意义的。在我们可接触到的各种电码翻译系统中,翻译系统的实现采用了多种语言,本文提供一种基于C语言的电码翻译系统,根据地面报文电码的特点通过相关的语句翻译出所表示的气象信息。
世界气象组织所属的天气监测网由一百多个成员国组成,其观测系统中包括十多颗卫
星、三千多架飞机、一万多个陆上观测站、七千多个船舶观测站以及九百多个携带自动气象站的系统航标和浮标。世界天气观测网络就是通过这个观测系统提供最新的全球天气预报的。每天,高速电信链路通过三个世界级气象中心、34个区域性气象中心和187个国家级气象中心向全球传输气象资料和气象图。
气象资料是气象科学对天气过程进行的预测及对大气活动规律进行研究的主要依据,气象资料交换是气象业务的科研的基础。但是,由于各国文字的不一致性,和文字占据大容量存储空间的问题,决定将其以规定的编码形式在国际国内间进行交换。气象地面电码和探空电码就是其中的一种可供交换编码。
各个行业都有各自的国际电码。地面气象观测的天气电码,不但反映天气实况,而且也反映了天气的演变规律。因此,必须从天气学的角度去理解和选用天气报告电码。这是全面、准确反映测站天气实况和保证天气预报工作、减少人为失误的重要环节。电码需要按照一定的规则编写,这样,译码者才能按照那个规则译出电码所代表的通俗易懂的信息。
随着社会、经济的飞速发展和人民生活水平生活质量的大幅度提高,社会上各行各业对气象部门提出了全方位、多时效、针对性强、准确度高的天气预报服务要求。社会需求永远是天气预报发展的动力和压力。为了适应日益增长的社会需要,做好预报服务,预报员需要用到近年来许多新的知识和参考资料,尤其是各个地区的地面和探空气象资料分析,能够有效帮助预报员分析当地的天气现象,从而做出比较准确的天气预报。
二、需求分析
1、提供给天气预报员实时天气资料,以便实时进行天气分析及准确预报。实时天气资料是天气分析和预报的基础,因为天气总在不断的变化,依据最接近所要预报的时间的实时天气资料所得出天气预报的准确程度最高,短期的天气预报总比长期和中长期的天气预报准确。所以想要得到较为准确的天气预报,必不可少的是方便及时地获得实时资料信息,这就需要电码译码系统来帮助实现。编写成电码的方式,能有效地节约信息传送的时间和空间,增加了天气预报的时效。
2、提供给科研人员过去和现在的天气各要素资料,从气温、气压、风、云、降水、能见度和空气湿度等,得出天气的性质,并且广泛地采用绘图,建表等分析方法,加上具体情况的具体分析,联系各个地方、各个时段的天气情况,找出天气变化规律,系统地进行研究,以便分析总结,研究天气的发展、演变,为揭示天气变化、研究大自然的奥妙,进而应用天气现象做出贡献。该系统对于这些大型的研究来说只是渺小的一小步,但确是不可或缺的一部分。
3、为二次天气应用开发提供天气资料,从而生产各种应用产品。天气应用十分广泛,天气信息可以直接应用播报天气情况,还可以应用在二次天气软件上,如可以设计出查询实时天气情况的软件,输入年月日时段和地点,即可显示出具体气象要素的信息,把软件安装在手机上,随身携带,方便快捷,符合大众的应用要求。
4、提供给开发人员一个译码工具,方便开发人员优化开发,充分利用译码的语句和设计流程,不需要开发人员重新设计,可以直接使用,如此简化了气象台的工作量,增加了其工作效率。此外,还给教师的教学提供了很大的方便,教师直接输入需要知道的时间站点信息即可得到对应的气象要素值,学生可以很好地了解具体的气象要素信息,能更好地学习气象知识。
5、提供给普通用户查询天气实时或过去天气资料,用户自己总结天气状况,决定自己在穿衣御寒防热还有度假出行等方面的生活。
6、提供给农民获取实时天气和过去天气资料,对比现在天气情况,从而比较好地进行播种、收割等农家活动。有了科学技术的支持,农业生产能取得迅速地发展,收获更多地粮食,养活更多的人口。
7、提供给工厂天气情况,有些产品的生产与天气的要素如温度、湿度等有着很大的关系,清楚地了解了具体的天气情况就能及时调整这些因素,这对产品的生产有很大的益处,工厂生产效率也能极大的提高。
三、 概要设计
1、 设计思路
读取气象电报电码文件,经过本电码译码系统,生产各气象要素。地面电码资料的气象要素有:温度、露点、本站气压、海平面气压、气压趋势、气压变化量、降水量、天气现象、云状、能见度,风向飞速、总云量等;高空电码资料的气象要素分13层:地面、1000hPa 、925hPa 、850hPa 、700hPa 、500hPa 、400hPa 、300hPa 、250hPa 、200hPa 、150hPa 、100hPa ;高空电码资料的每层气象要素是:温度、温度露点差、气压、风向飞速。
编程思路是:由用户输入要译码的年、月、日、世界时次和台站号(注:有可能的话用地名),并选择地面或高空;由译码系统进行译码,生产出气象各要素,在屏幕上显示。
2、 地面/探空电报译码数据流图
图3-1
3、 地面/探空电报译码程序总流程图
图3-2
四、详细设计
1.读文件中的记录行功能流程图
图4.1读文件中的一个记录行功能流程图
2.地面各要素的译码,输入参数,前五位为台站号,下面依次按照各要素翻译
图4.2 译出地面各要素功能流程图
3.输入参数,分解已读入的字符串,第0-11字符串不用,12-16字符为台站号,剩下的
代码根据探空译码资料分别进行译码,具体流程图如下图4-3所示。
图4.3 译出探空各要素功能流程图
4. 1sTTT组电码翻译流程图
首先输入参数,判断是否超出范围,若超出则提示出错,若未超出判断第二个数是否为0,若为0则气温为正,否则为负,将TTT翻译成气温,以0.1度为单位输出气温,最后结束程序,流程图如下图4-4
图4-4
5. 4PPPP组电码
首先输入参数,判断PPPP是否大于500,若大于500则海平面气压值在原来基础上增加1000,若大于500则直接以PPPP值作为海平面气压,最后结束程序,流程图如下图5-5所示。
图4-5
五、编码设计
#include
#include
int str2int(char *ch,int k,int n);
void dmdisp(char *ch); // 对ch进行地面译码的功能函数由学生自行完成
void updisp(char *ch); // 对ch进行高空译码的功能函数由学生自行完成
void main(void)
{ int year,month,day,hour,n,p;
char station[6],name[]="AAXX0000.T00",ch[400];
FILE *fp;
printf("请输入年、月、日\n");
scanf("%d%d%d",&year,&month,&day);
name[4]='0'+month/10; name[5]='0'+month%10;
name[6]='0'+day/10; name[7]='0'+day%10;
printf("请选择:1-地面;2-高空\n");
scanf("%d",&p);
if (p!=1)
{ name[0]='T'; name[1]='T'; name[2]='A'; name[3]='A';
p=13;
}
if (p!=1) printf("请输入高空世界时,供选择:0、6、12、18\n");
else printf("请输入地面世界时,供选择:0、3、6、9、12、15、18、21\n"); scanf("%d",&hour);
name[10]='0'+hour/10; name[11]='0'+hour%10;
printf("请输入台站号,南京为58238\n");
scanf("%s",station);
if (fp=fopen(name,"rt"))
{ fgets(ch,80,fp);
fgets(ch,80,fp);
if (p==1) fgets(ch,80,fp);
while(!feof(fp))
{ fgets(ch,80,fp);
n=strlen(ch);
while (n<300 && ch[n-1] != '=' && !feof(fp))
{ ch[n]= ' ';
fgets(&ch[n+1],80,fp);
n=strlen(ch)-1;
}
if (!strncmp(&ch[p-1],station,5))
{ if (p==1) dmdisp(ch);
else updisp(ch);
p=0;
break;
}
}
fclose(fp);
if (p!=0) printf("%s--台站未找到,请检查!!!\n",station);
}
else printf("%s--文件不存在,请检查!!!\n" ,name);
}
//长度为n的字符串转换为整形值。对于含有非数字字符,则返回负1。
//k:字符串的起始位置
int str2int(char *ch,int k,int n)
{ int i,m=0;
for(i=0;i { if (ch[k+i]<'0' || ch[k+i]>'9') {m=-1; break;} m=m*10+ch[k+i]-'0'; } return m; } //对字符串电码ch进行译码,翻译出地面各要素的值进行显示。 void dmdisp(char *ch) { int i; long int vv; int dd,ff,x,y,ww,m,n; // 对ch进行译码,由学生自行完成 //puts(ch); // 显示读到的字符串电码内容 printf("台站号:"); for(i=0;i<5;i++) printf("%c",ch[i]); printf("\n"); switch(ch[8]) { case '0' : printf("云底高度<50米");break; case '1' : printf("云底高度50-<100米");break; case '2' : printf("云底高度100-<200米");break; case '3' : printf("云底高度200-<300米");break; case '4' : printf("云底高度300-<600米");break; case '5' : printf("云底高度600-<1000米");break; case '6' : printf("云底高度1000-<1500米");break; case '7' : printf("云底高度1500-<2000米");break; case '8' : printf("云底高度2000-<2500米");break; case '9' : printf("云底高度>=2500米");break; default:printf("缺测"); } printf("\n"); vv=str2int(ch,9,2); if (vv==0) printf("有效能见度<100米"); else if (vv<=50) {vv=vv*100; printf("有效能见度%d米",vv); } else if(vv<=55) printf("不用"); else if (vv<=79) {vv=vv-50; printf("有效能见度%d千米",vv); } else if (vv==80) printf("有效能见度>=30千米"); else if (vv<=88) {vv=(vv-80)*5+30; printf("有效能见度%dq千米",vv); } else if (vv==89) printf("有效能见度>70千米"); else if (vv==90) printf("有效能见度<50米"); else if (vv==91) printf("有效能见度为50米"); else if (vv==92) printf("有效能见度为200米"); else if (vv==93) printf("有效能见度为500米"); else if (vv==94) printf("有效能见度为1千米"); else if (vv==95) printf("有效能见度为2千米"); else if (vv==96) printf("有效能见度为4千米"); else if (vv==97) printf("有效能见度为10千米"); else if (vv==98) printf("有效能见度为20千米"); else if (vv==99) printf("有效能见度>=50千米"); printf("\n"); switch(ch[12]) { case '0' : printf("无云");break; case '1' : printf("总云量为1");break; case '2' : printf("云底高度总云量为2-3");break; case '3' : printf("总云量为4");break; case '4' : printf("总云量为5");break; case '5' : printf("总云量为6");break; case '6' : printf("总云量为7-8");break; case '7' : printf("总云量为9");break; case '8' : printf("总云量为10");break; case '9' : printf("有雾");break; default:printf("缺测"); } printf("\n"); dd=str2int(ch,13,2); m=dd%10; n=dd/10; if(m<5) dd=n*10; else dd=(n+1)*10; if (dd==0) printf("为静止风"); else { dd=dd*10; printf("风向为%d度",dd); } printf("\n"); ff=str2int(ch,15,2); m=ff%10; n=ff/10; if(m<5) ff=n*10; else ff=(n+1)*10; ff=ff/10*10; printf("风速为%d米/秒",dd); printf("\n"); n=18; if(ch[n]=='1') { printf("气温资料为:"); switch(ch[n+1]) { case'0': printf(" ");break; case'1': printf("-");break; default:printf("数据出错"); } x=str2int(ch,n+2,2); y=str2int(ch,n+4,1); printf("%d.%d度",x, y); n+=6; } printf("\n"); if(ch[n]=='2') { printf("露点温度资料为:"); switch(ch[n+1]) { case'0': printf(" ");break; case'1': printf("-");break; default:printf("数据出错"); } x=str2int(ch,n+2,2); y=str2int(ch,n+4,1); printf("%d.%d度",x,y); n+=6; } printf("\n"); if(ch[n]=='3') { printf("本站气压资料为:"); x=str2int(ch,n+1,3); y=str2int(ch,n+4,1); printf("本站气压为%d.%d百帕",x,y); n+=6; } printf("\n"); if(ch[n]=='4') { printf("海平面气压资料为:"); x=str2int(ch,n+1,3); y=str2int(ch,n+4,1); if (x<5) x=x+10; printf("气压值为%d.%d百帕",x,y); n+=6; } printf("\n"); if(ch[n]=='5') { printf("过去三小时本站气压变化量为:"); if (ch[n+1]>4) printf("上升"); else printf("下降"); x=str2int(ch,n+2,2); y=str2int(ch,n+4,1); printf("%d.%d百帕",x,y); n+=6; } printf("\n"); if(ch[n]=='6') { printf("过去六小时降水量资料:"); x=str2int(ch,n+1,3); if (x==0) printf("降水量无"); else if (x<=998) printf("降水量为%d毫米",x); else if(x==990) printf("降水量微量"); else if(x<=999) printf("降水量为%d毫米",(x-990)/10); n+=6; } printf("\n"); if(ch[n]=='7') { printf("观测时和过去的天气现象资料为:"); ww=str2int(ch,n+1,2); if ((ww==00)||(ww==01)||(ww==02)||(ww==03)) printf("观测时天气现象无"); else if (ww==4) printf("观测时天气现象为烟"); else if (ww==5) printf("观测时天气现象为霾"); else if (ww<=9) printf("观测时天气现象为沙尘"); else if (ww<=12) printf("观测时天气现象为轻、浅雾"); printf("观测时天气现象为闪电"); else if (ww<=16) printf("观测时天气现象为降水"); else if (ww==17) printf("观测时天气现象为雷暴"); else if (ww==18) printf("观测时天气现象为飑"); else if (ww==19) printf("观测时天气现象为龙卷"); else if (ww==20) printf("观测时天气现象为毛毛雨"); else if (ww==21) printf("观测时天气现象为雨"); else if (ww==22) printf("观测时天气现象为雪、米雪"); else if (ww==23) printf("观测时天气现象为雨夹雪"); else if (ww==24) printf("观测时天气现象为雨、雨凇"); else if (ww==25) printf("观测时天气现象为阵雪"); else if (ww==26) printf("观测时天气现象为阵雨夹雪"); else if (ww==27) printf("观测时天气现象为冰雹"); else if (ww==28) printf("观测时天气现象为大雾"); else if (ww==29) printf("观测时天气现象为雷暴"); else if (ww<=35) printf("观测时天气现象为沙尘暴"); else if (ww<=39) printf("观测时天气现象为吹雪"); else if (ww<=49) printf("观测时天气现象为浓雾"); else if (ww<=59) printf("观测时天气现象为浓毛毛雨"); else if (ww<=61) printf("观测时天气现象为小雨"); else if (ww<=63) printf("观测时天气现象为中雨"); else if (ww<=65) printf("观测时天气现象为大雨"); printf("观测时天气现象为雨凇"); else if (ww<=69) printf("观测时天气现象为中雨降水"); else if (ww<=71) printf("观测时天气现象为小雪"); else if (ww<=73) printf("观测时天气现象为中雪"); else if (ww<=75) printf("观测时天气现象为大雪"); else if (ww==76) printf("观测时天气现象为冰针"); else if (ww==77) printf("观测时天气现象为米雪"); else if (ww==78) printf("观测时天气现象为雪晶"); else if (ww==79) printf("观测时天气现象为冰粒"); else if (ww==80) printf("观测时天气现象为小阵雨"); else if (ww==81) printf("观测时天气现象为中阵雨"); else if (ww==82) printf("观测时天气现象为大阵雨"); else if (ww==83) printf("观测时天气现象为小阵性雨夹雪"); else if (ww==84) printf("观测时天气现象为大阵性雨夹雪"); else if (ww==85) printf("观测时天气现象为小阵雪"); else if (ww==86) printf("观测时天气现象为中或大阵雪"); else if (ww==87) printf("观测时天气现象为小阵性霰"); else if (ww==88) printf("观测时天气现象为中或大阵性霰"); else if (ww==89) printf("观测时天气现象为轻冰雹"); else if (ww==90) printf("观测时天气现象为中或强冰雹"); else if (ww==91) printf("观测时天气现象为雷暴后小雨"); else if (ww==92) printf("观测时天气现象为雷暴后中雨"); printf("观测时天气现象为雷暴后小雪"); else if (ww==94) printf("观测时天气现象为雷暴后大雪"); else if (ww==95) printf("观测时天气现象为小雷暴伴雨雪"); else if (ww==96) printf("观测时天气现象为小雷暴伴冰雹"); else if (ww==97) printf("观测时天气现象为大雷暴伴雨雪"); else if (ww==98) printf("观测时天气现象为雷暴、沙尘暴"); else if (ww==99) printf("观测时天气现象为大雷暴伴冰雹"); printf("\n"); switch(ch[n+3]) { case'0':printf("主要过去六小时天气现象无");break; case'3':printf("主要过去六小时天气现象为沙尘暴");break; case'4':printf("主要过去六小时天气现象为雾");break; case'5':printf("主要过去六小时天气现象为毛毛雨");break; case'6':printf("主要过去六小时天气现象为非阵性雨");break; case'7':printf("主要过去六小时天气现象为固体降水");break; case'8':printf("主要过去六小时天气现象为阵雨");break; case'9':printf("主要过去六小时天气现象为雷暴");break; default:printf("数据错误"); } switch(ch[n+4]) { case'0':printf("次要过去六小时天气现象无");break; case'3':printf("次要过去六小时天气现象为沙尘暴");break; case'4':printf("次要过去六小时天气现象为雾");break; case'5':printf("次要过去六小时天气现象为毛毛雨");break; case'6':printf("次要过去六小时天气现象为非阵性雨");break; case'7':printf("次要过去六小时天气现象为固体降水");break; case'8':printf("次要过去六小时天气现象为阵雨");break; case'9':printf("次要过去六小时天气现象为雷暴");break; default:printf("数据错误"); } n+=6; } printf("\n"); if(ch[n]=='8') { printf("云的资料为:"); switch(ch[n+1]) { case '0' : printf("无云");break; case '1' : printf("总云量为1");break; case '2' : printf("云底高度总云量为2-3");break; case '3' : printf("总云量为4");break; case '4' : printf("总云量为5");break; case '5' : printf("总云量为6");break; case '6' : printf("总云量为7-8");break; case '7' : printf("总云量为9");break; case '8' : printf("总云量为10");break; case '9' : printf("有雾");break; default:printf("缺测"); } switch(ch[n+2]) { case '0' : printf("无低云");break; case '1' : printf("低云状为淡积云");break; case '2' : printf("低云状为浓积云");break; case '3' : printf("低云状为积层云");break; case '4' : printf("低云状为积层云");break; case '5' : printf("低云状为积层云");break; case '6' : printf("低云状为碎雨云");break; case '7' : printf("低云状为碎雨云");break; case '8' : printf("低云状为积云");break; case '9' : printf("低云状为鬃积云");break; default:printf("数据错误"); } switch(ch[n+3]) { case '0' : printf("无中云");break; case '1' : printf("中云状为高层云");break; case '2' : printf("中云状为雨层云");break; case '3' : printf("中云状为高积云");break; case '4' : printf("中云状为荚状云");break; case '5' : printf("中云状为层积云");break; case '6' : printf("中云状为积雨云");break; case '7' : printf("中云状为积层云");break; case '8' : printf("中云状为积云");break; case '9' : printf("中云状为散积云");break; default:printf("数据错误"); } switch(ch[n+4]) { case '0' : printf("无低云");break; case '1' : printf("高云状为毛卷云");break; case '2' : printf("高云状为密卷云");break; case '3' : printf("高云状为伪卷云");break; case '4' : printf("高云状为钩卷云");break; case '5' : printf("高云状为卷云");break; case '6' : printf("高云状为辐卷云");break; case '7' : printf("高云状为卷层云");break; case '8' : printf("高云状为层云");break; case '9' : printf("高云状为卷积云");break; default:printf("数据错误"); } n+=6; } printf("\n"); if(ch[n]=='9') { x=str2int(ch,n+1,2); y=str2int(ch,n+3,2); printf("实际观察时间为%d小时%d分钟",x,y); n+=6; } printf("\n"); } //对字符串电码ch进行译码,翻译出高空各层各要素的值进行显示。 void updisp(char *ch) { // 对ch进行译码,由学生自行完成 //puts(ch); // 显示读到的字符串电码内容 int n,i,p,y,t,d,f; n=(ch[10]==' ')?11:12; y=str2int(ch,n-6,2); printf("区站号:\n"); for(i=0;i<5;i++)printf("%c",ch[n+i]); printf("\n"); while(1) { n+=6; p=str2int(ch,n+2,3); if(ch[n]=='9'&&ch[n+1]=='9') { if(p<=100) printf("地面或本站气压的位势米:%d",(p+1000)); else printf("地面或本站气压的位势米:%d",p); } else if(ch[n]=='0'&&ch[n+1]=='0') {