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!