Doppler天气雷达格栅产品(RasterImage)

本文介绍了一种用于处理多普勒天气雷达体扫产品的代码实现,主要包括RasterImage、RasterImageBlock和RasterProductBlock三个核心类,用于读取和绘制雷达栅格图像。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多普勒天气雷达的体扫产品处理代码。
包含RasterImage.java、RasterImageBlock.java、RasterProductBlock.java三个类。
由SymbologyImage.java类判断产品为Symbology且特征码为BA0F或BA07时调用。

 


RasterImage.java
001 /**
002  * PACKAGE      : cma.gmb.doppler
003  * FILENAME     : RasterImage.java
004  * DESCRIPTION  : 处理多普勒雷达产品数据(格栅产品Raster)
005  * AUTHOR       : 刘泽军
006  * EMAIL        : BJ0773@gmail.com
007  * Date         : 2007-06-02 23:52:38
008  * Update       : 2007-06-13 从SymbologyImage.java中独立出来
009  * Reference    : 《National Climatic Data Center DATA DOCUMENTATION FOR TD7000 -
010  *                 TD7599 NEXRAD LEVEL III》
011  *
012  */
013 
014 package cma.gmb.doppler;
015 
016 import java.io.*;
017 import java.awt.*;
018 
019 import cma.common.dataio.*;
020 import cma.common.projection.*;
021 import cma.micaps.diamond.*;
022 import cma.gmb.doppler.datatype.*;
023 
024 public class RasterImage {
025     //外部传入的数据
026     public  MessageHeaderBlock          messageHeaderBlock;
027     public  ProductDescriptionBlock     productDescriptionBlock;
028     public  ProductSymbologyBlock       productSymbologyBlock;
029     public  ProductSymbologyLayerBlock  productSymbologyLayerBlock;
030     //需要读取的数据
031     public  RasterProductBlock          rasterProductBlock;
032     public  RasterImageBlock[]          rasterImageBlock;
033 
034     public  static  Color[] levels  = {
035         new Color(  0,  0,  0)new Color(  0,  0,246)new Color(  1,159,246)new Color(  0,236,236),
036         new Color(  1,255,  0)new Color(  0,200,  0)new Color(  1,144,  0)new Color(255,255,  0),
037         new Color(231,192,  0)new Color(255,144,  0)new Color(254,  0,  0)new Color(214,  0,  0),
038         new Color(192,  0,  0)new Color(255,  0,250)new Color(174,144,240)new Color(255,255,255)
039     };
040 
041 /**
042  * 功能:构造函数
043  * 参数:
044  *      无
045  * 返回值:
046  *      无
047  */
048     public RasterImage() {
049     }
050 
051 /**
052  * 功能:读取多普勒栅格数据Raster Image,不包括文件头信息,注意在调用前先定位好偏移量
053  * 参数:
054  *      fin     - 随机访问的文件对象
055  * 返回值:
056  *      是否成功
057  */
058     public boolean read(RandomAccessFile finthrows Exception {
059 
060         if(     !"BA0F".equalsIgnoreCase(productSymbologyLayerBlock.PacketCode&&
061                 !"BA07".equalsIgnoreCase(productSymbologyLayerBlock.PacketCode) ) {//非栅格数据 Raster Image
062             return(false);
063         }
064         boolean ok  = false;
065         rasterProductBlock          = new RasterProductBlock();
066         ok  = rasterProductBlock.read(fin);
067         ifrasterProductBlock.NumberOfRows > ) {
068             rasterImageBlock    = new RasterImageBlock[rasterProductBlock.NumberOfRows];
069             for(int i=0;i<rasterProductBlock.NumberOfRows;i++) {
070                 rasterImageBlock[inew RasterImageBlock();
071                 ok  = ok && rasterImageBlock[i].read(fin);
072             }
073         }
074         return(ok);
075     }
076 
077 /**
078  * 2007-06-04增加,并在相关的类中增加 read(InputStream fin) 方法
079  *
080  * 功能:从数据流中读取多普勒栅格数据Raster,主要是考虑直接从 .tar.gz 中读取
081  * 参数:
082  *      fin     - InputStream,注意不能使用 fin.close() 方法,因为在函数外部可能还需要继续从 fin 读数据
083  * 返回值:
084  *      是否成功
085  */
086     public boolean read(InputStream finthrows Exception {
087 
088         if(     !"BA0F".equalsIgnoreCase(productSymbologyLayerBlock.PacketCode&&
089                 !"BA07".equalsIgnoreCase(productSymbologyLayerBlock.PacketCode) ) {//非栅格数据 Raster Image
090             return(false);
091         }
092         boolean ok  = false;
093         rasterProductBlock          = new RasterProductBlock();
094         ok  = rasterProductBlock.read(fin);
095         ifrasterProductBlock.NumberOfRows > ) {
096             rasterImageBlock    = new RasterImageBlock[rasterProductBlock.NumberOfRows];
097             for(int i=0;i<rasterProductBlock.NumberOfRows;i++) {
098                 rasterImageBlock[inew RasterImageBlock();
099                 ok  = ok && rasterImageBlock[i].read(fin);
100                 //rasterImageBlock[i].print();
101             }
102         }
103         return(ok);
104     }
105 
106 /**
107  * 功能:绘制雷达背景图(图形区域为640*480,雷达图形区域为480*480,雷达站点信息区域为160*480)
108  * 参数:
109  *      z       - 缩放系数
110  *      g       - 图形设备
111  *      c       - 雷达中心位置
112  *      pc      - 极圈
113  *      agl     - 径线间隔,非正值则不画径线
114  *      bnd     - 省市县边界
115  * 返回值:
116  *      是否成功
117  */
118     public boolean drawBackground(double z, Graphics2D g, Point c, boolean pc, double agl, boolean bnd) {
119         ifz <= 0.0 ) {
120             return(false);
121         }
122         try {
123             Polar   polar   = new Polar(c, 0.001*productDescriptionBlock.RadarLongitude, 0.001*productDescriptionBlock.RadarLatitude);
124             polar.setScale(1.0*z);
125             //以下两行改进线条的锯齿
126             RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
127             g.setRenderingHints(renderHints);
128 
129 //          g.setColor(Color.black);//背景色
130 //          g.fillRect(c.x-(int)(z*240), c.y-(int)(z*240), (int)(z*240*2), (int)(z*240*2));
131 
132             g.setColor(Color.white);//雷达图形区域的边框颜色
133             g.drawRect(c.x-(int)(z*240), c.y-(int)(z*240)(int)(z*240*2)(int)(z*240*2)-2);
134 
135             ifbnd ) {//画行政边界
136                 Coordinate  coordinate  = new Coordinate(polar);
137                 Diamond09.drawBorderline(g, new Color(92,92,92), coordinate, "/GIMDR/gmiss/config/CountyMap.dat");
138                 Diamond09.drawBorderline(g, new Color(160,160,160), coordinate, "/GIMDR/gmiss/config/ProvinceMap.dat");
139             }
140 
141             ifpc ) {//画极圈
142                 g.setColor(new Color(255,255,255));
143                 for(int i=50;i<=200;i=i+50) {//每50公里画一个圈
144                     g.drawArc(c.x-(int)(z*i), c.y-(int)(z*i)(int)(z*i)*2(int)(z*i)*20360);
145                 }
146                 g.drawArc(c.x-(int)(z*240), c.y-(int)(z*240)(int)(z*240)*2(int)(z*240)*20360);//外圈240公里
147             }
148 
149             ifagl >= 1.0 ) {//画极径
150                 Point   pos1, pos2;
151                 for(double i=0.0;i<180.0;i=i+agl) {
152                     pos1    = polar.getXY(z*240.0,   0.0+i);
153                     pos2    = polar.getXY(z*240.0180.0+i);
154                     g.drawLine(pos1.x, pos1.y, pos2.x, pos2.y);
155                 }
156             }
157             return(true);
158         }
159         catch(Exception ex) {
160             System.out.println(ex.getMessage());
161             ex.printStackTrace();
162             return(false);
163         }
164     }
165 
166 /**
167  * 功能:绘制雷达信息区域
168  * 参数:
169  *      g       - 图形设备
170  *      m       - 雷达信息区域左上角位置
171  * 返回值:
172  *      是否成功
173  */
174     public boolean drawInformation(Graphics2D g, Point m) {
175         //以下两行改进线条的锯齿
176         RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
177         g.setRenderingHints(renderHints);
178         g.setColor(Color.white);//信息区域的边框颜色
179         g.drawRect(m.x, m.y, 160479);//住处区域的边框
180         return(true);
181     }
182 
183 /**
184  * 功能:绘制雷达产品图,根据不同类型分别调用相应的画图函数
185  * 参数:
186  *      z       - 缩放系数
187  *      g       - 图形设备
188  *      c       - 雷达中心位置
189  * 返回值:
190  *      是否成功
191  */
192     public boolean draw(double z, Graphics2D g, Point c) {
193         return(
194             z <= 0.0 ||
195             null == rasterProductBlock ||
196             rasterProductBlock.NumberOfRows <= ||
197             drawRasterImage(z, g, c)
198         );
199     }
200 
201 /**
202  * 功能:绘制RasterImage栅格图像(采用多边形填充法代替弧形填充)
203  * 参数:
204  *      z       - 缩放系数
205  *      g       - 图形设备
206  *      c       - 雷达中心位置
207  * 返回值:
208  *      是否成功
209  */
210     public boolean drawRasterImage(double z, Graphics2D g, Point c) {
211         Color[] colorRun    = {
212             new Color(  0,  0,  0)new Color(156,156,156)new Color(118,118,118)new Color(250,170,170),
213             new Color(238,140,140)new Color(200,112,112)new Color(  0,250,144)new Color(  0,186,  0),
214             new Color(254,254,112)new Color(208,20896)new Color(2549696)new Color(218,  0,  0),
215             new Color(174,  0,  0)new Color(  0,  0,254)new Color(254,254,254)new Color(230,  0,254)
216         };
217 //      Polar   polar   = new Polar(c, 0.001*productDescriptionBlock.RadarLongitude, 0.001*productDescriptionBlock.RadarLatitude);
218 //      polar.setScale(1.0);
219 //背景
220         //以下两行改进线条的锯齿
221         RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
222         g.setRenderingHints(renderHints);
223 
224         Point   pos = new Point(rasterProductBlock.CoordinateStartI, rasterProductBlock.CoordinateStartJ);
225         Polygon p   = new Polygon();
226         int     iRun    = -1;
227         int     iColor  = -1;
228         for(int i=0;i<rasterProductBlock.NumberOfRows;i++) {
229             pos.x   = rasterProductBlock.CoordinateStartI + 8;
230             pos.y   = rasterProductBlock.CoordinateStartJ + i * rasterProductBlock.ScaleY + 8;
231             for(int j=0;j<rasterImageBlock[i].NumberOfBytesInRow;j++) {
232                 iRun    = rasterImageBlock[i].Data[j>> 0xF;
233                 iColor  = rasterImageBlock[i].Data[j]      0xF;
234                 ifiColor >=&& iColor < 16 ) {
235                     g.setColor(colorRun[iColor]);
236                     g.fillRect(pos.x, pos.y, (int)(iRun*rasterProductBlock.ScaleX), rasterProductBlock.ScaleY);
237                     g.drawRect(pos.x, pos.y, (int)(iRun*rasterProductBlock.ScaleX), rasterProductBlock.ScaleY);
238                 }
239                 pos.x   = pos.x + iRun*rasterProductBlock.ScaleX;
240             }
241         }
242         return(true);
243     }
244 }

 


RasterImageBlock.java
001 /**
002  * PACKAGE     : cma.gmb.doppler.datatype
003    FILENAME    : RasterImageBlock.java
004  * DESCRIPTION : 多普勒雷达产品数据结构(Raster格式)
005  * AUTHOR      : 刘泽军
006  * EMAIL       : BJ0773@gmail.com
007  * Date        : 2007-06-07 16:24:11
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 RasterImageBlock {//极坐标栅格图像数据
020 
021     public  static  int SIZE    = 2;
022 
023     public  short   NumberOfBytesInRow;
024     public  byte[]  Data;
025 
026 /**
027  * 功能:构造函数
028  * 参数:
029  *      无
030  * 返回:
031  *      无
032  */
033     public RasterImageBlock() {
034     }
035 
036 /**
037  * 功能:从随机文件中读取数据,并进行BigEndian转换
038  * 参数:
039  *      raf     - 随机访问的文件对象
040  * 返回:
041  *      是否成功
042  */
043     public boolean read(RandomAccessFile raf) {
044         try {
045             byte[]  buf     = new byte[RasterImageBlock.SIZE];
046             int     len = raf.read(buf);
047             boolean ok  = len == RasterImageBlock.SIZE ? parse(buf, 0false;
048             ifok && NumberOfBytesInRow > ) {
049                 Data    = new byte[NumberOfBytesInRow];
050                 len     = raf.read(Data);
051             }
052             return(ok && len == NumberOfBytesInRow);
053         }
054         catch(Exception ex) {
055             return(false);
056         }
057     }
058 
059 /**
060  * 功能:从输入流文件中读取数据,并进行BigEndian转换
061  *       (主要是为了从 .tar.gz 中读取)
062  * 参数:
063  *      in      - InputStream对象
064  * 返回:
065  *      是否成功
066  */
067     public boolean read(InputStream in) {
068         try {
069             byte[]  buf = new byte[RasterImageBlock.SIZE];
070             int     len = in.read(buf);
071             boolean ok  = len == RasterImageBlock.SIZE ? parse(buf, 0false;
072             ifok && NumberOfBytesInRow > ) {
073                 Data    = new byte[NumberOfBytesInRow];
074                 len     = in.read(Data);
075             }
076             return(ok && len == NumberOfBytesInRow);
077         }
078         catch(Exception ex) {
079             return(false);
080         }
081     }
082 
083 /**
084  * 功能:从缓冲区中读取数据,并进行BigEndian转换
085  * 参数:
086  *      in      - InputStream对象
087  * 返回:
088  *      是否成功
089  */
090     public int read(byte[] buf, int index) {
091         boolean ok  = parse(buf, index);
092         ifok && NumberOfBytesInRow > && buf.length >= index+NumberOfBytesInRow ) {
093             Data    = new byte[NumberOfBytesInRow];
094             for(int i=0;i<NumberOfBytesInRow;i++) {
095                 Data[i= buf[index+i];
096             }
097             return(RasterImageBlock.SIZE+NumberOfBytesInRow);
098         }
099         return(0);
100     }
101 
102 /**
103  * 功能:从缓冲区中分析出数据
104  * 参数:
105  *      buf     - 缓冲数据
106  * 返回:
107  *      是否成功
108  */
109     public boolean parse(byte[] buf) {
110         return(parse(buf, 0));
111     }
112 
113 /**
114  * 功能:从缓冲区中分析出数据
115  * 参数:
116  *      buf     - 缓冲数据
117  *      index   - 偏移
118  * 返回:
119  *      是否成功
120  */
121     public boolean parse(byte[] buf, int index) {
122         NumberOfBytesInRow  = DataConverterBE.getShort(buf, index+ 0);
123         return(true);
124     }
125 
126 /**
127  * 功能:获得数据信息
128  * 参数:
129  *      无
130  * 返回:
131  *      数据信息
132  */
133     public String info() {
134         String  msg =
135             "/nRasterImageBlock.SIZE  = " + String.valueOf(RasterImageBlock.SIZE+
136             "/n    NumberOfBytesInRow = " + String.valueOf(NumberOfBytesInRow+
137             "/n";
138 /*      for(int i=0;i<NumberOfRadialRLE*2;i++) {
139             msg = msg + String.valueOf((new Byte(Data[i])).intValue()/16)+","+String.valueOf((new Byte(Data[i])).intValue()%16)+" ";
140         }
141         msg = msg + "/n";
142 */
143         return(msg);
144     }
145 /**
146  * 功能:打印数据,主要用于测试
147  * 参数:
148  *      无
149  * 返回:
150  *      无
151  */
152     public void print() {
153         System.out.println(info());
154     }
155 
156 }

 


RasterProductBlock.java
001 /**
002  * PACKAGE     : cma.gmb.doppler.datatype
003    FILENAME    : RasterProductBlock.java
004  * DESCRIPTION : 多普勒雷达产品数据结构(Raster格式)
005  * AUTHOR      : 刘泽军
006  * EMAIL       : BJ0773@gmail.com
007  * Date        : 2007-06-07 17:09:47
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 RasterProductBlock {//层数据包
020 
021     public  static  int SIZE    = 20;
022 
023     public  String  PacketCode1;
024     public  String  PacketCode2;
025     public  short   CoordinateStartI;
026     public  short   CoordinateStartJ;
027     public  short   ScaleX;
028     public  short   ScaleFractionalX;
029     public  short   ScaleY;
030     public  short   ScaleFractionalY;
031     public  short   NumberOfRows;
032     public  short   PackingDescriptor;
033 
034 /**
035  * 功能:构造函数
036  * 参数:
037  *      无
038  * 返回:
039  *      无
040  */
041     public RasterProductBlock() {
042     }
043 
044 /**
045  * 功能:从文件中读取数据,并进行BigEndian转换
046  * 参数:
047  *      raf     - 随机访问的文件对象
048  * 返回:
049  *      是否成功
050  */
051     public boolean read(RandomAccessFile raf) {
052         try {
053             byte[]  buf = new byte[RasterProductBlock.SIZE];
054             int     len = raf.read(buf);
055             return(len == RasterProductBlock.SIZE ? parse(buf, 0false);
056         }
057         catch(Exception ex) {
058             return(false);
059         }
060     }
061 
062 /**
063  * 功能:从输入流文件中读取数据,并进行BigEndian转换
064  * 参数:
065  *      in      - InputStream对象
066  * 返回:
067  *      是否成功
068  */
069     public boolean read(InputStream in) {
070         try {
071             byte[]  buf = new byte[RasterProductBlock.SIZE];
072             int     len = in.read(buf);
073             return(len == RasterProductBlock.SIZE ? parse(buf, 0false);
074         }
075         catch(Exception ex) {
076             return(false);
077         }
078     }
079 
080 /**
081  * 功能:从缓冲区中读数据
082  *       (在外部方法中,一次性读入所有数据,然后逐类分析数据)
083  * 参数:
084  *      buf     - 缓冲数据
085  *      index   - 偏移
086  * 返回:
087  *      正确读出的数据字节数
088  */
089     public int read(byte[] buf, int index) {
090         return(parse(buf, index)?RasterProductBlock.SIZE:0);
091     }
092 
093 /**
094  * 功能:从缓冲区中分析出数据
095  * 参数:
096  *      buf     - 缓冲数据
097  * 返回:
098  *      是否成功
099  */
100     public boolean parse(byte[] buf) {
101         return(parse(buf, 0));
102     }
103 
104 /**
105  * 功能:从缓冲区中分析出数据
106  * 参数:
107  *      buf     - 缓冲数据
108  *      index   - 偏移
109  * 返回:
110  *      是否成功
111  */
112     public boolean parse(byte[] buf, int index) {
113         PacketCode1         = DataConverterBE.getHex  (buf, index+ 02);
114         PacketCode2         = DataConverterBE.getHex  (buf, index+ 22);
115         CoordinateStartI    = DataConverterBE.getShort(buf, index+ 4);
116         CoordinateStartJ    = DataConverterBE.getShort(buf, index+ 6);
117         ScaleX              = DataConverterBE.getShort(buf, index+ 8);
118         ScaleFractionalX    = DataConverterBE.getShort(buf, index+10);
119         ScaleY              = DataConverterBE.getShort(buf, index+12);
120         ScaleFractionalY    = DataConverterBE.getShort(buf, index+14);
121         NumberOfRows        = DataConverterBE.getShort(buf, index+16);
122         PackingDescriptor   = DataConverterBE.getShort(buf, index+18);
123         return(true);
124     }
125 
126 /**
127  * 功能:获得数据信息
128  * 参数:
129  *      无
130  * 返回:
131  *      数据信息
132  */
133     public String info() {
134         String  msg =
135             "/nRasterProductBlock.SIZE = " + String.valueOf(RasterProductBlock.SIZE+
136             "/n    PacketCode1         = " + String.valueOf(PacketCode1+
137             "/n    PacketCode2         = " + String.valueOf(PacketCode2+
138             "/n    CoordinateStartI    = " + String.valueOf(CoordinateStartI+
139             "/n    CoordinateStartJ    = " + String.valueOf(CoordinateStartJ+
140             "/n    ScaleX              = " + String.valueOf(ScaleX+
141             "/n    ScaleFractionalX    = " + String.valueOf(ScaleFractionalX+
142             "/n    ScaleY              = " + String.valueOf(ScaleY+
143             "/n    ScaleFractionalY    = " + String.valueOf(ScaleFractionalY+
144             "/n    NumberOfRows        = " + String.valueOf(NumberOfRows+
145             "/n    PackingDescriptor   = " + String.valueOf(PackingDescriptor+
146             "/n";
147         return(msg);
148     }
149 
150 /**
151  * 功能:打印数据,主要用于测试
152  * 参数:
153  *      无
154  * 返回:
155  *      无
156  */
157     public void print() {
158         System.out.println(info());
159     }
160 
161 }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值