记录一次ncl从前端到后端出图过程:调用linux-shell执行ncl命令从nc文件出图
2020-06-06 05:08
399 查看
ncl出图大概长这样子:
数据文件:
ncl脚本:
[code];************************************************ ; ; These files are loaded by default in NCL V6.2.0 and newer ; load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" ; load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" ; ; @Author Zhou ; @Date 2016-07-25 ; ;************************************************ begin ;************************************************ ;try to read file name from command line parameter ;************************************************ if (.not. isvar("fileName")) then ; is fileName on command line? fileName = "hgt.2000.nc,hgt.2003.nc"; end if fileArray = str_split(fileName, ","); print(fileArray); if (.not. isvar("filePath")) then ; is filePath on command line? filePath = "./"; end if ;************************************************ ; for time dimesion ;************************************************ if (.not. isvar("timeDimension")) then ; is timeDim command line? timeDimension = 0; end if if (.not. isvar("timeDimensionStep")) then ; is timeDim command line? timeDimensionStep = 5; end if ;if (.not. isvar("level")) then ; is levelSpace command line? ; level = 5; ;end if ;************************************************ ; for spacing ;************************************************ if (.not. isvar("levelSpace")) then ; is levelSpace command line? levelSpace = 5; end if ;************************************************ ; for display rectangle ;************************************************ if (.not. isvar("rectMinLat")) then ; is rectMinLat command line? rectMinLat = -90; end if if (.not. isvar("rectMaxLat")) then ; is rectMaxLat command line? rectMaxLat = 90; end if if (.not. isvar("rectMinLon")) then ; is rectMinLon command line? rectMinLon = -180; end if if (.not. isvar("rectMaxLon")) then ; is rectMaxLon command line? rectMaxLon = 180; end if if (.not. isvar("outputFile")) then ; is outputFile command line? outputFile = "/cygdrive/c/out"; end if if (.not. isvar("cdfVar")) then ; is outputFile command line? cdfVar = "hgt"; end if ;************************************************ ; open file and read in data ;************************************************ fileCount = dimsizes(fileArray); print(fileCount); i = 0 do while(i.lt.fileCount) tempFile = fileArray(i); print(tempFile); tempIn = addfile(filePath+tempFile,"r"); yearDays = dimsizes(tempIn->time); if(yearDays .gt. 365) if ( isvar("level") ) then first = tempIn->$cdfVar$(0:58,:,:,:); last = tempIn->$cdfVar$(60:365,:,:,:); else first = tempIn->$cdfVar$(0:58,:,:); last = tempIn->$cdfVar$(60:365,:,:); end if tempT = array_append_record(first,last,0); else tempT = tempIn->$cdfVar$; end if if(isatt(tempIn->$cdfVar$,"add_offset")) then tempT1 = tempT*tempIn->$cdfVar$@scale_factor + tempIn->$cdfVar$@add_offset; else tempT1 = tempT; end if if (.not. isvar("totalT")) then totalT = tempT1; else totalT = tempT1 + totalT; end if i=i+1 end do avgT = totalT / fileCount; t = avgT; if ( timeDimensionStep .gt. 0) then printVarSummary(t) if ( isvar("level") ) then tt = t(timeDimension:timeDimension+timeDimensionStep,level,:,:); else tt = t(timeDimension:timeDimensionStep,:,:); end if t1 = dim_avg_n( tt, 0 ); ;printVarSummary(tt); else if ( isvar("level") ) then t1 = t(timeDimension,level,:,:); else t1 = t(timeDimension,:,:); end if end if wks_type = "png" wks = gsn_open_wks(wks_type ,outputFile); res = True ; plot mods desired res@vpXF = 0.10; res@vpYF = 0.90; res@gsnDraw = False; do not draw res@gsnFrame = False; res@vpKeepAspect = True; ;res@gsnPanelTop = 0.1; res@gsnPaperOrientation = "landscape"; res@cnFillOn = True ; turn on color fill res@cnLinesOn = True ; turn of contour lines res@cnLevelSelectionMode = "AutomaticLevels" ;res@cnLevelSpacingF = levelSpace ; contour spacing res@cnFillPalette = "BlAqGrYeOrRe" ; res@pmTickMarkDisplayMode = "Always"; use NCL default lat/lon labels res@gsnAddCyclic = True ; data already has cyclic point res@mpCenterLonF = 180; ;center with percific ocean ; this must also be set for any zoom res@gsnMaximize = False ;maximize size ; note that the gsn_csm_*map_ce templates automatically set ; res@mpLimitMode="LatLon" for you. If you are plotting a different projection, ; you may have to set this resource. res@mpMinLatF = rectMinLat ; range to zoom in on res@mpMaxLatF = rectMaxLat; res@mpMinLonF = rectMinLon; res@mpMaxLonF = rectMaxLon; ;print(res); plot = gsn_csm_contour_map(wks,t1, res) ;**************************************************************************** ; sections for shapefiles ;**************************************************************************** shpfn1="shp/prov.shp" lnres = True lnres@minlat = rectMinLat lnres@maxlat = rectMaxLat lnres@minlon = rectMinLon lnres@maxlon = rectMaxLon ;shp_plot1 = gsn_add_shapefile_polylines(wks,plot,shpfn1,lnres) maximize_output(wks,False); ;************************************************ exit() end
linux服务器需安装ncl:
ncl命令:ncl "需要的参数" "脚本文件", 比如:
ncl 'fileName="hgt.2016.nc"' 'filePath="/data/ncep/hgt/"' 'outputFile="/home/exportImage/ncl/ncl_1565315022748_1232/out.png"' 'cdfVar="hgt"' rectMinLat=-90.0 rectMaxLat=90.0 rectMinLon=-180.0 rectMaxLon=180.0 'years="2016"' timeDimension=182 timeDimensionStep=14 level=2 myNcepYearMerg.ncl
前端页面用extjs编写,后端java+hibernate+struts.
- 前端post请求:
-
[code]actionName = "exportNclImag"; extraParam = { "dataType": 1, "dataResolution": 2, "element": "hgt", "subLevel": "850hPa",//高度 "startDate": "2015-07-01T00:00:00", "endDate": "2015-07-15T00:00:00", "reference": 1981, "renderType": "ncl", "years": "2016",//年份 "maxLong": 180,//显示范围的经纬度 "minLong": -180, "maxLat": 90, "minLat": -90 }; toJson = Ext.encode(extraParam); paramObj = { params: { 'extraParam': toJson } }; Ext.doAjaxRequest(actionName, paramObj, this, _onLoadNcepImage, _LoadNcepImageError);
struts通过前端post请求的actionName去到对应的类和方法:
[code]NclExportParam nclExportParam = getNclExportParam(); ExportResult exportResult = exportService.export(null, null, ExportEngine.EXPORT_ENGINE_NCL, EngineHelper.FORMAT_PIC_PNG, nclExportParam);
后端需要做的事:
- 从前端穿过来的参数拼接ncl所需参数字符串,设置nc文件存放目录,设置png图片和ncl日志输出目录。然乎手动把ncl脚本放到 /home 目录下面(或者其他目录也行),把nc文件放到存放目录(注意权限问题);
- 输出重定向(日志输出,记录出图过程):String cmd1 = cmd + " >> "+ outputFilePathAndName+"out.txt ";
- command命令:String[] command = { "sh", "--login", "-c", cmd1};
- Process process = Runtime.getRuntime().exec(command, null, "/home");
- 处理process输出流:(不处理进程不会退出,一直卡住,但是也能生成图片)
-
[code]BufferedReader brError = new BufferedReader(new InputStreamReader(process.getErrorStream())); //单独开一个线程去处理输出流 startConsoleReaderThread(brError); BufferedReader brOut = new BufferedReader(new InputStreamReader(process.getInputStream())); //单独开一个线程去处理输出流 startConsoleReaderThread(brOut); int returnCode = process.waitFor(); System.out.println("Process exit with code : " + returnCode); if (returnCode != 0) { // something wrong // do nothing for now } else { // success } //单独开一个线程去处理输出流 protected void startConsoleReaderThread(final BufferedReader br) { Thread readThread = new Thread() { public void run() { try { // String line; char[] charArray = new char[1024]; int readCount = 0; while ((readCount = br.read(charArray)) >= 0) { String tempStr = new String(charArray, 0, readCount); System.out.println(tempStr); } } catch (IOException e) { e.printStackTrace(); } finally { if(br != null) { try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }; readThread.start(); }
- 生成结果:
- 对图片进行处理(裁剪、缩放等),然后以 stream形式传回前端:
-
<result name="success" type="stream"> <param name="contentType">application/octet-stream;charset=UTF-8</param> <param name="contentDisposition">attachment;filename="${exportFileName}"</param> <param name="inputName">exportFileInputStream</param> </result> 前端拿到结果,显示图片:
- /*
imageInfo = {
title:"ncep图",
url: "返回的stream"
} */
-
this.updateImage = function(imageInfo){ var title = imageInfo.title || ""; var htmlStr = '<img id="_img" height="100%" src = '+ imageInfo.url +'></img>'; this.setTitle(title); this.update(htmlStr); };
结果:
大概就酱紫了吧.Done!
相关文章推荐
- 记录一次Linux操作系统最大文件数限制的解决过程
- Linux的系统调用、网络连接状态、磁盘I/O;可疑行为监控/日志收集、SHELL命令执行流程
- Mysql 将结果保存到文件 从文件中执行sql语句 记录操作过程(tee 命令的使用)
- java 中调用window系统中的文件,或者执行命令(shell、.CMD、.EXE)并获取返回值(如果有的话)
- Linux的系统调用、网络连接状态、磁盘I/O;可疑行为监控/日志收集、SHELL命令执行流程
- java本地调用cmd,shell命令,远程调用Linux执行命令方法总结
- linux中Shell历史命令记录文件的路径是什么
- Linux/shell命令的实际应用——ldd查看可执行程序依赖的库文件
- Linux/shell命令的实际应用——ldd查看可执行程序依赖的库文件
- linux中Shell历史命令记录文件的路径是什么
- loadrunner调用plink,远程linux执行shell命令
- PHP调用Linux的命令行执行文件压缩命令
- windows到linux下面文本从ansi转utf-8(java调用shell命令,java文件复制)
- linux下c调用shell命令,以及判断文件是否存在
- C#远程执行Linux系统中Shell命令和SFTP上传文件
- Java调用linux系统shell执行命令
- 简易登录,批量执行命令,批量copy文件shell脚本【Linux运维之道之脚本案例】
- 执行文件下载Java 调用 FFMPEG 命令时用 url 作为输入源,Linux 下出现 “no such file or directory” 问题的解决
- Linux库文件和Shell可执行程序命令文件搜索路径变量的设置
- PHP调用Linux的命令行执行文件压缩命令&&创建文件夹修改权限