地形起伏度:是指在一个特定的区域内,最高点海拔高度与最低点海拔高度的差值。它是描述一个区域地形特征的一个宏观性的指标。
在很多具有栅格分析的软件中都没有提供计算地形起伏度的功能,虽然可以根据现有的工具进行组合计算,但是还是比较麻烦。ENVI/IDL的栅格运算功能强大,效率高。本文利用IDL制作了计算地形起伏度的程序,并且能集成在ENVI中使用。
注意事项:将dixingqifudu.pro文件放到ENVI的安装目录\ProgramFiles\ITT\IDLxx\products\enviXX\save_add下,启动ENVI+IDL,出现在ENVI的topographic菜单下:(或者编译成sav文件,只打开ENVI即可。)

源码:
;;===界面居中的函数======================
PRO CENTERTLB, tlb, x, y, NoCenter=nocenter
COMPILE_OPT StrictArr
geom = WIDGET_INFO(tlb, /Geometry)
IF N_ELEMENTS(x) EQ 0 THEN xc = 0.5 ELSE xc = FLOAT(x[0])
IF N_ELEMENTS(y) EQ 0 THEN yc = 0.5 ELSE yc = 1.0 - FLOAT(y[0])
center = 1 - KEYWORD_SET(nocenter)
;
oMonInfo = OBJ_NEW('IDLsysMonitorInfo')
rects = oMonInfo -> GetRectangles(Exclude_Taskbar=exclude_Taskbar)
pmi = oMonInfo -> GetPrimaryMonitorIndex()
OBJ_DESTROY, oMonInfo
screenSize =rects[[2, 3], pmi]
; Get_Screen_Size()
IF screenSize[0] GT 2000 THEN screenSize[0] = screenSize[0]/2 ; Dual monitors.
xCenter = screenSize[0] * xc
yCenter = screenSize[1] * yc
xHalfSize = geom.Scr_XSize / 2 * center
yHalfSize = geom.Scr_YSize / 2 * center
XOffset = 0 > (xCenter - xHalfSize) < (screenSize[0] - geom.Scr_Xsize)
YOffset = 0 > (yCenter - yHalfSize) < (screenSize[1] - geom.Scr_Ysize)
WIDGET_CONTROL, tlb, XOffset=XOffset, YOffset=YOffset
END
;;;================================================
;自动添加envi菜单
PRO dixingqifudu_define_buttons, buttonInfo
ENVI_DEFINE_MENU_BUTTON, buttonInfo, VALUE = '地形起伏度计算', uValue=′′,
event_pro ='dixingqifudu', $
REF_VALUE = 'Topographic',position=2
end
pro qifudu_result, pp, flag, out_name=out_name ;pp是窗口大小,flag是存贮方式
compile_opt idl2
envi_batch_init
pp=pp;窗口大小
p1=(pp-1)/2;用于建立窗口大小
envi_select,fid=fid,pos=pos,dims=dims
if fid eq -1 then begin
envi_batch_exit
return
endif
ENVI_FILE_QUERY, fid, bnames=bnames
nl=dims[4]-dims[3]+1
ns=dims[2]-dims[1]+1
nb=size(pos)
nb=nb[1]
; print,nb
tfid=indgen(nb)
posss=intarr(nb);因为后面生成的都是单波段文件及r_fid,所以都是0表示第一个波段。
FOR g=0,nb-1 DO BEGIN
data1 = ENVI_GET_DATA(DIMS=dims, FID=fid , POS=pos[g])
inherit = envi_set_inheritance(fid, dims, pos[g], /full)
data2=data1
FOR i =p1,ns-p1-1 DO BEGIN
FOR j =p1, nl-p1-1 DO BEGIN
;获取一个pp*pp的窗口
t= data1[[i-p1]:[i+p1],[j-p1]:[j+p1]]
tmax=max(t,min=tmin)
data2[i,j]=tmax-tmin
ENDfor
ENDFOR
ENVI_WRITE_ENVI_FILE, data2,inherit=inherit ,r_fid=t,out_name=out_name+bnames[pos[g]] ;,/NO_OPEN
; ENVI_FILE_MNG, id=t, /REMOVE
tfid[g]=t
ENDfor
if flag eq 1 then begin
envi_doit, 'cf_doit', fid=tfid, pos=posss, dims=dims, remove=0,outname=outname,rfid=rfidendifelsebeginenvidoit,′cfdoit′,fid=tfid,pos=posss,dims=dims,
remove=0, /IN_MEMORY, r_fid=r_fid
endelse
end
;事件响应程序
pro dixingqifudu_event,event
widget_control,event.top,get_uvalue=pstate
if TAG_NAMES(event,/STRUCTURE_NAME) eq 'WIDGET_KILL_REQUEST' then begin
WIDGET_CONTROL,event.top,/destroy
ptr_free,pstate
RETURN
endif
widget_control,event.id,get_uvalue=uval
case uval of
'list': begin
(*pstate).chuangkou=fix(event.str)
print, fix(event.str)
; if event.index eq -1 then a=fix(event.str)
; help,fix(event.str)
end
'file_m':begin
if event.value eq '内存' then begin
(*pstate).flag=0
widget_control,(*pstate).i_base52,map=0
endif else begin
(*pstate).flag=1
widget_control,(*pstate).i_base52,map=1
endelse
end
'xuanze':begin
out_name=Dialog_Pickfile(Path=current, /NoConfirm, $