GrADS.java
0001 /**
0002 *
0003 * 根据863项目《中国气象应用网格CMAG》要求,编写于2004年11-12月,国防科技大学611重点实验室)
0004 *
0005 * PACKAGE : cma.common.grads
0006 * DESCRIPTION : 解析 GrADS 的 CTL 描述文件
0007 * AUTHOR : 刘泽军
0008 * EMAIL : BJ0773@gmail.com
0009 * Date : 2004-12-01
0010 * Time : 21:43:32
0011 * Relation : gradsDim.java, gradsCtl.java, gradsVar.java, grads.java
0012 * Compile : javac -d . gradsDim.java gradsCtl.java gradsVar.java grads.java
0013 */
0014
0015 package cma.common.grads;
0016
0017 import java.io.*;
0018 import java.lang.*;
0019 import java.util.*;
0020 import java.text.NumberFormat;
0021 import java.text.DecimalFormat;
0022
0023 import cma.common.dataio.*;
0024
0025 public class GrADS {
0026
0027 //测试
0028 public static void main ( String argv []) throws Exception {
0029
0030 if ( 1 == argv.length ) {
0031 GrADS g = new GrADS () ;
0032 boolean enabled = g.loadFromFile ( argv [ 0 ]) ;
0033 if ( g.enabled ) {
0034 enabled = g.writeToFile ( "tmp_GrADS.ctl" ) ;
0035 String env [] = { "PATH=$PATH:/usr/local/bin" } ;
0036 try {
0037 g.procScript ( env, "/home/grapes/grapes_grads/" , "/home/grapes/Result" , "h" , "500" , "1" ) ;
0038 g.overlapping = true ;
0039 g.procScript ( env, "/home/grapes/grapes_grads/" , "/home/grapes/Result" , "t" , "850" , "1" ) ;
0040 }
0041 catch ( Exception e ) {
0042 System.out.println ( e.toString ()) ;
0043 e.printStackTrace () ;
0044 }
0045 }
0046 }
0047 }
0048
0049 //
0050 public int width = 1024 ; //缺省的图像宽度
0051 public int height = 768 ; //缺省的图像高度
0052 public int border = 0 ; //裁掉的边框格点数
0053 public String background = "white" ; //缺省的图像背景色
0054 public String model = "" ; //模式名,主要用于图像文件名的前缀
0055
0056 private double LEFT = 104.0 ; //广西区域 暂时未用
0057 private double TOP = 26.5 ;
0058 private double RIGHT = 112.5 ;
0059 private double BOTTOM = 20.0 ;
0060
0061 public double left = 104.0 ;
0062 public double top = 26.5 ;
0063 public double right = 112.5 ;
0064 public double bottom = 20.0 ;
0065
0066 public gradsCtl ctl = new gradsCtl () ;
0067 public boolean overlapping = false ; //是否迭加
0068 public boolean shading = true ; //是否填充阴影
0069
0070 public String title = "" ;
0071
0072 private String pathname = "." ; //当前解释的 CTL 文件所在的目录名
0073 private String filename = "" ; //当前解释的 CTL 文件名
0074 private String element = "" ; //要素
0075 private String level = "" ; //层次
0076 private String valid = "" ; //时次
0077 private String message = "" ; //执行 GrADS 命令时输出的内容
0078 private String command = "/public/local/grads/gradsc" ; //
0079 private String scriptfile = "gimdr_grads.gs" ;
0080 private boolean enabled = false ;
0081
0082 private static int size = 4096 ; //一个 GrADS 的描述文件最大不能超过的字节数
0083 //
0084 public boolean isEnabled () {
0085 return ( enabled ) ;
0086 }
0087 //获得经向格点数
0088 public int getLongitudeNumber () {
0089 if ( enabled ) {
0090 return ( ctl.xdef.count ) ;
0091 }
0092 return 0 ;
0093 }
0094 //获得纬向格点数
0095 public int getLatitudeNumber () {
0096 if ( enabled ) {
0097 return ( ctl.ydef.count ) ;
0098 }
0099 return 0 ;
0100 }
0101 //获得层次数
0102 public int getLevelNumber () {
0103 if ( enabled ) {
0104 return ( ctl.zdef.count ) ;
0105 }
0106 return 0 ;
0107 }
0108 //获得要素数
0109 public int getElementNumber () {
0110 if ( enabled ) {
0111 return ( ctl.vars.size () ) ;
0112 }
0113 return 0 ;
0114 }
0115 //获得要素的中文说明
0116 public String getElementUnicode () {
0117 return ( getElementUnicode ( element )) ;
0118 }
0119
0120 //获得要素的中文说明
0121 public String getElementUnicode ( String _name ) {
0122 if ( null == _name || "" .equals ( _name.trim ()) ) {
0123 return ( "" ) ;
0124 }
0125 String eGrapesUnicode [][] = { //GRAPES
0126 { "u" , "风U分量" } , { "v" , "风V分量" } , { "t" , "温度" } , { "h" , "高度" } , { "qv" , "比湿" } ,
0127 { "qc" , "云水" } , { "qr" , "雨水" } , { "qv" , "比湿" } , { "q1" , "比湿" } , { "q2" , "比湿" } ,
0128 { "q3" , "比湿" } , { "q4" , "比湿" } , { "w" , "垂直速度" } , { "ps" , "地面气压" } , { "psl" , "海平面气压" } ,
0129 { "rainc" , "对流降水" } , { "rainnc" , "非对流降水" } , { "ts" , "地面气温" } , { "glw" , "地面长波辐射" } , { "gsw" , "地面短波辐射" } ,
0130 { "hfx" , "地面热通量" } , { "qfx" , "地面水汽通量" } , { "q2m" , "2米比湿" } , { "t2m" , "2米温度" } , { "u10m" , "10米风U分量" } ,
0131 { "v10m" , "10米风V分量" } , { "lu" , "陆面" } , { "zs" , "地形" } ,
0132 { "u;v" , "风场" } , { "uv" , "流场" } , { "rain" , "降水(对流+非对流)" } , { "u10m;v10m" , "10米风场" }
0133 } ;
0134
0135 String eMM5Unicode [][] = { //MM5
0136 { "rc" , "对流降水" } , { "rn" , "非对流降水" } , { "ter" , "地形高度" } , { "xlat" , "纬度" } , { "xlon" , "经度" } ,
0137 { "lu" , "陆面" } , { "t2m" , "2米温度" } , { "q2m" , "2米比湿" } , { "u10" , "10米风U分量" } , { "v10" , "10米风V分量" } ,
0138 { "pslv" , "海平面气压" } , { "cref" , "" } , { "iclw" , "整层云水" } , { "irnw" , "整层雨水" } , { "pwat" , "可降水量" } ,
0139 { "clfrlo" , "低云量" } , { "clfrmi" , "中云量" } , { "clfrhi" , "高云量" } , { "u" , "风U分量" } , { "v" , "风V分量" } ,
0140 { "w" , "垂直速度" } , { "pp" , "" } , { "t" , "温度" } , { "q" , "比湿" } , { "clw" , "云水" } ,
0141 { "rnw" , "雨水" } , { "rtnd" , "辐射趋势" } , { "z" , "地表高度" } , { "h" , "高度" } , { "td" , "露点温度" } ,
0142 { "rh" , "相对湿度" } , { "vor" , "涡度" } , { "div" , "散度" } ,
0143 { "u;v" , "风场" } , { "uv" , "流场" } , { "rain" , "降水(对流+非对流)" } , { "u10;v10" , "10米风场" }
0144 } ;
0145
0146 String rainName [] = { "rainc" , "rainnc" , "rc" , "rn" , "rain" } ;
0147 String prefix = ctl.tdef.increment;
0148 String dateNames [] = { "yr" , "mo" , "dy" , "hr" , "mn" , "we" } ;
0149 String dateValues [] = { "年" , "月" , "日" , "小时" , "分钟" , "星期" } ;
0150 String _name_tmp = _name.trim () ;
0151 if ( _name_tmp.startsWith ( "_" ) ) { //如果要素名以 "_" 开始,则为对应要素的当前预报时段与上一预报时段的差值
0152 _name_tmp = _name.trim () .substring ( 1 ) ;
0153 for ( int i= 0 ;i<dateNames.length;i++ ) {
0154 prefix = prefix.replaceAll ( dateNames [ i ] , dateValues [ i ]) ;
0155 }
0156 }
0157 else {
0158 _name_tmp = _name.trim () ;
0159 prefix = "" ;
0160 for ( int i= 0 ;i<rainName.length;i++ ) {
0161 if ( _name_tmp.equalsIgnoreCase ( rainName [ i ]) ) {
0162 prefix = "累积" ;
0163 }
0164 }
0165 }
0166
0167 if ( "grapes" .equalsIgnoreCase ( model ) ) { //grapes 模式的 GrADS 描述文件
0168 for ( int i= 0 ;i<eGrapesUnicode.length;i++ ) {
0169 if ( 0 == eGrapesUnicode [ i ][ 0 ] .compareToIgnoreCase ( _name_tmp ) ) {
0170 return ( prefix + eGrapesUnicode [ i ][ 1 ]) ;
0171 }
0172 }
0173 }
0174 else if ( "mm5" .equalsIgnoreCase ( model ) ) { //mm5 模式的 GrADS 描述文件
0175 for ( int i= 0 ;i<eMM5Unicode.length;i++ ) {
0176 if ( 0 == eMM5Unicode [ i ][ 0 ] .compareToIgnoreCase ( _name_tmp ) ) {
0177 return ( prefix+ eMM5Unicode [ i ][ 1 ]) ;
0178 }
0179 }
0180 }
0181 else { //其它模式
0182 for ( int i= 0 ;i<eGrapesUnicode.length;i++ ) {
0183 if ( 0 == eGrapesUnicode [ i ][ 0 ] .compareToIgnoreCase ( _name_tmp ) ) {
0184 return ( prefix + eGrapesUnicode [ i ][ 1 ] ) ;
0185 }
0186 }
0187 for ( int i= 0 ;i<eMM5Unicode.length;i++ ) {
0188 if ( 0 == eMM5Unicode [ i ][ 0 ] .compareToIgnoreCase ( _name_tmp ) ) {
0189 return ( prefix + eMM5Unicode [ i ][ 1 ] ) ;
0190 }
0191 }
0192 }
0193 return ( getElementDescription ( _name_tmp )) ;
0194 }
0195
0196 //获得时效数
0197 public int getValidNumber () {
0198 if ( enabled ) {
0199 return ( ctl.tdef.count ) ;
0200 }
0201 return 0 ;
0202 }
0203 //设置 GrADS 的命令行
0204 public boolean setCommand ( String cmd ) {
0205 if ( null != cmd &&
0206 ( cmd.trim () .startsWith ( "grads" ) || (( new File ( cmd )) .getName () .startsWith ( "grads" )) ) ) {
0207 command = cmd.trim () ;
0208 return ( true ) ;
0209 }
0210 return ( false ) ;
0211 }
0212 //获得 GrADS 命令的输出
0213 public String getMessage () {
0214 return ( message ) ;
0215 }
0216 //根据缺省参数获得生成的图像文件的说明,以作为网页中<img>的title
0217 public String getTitle ( boolean unicode ) {
0218 //System.out.println("getTitle: " + element + " " + level + " " + valid);
0219 String tmpTitle =
0220 ( unicode? "初 始 场:" : "Start : " ) + ctl.tdef.start + "/n" +
0221 ( unicode? "预报时效:" : "Validate : " ) + getValid () + "/n" +
0222 ( unicode? "要 素 名:" : "Element : " ) + getElement () + ( unicode? "(" +getElementUnicode ( element ) + ")" :getElementDescription ()) + "/n" +
0223 ( unicode? "层 次:" : "Level : " ) + ( checkElement ( element ) > 1 ?getLevel () : "" ) ;
0224 return ( tmpTitle ) ;
0225 }
0226 //根据指定的参数获得生成的图像文件的说明,以作为网页中<img>的title
0227 public String getTitle ( String e, String l, String t ) {
0228 if ( !enabled || !setElement ( e ) || !setLevel ( l ) || !setValid ( t ) ) {
0229 return ( "" ) ;
0230 }
0231 return ( getTitle ( false )) ;
0232 }
0233 //根据缺省的参数获得在 gs 中生成的图像文件名
0234 public String getImageFilename () {
0235 String imageFile = getImageFilename ( model+ctl.xdef.increment, ".jpg" ) ;
0236 return ( imageFile ) ;
0237 }
0238 //根据指定的参数获得在 gs 中生成的图像文件名
0239 public String getImageFilename ( String prefix, String ext ) {
0240 String imageFile = "" ;
0241 if ( !enabled ) {
0242 return ( imageFile ) ;
0243 }
0244 String prefixString = null ==prefix|| "" .equals ( prefix.trim ()) ?
0245 model+ctl.xdef.increment : //"grapes" :
0246 prefix.trim () ;
0247 String extString = null ==ext || "" .equals ( ext.trim ()) ||!ext.trim () .startsWith ( "." ) ?
0248 ".jpg" :
0249 ext.trim () ;
0250 imageFile =
0251 prefixString + "_" + //文件名前缀
0252 ctl.tdef.start + "_" + //开始时间
0253 getElement () .replaceAll ( ";" , "" ) + "_" + //要素
0254 ( checkElement ( element ) > 1 ?getLevel () + "_" : "" ) + //层次
0255 getValid () + "_" + //预报时效
0256 width + "x" + height + "_" +
0257 ( background.equalsIgnoreCase ( "white" ) ? "W" : "B" ) +
0258 ( overlapping? "O" : "" ) +
0259 ( shading? "S" : "" ) +
0260 extString; //扩展名
0261 return ( imageFile ) ;
0262 }
0263 //与要素有关的方法
0264 public String getElement () { //获得当前指定的要素
0265 return ( element ) ;
0266 }
0267 public int checkElement ( String e ) { //检测要素名是否存在,返回值:0不存在、1单层要素、>1多层要素
0268 if ( !enabled || null == e || "" .equals ( e.trim ()) ) {
0269 return ( 0 ) ;
0270 }
0271 if ( "uv" .equals ( e ) ) {
0272 return ( 2 ) ;
0273 }
0274
0275 //原 CTL 中列出的要素
0276 for ( int i= 0 ;i<ctl.vars.size () ;i++ ) {
0277 if ( 0 == (( gradsVar ) ctl.vars.get ( i )) .name.compareToIgnoreCase ( e ) ) {
0278 return ((( gradsVar ) ctl.vars.get ( i )) .levels== 0 ? 1 : (( gradsVar ) ctl.vars.get ( i )) .levels ) ;
0279 }
0280 }
0281
0282 //扩展要素,在原 CTL 中列出的要素前加 _ 符号,用于显示该要素的当前时段与上一时段的差值
0283 for ( int i= 0 ;i<ctl.vars.size () ;i++ ) {
0284 if ( 0 == ( "_" + (( gradsVar ) ctl.vars.get ( i )) .name ) .compareToIgnoreCase ( e ) ) {
0285 return ((( gradsVar ) ctl.vars.get ( i )) .levels== 0 ? 1 : (( gradsVar ) ctl.vars.get ( i )) .levels ) ;
0286 }
0287 }
0288
0289 //扩展要素,用于显示 rainc+rainnc 之和
0290 if ( "rain" .equalsIgnoreCase ( e ) && "grapes" .equalsIgnoreCase ( model ) &&
0291 checkElement ( "rainc" ) > 0 && checkElement ( "rainnc" ) > 0 ) { //GRAPES
0292 return ( checkElement ( "rainc" )) ;
0293 }
0294
0295 //扩展要素,用于显示 rainc+rainnc 之和与上一时段的相应值之差
0296 if ( "_rain" .equalsIgnoreCase ( e ) && "grapes" .equalsIgnoreCase ( model ) &&
0297 checkElement ( "rainc" ) > 0 && checkElement ( "rainnc" ) > 0 ) { //GRAPES
0298 return ( checkElement ( "rainc" )) ;
0299 }
0300
0301 //扩展要素,用于显示 rc+rn 之和
0302 if ( "rain" .equalsIgnoreCase ( e ) && "mm5" .equalsIgnoreCase ( model ) &&
0303 checkElement ( "rc" ) > 0 && checkElement ( "rn" ) > 0 ) { //MM5
0304 return ( checkElement ( "rc" )) ;
0305 }
0306
0307 //扩展要素,用于显示 rc+rn 之和与上一时段的相应值之差
0308 if ( "_rain" .equalsIgnoreCase ( e ) && "mm5" .equalsIgnoreCase ( model ) &&
0309 checkElement ( "rc" ) > 0 && checkElement ( "rn" ) > 0 ) { //MM5
0310 return ( checkElement ( "rc" )) ;
0311 }
0312
0313 //组合要素
0314 String combineVar [] = { ";" , "+" , "-" , "*" , "/" } ;
0315 for ( int i= 0 ;i<combineVar.length;i++ ) {
0316 if ( 0 < e.indexOf ( combineVar [ i ]) ) {
0317 String e1 = "" , e2 = "" ;
0318 boolean b1 = false, b2 = false ;
0319 e1 = e.substring ( 0 ,e.indexOf ( combineVar [ i ])) ;
0320 e2 = e.substring ( e.indexOf ( combineVar [ i ]) + 1 ) ;
0321 for ( int j= 0 ;j<ctl.vars.size () ;j++ ) {
0322 b1 = (( gradsVar ) ctl.vars.get ( j )) .name.equals ( e1 ) ? true :b1;
0323 b2 = (( gradsVar ) ctl.vars.get ( j )) .name.equals ( e2 ) ? true :b1;
0324 }
0325 if ( b1 && b2 ) {
0326 element = e;
0327 return ( checkElement ( e1 )) ;
0328 }
0329 }
0330 }
0331 if ( e.startsWith ( "_" ) ) {
0332 return ( checkElement ( e.substring ( 1 ))) ;
0333 }
0334
0335 return ( 0 ) ;
0336 }
0337 public String getElementDescription () { //获得要素的说明
0338 for ( int i= 0 ;i<ctl.vars.size () ;i++ ) {
0339 if ( 0 == (( gradsVar ) ctl.vars.get ( i )) .name.compareToIgnoreCase ( element ) ) {
0340 return (
0341 "" .equals ((( gradsVar ) ctl.vars.get ( i )) .contents ) ?
0342 "" :
0343 "(" + (( gradsVar ) ctl.vars.get ( i )) .contents + ")" ) ;
0344 }
0345 }
0346 return ( "" ) ;
0347 }
0348 public String getElementDescription ( String e ) { //获得要素的说明
0349 for ( int i= 0 ;i<ctl.vars.size () ;i++ ) {
0350 if ( 0 == (( gradsVar ) ctl.vars.get ( i )) .name.compareToIgnoreCase ( e ) ) {
0351 return (
0352 "" .equals ((( gradsVar ) ctl.vars.get ( i )) .contents ) ?
0353 "" :
0354 "(" + (( gradsVar ) ctl.vars.get ( i )) .contents + ")" ) ;
0355 }
0356 }
0357 return ( "" ) ;
0358 }
0359 public boolean setElement ( String e ) { //设置要素名
0360 if ( checkElement ( e ) >= 0 ) {
0361 element = e;
0362 return ( true ) ;
0363 }
0364 System.out.println ( "ERROR: setElement( " + e + " )" ) ;
0365 return ( false ) ;
0366 }
0367 public boolean setElement ( int e ) { //索引
0368 if ( !enabled ) {
0369 return ( false ) ;
0370 }
0371 else if ( enabled && e >= 0 && e < ctl.vars.size () ) {
0372 element = (( gradsVar ) ctl.vars.get ( e )) .name;
0373 return ( true ) ;
0374 }
0375 else {
0376 return ( false ) ;
0377 }
0378 }
0379 public int createElementScript ( Vector vector ) { //根据当前给定的要素生成 gs 脚本
0380 int len = vector.size () ;
0381 if ( "u;v" .equals ( element ) ) { //风矢
0382 vector.add ( "'set gxout barb'" ) ;
0383 vector.add ( "'d skip(u,8);skip(v,8)'" ) ;
0384 }
0385 else if ( "uv" .equals ( element ) ) { //流场
0386 vector.add ( "'set gxout stream'" ) ;
0387 vector.add ( "'d skip(u,8);skip(v,8)'" ) ;
0388 }
0389 else if ( "h" .equals ( element ) ) {
0390 vector.add ( "'" + "set cint 4'" ) ;
0391 vector.add ( "'" + "d " + element + "/10'" ) ;
0392 }
0393 else if ( element.startsWith ( "t" ) || element.startsWith ( "td" ) ) {
0394 vector.add ( "'" + "set cint 4'" ) ;
0395 vector.add ( "'" + "d " + element + "-273.15'" ) ;
0396 }
0397 else if ( element.startsWith ( "p" ) ) {
0398 vector.add ( "'" + "set cint 2.5'" ) ;
0399 vector.add ( "'" + "d " + element + "'" ) ;
0400 }
0401 else if ( //累积降水量
0402 "rainc" .equals ( element ) || "rainnc" .equals ( element ) ||
0403 "rc" .equals ( element ) || "rn" .equals ( element ) ) {
0404 vector.add ( "'set cmin 0.01'" ) ;
0405 vector.add ( "'set clevs 0 10 25 50 100 250'" ) ;
0406 vector.add ( "'" + "d " + element + ( "mm5" .equals ( model ) ? "*10" : "" ) + "'" ) ;
0407 }
0408 else if ( "rain" .equalsIgnoreCase ( element ) ) { //总累积降水量rain=rainc+rainnc或rain=rc+rn
0409 String e1 = "" , e2 = "" ;
0410 if ( "grapes" .equalsIgnoreCase ( model ) && checkElement ( "rainc" ) > 0 && checkElement ( "rainnc" ) > 0 ) {
0411 e1 = "rainc" ;
0412 e2 = "rainnc" ;
0413 }
0414 else if ( "mm5" .equalsIgnoreCase ( model ) && checkElement ( "rc" ) > 0 && checkElement ( "rn" ) > 0 ) {
0415 e1 = "rc*10" ;
0416 e2 = "rn*10" ;
0417 }
0418 else {
0419 return ( vector.size () - len ) ;
0420 }
0421 vector.add ( "'set clevs 0 10 25 50 100 250'" ) ;
0422 vector.add ( "'" + "d " + e1 + "+" + e2 + "'" ) ;
0423 }
0424 else if ( element.startsWith ( "_rain" ) ) { //总降水量(当前预报时段与上一预报时段的差值)
0425 int tIndex = Integer.parseInt ( valid ) ;
0426 int tCount = "_rain" .equalsIgnoreCase ( element ) ? 1 : Integer.parseInt ( element.substring ( "_rain" .length ())) ;
0427 vector.add ( "'set clevs 0 10 25 50 100 250'" ) ;
0428 // vector.add("'set ccols 2 3 4 5 6 7 8'");
0429 // vector.add("'set cmin 0.01'");
0430 String e1 = "" , e2 = "" ;
0431 if ( "grapes" .equalsIgnoreCase ( model ) &&
0432 checkElement ( "rainc" ) > 0 &&
0433 checkElement ( "rainnc" ) > 0 ) {
0434 e1 = "rainc" ;
0435 e2 = "rainnc" ;
0436 }
0437 else if ( "mm5" .equalsIgnoreCase ( model ) &&
0438 checkElement ( "rc" ) > 0 &&
0439 checkElement ( "rn" ) > 0 ) {
0440 e1 = "10*rc" ;
0441 e2 = "10*rn" ;
0442 }
0443 else {
0444 return ( vector.size () - len ) ;
0445 }
0446 if ( tIndex > tCount ) {
0447 vector.add ( "'" + "d " + element + "'" ) ;
0448 vector.add (
0449 "'" + "d " + e1 + "(t=" + ( tIndex ) + ")-" + e1 + "(t=" + ( tIndex-tCount ) + ")+" + e2 + "(t=" + ( tIndex ) + ")-" + e2 + "(t=" + ( tIndex-tCount ) + ")'" ) ;
0450 }
0451 else {
0452 vector.add ( "'" + "d " + e1 + "+" + e2 + "'" ) ;
0453 }
0454 }
0455 else if ( element.startsWith ( "_006" ) || element.startsWith ( "_012" ) || element.startsWith ( "_024" ) || element.startsWith ( "_048" ) ) { //当前预报时段与指定的前某一预报时段的差值,一般用于统计时段内累积降水量
0456 int tIndex = Integer.parseInt ( valid ) ;
0457 int tCount = Integer.parseInt ( element.substring ( 1 , 4 )) ;
0458 vector.add ( "'set clevs 0 10 25 50 100 250'" ) ;
0459 if ( tIndex > tCount ) {
0460 vector.add ( "'" + "d " + element.substring ( 4 ) + "(t=" + ( tIndex ) + ")-" + element.substring ( 4 ) + "(t=" + ( tIndex-tCount ) + ")'" ) ;
0461 }
0462 else {
0463 vector.add ( "'" + "d " + element.substring ( 4 ) + "'" ) ;
0464 }
0465 }
0466 else if ( element.startsWith ( "_" ) ) { //当前预报时段与上一预报时段的差值,一般用于降水量
0467 int tIndex = Integer.parseInt ( valid ) ;
0468 vector.add ( "'set clevs 0 10 25 50 100 250'" ) ;
0469 if ( tIndex > 1 ) {
0470 vector.add ( "'" + "d " + element.substring ( 1 ) + "(t=" + ( tIndex ) + ")-" + element.substring ( 1 ) + "(t=" + ( tIndex- 1 ) + ")'" ) ;
0471 }
0472 else {
0473 vector.add ( "'" + "d " + element.substring ( 1 ) + "'" ) ;
0474 }
0475 }
0476 else { //其它
0477 vector.add ( "'" + "d " + element + "'" ) ;
0478 }
0479 return ( vector.size () - len ) ;
0480 }
0481 //与层次有关的方法
0482 public String getLevel () { //获得当前指定的层次
0483 return ( level ) ;
0484 }
0485 public boolean checkLevel ( String l ) { //检测层次
0486 if ( !enabled || null == l || "" .equals ( l ) ) {
0487 return ( false ) ;
0488 }
0489 for ( int i= 0 ;i<ctl.zdef.count;i++ ) {
0490 if ( ctl.zdef.value [ i ] .equals ( l ) ) {
0491 return ( true ) ;
0492 }
0493 }
0494 return ( false ) ;
0495 }
0496 public boolean setLevel ( String l ) { //设置层次(500、700、850、…………)
0497 if ( !enabled ) {
0498 return ( false ) ;
0499 }
0500 if ( null == l || "" .equals ( l.trim ()) ) {
0501 level = ctl.zdef.value [ 0 ] ;
0502 return ( false ) ;
0503 }
0504 for ( int i= 0 ;i<ctl.zdef.count;i++ ) {
0505 if ( ctl.zdef.value [ i ] .equals ( l ) ) {
0506 level = checkElement ( element ) > 1 ?l:ctl.zdef.value [ 0 ] ;
0507 return ( true ) ;
0508 }
0509 }
0510 return ( false ) ;
0511 }
0512 public boolean setLevel ( int l ) { //设置层次(第几层)
0513 if ( !enabled ) {
0514 return ( false ) ;
0515 }
0516 else if ( 0 <= l && l < ctl.zdef.count ) {
0517 level = checkElement ( element ) > 1 ?ctl.zdef.value [ l ] :ctl.zdef.value [ 0 ] ;
0518 return ( true ) ;
0519 }
0520 else {
0521 level = ctl.zdef.value [ 0 ] ;
0522 return ( false ) ;
0523 }
0524 }
0525 //与时效有关的方法
0526 public int getValidIndex () { //获得当前指定的时效
0527 try {
0528 int index = Integer.parseInt ( valid ) - 1 ;
0529 if ( 0 <= index && index < ctl.tdef.count ) {
0530 return ( index ) ;
0531 }
0532 }
0533 catch ( Exception e ) {
0534 }
0535 return ( 0 ) ;
0536 }
0537 public String getValid () { //获得当前指定的时效
0538 try {
0539 int index = Integer.parseInt ( valid ) - 1 ;
0540 if ( 0 <= index && index < ctl.tdef.count ) {
0541 return ( ctl.tdef.value [ index ]) ;
0542 }
0543 }
0544 catch ( Exception e ) {
0545 }
0546 return ( valid ) ;
0547 }
0548 public boolean checkValid ( String t ) { //检测时效
0549 if ( !enabled || null == t || "" .equals ( t ) ) {
0550 return ( false ) ;
0551 }
0552 for ( int i= 0 ;i<ctl.tdef.count;i++ ) {
0553 if ( ctl.zdef.value [ i ] .equals ( t ) ) {
0554 return ( true ) ;
0555 }
0556 }
0557 for ( int i= 0 ;i<ctl.tdef.count;i++ ) {
0558 if ( String.valueOf ( i+ 1 ) .equals ( t ) ) {
0559 return ( true ) ;
0560 }
0561 }
0562 return ( false ) ;
0563 }
0564 public boolean setValid ( String t ) { //设置时效
0565 if ( !enabled ) {
0566 return ( false ) ;
0567 }
0568 else if ( null == t || "" .equals ( t.trim ()) ) {
0569 valid = "1" ;
0570 return ( false ) ;
0571 }
0572 for ( int i= 0 ;i<ctl.tdef.count;i++ ) { //传入的是 000hr、006hr、012hr ...
0573 if ( ctl.tdef.value [ i ] .equals ( t.trim ()) ) {
0574 valid = String.valueOf ( i+ 1 ) ;
0575 return ( true ) ;
0576 }
0577 }
0578 for ( int i= 0 ;i<ctl.tdef.count;i++ ) { //传入的是 1、2、3 ...
0579 if ( String.valueOf ( i+ 1 ) .equals ( t.trim ()) ) {
0580 valid = String.valueOf ( i+ 1 ) ;
0581 return ( true ) ;
0582 }
0583 }
0584 return ( false ) ;
0585 }
0586 public boolean setValid ( int t ) { //设置时效(第几时效)
0587 if ( !enabled ) {
0588 return ( false ) ;
0589 }
0590 else if ( 0 <= t && t < ctl.tdef.count ) {
0591 valid = String.valueOf ( t + 1 ) ;
0592 return ( true ) ;
0593 }
0594 return ( false ) ;
0595 }
0596 //构造函数
0597 public GrADS () {
0598 ctl = new gradsCtl () ;
0599 }
0600 //将给定的 line 字符串按空格、回车、换行、TAB键分隔开
0601 public String [] separateLine ( String line ) {
0602 if ( null == line || "" .equals ( line.trim ()) ) {
0603 return ( null ) ;
0604 }
0605 String s = line.trim () ;
0606 Vector v = new Vector () ;
0607 //注:可以考虑使用 StringTokenizer,见 Diamond04.java 的 loadFromFile() 方法
0608 s = s.replaceAll ( "/r" , " " ) ; //回车
0609 s = s.replaceAll ( "/n" , " " ) ; //换行
0610 s = s.replaceAll ( "/t" , " " ) ; //TAB键
0611 while ( - 1 != s.indexOf ( " " ) ) { //双空格换为单空格
0612 s = s.replaceAll ( " " , " " ) .trim () ;
0613 }
0614 int index = - 1 ;
0615 while ( - 1 != ( index = s.indexOf ( " " )) ) {
0616 v.add ( s.substring ( 0 , index )) ;
0617 s = s.substring ( index+ 1 ) .trim () ;
0618 }
0619 if ( ! "" .equals ( s ) ) {
0620 v.add ( s ) ;
0621 }
0622 String str [] = new String [ v.size ()] ;
0623 for ( int i= 0 ;i<v.size () ;i++ ) {
0624 str [ i ] = ( String ) v.get ( i ) ;
0625 }
0626 return ( str ) ;
0627 }
0628 //判断该行是否以 GrADS 的关键字开头
0629 public boolean isSymbol ( String line ) {
0630 String symbol [] = { "dset" , "options" , "title" , "undef" , "pdef" , "xdef" , "ydef" , "zdef" , "tdef" , "vars" , "endvars" } ;
0631 for ( int i= 0 ;i<symbol.length;i++ ) {
0632 if ( line.toLowerCase () .startsWith ( symbol [ i ]) ) {
0633 return ( true ) ;
0634 }
0635 }
0636 return ( false ) ;
0637 }
0638 //判断 file 是否是一个有效的 GrADS 的 CTL 文件
0639 public static boolean isValid ( String file ) {
0640
0641 File f = new File ( file ) ;
0642 if ( f.exists () && f.isFile () && //确保文件存在
0643 f.length () > 32 && f.length () <= size ) { //文件大小符合要求
0644 try {
0645 FileReader fr = new FileReader ( file ) ;
0646 BufferedReader br = new BufferedReader ( fr ) ;
0647 String stringLine = null ;
0648 Vector v = new Vector () ;
0649 boolean match = false ;
0650
0651 while ( null != ( stringLine = br.readLine ()) ) {
0652 if ( ! "" .equals ( stringLine.trim ()) &&
0653 stringLine.toLowerCase () .startsWith ( "dset" ) ) { //数据文件所在行
0654 br.close () ;
0655 fr.close () ;
0656 String fData = stringLine.substring ( 4 ) .trim () ;
0657 if ( fData.startsWith ( "^" ) ) {
0658 fData = f.getParent () + "/" + fData.substring ( 1 ) ;
0659 }
0660 //System.out.println(fData);
0661 File d = new File ( fData ) ;
0662 return ( d.exists () && d.isFile ()) ;
0663 }
0664 }
0665 br.close () ;
0666 fr.close () ;
0667 }
0668 catch ( Exception e ) {
0669 }
0670 }
0671 return ( false ) ;
0672 }
0673 //在指定的目录中列出以 prefix 开头且以 suffix 结尾的有效的 GrADS 描述文件名(不含目录)
0674 public static String [] listFiles ( String path, String prefix, String suffix ) {
0675 File f = new File ( path ) ;
0676 Vector v = new Vector () ;
0677 if ( f.isDirectory () && f.exists () ) {
0678 //System.out.println(path + " , " + prefix + " , " + suffix);
0679 File files [] = f.listFiles () ;
0680 String fname = "" ;
0681 for ( int i= 0 ;i<files.length;i++ ) {
0682 //System.out.println(files[i]);
0683 fname = files [ i ] .getName () ;
0684 if (
0685 ( null == prefix || "" .equals ( prefix ) || fname.startsWith ( prefix )) &&
0686 ( null == suffix || "" .equals ( suffix ) || fname.endsWith ( suffix ) ) &&
0687 isValid ( files [ i ] .getAbsolutePath ()) ) {
0688 //System.out.println("true");
0689 v.add ( fname ) ;
0690 }
0691 }
0692 }
0693 if ( v.size () == 0 ) {
0694 return ( null ) ;
0695 }
0696 else {
0697 String fnames [] = new String [ v.size ()] ;
0698 for ( int i= 0 ;i<v.size () ;i++ ) {
0699 fnames [ i ] = ( String ) v.get ( i ) ;
0700 }
0701 java.util.Arrays.sort ( fnames ) ;
0702 return ( fnames ) ;
0703 }
0704 }
0705 //读取 GrADS 的 CTL 说明文件
0706 public boolean loadFromFile ( String file ) throws IOException {
0707 enabled = false ;
0708 ctl.vars.clear () ;
0709 pathname = "." ;
0710 filename = "" ;
0711 File f = new File ( file ) ;
0712 if ( !f.exists () ) {
0713 return ( false ) ;
0714 }
0715 pathname = f.getPath () ;
0716 if ( null == pathname || "" .equals ( pathname ) ) {
0717 pathname = "." ;
0718 }
0719 filename = f.getName () ;
0720 try {
0721 FileReader fr = new FileReader ( file ) ;
0722 BufferedReader br = new BufferedReader ( fr ) ;
0723 String stringLine = null ;
0724 Vector lines = new Vector () ;
0725 boolean vars = false ;
0726 while ( null != ( stringLine = br.readLine ()) ) {
0727 stringLine = stringLine.trim () ;
0728 if ( ! "" .equals ( stringLine ) ) {
0729 if ( stringLine.startsWith ( "vars" ) ) {
0730 vars = true ;
0731 }
0732 if ( isSymbol ( stringLine ) || vars ) {
0733 lines.add ( stringLine ) ;
0734 }
0735 else if ( lines.size () == 1 ) { //某些 CTL 文件的 options 行(第2行)并不带有 options 标识
0736 lines.add ( "options " + stringLine ) ;
0737 }
0738 else {
0739 if ( 0 == lines.size () ) {
0740 lines.add ( stringLine ) ;
0741 }
0742 else {
0743 lines.set (
0744 lines.size () - 1 ,
0745 ( String ) lines.get ( lines.size () - 1 ) + " " + stringLine ) ;
0746 }
0747 }
0748 }
0749 }
0750 br.close () ;
0751 fr.close () ;
0752 enabled = extractStrings ( lines ) ;
0753 return ( enabled ) ;
0754 }
0755 catch ( Exception e ) {
0756 return ( false ) ;
0757 }
0758 }
0759 //解析 GrADS 的 CTL 文件内容
0760 private boolean extractStrings ( Vector strings ) {
0761 String line = "" ;
0762 String str [] = null ;
0763 try {
0764 for ( int i= 0 ;i<strings.size () ;i++ ) {
0765 line = ( String ) strings.get ( i ) ;
0766 str = separateLine ( line ) ;
0767 if ( line.startsWith ( "dset" ) ) {
0768 ctl.dset = str [ 1 ] ;
0769 }
0770 else if ( line.startsWith ( "options" ) ) {
0771 ctl.options = line.substring ( "options" .length ()) .trim () ;
0772 }
0773 else if ( line.startsWith ( "title" ) ) {
0774 ctl.title = line.substring ( "title" .length ()) .trim () ;
0775 }
0776 else if ( line.startsWith ( "undef" ) ) {
0777 ctl.undef = line.substring ( "undef" .length ()) .trim () ;
0778 }
0779 else {
0780 if ( line.startsWith ( "xdef" ) ) {
0781 ctl.xdef.extractValue ( str ) ;
0782 }
0783 else if ( line.startsWith ( "ydef" ) ) {
0784 ctl.ydef.extractValue ( str ) ;
0785 }
0786 else if ( line.startsWith ( "zdef" ) ) {
0787 ctl.zdef.extractValue ( str ) ;
0788 }
0789 else if ( line.startsWith ( "tdef" ) ) {
0790 ctl.tdef.extractValue ( str ) ;
0791 }
0792 else if ( line.startsWith ( "vars" ) ) {
0793 int varCount = Integer.parseInt ( line.substring ( "vars" .length ()) .trim ()) ;
0794 for ( int j= 0 ;j<varCount;j++ ) {
0795 gradsVar var = new gradsVar () ;
0796 line = ( String ) strings.get ( i+j+ 1 ) ;
0797 str = separateLine ( line ) ;
0798 var.name = str [ 0 ] ;
0799 var.levels = Integer.parseInt ( str [ 1 ]) ;
0800 var.reserve = str [ 2 ] ;
0801 for ( int k= 3 ;k<str.length;k++ ) {
0802 var.contents = var.contents + str [ k ] + " " ;
0803 }
0804 var.contents = var.contents.trim () ;
0805 var.unicode = getElementUnicode ( var.name ) ;
0806 if ( "" .equals ( var.unicode ) ) {
0807 var.unicode = var.contents;
0808 }
0809 ctl.vars.add ( var ) ;
0810 }
0811 }
0812 }
0813 }
0814 }
0815 catch ( Exception e ) {
0816 return ( false ) ;
0817 }
0818 enabled = ( 0 < ctl.vars.size () && 0 < ctl.tdef.count && 0 < ctl.zdef.count ) ;
0819 setElement ( "" ) ;
0820 setLevel ( "" ) ;
0821 setValid ( "" ) ;
0822 return ( enabled ) ;
0823 }
0824 //生成 GrADS 的 CTL 说明文件
0825 public boolean writeToFile ( String file ) {
0826 if ( !enabled ) {
0827 return ( false ) ;
0828 }
0829 try {
0830 FileWriter fw = new FileWriter ( file ) ;
0831 BufferedWriter bw = new BufferedWriter ( fw ) ;
0832 bw.write ( "dset " + ctl.dset + "/n" ) ;
0833 bw.write ( "options " + ctl.options + "/n" ) ;
0834 bw.write ( "title " + ctl.title + "/n" ) ;
0835 bw.write ( "undef " + ctl.undef + "/n" ) ;
0836 bw.write ( ctl.xdef.convertToString () + "/n" ) ;
0837 bw.write ( ctl.ydef.convertToString () + "/n" ) ;
0838 bw.write ( ctl.zdef.convertToString () + "/n" ) ;
0839 bw.write ( ctl.tdef.convertToString () + "/n" ) ;
0840 bw.write ( "vars " + String.valueOf ( ctl.vars.size ()) + "/n" ) ;
0841 for ( int i= 0 ;i<ctl.vars.size () ;i++ ) {
0842 bw.write ((( gradsVar ) ctl.vars.get ( i )) .convertToString ()) ;
0843 bw.newLine () ;
0844 }
0845 bw.write ( "endvars" + "/n" ) ;
0846 bw.close () ;
0847 fw.close () ;
0848 return ( true ) ;
0849 }
0850 catch ( Exception e ) {
0851 System.out.println ( e.getMessage ()) ;
0852 e.printStackTrace () ;
0853 return ( false ) ;
0854 }
0855 }
0856 /** 根据给定的参数生成 GrADS 的 gs 脚本
0857 参数:
0858 path - 存放 gs 脚本文件及图像文件的路径
0859 e, l, t - 变量
0860 返回:
0861 脚本串
0862 */
0863 public String getScript ( String path, String e, String l, String t ) {
0864 if ( !setElement ( e ) || !setLevel ( l ) || !setValid ( t ) ) {
0865 return ( "" ) ;
0866 }
0867 /*
0868 System.out.println("element = " + element);
0869 System.out.println("level = " + level);
0870 System.out.println("valid = " + valid);
0871 */
0872 String gsString = "" ;
0873 String tmpTitle = getElement () + "_" + ( checkElement ( element ) > 1 ?getLevel () + "_" : "" ) + ctl.tdef.start + "+" + getValid () ; //getElementDescription();
0874
0875 Vector gsVector = new Vector () ;
0876 int originLength = 0 ;
0877 File f = new File ( path + ( path.endsWith ( "/" ) ? "" : "/" ) + scriptfile ) ;
0878 String strLine = null ;
0879 if ( overlapping && //迭加
0880 f.exists () && f.isFile () ) { //文件存在
0881 try {
0882 FileReader fr = new FileReader ( f ) ;
0883 BufferedReader br = new BufferedReader ( fr ) ;
0884 while ( null != ( strLine = br.readLine ()) ) {
0885 if ( ! "" .equals ( strLine.trim ()) ) {
0886 gsVector.add ( strLine.trim ()) ;
0887 }
0888 }
0889 br.close () ;
0890 fr.close () ;
0891 for ( int i=gsVector.size () - 1 ;i> 0 ;i-- ) {
0892 strLine = ( String ) gsVector.get ( i ) ;
0893 if ( strLine.startsWith ( "'" + "draw title" ) ) {
0894 tmpTitle = strLine.substring (( "'" + "draw title" ) .length () ,strLine.length () - 1 ) .trim () + "/" + tmpTitle;
0895 gsVector.set ( i, "" ) ;
0896 }
0897 if ( strLine.startsWith ( "'" + "draw xlab" ) ) {
0898 gsVector.set ( i, "" ) ;
0899 }
0900 if ( strLine.startsWith ( "'" + "set string" ) ) {
0901 gsVector.set ( i, "" ) ;
0902 }
0903 if ( strLine.startsWith ( "'" + "draw string" ) ) {
0904 gsVector.set ( i, "" ) ;
0905 }
0906 if ( strLine.startsWith ( "'" + "set lon" ) ) {
0907 gsVector.set ( i, "" ) ;
0908 }
0909 if ( strLine.startsWith ( "'" + "set lat" ) ) {
0910 gsVector.set ( i, "" ) ;
0911 }
0912 }
0913 for ( int i=gsVector.size () - 1 ;i> 0 ;i-- ) {
0914 strLine = ( String ) gsVector.get ( i ) ;
0915 if ( ( "'" + "quit'" ) .equalsIgnoreCase ( strLine ) ) {
0916 gsVector.set ( i, "" ) ;
0917 }
0918 }
0919 for ( int i= 0 ;i<gsVector.size () ;i++ ) {
0920 System.out.println (( String ) gsVector.get ( i )) ;
0921 }
0922 // gsVector.add("'set lon " + String.valueOf(Math.min(left, right)) + " " + String.valueOf(Math.max(left, right)) + "'");
0923 // gsVector.add("'set lat " + String.valueOf(Math.min(top, bottom)) + " " + String.valueOf(Math.max(top, bottom)) + "'");
0924 }
0925 catch ( Exception ex ) {
0926 }
0927 }
0928 String img = path + ( path.endsWith ( "/" ) ? "" : "/" ) + getImageFilename () ;
0929 originLength = gsVector.size () ;
0930 if ( - 1 == gsVector.indexOf ( "'" + "reinit" + "'" ) ) {
0931 gsVector.add ( "'" + "reinit" + "'" ) ;
0932 gsVector.add ( "'set grads off'" ) ;
0933 }
0934 gsVector.add ( "'set mpdset cnworld'" ) ; //画中国的省界,需要将 cnworld 文件复制到 /usr/local/lib/grads 路径
0935 gsVector.add ( "'set rgb 17 160 160 160'" ) ;
0936 gsVector.add ( "'set map 17 0 1'" ) ; //棕色 缺省线型 线宽为1
0937 if ( null != pathname && "" .equals ( pathname ) ) {
0938 gsVector.add ( "'" + "! cd " + pathname + "'" ) ;
0939 }
0940 gsVector.add ( "'" + "open " + filename + "'" ) ;
0941
0942 if ( !overlapping && shading ) { //非迭加时显示填充图
0943 gsVector.add ( "'" + "set gxout shaded" + "'" ) ;
0944 gsVector.add ( "'" + "set lev " + level + "'" ) ;
0945 gsVector.add ( "'" + "set t " + valid + "'" ) ;
0946 gsVector.add ( "'" + "set x " + ( border> 0 ?border: 1 ) + " " + ( border> 0 ?ctl.xdef.count - border:ctl.xdef.count ) + "'" ) ;
0947 gsVector.add ( "'" + "set y " + ( border> 0 ?border: 1 ) + " " + ( border> 0 ?ctl.ydef.count - border:ctl.ydef.count ) + "'" ) ;
0948
0949 // gsVector.add("'set lon " + String.valueOf(Math.min(left, right)) + " " + String.valueOf(Math.max(left, right)) + "'");
0950 // gsVector.add("'set lat " + String.valueOf(Math.min(top, bottom)) + " " + String.valueOf(Math.max(top, bottom)) + "'");
0951
0952 createElementScript ( gsVector ) ;
0953
0954 }
0955 gsVector.add ( "'" + "set gxout contour" + "'" ) ;
0956 gsVector.add ( "'" + "set lev " + level + "'" ) ;
0957 gsVector.add ( "'" + "set t " + valid + "'" ) ;
0958 gsVector.add ( "'" + "set x " + ( border> 0 ?border: 1 ) + " " + ( border> 0 ?ctl.xdef.count - border:ctl.xdef.count ) + "'" ) ;
0959 gsVector.add ( "'" + "set y " + ( border> 0 ?border: 1 ) + " " + ( border> 0 ?ctl.ydef.count - border:ctl.ydef.count ) + "'" ) ;
0960
0961 // gsVector.add("'set lon " + String.valueOf(Math.min(left, right)) + " " + String.valueOf(Math.max(left, right)) + "'");
0962 // gsVector.add("'set lat " + String.valueOf(Math.min(top, bottom)) + " " + String.valueOf(Math.max(top, bottom)) + "'");
0963
0964 createElementScript ( gsVector ) ;
0965
0966 gsVector.add ( "'" + "set font 0'" ) ;
0967 // gsVector.add("'" + "set string 19'");
0968 gsVector.add ( "'" + "draw title " + ( "" .equals ( title ) ?tmpTitle:title ) + "'" ) ;
0969 // String author = "广西气象减灾研究所";
0970 String author = "Guangxi Institude of Meteorology and Disaster-reducing Research" ;
0971 // gsVector.add("'" + "set xlopts 17 1 1'");
0972 // gsVector.add("'" + "draw xlab " + author + "'");
0973
0974 gsVector.add ( "'" + "set font 2'" ) ;
0975 gsVector.add ( "'" + "set string 17 bl'" ) ;
0976 gsVector.add ( "'" + "draw string 0 0.1 " + author + "'" ) ;
0977 gsVector.add ( "'draw map'" ) ; //画省界
0978 gsVector.add ( "'" + "printim " + img + " x" + width + " y" + height + " " + background + "'" ) ;
0979 gsVector.add ( "'" + "close 1" + "'" ) ;
0980 gsVector.add ( "'" + "quit" + "'" ) ;
0981
0982 for ( int i= 0 ;i<gsVector.size () ;i++ ) {
0983 strLine = (( String ) gsVector.get ( i )) .trim () ;
0984 if ( 0 < strLine.length () ) {
0985 gsString =
0986 gsString +
0987 (( String ) gsVector.get ( i )) .trim () +
0988 "/n" ;
0989 }
0990 }
0991 gsString = gsString + "/n/n" ;
0992
0993 return ( gsString ) ;
0994 }
0995 /**
0996 功能:合并两个 gs 文件
0997 */
0998 public String combineScript ( String gs1, String gs2 ) {
0999 return ( "" ) ;
1000 }
1001 /**
1002 功能:调用 GrADS 脚本
1003 参数:
1004 env[] - 运行 GrADS 所需要的环境,如:PATH=$PATH:/usr/local/bin,一般地,需要将 grads 所在的目录加入到 PATH 中
1005 resultPath - resultPath 所调用的 CTL 文件所在的路径
1006 imagePath - 所生成的图像的存放路径
1007 e, l, t - 变量
1008
1009 返回值:grads 的 gs 脚本
1010 */
1011 public String procScript ( String env [] , String resultPath, String imagePath, String e, String l, String t ) {
1012 //System.out.println("GrADS #1025: procScript(env, resultPath, imagePath, " + e + ", " + l + ", " + t + ")");
1013 message = "" ;
1014 File rPath = new File ( resultPath ) ;
1015 File iPath = new File ( imagePath ) ;
1016 if ( !enabled ||
1017 !rPath.exists () || !rPath.isDirectory () ||
1018 !iPath.exists () || !iPath.isDirectory () ||
1019 !setElement ( e ) || !setLevel ( l ) || !setValid ( t ) ) {
1020 System.out.println ( "ERROR: Grapes -> procScript : parameter(s)" ) ;
1021 return ( "ERROR: Grapes -> procScript : parameter(s)" ) ;
1022 }
1023 try {
1024 String imageFile =
1025 imagePath + ( imagePath.endsWith ( "/" ) ? "" : "/" ) + getImageFilename () ;
1026 File f = new File ( imageFile ) ;
1027 if ( f.exists () ) {
1028 f.delete () ;
1029 }
1030 String gs = imagePath + ( imagePath.endsWith ( "/" ) ? "" : "/" ) + scriptfile;
1031 String gsString;
1032 //生成 GrADS 的 gs 脚本
1033 gsString = getScript ( imagePath,element,level,valid ) ;
1034 FileWriter fw = new FileWriter ( gs ) ;
1035 BufferedWriter bw = new BufferedWriter ( fw ) ;
1036 bw.write ( gsString ) ;
1037 bw.close () ;
1038 fw.close () ;
1039
1040 message = procScript ( env, resultPath, imagePath, gs ) ;
1041 }
1042 catch ( IOException ex ) {
1043 System.out.println ( ex.getMessage ()) ;
1044 ex.printStackTrace () ;
1045 }
1046 return ( message ) ;
1047 } //调用 GrADS 脚本
1048 /**
1049 * 功能 : 调用 GrADS 脚本
1050 * 参数 :
1051 * env[] - 运行环境
1052 * path - 开始路径,一般地,设为 GrADS 数据文件所在的路径
1053 * gs - GrADS 的 gs 脚本文件名
1054 * 返回值 : GrADS 运行结果
1055 */
1056 public String procScript ( String env [] , String pathCtl, String pathShell, String gs ) {
1057 //System.out.println("GrADS #1070: procScript(env, " + pathCtl + ", " + pathShell + ", " + gs + ")");
1058 message = "" ;
1059 String cmdString = command + " -blc /"run " + gs + "/"" ;
1060 String cmdStrings [] = { command, "-blc" , "/"run " + gs + "/"" } ;
1061 //System.out.println(cmdStrings[0] + " " + cmdStrings[1] + " " + cmdStrings[2]);
1062
1063 try {
1064 File f = new File ( pathShell ) ;
1065 if ( f.isDirectory () && f.exists () ) {
1066 //System.out.println("GrADS #1079: " + pathShell);
1067 FileWriter fw = new FileWriter ( pathShell + "/gradsc.sh" ) ;
1068 BufferedWriter bw = new BufferedWriter ( fw ) ;
1069 bw.write ( "date" ) ;
1070 bw.newLine () ;
1071 bw.write ( "source /etc/profile" ) ; //确保 .sh 的执行环境与人工执行时一样
1072 bw.newLine () ;
1073 bw.write ( "source $HOME/.bash_profile" ) ; //确保 .sh 的执行环境与人工执行时一样
1074 bw.newLine () ;
1075 bw.write ( "cd " + pathCtl ) ;
1076 bw.newLine () ;
1077 bw.write ( cmdString ) ;
1078 bw.newLine () ;
1079 bw.close () ;
1080 fw.close () ;
1081 String stringLine;
1082 Process cmd = Runtime.getRuntime () .exec ( "/bin/chmod +x " + pathShell + "/gradsc.sh" , env, f ) ;
1083 cmd.waitFor () ;
1084 /*
1085 cmd = Runtime.getRuntime().exec("/bin/ls -ltr " + pathShell, env, f);//测试
1086 BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(cmd.getInputStream()));
1087 while(null != (stringLine = bufferedReader.readLine()) ) {
1088 System.out.println(stringLine);
1089 }
1090 System.out.println("/bin/bash " + pathShell + "/gradsc.sh");
1091 */
1092 cmd = Runtime.getRuntime () .exec ( "/bin/bash " + pathShell + "/gradsc.sh" , env, f ) ;
1093 BufferedReader bufferedReader = new BufferedReader ( new InputStreamReader ( cmd.getInputStream ())) ;
1094 while ( null != ( stringLine = bufferedReader.readLine ()) ) {
1095 //stringLine = stringLine.replaceAll(" ", " ");
1096 //System.out.println(stringLine);
1097 message = message + stringLine + "/n" ;
1098 }
1099 // message = message.replaceAll("/n", "<br>");
1100 bufferedReader.close () ;
1101 // cmd = Runtime.getRuntime().exec("/bin/rm -f " + pathShell + "/grads.sh", env, f);
1102 }
1103 }
1104 catch ( Exception ex ) {
1105 System.out.println ( "GrADS Exception: " + ex.getMessage ()) ;
1106 ex.printStackTrace () ;
1107 }
1108 return ( message ) ;
1109 } //调用 GrADS 脚本
1110 //删除图像文件,在 JSP 中当获得的要素、时次、层次等三个参数的值均为空时执行本函数,以避免保留过多的垃圾文件。
1111 public static int deleteImageFile ( String path, String ext ) { //suffix=.ext
1112 if ( null == ext || "" .equals ( ext.trim ()) ) {
1113 return ( 0 ) ;
1114 }
1115 boolean isImageFile = false ;
1116 String exts [] = { ".jpg" , ".jpeg" , ".gif" , ".bmp" , ".dib" , ".png" , ".ico" } ;
1117 for ( int i= 0 ;i<exts.length;i++ ) { //确保删除的是图像文件
1118 if ( 0 == ext.compareToIgnoreCase ( exts [ i ]) ) {
1119 i = exts.length;
1120 isImageFile = true ;
1121 }
1122 }
1123 if ( false == isImageFile ) {
1124 return ( 0 ) ;
1125 }
1126 File f = new File ( path ) ;
1127 int iCount = 0 ;
1128 if ( f.exists () && f.isDirectory () ) {
1129 File listFiles [] = f.listFiles () ;
1130 for ( int i= 0 ;i<listFiles.length;i++ ) {
1131 if ( !listFiles [ i ] .isDirectory () && listFiles [ i ] .getName () .endsWith ( ext ) ) {
1132 iCount = iCount + ( listFiles [ i ] .delete () ? 1 : 0 ) ;
1133 }
1134 }
1135 }
1136 return ( iCount ) ;
1137 }
1138 /**
1139 * 功能:列出所有文件
1140 * 参数:
1141 * result - 存放搜索结果
1142 * path - 目录
1143 * prefix - 文件名前缀
1144 * suffix - 文件后缀
1145 * recrise - 是否包括子目录
1146 * 返回值:
1147 * 找到的文件总数
1148 */
1149 public static int listGrADS ( Vector result, String path, String prefix, String suffix, boolean recuise ) {
1150 File f = new File ( path ) ;
1151 int resultCount = result.size () ;
1152 if ( f.exists () && f.isDirectory () ) {
1153 File listFiles [] = f.listFiles () ;
1154 for ( int i= 0 ;i<listFiles.length;i++ ) {
1155 //System.out.println(listFiles[i].getAbsolutePath());
1156 if ( recuise && listFiles [ i ] .isDirectory () ) {
1157 listGrADS ( result, listFiles [ i ] .getAbsolutePath () , prefix, suffix, recuise ) ;
1158 }
1159 if ( !listFiles [ i ] .isDirectory () &&
1160 listFiles [ i ] .getName () .startsWith ( prefix ) &&
1161 listFiles [ i ] .getName () .endsWith ( suffix ) ) {
1162 result.add ( listFiles [ i ] .getAbsolutePath ()) ;
1163 }
1164 }
1165 }
1166 return ( result.size () - resultCount ) ;
1167 }
1168 //获得数据 - 未完成
1169 public int getData ( String file, float [][] data, int lon, int lat ) {
1170 int count = 0 ;
1171 byte [] b = new byte [ 4 ] ;
1172 try {
1173 RandomAccessFile raf = new RandomAccessFile ( file, "r" ) ;
1174 DecimalFormat df = new DecimalFormat ( "0.000000" ) ;
1175
1176 String s = " " ;
1177 String s1 = "" ;
1178 for ( int j= 0 ;j<lat;j++ ) {
1179 for ( int i= 0 ;i<lon;i++ ) {
1180 raf.read ( b ) ;
1181 data [ i ][ j ] = DataConverter.getFloat ( b ) ;
1182 s1 = s + df.format ( data [ i ][ j ]) ;
1183 System.out.print (( i% 10 == 0 ? "/r/n" : "" ) + s1.substring ( s1.length () - 16 )) ;
1184 count++;
1185 }
1186 System.out.println ( "" ) ;
1187 }
1188 raf.close () ;
1189 }
1190 catch ( Exception e ) {
1191 System.out.println ( e.getMessage ()) ;
1192 e.printStackTrace () ;
1193 }
1194 return ( count ) ;
1195 }
1196 }