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 }