AI智能
改变未来

记录一次ncl从前端到后端出图过程:调用linux-shell执行ncl命令从nc文件出图

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 iffileArray = 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 ifif (.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 ifif (.not. isvar(\"rectMaxLat\")) then      ; is rectMaxLat command line?rectMaxLat = 90;end ifif (.not. isvar(\"rectMinLon\")) then      ; is rectMinLon command line?rectMinLon = -180;end ifif (.not. isvar(\"rectMaxLon\")) then      ; is rectMaxLon command line?rectMaxLon = 180;end ifif (.not. isvar(\"outputFile\")) then      ; is outputFile command line?outputFile = \"/cygdrive/c/out\";end ifif (.not. isvar(\"cdfVar\")) then      ; is outputFile command line?cdfVar = \"hgt\";end if;************************************************; open file and read in data;************************************************fileCount = dimsizes(fileArray);print(fileCount);i = 0do 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\") ) thenfirst = tempIn->$cdfVar$(0:58,:,:,:);last = tempIn->$cdfVar$(60:365,:,:,:);elsefirst = tempIn->$cdfVar$(0:58,:,:);last = tempIn->$cdfVar$(60:365,:,:);end iftempT = array_append_record(first,last,0);elsetempT = tempIn->$cdfVar$;end ifif(isatt(tempIn->$cdfVar$,\"add_offset\")) thentempT1 = tempT*tempIn->$cdfVar$@scale_factor + tempIn->$cdfVar$@add_offset;elsetempT1 = tempT;end ifif (.not. isvar(\"totalT\")) thentotalT = tempT1;elsetotalT = 	tempT1 + totalT;end ifi=i+1end doavgT = totalT / fileCount;t = avgT;if ( timeDimensionStep .gt. 0) thenprintVarSummary(t)if ( isvar(\"level\") ) thentt = t(timeDimension:timeDimension+timeDimensionStep,level,:,:);elsett = t(timeDimension:timeDimensionStep,:,:);end ift1 = dim_avg_n( tt, 0 );;printVarSummary(tt);elseif ( isvar(\"level\") ) thent1 = t(timeDimension,level,:,:);elset1 = t(timeDimension,:,:);end ifend ifwks_type = \"png\"wks = gsn_open_wks(wks_type ,outputFile);res                       = True     ; plot mods desiredres@vpXF									= 0.10;res@vpYF									= 0.90;res@gsnDraw                 = False;  do not drawres@gsnFrame                = False;res@vpKeepAspect					= True;;res@gsnPanelTop						= 0.1;res@gsnPaperOrientation		= \"landscape\";res@cnFillOn              = True     ; turn on color fillres@cnLinesOn             = True    ; turn of contour linesres@cnLevelSelectionMode  = \"AutomaticLevels\";res@cnLevelSpacingF       = levelSpace      ; contour spacingres@cnFillPalette         = \"BlAqGrYeOrRe\" ;res@pmTickMarkDisplayMode = \"Always\"; use NCL default lat/lon labelsres@gsnAddCyclic          = True    ; data already has cyclic pointres@mpCenterLonF    = 180;        ;center with percific ocean; this must also be set for any zoomres@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 onres@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        = Truelnres@minlat = rectMinLatlnres@maxlat = rectMaxLatlnres@minlon = rectMinLonlnres@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 blocke.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!

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 记录一次ncl从前端到后端出图过程:调用linux-shell执行ncl命令从nc文件出图