ProductDescriptionBlock.java
001 /**
002 * PACKAGE : cma.gmb.doppler.datatype
003 * FILENAME : ProductDescriptionBlock.java
004 * DESCRIPTION : 多普勒雷达产品数据结构
005 * AUTHOR : 刘泽军
006 * EMAIL : BJ0773@gmail.com
007 * Date : 2007-05-21 09:55:21
008 * Update :
009 * Reference : 《NEXRAD LEVEL II数据格式》中文版及英文版
010 */
011
012 package cma.gmb.doppler.datatype;
013
014 import java.io.*;
015 import java.lang.*;
016
017 import cma.common.dataio.*;
018
019 public class ProductDescriptionBlock { //产品说明数据结构
020
021 public static int SIZE = 102 ;
022
023 public short BlockDivider; //18~19 数据块分隔符,为-1
024 public int RadarLatitude; //20~23 雷达站经度,单位:0.001度
025 public int RadarLongitude; //24~27 雷达站纬度,单位:0.001度
026 public short RadarHeight; //28~29 海拔高度,单位:英尺
027 public short ProductCode; //30~31 产品代号
028 public short OperationalMode; //32~33 运行模式,
029 // 0=Maintenance
030 // 1=Clear Air
031 // 2=Precipitation/Server Weather
032 public short VolumeCoveragePattern; //34~35 VCP方式
033 public short SequenceNumber; //36~37 产品生成序列号
034 public short VolumeScanNumber; //38~39 体扫计数,1~80之间循环
035 public short VolumeScanDate; //40~41 体扫日期(Julian-1/1/70)
036 public int VolumeScanTime; //42~45 体扫时间(GMT)
037 public short ProductGenerationDate; //46~47产品生成日期
038 public int ProductGenerationTime; //48~51 产品生成GMT时间
039 public short P1; //52~53
040 public short P2; //54~55
041 public short ElevationNumber; //56~57 表示体扫中的第几个仰角层(1~20)
042 public short P3; //58~59
043 public short [] DataLevelThreshold; //60~91 数据分级门限值,共16个数据
044 public short P4; //92~93
045 public short P5; //94~95
046 public short P6; //96~97
047 public short P7; //98~99
048 public short P8; //100~101
049 public short P9; //102~103
050 public short P10; //104~105
051 public short NumberOfMaps; //106~107 底图数据中的块数;
052 // Version; 高字节表示 产品的版本号,原始产品为0;
053 // StopBlank; 低字节1=Stop ON, 2=Stop OFF
054 public int OffsetToSymbology; //108~111 符号数据偏移
055 public int OffsetToGraphic; //112~115 图形数据偏移
056 public int OffsetToTabular; //116~119 表格数据偏移
057
058 /**
059 * 功能:构造函数
060 * 参数:
061 * 无
062 * 返回:
063 * 无
064 */
065 public ProductDescriptionBlock () {
066 DataLevelThreshold = new short [ 16 ] ;
067 }
068
069 /**
070 * 功能:从文件中读取数据,并进行BigEndian转换
071 * 参数:
072 * raf - 随机访问的文件对象
073 * 返回:
074 * 是否成功
075 */
076 public boolean read ( RandomAccessFile raf ) {
077 try {
078 byte [] buf = new byte [ ProductDescriptionBlock.SIZE ] ;
079 int len = raf.read ( buf ) ;
080 return ( len == ProductDescriptionBlock.SIZE ? parse ( buf, 0 ) : false ) ;
081 }
082 catch ( Exception ex ) {
083 return ( false ) ;
084 }
085 }
086
087 /**
088 * 功能:从输入流文件中读取数据,并进行BigEndian转换
089 * 参数:
090 * in - InputStream对象
091 * 返回:
092 * 是否成功
093 */
094 public boolean read ( InputStream in ) {
095 try {
096 byte [] buf = new byte [ ProductDescriptionBlock.SIZE ] ;
097 int len = in.read ( buf ) ;
098 return ( len == ProductDescriptionBlock.SIZE ? parse ( buf, 0 ) : false ) ;
099 }
100 catch ( Exception ex ) {
101 return ( false ) ;
102 }
103 }
104
105 /**
106 * 功能:从缓冲区中读数据
107 * (在外部方法中,一次性读入所有数据,然后逐类分析数据)
108 * 参数:
109 * buf - 缓冲数据
110 * index - 偏移
111 * 返回:
112 * 正确读出的数据字节数
113 */
114 public int read ( byte [] buf, int index ) {
115 return ( parse ( buf, index ) ?ProductDescriptionBlock.SIZE: 0 ) ;
116 }
117
118 /**
119 * 功能:从缓冲区中分析出数据
120 * 参数:
121 * buf - 缓冲数据
122 * 返回:
123 * 是否成功
124 */
125 public boolean parse ( byte [] buf ) {
126 return ( parse ( buf, 0 )) ;
127 }
128
129 /**
130 * 功能:从缓冲区中分析出数据
131 * 参数:
132 * buf - 缓冲数据
133 * index - 偏移
134 * 返回:
135 * 是否成功
136 */
137 public boolean parse ( byte [] buf, int index ) {
138 if ( buf.length < index + ProductDescriptionBlock.SIZE ) {
139 return ( false ) ;
140 }
141 BlockDivider = DataConverterBE.getShort ( buf, index+ 0 ) ; //18~19 数据块分隔符,为-1
142 RadarLatitude = DataConverterBE.getInt ( buf, index+ 2 ) ; //20~23 雷达站经度,单位:0.001度
143 RadarLongitude = DataConverterBE.getInt ( buf, index+ 6 ) ; //24~27 雷达站纬度,单位:0.001度
144 RadarHeight = DataConverterBE.getShort ( buf, index+ 10 ) ; //28~29 海拔高度,单位:英尺
145 ProductCode = DataConverterBE.getShort ( buf, index+ 12 ) ; //30~31 产品代号
146 OperationalMode = DataConverterBE.getShort ( buf, index+ 14 ) ; //32~33 运行模式,
147 VolumeCoveragePattern = DataConverterBE.getShort ( buf, index+ 16 ) ; //34~35 VCP方式
148 SequenceNumber = DataConverterBE.getShort ( buf, index+ 18 ) ; //36~37 产品生成序列号
149 VolumeScanNumber = DataConverterBE.getShort ( buf, index+ 20 ) ; //38~39 体扫计数,1~80之间循环
150 VolumeScanDate = DataConverterBE.getShort ( buf, index+ 22 ) ; //40~41 体扫日期(Julian-1/1/70)
151 VolumeScanTime = DataConverterBE.getInt ( buf, index+ 24 ) ; //42~45 体扫时间(GMT)
152 ProductGenerationDate = DataConverterBE.getShort ( buf, index+ 28 ) ; //46~47 产品生成日期
153 ProductGenerationTime = DataConverterBE.getInt ( buf, index+ 30 ) ; //48~51 产品生成GMT时间
154 P1 = DataConverterBE.getShort ( buf, index+ 34 ) ; //52~53
155 P2 = DataConverterBE.getShort ( buf, index+ 36 ) ; //54~55
156 ElevationNumber = DataConverterBE.getShort ( buf, index+ 38 ) ; //56~57 表示体扫中的第几个仰角层(1~20)
157 P3 = DataConverterBE.getShort ( buf, index+ 40 ) ; //58~59 一般为仰角度数 *0.1
158 for ( int i= 0 ;i< 16 ;i++ ) {
159 DataLevelThreshold [ i ] = ( short )(( int ) DataConverterBE.getShort ( buf, index+ 42 +i* 2 ) % 256 ) ; //60~91 数据分级门限值
160 }
161 P4 = DataConverterBE.getShort ( buf, index+ 74 ) ; //92~93
162 P5 = DataConverterBE.getShort ( buf, index+ 76 ) ; //94~95
163 P6 = DataConverterBE.getShort ( buf, index+ 78 ) ; //96~97
164 P7 = DataConverterBE.getShort ( buf, index+ 80 ) ; //98~99
165 P8 = DataConverterBE.getShort ( buf, index+ 82 ) ; //100~101
166 P9 = DataConverterBE.getShort ( buf, index+ 84 ) ; //102~103
167 P10 = DataConverterBE.getShort ( buf, index+ 86 ) ; //104~105
168 NumberOfMaps = DataConverterBE.getShort ( buf, index+ 88 ) ; //106~107 底图数据中的块数;
169 OffsetToSymbology = DataConverterBE.getInt ( buf, index+ 90 ) ; //108~111
170 OffsetToGraphic = DataConverterBE.getInt ( buf, index+ 94 ) ; //112~115
171 OffsetToTabular = DataConverterBE.getInt ( buf, index+ 98 ) ; //116~119
172 return ( true ) ;
173 }
174
175 /**
176 * 功能:获得数据信息
177 * 参数:
178 * 无
179 * 返回:
180 * 数据信息
181 */
182 public String info () {
183 String msg =
184 "/nProductDescriptionBlock.SIZE = " + String.valueOf ( ProductDescriptionBlock.SIZE ) +
185 "/n BlockDivider = " + String.valueOf ( BlockDivider ) +
186 "/n RadarLatitude = " + String.valueOf ( RadarLatitude ) +
187 "/n RadarLongitude = " + String.valueOf ( RadarLongitude ) +
188 "/n RadarHeight = " + String.valueOf ( RadarHeight ) +
189 "/n ProductCode = " + String.valueOf ( ProductCode ) +
190 "/n OperationalMode = " + String.valueOf ( OperationalMode ) +
191 "/n VolumeCoveragePattern = " + String.valueOf ( VolumeCoveragePattern ) +
192 "/n SequenceNumber = " + String.valueOf ( SequenceNumber ) +
193 "/n VolumeScanNumber = " + String.valueOf ( VolumeScanNumber ) +
194 "/n VolumeScanDate = " + String.valueOf ( VolumeScanDate ) + "(" +MessageHeaderBlock.getDate ( VolumeScanDate ) + ")" +
195 "/n VolumeScanTime = " + String.valueOf ( VolumeScanTime ) + "(" +MessageHeaderBlock.getTime ( VolumeScanTime ) + ")" +
196 "/n ProductGenerationDate = " + String.valueOf ( ProductGenerationDate ) + "(" +MessageHeaderBlock.getDate ( ProductGenerationDate ) + ")" +
197 "/n ProductGenerationTime = " + String.valueOf ( ProductGenerationTime ) + "(" +MessageHeaderBlock.getTime ( ProductGenerationTime ) + ")" +
198 "/n P1 = " + String.valueOf ( P1 ) +
199 "/n P2 = " + String.valueOf ( P2 ) +
200 "/n ElevationNumber = " + String.valueOf ( ElevationNumber ) +
201 "/n P3 = " + String.valueOf ( P3 ) ;
202 for ( int i= 0 ;i< 16 ;i++ ) {
203 msg = msg + "/n DataLevelThreshold[" + ( i< 10 ? " " : "" ) +String.valueOf ( i ) + "] = " + String.valueOf ( DataLevelThreshold [ i ]) ;
204 }
205 msg = msg +
206 "/n P4 = " + String.valueOf ( P4 ) +
207 "/n P5 = " + String.valueOf ( P5 ) +
208 "/n P6 = " + String.valueOf ( P6 ) +
209 "/n P7 = " + String.valueOf ( P7 ) +
210 "/n P8 = " + String.valueOf ( P8 ) +
211 "/n P9 = " + String.valueOf ( P9 ) +
212 "/n P10 = " + String.valueOf ( P10 ) +
213 "/n NumberOfMaps = " + String.valueOf ( NumberOfMaps ) +
214 "/n OffsetToSymbology = " + String.valueOf ( OffsetToSymbology ) +
215 "/n OffsetToGraphic = " + String.valueOf ( OffsetToGraphic ) +
216 "/n OffsetToTabular = " + String.valueOf ( OffsetToTabular ) +
217 "/n" ;
218 return ( msg ) ;
219 }
220
221 /**
222 * 功能:打印数据,主要用于测试
223 * 参数:
224 * 无
225 * 返回:
226 * 无
227 */
228 public void print () {
229 System.out.println ( info ()) ;
230 }
231
232 }