您的位置:首页 > 运维架构 > Shell

记录一次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!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐