idl 高级培训 基础篇

111
IDL IDL 高高高高 高高高高 高高高 高高高

Upload: tracey

Post on 12-Jan-2016

186 views

Category:

Documents


0 download

DESCRIPTION

IDL 高级培训 基础篇. 基础篇 - 语法基础. 1. 变量及其属性. 整型为短整型,注意使用 L 变量的属性是动态改变的 var=5 为整型 var=var*2.0 变为浮点 NaN : ! VALUES.F_NAN、 ! VALUES.D_NAN var= ! VALUES.F_NAN, 则 f inite(var)=1. 基础篇 - 语法基础. 2. 数组 IDL 是面向矩阵的语言,几乎所有运算都可以在数组上使用。 数组表达 : array[n,m] 表示 n 列 m 行(与其他语言有别),按行排列, 0 为下标起点 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: IDL  高级培训 基础篇

IDL IDL 高级培训高级培训

基础篇基础篇

IDL IDL 高级培训高级培训

基础篇基础篇

Page 2: IDL  高级培训 基础篇

基础篇 -语法基础

1. 变量及其属性

数据类型 字节 值域 创建 类型函数字节 1 0~255 0B byte()

16位有符号整型 2 -32,768~32,767 0 fix()

32位有符号整型 4 0L long()

64位有符号整型 8 0LL long64()

16位无符号整型 2 0~65535 0U uint()

32位无符号整型 4 0~2^32-1 0UL ulong()

64位无符号整型 8 0~2^64-1 0ULL ulong64()

浮点型 4 ±10^38 0.0 float()

双精度浮点型 8 0.0D double()

复数 8 complex(0.0,0.0) complex()

双精度复数 16 complex(0.0D,0.0D) dcomplex()

字符串 0~32767 ‘ ’ 或“ ” string()

指针 4 ptr_new() -

对象 4 obj_new() -

• 整型为短整型,注意使用 L• 变量的属性是动态改变的 var=5 为整型 var=var*2.0 变为浮点• NaN : !VALUES.F_NAN 、 !VALUES.D_NAN var=!VALUES.F_NAN ,则 finite(var)=1

Page 3: IDL  高级培训 基础篇

基础篇 -语法基础

2. 数组 IDL 是面向矩阵的语言,几乎所有运算都可以在数组上使用。

数组表达: array[n,m] 表示 n列m 行(与其他语言有别),按行排列 , 0 为下标起点 数组引用: array[subscript] ,或( array) [subscript] 下标语法: e、 e0:e1、 e:*、 *、 array。 array=make_array(10,10,/integer), sub=indgen(12) 合法的下标表示: array[5,5] 、 array[2:3,5] 、 array[*,4] 、 array[*,5:8] 、 array[4,4:*] 、 array[sub]、 A[[1,3,5],7:9] reform() : array[4,4:*] 为 1 列 4 行(列向量), reform(array[4,4:*]) 则为 4 列 1 行(行向量) 常数的数组表示: var=5 ,则 var[0]=5 (合法! ) 赋值: array[[2, 4, 6],5]=[4, 16, 36] where(): array[where(array lt 0)]=-999 数学运算:与普通变量基本相同。 * 和 / :表示两个同维数数组对应元素运算 arr1=indgen(5)+1 , arr2=arr1 。则: arr1*arr2=[1,4,9,16,25] , arr1/arr2=[1,1,1,1] # 和 ## :矩阵运算 arr1(n1,m)#arr2(m,n2)=arr(n1,n2) , arr1(n,m1)##arr2(m2,n)=arr(m2,m1) 数组串连: arr1(5,6) , arr2(5,2) 。则: arr3=[[arr1],[arr2]] 为( 5,8 ) 注意: arr3=[arr1,arr2] 不合法!(一维除外)

Page 4: IDL  高级培训 基础篇

数据类型 初始化函数 产生索引值函数创建字节 bytarr bindgen

16位有符号整型 intarr indgen

32位有符号整型 lonarr lindgen

64位有符号整型 lon64arr l64indgen

16位无符号整型 uintarr uindgen

32位无符号整型 ulonarr ulindgen

64位无符号整型 ulon64arr ul64indgen

浮点型 fltarr findgen

双精度浮点型 dblarr dindgen

复数 complexarr cindgen

双精度复数 dcomplexarr dcindgen

字符串 strarr slindgen

指针 ptrarr -

对象 objarr -

其他常用函数: array_equal、 rebin()、 congrid()、 expand()、 reverse()

数组常用函数:

基础篇 -语法基础

Page 5: IDL  高级培训 基础篇

基础篇 -语法基础

3. 结构 一种复合变量,它可以将多种类型的数据存储在一个变量中,对于表示意义相关的数据、程序间交换数据均非常有意义。 类型及定义 命名结构: dot={PIXEL ,x:128 ,y:236 ,color:bytarr(3)} ,定义后可使用 FIXEL 定义其他结构 dot1={PIXEL ,x:58 ,y:46 ,color:[255,0,255]}、 dot2={PIXEL ,58 ,46 ,[255,0,255]}、 dot3= {PIXEL} 匿名结构: person={name:’jack’ ,id:123456L} ,定义后无固定结构,可任意改变 person={name:’jack’ ,id:123456L ,phone:’123-4567’} 引用 变量引用:使用变量名或变量在结构中的位置索引。如: dot.x 或 dot.(0) 数组变量: s={arr:indgen(10)} ,则 s.arr=10 将数组所有元素赋值为 10 。 结构数组 定义: dotarr=replicate({PIXEL} ,10) ,或 dotarr=replicate(dot ,10) 引用: dotarr[1].x=10 、 dotarr.x=10 将所有结构的 x 赋值为 10 、 dotarr.y=indgen(10) 结构中的变量的类型和(数组)大小 结构定义后,各变量的数据类型以及数组变量的维数均不可改变。当使用中出现不一致时向原类型转换,不能转换时报错。 var=dot.x*1.0=128.0 ,为浮点,而 dot.x=dot 仍为整型。 s.arr=-indgen(8) 会改变 s.arr 中前 8 个元素的值,而 s.arr=-indgen(11) 会出错。 结构继承 dot3d={POINT ,INHERITS PIXEL ,z:0} 常用函数 creat_struct()、 n_tags()、 tag_names()、 struct_assign()

Page 6: IDL  高级培训 基础篇

基础篇 -语法基础

4. 指针 建立动态数据结构的有效工具,是实现 IDL 面向对象编程和 Widget 编程的基本要素之一。 IDL 的指针与其他语言的指针有很大的不同,它不是指向存储的地址而仅仅是一个轻型的指向一个堆变量的引用(指针变量)。堆变量可以动态分配(数据类型和数组维数),这意味着传递指针变量就相当于传递动态数据。

Pointer Reference

Pointer Data

Pointer in Heap Variables

指针基本操作 创建: ptr=ptr_new( [initexpr] [, /allocate_heap] [, /no_copy] ) 释放: ptr_free ,ptr

•标量•数组•结构

Page 7: IDL  高级培训 基础篇

基础篇 -语法基础

标量指针 创建: v=5.5, p=ptr_new(v) 引用: print , p ,*p ; p1=p , *p1=20 , print ,*p 数组指针 创建: arr=findgen(10), p=ptr_new(arr) 引用: print ,(*p)[5] 结构指针 创建: s={name:’joe’ ,age:40 ,height:180} , p=ptr_new(s) 引用: print , (*p).name 结构内指针 创建: rec={lon:120 ,lat:20 ,data:ptr_new(findgen(2,10))} , p=ptr_new(rec) 引用: * (*p).data=findgen(2,20) 特殊指针 Null 指针: nptr=ptr_new() ,仅定义一个指针,并不指向一个堆变量。引用时需重新定义指针。 Empty 指针: eptr=ptr_new(/allocate_heap) ,定义一个指向一个堆变量的指针,但并未定义变量,引用时可以直接定义变量 指针释放 ptr_free ,ptr 相关函数 ptr_valid(): ptr_valid(nptr)=0 , ptr_valid(eptr)=1 heap_gc :释放没有引用的堆变量 指针数组 ptrarr( d1, ... , d8 [, /allocate_heap] )

Page 8: IDL  高级培训 基础篇

基础篇 -编程基础

IDLDE是 IDL 的集成开发环境,可以使用 IDL 命令进行交互式命令运行,编写、调试、运行 IDL程序,使用 GUI Builer 开发用户界面,使用项目管理器管理工程项目等。

1. IDL 程序 批处理:由一系列 IDL 命令组成,以 IDL->@batchfile 方式运行。批处理文件运行时并不编译,因此使用控制结构时必须大量使用续行符( $ ) , 给书写、理解造成困难。 主程序:与批处理相似,但以 end 结束,以 IDL->.run profile 方式运行。主程序运行时先编译,因此可以正常使用控制结构。 过程:与主程序相似,但以 pro proname 开始,以 end 结束。以 IDL->proname 方式运行(也可以先运行 IDL->.compile proname ,编译但不运行)。 函数:与过程相似,但以 function fnname 开始,以 end 结束,并以 return 语句返回一个 IDL变量。以 IDL->ret=fnname(para_list) 方式运行。 在 IDL 系统中,一个过程或函数即为一个新的 IDL 命令。 变量作用范围:批处理和主程序方式的变量为全局变量,可以在 IDL 开发环境中使用。过程和函数的变量为局部变量,只在过程和函数运行过程中有效。

Page 9: IDL  高级培训 基础篇

基础篇 -编程基础

2. 参数传递 位置参数:在参数列表中按位置列出参数名,严格的顺序限制。通常用于必选参数。 定义: pro batch ,para1 ,para2 ,... 调用: IDL->batch ,para1 ,para2 ,… 关键字参数:关键字参数与位置无关,且可以与位置参数混合位置。通常放在位置参数之后,用于可选参数。 定义: pro batch ,keywordname=keywordsymbol ,... 调用: IDL->batch ,keywordname=keywordsymbol ,… IDL->batch ,/keywordname 注意: keywordname 用于定义, keywordsymbol 用于调用。 引用传递和值传递:所有变量为引用传递,其值会被修改。系统变量、下标变量、表达式和常量均为值传递,原变量的值不被修改。 参数传递了吗?传递了什么? n_params() :返回位置参数的个数 keyword_set() :关键字参数为不为 0 常量或已定义的引用传递时返回 1 ,否则返回 0 arg_present() :关键字参数为引用传递时返回 1 (无论是否定义),否则返回 0 n_elements() :关键字参数未传递或未定义返回 0 ,否则返回非 0 数

Page 10: IDL  高级培训 基础篇

基础篇 -编程基础

3. 错误处理 on_ioerror :当出现 I/O 错误时,跳转指定的语句。两种用途:跳过错误返回或跳过错误继续。 注意:使用 on_ioerror , null on_error :当程序运行出错时,并不执行一个新的语句,而是指明 IDL 应该怎样做。

可以设置 on_error ,1 ,或在命令行使用 retall catch :格式: catch ,error_var 。当程序执行到 catch 语句时, IDL 为改模块记录一个错误处理语句,并将 error_var 赋值为 0 。若程序执行出错,则给 error_var 赋值相应的错误码,然后跳转到 catch 后第一条语句。注意:使用 catch ,/cancel

值 行动0 立即停止。缺省1 立即停止,返回主程序2 立即停止,返回程序调用模块3 立即停止,返回程序模块

Page 11: IDL  高级培训 基础篇

Error or Exception is Generated

Is it an I/O error?

Is there an error handler

defined by the CATCH routine?

Is ON_IOERROR routine in use?

Handle error as indicated by setting of ON_ERROR routine or use default error handling.

Handle error as indicated by ON_IOERROR setting.

Handle error with CATCH-defined error handler and continue program execution.

Yes

Yes

Yes

NoNo

No

基础篇 -编程基础

IDL 出错处理示意

Page 12: IDL  高级培训 基础篇

基础篇 -编程基础

4. 编译与运行 批处理: @bacthfile ,运行 主程序: .run ,编译、运行 过程和函数: .compile ,编译; ->proname ,编译、运行。 编译规则:( 1)编译到主程序后,编译停止 ( 2)编译到与文件同名的程序模块时,停止编译 ( 3)编译到文件末尾或适合其他规则时,停止编译 自动编译规则:当过程或函数出现在命令或代码中时,会自动被编译执行。 ( 1)过程或函数所在的文件应在当前工作路径和 !Path 指定的路径中 ( 2)过程或函数名与文件名相同 编译函数: resolve_routine 、 resove_all 。可用于程序模块中。 .sav : IDL->save ,编译后存储为 .sav 文件,便于发布。但版本间不兼容。

Page 13: IDL  高级培训 基础篇

基础篇 -输入输出

1. 常用概念 文件操作: openr, openw, openu, close 逻辑设备号: 1~ 99,直接使用 100~ 128,使用 get_lun获取, free_lun释放 常用函数: dilog_pickfile, findfile, filepath

2.文本文件的格式处理 自由格式: readf, printf, strsplit readf中只接收变量引用,不接收值引用 format语法: format=‘()’,括号内为格式符及其组合 A: [n]a[w], n为重复次数, w为输出宽度 I: [n]i[w]或 [n]I[w.m],缺省 w=7,特殊用法: i0 F: [n]f[w.d],缺省 w=15 X: [n]X,空格 /:换行符 ::其后的格式不用于最后一项。如每个输出项后加一个‘,’时,最后一项不加。 C: c(),表示日期,接受 julian日期。有丰富的子集

Page 14: IDL  高级培训 基础篇

基础篇 -输入输出

3. 二进制文件的关连变量处理 基本命令: readu, writeu 关联变量:大型重复单元二进制文件的有效读取手段,可以随机读取。 一个文件可建立多个关联,解决重复单元不一致的情况。 assoc(): result=assoc(unit,array_structure [,offset] [,/packed])

4. 使用与机器无关的数据格式

Page 15: IDL  高级培训 基础篇

IDL IDL 高级培训高级培训

直接图形篇直接图形篇

IDL IDL 高级培训高级培训

直接图形篇直接图形篇

Page 16: IDL  高级培训 基础篇

直接图形篇 -直接图形篇 -色彩控制色彩控制

1. 基本概念 颜色构成:( r,g,b) ,每个颜色值在 0~255 之间,所以 IDL 可以表现 256*256*256 种颜色 颜色表:一个颜色表由一个 3 列的数组构成,各列分别表示 r、 g、 b 值,通常 256 行。 索引号:颜色表中的索引位置。可以用来获得颜色的 r、 g、 b 值 8 位显示器和 24位显示器: 8 位显示器只能显示 256色, 24 位则可以显示 256*256*256色

2. 索引颜色模式和 RGB 颜色模式 索引颜色模式:通过颜色表的索引号获得颜色的 r、 g、 b 值,用于 8 位显示器。 RGB 颜色模式:直接指定颜色的 r、 g、 b 值,用于 24 位显示器。 IDL 使用一个长整数表示所有颜色的索引号, c=r+g*256L+b*256L*256L。 3. 动态显示和静态显示 动态显示:索引模式将索引号与颜色表中的特定位置连接,称为动态颜色显示。改变颜色表会影响当前索引号所对应的颜色。通常, 8 位显示是动态显示 静态显示: RGB 模式直接指定颜色本身,称为静态颜色显示。通常 24 位显示是静态显示。

Page 17: IDL  高级培训 基础篇

直接图形篇 -直接图形篇 -色彩控制色彩控制

4. device ,decomposed=0|1 decomposed=0:关闭颜色分解,使用索引颜色模式。适用于 8 位显示和 24 位显示,但 24 位时仍是静态显示。此时,可以使用 IDL预设的 41 个颜色表。 decomposed=1: IDL缺省模式,打开颜色分解,使用 RGB颜色模式。只适用于 24位显示。此时,只能使用长整数的全索引。

5. tvlct ,r ,g ,b [,start] [,/get] :( RGB 模式) tvlct ,r ,g ,b ,/get可以获取当前的颜色表。 tvlct ,r ,g ,b ,start可以加载一个颜色表到 start 指定的入口处。

6. loadct ,table 加载 IDL预设的 41 各颜色表之一

7. 创建自己的颜色表 根据颜色表的原理,可以很容易地创建一个 3*n 数组作为自己的颜色表,用 tvlct加载使用。

Page 18: IDL  高级培训 基础篇

直接图形篇 -直接图形篇 -坐标系

data :数据单位(缺省) dvice :像素单位 normal :归一化坐标, x: 0~1, y: 0~1

一般来说,在输出图形时, 3 个坐标系同时存在并都可以使用。 例:对于一个一维数组,在未指定坐标系时, IDL 会把数组的下标值作为 data坐标系下 x轴的值,数组的值作为 y 值画出曲线。

Page 19: IDL  高级培训 基础篇

直接图形篇 -直接图形篇 - 22DD 图形图形

创建自己的标注

Page 20: IDL  高级培训 基础篇

直接图形篇 -直接图形篇 - 22DD 图形图形

多坐标系数据集显示

Page 21: IDL  高级培训 基础篇

画真正的圆

直接图形篇 -直接图形篇 - 22DD 图形图形

Page 22: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 22DD 图形图形

在背景上叠加等值线

Page 23: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 22DD 图形图形

等值线图填充中的“黑洞”

Page 24: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 添加文本添加文本

给图形加文本标注 xyouts ,x ,y ,string ,font=

TrueType 字体设置: ( 1) DEVICE ,SET_FONT=font_str ,/TT_FONT ,输出时,使用 font=-1|0|1 ( 2) font = fnont_str Windows 环境下 TrueType 字体设置: font_str='font*modifier1*modifier2*...modifiern’

• For font weight: THIN, LIGHT, BOLD, HEAVY• For font quality: DRAFT, PROOF• For font pitch: FIXED, VARIABLE• For font angle: ITALIC• For strikeout text: STRIKEOUT• For underlined text: UNDERLINE

注意:并非所有选项在两种方式下均合法!

!P.Font 字体(对 device)-1 矢量字体(软字体、Hershay字体)0 硬字体(设备字体),缺省1 TrueType轮廓字体

Page 25: IDL  高级培训 基础篇

直接图形篇 -直接图形篇 -添加文本添加文本

使用汉字: font_str=“中文 TrueType 字体名称”

device ,set_font=‘隶书’ ,/tt_fontxyouts ,x ,y ,‘ ’ ,font=1

使自己的字体成为 IDL 的系统字体:编辑 \RSI\IDL54\resource\fonts\tt\ttfont.map

Page 26: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 33DD 图形图形

建立三维坐标系 IDL 使用变换矩阵与三维空间的点相乘,实现在二维显示上模拟三维坐标系。该变换矩阵装入 !P.T 。实现时,先装入正确的变换矩阵,然后在图形显示前,保证图形命令已经被变换矩阵乘过。

常用方法:( 1 )带 save 关键字的 surface 命令 surface ,data ,/nodata ,/save ( 2 )在 surface 后,使用 surfr 命令 surface ,data surfr ( 3) scale3 命令( scale3d :单位立方体) scale3 [,xrange=vector] [,yrange=vector] [,zrange=vector] [,ax=degrees] [,az=degrees] ( 4) t3d 命令 严格、完整、复杂的方法

Page 27: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 33DD 图形图形

三维散点图

Page 28: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 33DD 图形图形

曲面图

阴影曲面图图中色彩变化表示光源的方向

Page 29: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 33DD 图形图形

用颜色表现另一个数据集的信息上图为属性数据集右上、下图为用颜色表示的属性分布信息

Page 30: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 33DD 图形图形

用彩色图形叠加表现另一个数据集的信息左图为属性数据集右图为用叠加在阴影曲面上的彩色曲面表示属性分布信息

Page 31: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 33DD 图形图形

等值线叠加

Page 32: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 33DD 图形图形

三维实体创建: shade_volume, volume, value, vertex, polygons scale3 image=polyshade( vertex, polygons) tv, image

Page 33: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图形定位图形定位

图形定位: !p.region=[x0,x1,y0,y1](归一化坐标) !p.position=[x0,x1,y0,y1](归一化坐标) !x|y|z.margin=[p1,p2](字符个数,会随 charsize改变) 多数图形命令中都带有 margin和 position关键字,优先级较!变量高

图形位置:指被坐标轴包围的区域可以使用 !X|Y|Z.margin 、 !p.position 设置

图形区域包括图形标题其它注释的区域可以使用! P.region 设置 图形边缘

Page 34: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图形组合显示图形组合显示

如何在一个窗口里显示多个具有不同坐标系的图形?( 1) position=[x0,y0,x1,y1]( 2) !Multi=[p1,p2,p3,p4,p5] p1 :页面上剩余的部分的数目。通常为 0 ,表示擦除窗口开始输出 p2 :页面上图形的列数 p3 :页面上图形的行数 p4 :页面上 Z 方向上叠加的数目 p5: 0 ,按行显示; 1 ,按列显示

Page 35: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图形组合显示图形组合显示

!Y.omargin=[0,4]

!p.multi=[0,2,2,0,0]

Page 36: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图形组合显示图形组合显示

!Y.omargin=[0,4]

!p.multi=[0,2,2,0,0] . . .!p.multi=[1,1,2,0,0]

Page 37: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图形文件读写图形文件读写

作为一个数据分析和可视化的工具, IDL 支持大量的图形格式。包括: bmp, geo tiff, interfile , jpeg, pict, png, ppm, srf, tiff, x11 bitmap, xwd 。但从 v5.4起,不再支持 gif。

PNG 格式:支持最多 4 个通道的 8 位或 16 位数据 单通道数据时,支持调色板 wirte_png ,filename ,image ,[r,g,b]:将图形数据写入 PNG 文件 其中:( 1)如果 image 为 2 维数组,并且提供 r、 g、 b 值,则转换为 byte 以 8 位数据写入,否则转换为 16 位无符号整数。 ( 2 )对单通道数据, r、 g、 b 值必须提供,对多通道数据, r、 g、 b 值被忽略 ok=query_png(filename ,s):获取 PNG 文件的属性。 其中: ok=0 ,不是合法的 PNG 文件。 s 为一个结构,包含 PNG 文件的属性。若 s.has_palette=1 ,为单通道数据,否则为多通道数据。 image=read_png(filename [,r,g,b]):读出 PNG 文件的数据 其中: r,g,b 对单通道数据,读出调色板 , 否则忽略。 常见用法: write_png ,filename ,tvrd(true=1) (作为 3 通道数据写入) ok=query_png(filename ,s) . . image=read_png(filename) tv image ,/true

Page 38: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图像处理图像处理

图像:任何一个二维数组都可以视为一幅图像。 8 位图像:总表示为一个二维数组。 24 位(真彩色)图像:总表示为一个 3 维数组,其中一维为 3 。 m*n*3 :隔波段扫描( band-interleaved , true=3) m*3*n :隔行扫描( row-interleaved , true=2) 3*m*n :隔象素扫描( pixel-interleaved, true=1) 在 8 位显示设备上,所有数据要转换位字节类型;在 24 位显示设备上, 24 位图像的 r、 g、 b 值必须转换位字节类型。

Page 39: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图像处理图像处理

1. 基本操作 显示: tv和 tvscl。两个命令几乎一样,包括可以使用的关键字。都不删除当前窗口的内容。 tvscl:将图像数据调整为与运行时刻所有可用颜色数目相同的字节数据。通常用于 8位图像 tv:取图像数据本身,作为字节数据显示。如果图像数据以整形和更多位数表示,则被截断以适合字节类型。因此,图形可能会显示不正确。 在 24 位设备上显示图像一般方法: device ,decomposed=0 [loadct ,ct] tv/ tvscl ,image( 8 位图像) tv ,image ,true=1|2|3( 24 位图像 ))

Page 40: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图像处理图像处理

2. 调整数据为字节类型并可以使用统一的颜色集 bytscl(image ,min= ,max= ,top=) 如: scaleImage=bytscl(image ,min=5 ,max=30)

3. 改变图像尺寸 IDL提供了两个改变图像大小的命令: rebin和 congrid rebin:新建的图象的大小必须是原始尺寸的整数比例。缺省放大时采用双线性插值,缩小时采用邻近平均法。 sample关键字指定最近邻近采样法。 congrid:新建的图象的大小可以是原始尺寸的任意比例。缺省对三维以下数据采用最近邻近采样法,三维采用线性插值法。 interp关键字指定线性插值法

4. 在窗口中定位图像 (1) tv ,image ,index :根据图像尺寸,从窗口左上角开始计算位置,逐行至右下角。 (2) tv ,image ,x ,y :指定左下角开始计算的坐标( devic|data|normal)。 利用 !d.x_vsize 和 !d.y_vsize (象素值)计算归一化坐标以确定图像位置和大小。

5. 从窗口中读取图像 8 位显示: image=tvrd() 24 位显示: image=tvrd(true=1) tvrd命令支持读取指定区域的图像

Page 41: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图像处理图像处理

6. 基本图像处理

上图:原始图中图: hist_equal 函数下图: adapt_hist_equal 函数

直方图均衡化:观察图像中的象素值分布,往往会发现象素值分布趋于一个较狭窄的数值范围内。如果将象素值分散开,使象素值得每个子范围都有与这些象素值大约相同的象素,则该图像的信息内容有可能增加。将象素分布道整个颜色范围的过程称为直方图均衡化。

Page 42: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图像处理图像处理

负片:将原始图像的显示色板翻转,象素的字节值不变所得到的图像。

Page 43: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图像处理图像处理

消除噪声:噪声来自多方面,影响对图像质量。噪声的一般表现形式是随机的具有极端值的象素(黑白噪声)。 median :计算相邻象素的中间值。这样既可以消除极端值,又不会使大于邻域的部分图像边缘或特征模糊。

Page 44: IDL  高级培训 基础篇

平滑:通过将每个象素值与它周围相邻象素值进行平均来平滑图像。称为均值或核状平滑。 smooth :在给定的奇数宽度的范围内通过等加权值实现平滑。 convol :使用给定的方形滤波核通过卷积实现平滑。 晕光蒙片:将原始图像减去平滑后的图像。可以定位图像上的边缘或象素值突然变化的地方

直接图形篇 - 直接图形篇 - 图像处理图像处理

上图: smooth, w=5中图: smooth, w=3下图: convol, k=1,2,1 2,8,2 1,2,1

Page 45: IDL  高级培训 基础篇

边缘增强:通过锐化或微分以增强边缘。 roberts: sobel: convol :使用给定的方形滤波核通过卷积实现。

直接图形篇 - 直接图形篇 - 图像处理图像处理

右图:原始图像下图:自左至右依次为 roberts、 sobel、 convol

Page 46: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图像处理图像处理

7. 频域滤波 频域滤波是图像 和信号处理的常规手段。可以用于平滑图像、锐化图像、降低图像的模糊程度和恢复图像。

基本步骤:( 1 )用快速傅立叶变换( FFT )将图像从空间域转换为频率域 ( 2 )将转换后的图像与一个频率滤波器相乘 ( 3 )将滤波后的图像逆变换转换为空间域 方法: filtered_img=fft( fft(img,-1)*filter ,1) img可以是一维矢量,也可以是二维图像 filter为滤波器,用于滤波图像中某些特定频率的一维矢量和二维数组。 创建滤波器: 欧氏距离图(频率图像): r=dist(n [,m]), n和 m与实际图像相同 Butterworth频率滤波器: 低通滤波: filter=1/[1+c*(r/r0)2n] 高通滤波: filter=1/[1+c*(r0/r)2n] 其中: c=1.0或 0.414(即当 r=r0 时,滤波幅度为 0.5或 1/sqrt(2)) r0 为滤波器截止频率(实际中使用象素宽度) n为滤波器阶数,通常 n=1 通常,低频项代表图像的一般形状,高频项对应图像的细节

Page 47: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图像处理图像处理

东海海表面温度图NOAA12 2000.9.23 20:40

左图:原始图中图:低通( w=10)右图:高通( w=10)

Page 48: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图形窗口输出图形窗口输出

IDL 支持多种设备输出,并可以简单地在设备之间切换。 set_plot ,’option’: option=win|ps|printer ,大小写不敏感。 !d.name:当前设备名。 一般用法: cDevName=!d.name set_plot ,‘printer’ help ,/device set_plot ,cDevName 常用关键字: close_document:刷新输出缓冲区后关闭图形文档,用于从打印机排出打印页。 close_file:刷新输出缓冲区后关闭图形输出文件。 Filename:当输出为文件时地文件名,默认‘ idl.option’ landscape:横向输出 portrait:纵向输出,缺省值 xoffset:确定纵向模式下输出窗口左下角(横向模式下 ps和 printer算法不同) yoffset:确定纵向模式下输出窗口左下角(横向模式下 ps和 printer算法不同) xsize:确定输出窗口宽度 ysize :确定输出窗口长度 inches:以英寸为单位,缺省为厘米

Page 49: IDL  高级培训 基础篇

直接图形篇 - 直接图形篇 - 图形窗口输出图形窗口输出

ps 输出的一般方法: img=tvrd(true=1) set_plot ,‘ps’ device, filename=‘ .ps’ ,color=1 device ,xsize= ,ysize= ,xoffset= ,yoffset= tvscl, img ,/true device, /close_file set_plot ,‘win’

printer 输出的一般方法: ok=dialog_printersetup() img=tvrd(true=1) ratio=float(!d.y_vsize)/!d.x_vsize ( printer 设备不能自动保持纵横比) set_plot,'printer' device,get_page_size=spagesize spagesize=spagesize/[!d.x_px_cm,!d.x_px_cm] device ,xoffset= ,yoffset= tvscl ,img ,/true ,/centimeters ,xsize= ,ysize= *ratio device ,/close_document set_plot ,’win’

Page 50: IDL  高级培训 基础篇

IDL IDL 高级培训高级培训

应用程序构造篇应用程序构造篇

IDL IDL 高级培训高级培训

应用程序构造篇应用程序构造篇

Page 51: IDL  高级培训 基础篇

编程篇 -编程篇 -建立、管理应用程序建立、管理应用程序

IDL 有两种应用程序管理方法:主程序和工程 主程序:建立与程序名同名的 .pro 文件,编译执行。 pro test … end 在这种方式下,根据 IDL 的自动编译规则,所有被调用的子程序或者与主程序写入同一个文件并放置在主程序的上部;或者写成与子程序同名的 .pro 文件,存储在可搜索的路径下。(子程序指过程或函数)

工程:建立若干个 .pro 文件,每个文件不必与任何子程序同名。指定其中一个过程为主程序,该过程的名字作为工程执行时首先调用的过程(即 run command)。 在这种方式下,由于程序编写未必遵守 IDL 的自动编译规则,因此在运行前必须编译工程中所有的文件。

分发:将源程序编译为 .sav 文件。• 主程序方式,需手工编译、存储为 .sav 文件

.compile app_pro resolve_all save, /routines, app_pro ,app_sav

• 工程方式,设置工程属性为形成 .sav 文件,使用工程菜单项下的 build 选项即可。

Page 52: IDL  高级培训 基础篇

编程篇 -编程篇 -应用程序结构应用程序结构

XManger

WidgetCreationRoutine(TLB)

call xmanager

Event

Handler

Calling RoutineEvent structure

Only if TLB is destoryed

主程序

调用相关子程序

Page 53: IDL  高级培训 基础篇

编程篇 -编程篇 -主程序结构主程序结构

主程序的一般结构: pro app_pro compile_opt idl2 create top layout base(TLB) create gui base on TLB (initial application) realize TLB collect user information call xmanager [,/NO_BLOCK] end

initial application 该过程可以在主程序里进行。但更好的办法是编写单独的过程,用 TLB的notify_realize 关键字指定过程名,当 realize TLB 时执行。

/NO_BLOCK 使用该关键字,主程序运行后,命令行仍然可以使用,主程序自身仍可修改编译,有利于调试。

compile_opt idl2 改变默认编译选项, idl2 表示 defint32和 strictarr

Page 54: IDL  高级培训 基础篇

编程篇 -编程篇 - TLBTLB

TLB 的三种基本形式

standard TLB: tlb_id=widget_base( group_leader=group $ ,uname=’tlb‘ ,title=’idl app‘ ) 适用于一般的应用程序,可以单独运行或被调用。 group 可以不存在。

modal TLB: tlb_id=widget_base( group_leader=group ,/modal ,uname=’tlb‘ ,title=’modal app‘ ) 适用于对话框类的应用程序,通常不可以单独运行,只能被调用。 group 必须合法。调用该类程序后,调用者暂时挂起,直至该程序返回。

floating TLB: tlb_id=widget_base( group_leader=group ,/floating ,uname=’tlb‘ ,title=’floating app‘ ) 适用于任务优先类的应用程序,通常不可以单独运行,只能被调用。 group 必须合法。调用该类程序后,调用者可以继续运行。该程序总在最前面。

Page 55: IDL  高级培训 基础篇

编程篇 -编程篇 - GUIGUI 基本组件基本组件

容器组件: widget_base :任何 GUI 组件必须在某 BASE 组件上实现。一个 BASE 组件可以包含其它的 BASE。

GUI 组件: widget_draw :图形窗口,所有的图形、图像显示均在此实现 widget_label :标签,不可编辑的文本,可用于提示、说明 widget_button :按钮,分为 push button、 radio button和 checkbox。 可用于命令、单选以及多选 widget_text :文本框,可编辑的文本,可用于用户输入 widget_slider :滑动条,分为水平和垂直,可用于调整预设值 widget_listbox :列表框,用于项目选择 widget_droplist :下拉列表框 widget_table :表格,可编辑的二维数据

组件标识: 每一个组件创建时都会产生一个 id ,并且可以指定一个 uname 。这些都是以后检索、操作这个组件的标识。

TrueType 字体设置: draw :使用 device ,set_font=fnt_str ,/tt_font ,输出时使用 font=1 。通常在与用户交互时使用。 其它:使用 font=fnt_str 。通常在创建时使用

Page 56: IDL  高级培训 基础篇

编程篇 -编程篇 - GUIGUI 其他组件其他组件

Compound Widgets 组合组件是一组完备、自容、可重用的应用程序,使用时与基本组件大致相同,但它们是用 IDL 编写的。所有组合组件得名称都以 cw_ 开始。 组合组件包括一下几类:

• Animation (动画)• Color Manipulation(颜色操作)• Data Entry and Display(数据输入输出)• Image Manipulation(图像处理)• Orientation(定位操作)• User Interface(用户界面)

组合组件一般目的是扩充了相应的基本组件的功能。

Dialogs 对话框用于用户界面,可以象组件一样使用,但它不属于组件构造层次。对话框是modal 元素,当调用一个对话框时,其他界面元素暂时刮起直至对话框返回。 对话框包括以下几种:

• File and Directory Selection : DIALOG_PICKFILE• MessageDIALOG_MESSAGE• Printing : DIALOG_PRINTJOB 、 DIALOG_PRINTERSETUP

Page 57: IDL  高级培训 基础篇

编程篇 -编程篇 - GUIGUI 的构造层次及实现的构造层次及实现

TLB

base

base

base

base base

itemitem

item

item

GUI层次: Every GUI element is over BASE

GUI 实现:指 GUI 第一次在屏幕上显示 widget_control ,tlb ,/realize TLB实现后,所有层次关系属于 TLB 的组件均实现。可以使用 map=0 关键字使某些子层次暂不显示。

Page 58: IDL  高级培训 基础篇

编程篇 -编程篇 - xmanagerxmanager

Xmanager提供事件循环、监视并发送事件至事件处理程序,直至程序结束。

xmanager ,name ,widget_id ,/just_reg ,/no_block ,group_leader=widget_id ,event_handler=`event_pro’ ,cleanup=‘cleanup_pro’

name:创建 TLB的过程名widget_id: TLB的 idjust_reg:登记一个 TLB,但并不进入事件循环no_block:在程序运行期间仍然允许 IDL环境可以使用group_leader:指定上一层次的 widget_idevent_handler:指定事件处理程序。缺省为 name_event 语法: event_pro ,eventcleanup:指定程序退出时执行的程序。若指定,拥有最高优先级 语法: clenup_pro ,widget_id

程序运行了吗? Result = XREGISTERED( name [,/NO_SHOW] )

Page 59: IDL  高级培训 基础篇

编程篇 -编程篇 -事件结构事件结构

事件 用户在 GUI上的每一个‘认可的’ 操作都会产生一个事件, xmanager 将事件信息打包传给 IDL, IDL 将事件信息解读后打包成一个结构类型的数据,即事件结构,并把这个事件结构做为唯一的位置参数发送给事件处理程序。

事件结构 事件结构是一个命名结构。包括一个结构名、三个公共字段和一些个体字段。 { event_type ,id: ,top: ,handler , … } even_type :标识事件类型。 id :长整数,产生事件的标识符。 top :长整数, id 所表示的组件所在的 TLB。 handler :长整数,事件处理程序标识符。事实上,由于事件处理程序总与某一特定的组件相联系,该标识符就是组件标识符。 任何前三个字段定义与上述意义相同的命名字段,都可以认为是 IDL 的一个事件结构。

Page 60: IDL  高级培训 基础篇

编程篇 -编程篇 -事件处理事件处理

事件处理方式 当事件发生时, IDL 会从当前组件层次开始,逐层向上查找与该事件相关联的事件处理程序。 handler 字段记录该组件的标识。

TLB

A B

F

G

D EC

Event occurs here

Eventhandler TLB

A B

F

G

D EC

Event occurs here

Eventhandler

Eventhandler

{ , id: G ,top: A ,handler: A , … } { , id: G ,top: A ,handler: F , … }

Page 61: IDL  高级培训 基础篇

编程篇 -编程篇 -为为组件指定事件处理程序组件指定事件处理程序

为组件指定事件处理程序 1. 由 xmanager 指定的事件处理程序(通常是 TLB )处理所有事件。 2. 使用组件创建时的关键字 event_pro或 event_func 为每一个事件单独指定一个处理程序。 注意到: xmanager总会为其直接管理的组件(通常是 TLB )指定一个事件处理程序(而且是一个过程),因此,该组件的事件处理程序不能用 event_pro或 event_func 指定。

Page 62: IDL  高级培训 基础篇

编程篇 -编程篇 -事件处理程序事件处理程序

事件处理程序 事件处理程序可以是过程或函数。 过程:事件处理完毕后被中止,程序等待下一个事件。 函数:由于函数有返回值,如果返回值是一个结构,又恰恰符合 IDL事件结构标准,则IDL 会将这个返回值做为一个事件处理。(此乃伪事件,可以用来‘欺骗’ IDL) 事件处理程序接受并且只接受一个位置参数, event

事件处理程序基本结构( TLB 结构)pro app_pro_event ,event uname=widget_info(event.id ,/uname) case uname of ‘TLB_uname’: begin if tag_names(event ,/structure_name) eq 'widget_kill_request' ) then begin … … (some cleanup work) widget_control ,event.top ,/destroy return endif end ‘uname1’: begin … … (do something) end ‘uname2’: uname2_event_pro ,event (如果已经为 uname2 组件指定了该事件处理程序,则该行略去) else: endcaseend

Page 63: IDL  高级培训 基础篇

编程篇 -编程篇 -数据传递数据传递

注意到,对于一个应用程序, IDL 所做的只是“捕获”各种组件事件,将事件结构做为唯一的位置参数传递给事件处理程序,因此,无法通过通常的参数传递的方法交换数据。 IDL提供了 user_value ,通过为 widget_id“绑定” user_value 的方法传递数据。

方法: widget_control ,widget_id ,set_uvalue=value [,/NO_COPY] 将用户数据绑定到一个组件 widget_control ,widget_id ,get_uvalue=value [,/NO_COPY] 从一个组件获取用户数据

为 TLB绑定用户数据 一般地,在主程序中, xmanager 之前,会创建一个结构,该结构的各个字段是用户在整个应用程序运行期间所需要相互传递的数据。然后把这个结构绑定给 TLB。 sState={ … } widget_control ,TLB_id ,set_uvalue=sState 当事件发生时, IDL 会把事件结构传递给事件处理程序,事件处理程序可以通过事件结构的 top 字段来获得用户数据。 Widget_control ,event.top ,get_uvalue=sState 注意到,用户数据的传递是值引用,这就意味着一旦在事件处理程序里改变了用户数据的值,必须把改变了值的用户数据传回给 top才会使改变了的值在其它事件处理程序里生效。 Widget_control ,event.top ,set_uvalue=sState

Page 64: IDL  高级培训 基础篇

编程篇 -编程篇 -数据传递数据传递

有问题发生 事实上, sState 是一个局部变量,因此当绑定给 TLB_ID 时,是 copy了一份到全局内存。而当事件处理程序获得用户数据时,又是从全局内存中 copy 一份到该事件处理程序的局部变量中。于是,一份数据就有了 3份 copy。 指定 /NO_COPY 关键字,就只使用一份。

烦恼: ( 1) copy 一事会给我们带来烦恼。因为一旦 no_copy ,则当前的用户数据变量就不再有效。这意味着返回用户数据的命令应该是事件处理程序的最后一行,显然这是不现实的。 ( 2 )事实上,必须返回用户数据才会使修改有效这件事也会给我们带来烦恼,这要求我们必须时刻保持警惕!是不是精神会有点紧张? :)

Page 65: IDL  高级培训 基础篇

编程篇 -编程篇 -数据传递数据传递

解决的方法 用一个指针变量可以解决这个问题! (我们不必等 IDL把用户数据 copy 到全局内存,我们有能力自己干!)

TLB: sState={ … } pState=ptr_new(sState ,/no_copy) widget_control ,TLB_id ,set_uvalue=pState EH: widget_control ,ebent.top ,get_uvalue=pState 这时, *pState 就是 sState

有了指针,我们方便多了! ( 1 )任何修改立即生效,免去返回的烦恼。 ( 2 )由于指针仅仅是“指针”,我们可以在 sState里也设置一些必要的指针,比如数组指针,这样又可以免去结构数据不能更改数组维数的烦恼。

Page 66: IDL  高级培训 基础篇

编程篇 -编程篇 -数据传递数据传递

没有免费的午餐! 指针仍然有一个小小的问题。必须在 cleanup里将指针释放,否则会引起内存泄漏。

最后 没有证据证明传递 sState 和 pState 哪一个更好。 由于用户数据是值传递,这就带给我们可以在愿意的时候随便传递一个“什么”给 TLB的便利。这时,使用 pState 未必就比使用 sState更方便。你需要 ptr_free() ! 再者,太多的 * 仍然带来麻烦。

Page 67: IDL  高级培训 基础篇

编程篇 -编程篇 -数据传递数据传递

widget_list 和 widget_droplist 的 uvalue 通常我们在 list 里放置的是带有说明性的字符串数组,然而一旦进入事件循环我们就再也不会得到这个数组,我们只能得到这个数组的 index 值,即数组下标。 通过绑定字符串数组到 list_id 就可以在需要的时候仍然得到特定的字符串

TLB: widget_control ,list.id ,set_value = aStr widget_control ,list.id ,set_uvalue = aStr

EH: index = widget_info( list_id ,/droplist_select ) OR index = widget_info( list_id ,/list_select )

widget_control ,list.id ,get_uvalue = aStr string = aStr[index]

Page 68: IDL  高级培训 基础篇

编程篇 -编程篇 -操作操作组件组件

操作组件分为两个部分:获取组件属性和设置组件属性 widget_info函数用来获取组件属性, widget_control函数用来设置组件属性

result=widget_info(widget_id , …… ) general: ,/uname ,find_by_uname=string ,/valid_id ,/geometry widget_droplist: ,/droplist_select widget_list: ,/list_select

widget_control ,widget_id , …… general: ,/hourglass ( no widget_id ) ,/realize ,map=0|1 ,sensitive=0|1 ,/destroy ,get_uvalue= value ,set_uvalue= value ,send_event={…} widget_base: ,cancel_button=button_id (for modal) ,/iconify widget_draw: ,draw_xsize=int ,draw_ysize=int ,get_draw_view=var ,set_draw_view=[x, y] widget_droplist: ,set_droplist_select=integer ,set_value=value widget_list: ,set_list_select=value ,set_value=value widget_slider: ,set_slider_max=value ,set_slider_min=value widget_text: ,editable=0|1

,get_value=var: except base 、 droplist 、 listbox ,set_value=var: except base 、 draw

Page 69: IDL  高级培训 基础篇

编程篇 -编程篇 - drawdraw 事件事件

TLB: wDraw=widget_draw( tlb_id ,uname=‘wDraw’ ,/button_events ,/motion_events ,/viewport_events ,/expose_events ,retain=0|1|2 ,…)EH: widget_info(event.id ,/uname)=‘wDraw’ tag_names(event, /structure_name)=‘WIDGET_DRAW’

event={ WIDGET_DRAW ,ID: 0L ,TOP: OL ,HANDLER: 0L ,TYPE: 0 ,X: 0L ,Y: 0L ,PRESS: 0B ,RELEASE: 0B ,CLICKS :0 , MODIFIERS:0L} event.TYPE: 0 mouse press 1 mouse release 2 mouse motion 3 viewport moved (scrollbars) 4 visibility changed (exposed) event.X & event.Y mouse coordinate ,device event.PRESS for mouse press left 1 mouse left event.RELEASE for mouse release 2 mouse middle 4 mouse right event.CLICKS 1 mouse clicks 2 mouse double clicks event.MODIFIERS keyboard modifier key state when mouse event 1 shift 2 control 4 capslock 8 alt(win)

Page 70: IDL  高级培训 基础篇

编程篇 -编程篇 - table_resizetable_resize 事件事件

改变窗口大小,一般来说,对 draw 的影响最大, draw应该随窗口的改变而改变, draw 中的内容也应该随之改变。

TLB: tlb=widget_base( uname=‘tlb’ ,/tlb_size_events ,… )EH: wDraw=widget_info(event.top find_by_uname=‘wDraw’) ( get new xsize ,ysize of draw ) widget_control ,wDraw ,draw_xsize=new_xsize widget_control ,wDraw ,draw_ysize=new_ysize ( refresh work … )

when table resizedtable resized event={WIDGET_BASE ,ID: 0L ,TOP: 0L ,HANDLER: 0L ,X: 0L ,Y: 0L } event.x current xsize of WIDGET_BASE event.y current ysize of WIDGET_BASE 显然, event.x和 event.y并不能直接用于 draw的 draw_xsize和 draw_ysize。

Page 71: IDL  高级培训 基础篇

编程篇 -编程篇 - table_resizetable_resize 事件事件

方法: sGeom=widget_info(widget_id ,/geometry) 返回一个描述 widget_id的相关坐标信息的结构数据 ,利用这些数据就可以计算出新的 draw的 xsize和 ysize

sGeom = { WIDGET_GEOMETRY ,XOFFSET:0.0 ,YOFFSET:0.0 ,XSIZE:0.0 ,YSIZE:0.0 ,SCR_XSIZE:0.0 ,SCR_YSIZE:0.0, ,DRAW_XSIZE:0.0 ,DRAW_YSIZE:0.0, ,MARGIN:0.0 ,XPAD:0.0 ,YPAD:0.0 ,SPACE:0.0 }

Page 72: IDL  高级培训 基础篇

编程篇 -编程篇 - timertimer 事件事件

一个 timer事件,就是一个定时器,它按照设定的时间间隔自动产生WIDGET_TIMER事件,适当地设置 timer事件处理程序,就可以让 IDL 自动地为我们工作了。 timer事件可以绑定在任何合法的 widget_id 上,只要你能用事件处理程序关联它。

pro timer_example_event, event widget_control, event.id, get_uvalue=uval if (tag_names(event, /structure_name) eq 'WIDGET_TIMER') then begin print, 'timer fired' widget_control, event.top, timer=2 end case uval of 'timer' : widget_control, event.top, timer=2 'exit' : widget_control, event.top, /destroy else: endcaseend pro timer_example base = widget_base(/column, uvalue='base') b1 = widget_button(base, value='fire event', uvalue='timer') b2 = widget_button(base, value='exit', uvalue='exit') widget_control, base, /realize xmanager, 'timer_example', base, /no_blockend

Page 73: IDL  高级培训 基础篇

IDL IDL 高级培训高级培训

对象图形篇对象图形篇

IDL IDL 高级培训高级培训

对象图形篇对象图形篇

Page 74: IDL  高级培训 基础篇

对象图形篇 -概述对象图形篇 -概述

Basic

对象图形是 IDL引入面向对象编程概念后出现的。 面向对象编程的基础是对象类的使用。对象类允许程序员将数据和方法封装成为一个包,称之为对象。一个对象类可以反复使用而每次使用都封装不同的数据。 IDL里对象类的实现主要是用一组预建的对象类构成对象图形系统。对象图形系统是一个 IDL内建的对象类库,可用于创建场景。 对象类也可以用 IDL编写以实现程序员自己的要求。程序员可以在 IDL环境中用传统的过程和函数的编写方法加上对象特性编写自己的对象模块。

Page 75: IDL  高级培训 基础篇

对象图形篇 -概述对象图形篇 -概述

Direct Graphics vs. Object Graphics

Direct Graphics:• 创建 2D图形有优秀表现,如: X-Y plot ,contours ,mapping等• 可以在命令行使用,简单、快速• 图形创建命令通常连同坐标系一起创建• 图形生成时,针对当前图形设备• 图形生成并输出后,不可修改或再用。如果需要修改或向其他设备输出,必须重新输出。• 后输出的项目总在先输出的项目的“上面”

Object Graphics:• 硬件加速的 3D场景显示,灵活,交互性强• 对象图形系统主要以程序方式使用• 图形对象是功能性封装的。即独立的对象包含自己的方法,操作自己的数据• 图形输出没有当前设备的概念,图形对象为层次结构,并使用输出目标概念• 图形创建后,数据及其属性驻留内存,便于修改,反复使用• 对象图形驻留内存,因此在退出时要释放内存,避免内存泄漏

Page 76: IDL  高级培训 基础篇

对象图形篇 -内容对象图形篇 -内容

LIVE_TOOLS 工具集• 一组预建的 IDL 组件应用程序,使用 IDL 的对象图形系统,可以构造高质量的可交互的场景• 每一个 LIVE 工具既可以做为单独的应用程序使用,也可以做为组件用于编程• LIVE 工具可以既可以使用鼠标操纵,也可以编程操纵

图形对象系统( IDLxxYyyy)• 一组预建的对象类,可用于构造高质量的 2D、 3D场景• 使用最新的图形硬件加速技术• 采用灵活的结构,可以多场景输出• 使用 IDL 的过程或函数构造图形对象的层次结构• 图形创建后,场景可以很容易操纵、修改

创建自己的图形对象类 利用 IDL 的面向对象编程概念和方法,程序员可以创建自己的对象类

Page 77: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 - LIVE_TOOLSLIVE_TOOLS

LIVE_PLOT plotLIVE_CONTOUR contourLIVE_SURFACE surfaceLIVE_IMAGE imageLIVE_OPLOT insert dataLIVE_LINE add lineLIVE_RECT add rectangleLIVE_TEXT add textLIVE_STYLE creation of common characteristicsLIVE_EXPORT export to graphics file formatsLIVE_PRINT printLIVE_INFO get propertyLIVE_CONTROL set propertyLIVE_LOAD load LIVE tools into IDL memoryLIVE_DESTROY destroy elements of LIVE tools

LIVE_TOOLS共有 15 个例程,包括创建图形、图形文件输出、打印输出、标注以及控制。

Page 78: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 - LIVE_TOOLSLIVE_TOOLS

Stand-Alone LIVE Tools LIVE_PLOT ,LIVE_CONTOUR ,LIVE_SURFACE ,LIVE_IMAGE 完整的 IDL 组件例程,窗口调整、属性设置均可通过鼠标操纵。可以从命令行直接运行。

sincurve=sin(findgen(360)*!dtor) live_plot ,sincurve

可以通过调用时设置关键字参数,调整交互界面 live_plot ,sincurve ,/no_toolbar ,/no_status

LIVE_OPLOT 向已经创建的 LIVE窗口中叠加,只有适合已有坐标系的数据才会加入

sincurve=sin(findgen(360)*!dtor) live_plot ,sincurve for i=0.9 ,0.1 ,-0.1 do live_oplot ,sincurve*I

Page 79: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 - LIVE_TOOLSLIVE_TOOLS

Multiple LIVE Tools and LIVE_OPLOT 完当同时启动多个 LIVE 时, LIVE_OPLOT就不知道应该向哪一个窗口叠加。

REFERENCE_OUT=ref 返回窗口信息,结构数据。其中 win 字段即为窗口标识。WINDOW_IN=ref.win 指定叠加的窗口

sincurve=sin(findgen(360)*!dtor) live_plot ,sincurve , reference_out=ref for i=0.9 ,0.1 ,-0.1 do live_oplot ,sincurve*i ,window_in=ref.win

x=[1.2,2.0,7.7,4.5,23.4] y=3.0*x+2.0 new_x=[3.9,6.9,12.0,15.6] new_y=interpol(x,y,new_x) pProps={color:'Light Blue',linestyle:2,symbol_size:0.05,symbol_type:2} pStyle = live_style('plot', GRAPHIC_PROPERTIES = pProps)

live_plot, y, INDEPENDENT = x, REFERENCE_OUT = refout2, STYLE = pStyle live_oplot, new_y, INDEPENDENT = new_x, WINDOW_IN = refout2.win

Page 80: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 - LIVE_TOOLSLIVE_TOOLS

LIVE_STYLE('contour' | 'image' | 'plot' | 'surface’ , … ) 设置 LIVE 的窗口风格。可以创建一个包括所有输出窗口的图形属性的结构数据,然后传给所有准备创建的 LIVE。 IDL 的灵活的结构数据的特点使得每一个 LIVE 只保留与之相关的字段值并修改之。

a = findgen(40) a = sin(a/5) / exp(a/50) wave = a # a

gp = {bottom:'Blue', color:'Brown', shading:1, style:2} surfstyle = live_style('surface', GRAPHIC_PROPERTIES = gp) live_surface, wave, STYLE = surfstyle

Page 81: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 - LIVE_TOOLSLIVE_TOOLS

Multiple Plots in One Window 通过设置图形在窗口中的位置和大小,可以实现在一个窗口中同时显示多个图形。

LOCATION :图形在窗口中的位置, normal坐标DIMENSION :图形显示的大小, normal坐标

a = findgen(40) a = sin(a/5) / exp(a/50) wave = a # a

live_image, wave, REFERENCE_OUT = refout, $ LOCATION = [0.0,0.5], DIMENSIONS = [1.0, 0.5] live_contour, wave, WINDOW_IN = refout.win, $ LOCATION = [0.0,0.0], DIMENSIONS = [0.5,0.5] live_surface, wave, WINDOW_IN = refout.win, $ LOCATION = [0.5,0.0], DIMENSIONS = [0.5,0.5]

Page 82: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 - LIVE_TOOLSLIVE_TOOLS

LIVE Annotations LIVE_TEXT ,LIVE_RECT ,LIVE_LINE 这些工具可以为一个已创建的 LIVE 在窗口内的任意位置添加标注。并可以在添加以后仍然可以通过鼠标操纵修改。 normal坐标。

data = alog10(findgen(100)+1) live_plot, data, REFERENCE_OUT = refout

live_text, '对数曲线 ', WINDOW_IN = refout.win, $ LOCATION = [.5, .9], ALIGNMENT = 0.5, $ FONTNAME = ’隶书 ', FONTSIZE = 18, COLOR = 'Blue'

live_rect, WINDOW_IN = refout.win, COLOR = 'Light Green’, $ LOCATION = [.2, .87], DIMENSION = [.6, .1] live_line, WINDOW_IN = refout.win, $ LOCATION = [.2,.05], DIMENSION = [.6,0], $ /ARROW_START, /ARROW_END

Page 83: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 - LIVE_TOOLSLIVE_TOOLS

LIVE_DESTROY ,/ENVIRONMENT 关闭所有 LIVE ,释放所有与之相关的内存。

LIVE_DESTROY ,WINDOW_IN=ref.win , … 关闭 ref.win 指定的 LIVE 或其中的图形元素。灵活使用 REFERENCE_OUT和WINDOW_IN ,就可以去掉窗口内的指定图形元素。

data = alog10(findgen(100)+1)live_plot, data, REFERENCE_OUT = refoutlive_text, ’对数曲线 ', LOCATION = [.5, .9], ALIGNMENT = 0.5, $ FONTNAME = ‘隶书 ', FONTSIZE = 18, COLOR = 'Blue', $ WINDOW_IN = refout.winlive_rect, LOCATION = [.2, .87], DIMENSION = [.6, .1], $ COLOR = 'Light Green', WINDOW_IN = refout.winlive_line, LOCATION = [.2,.05], DIMENSION = [.6,0], $ WINDOW_IN = refout.win, /ARROW_START, /ARROW_END; add a line that will be destroyedlive_line, LOCATION = [.5,.5], DIMENSIONS = [0.0, .25], $ WINDOW_IN = refout.win, REFERENCE_OUT = linerefoutwait, 3live_destroy, linerefout.graphic, WINDOW_IN = refout.winwait, 3live_destroy, refout.graphicwait, 3live_destroy, WINDOW_IN = refout.win

Page 84: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 - LIVE_TOOLSLIVE_TOOLS

Embedded LIVE Tools 除可以做为独立的例程使用之外, LIVE 工具可以嵌入到 IDL 组件程序中,不仅保持原有的功能,还与 IDL 的其他组件共同使用,

PARENT_BASE LIVE_TOOLS ,PARENT_BASE=base_id 在应用程序中使用 LIVE ,通常为 LIVE 创建一个 BASE 将其嵌入。

Event Handling 在 widget 的用户数据里,通常必须保存 LIVE的 ref ,这样在整个程序运行期间就可以根据事件的需求对 LIVE进行控制。

LIVE_CONTROL 在事件处理程序中,所有需要对 LIVE进行控制的请求都通过LIVE_CONTROL实现。其功能类似 widget_control。 特别注意:任何时刻需要更新 LIVE 的数据时,只能用一个与初始化该 LIVE时的数据变量同名的变量来传递数据。

LIVE_INFO 用于获取指定的 LIVE 的属性,返回一个结构数据。功能类似 widget_info。

LIVE_DESTROY 当 widget 结束时,必须将 LIVE 释放。

Page 85: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

概述 IDL 的对象图形系统是一个内建的对象类库,通过选择适当的内建对象、构造层次结构来创建图形场景。层次结构描述各种图形元素在 3D 中的层次以及各层之间的关系。 IDL 的图形对象类命名方式为 IDLgrYyyy ,其中 Yyyy 标识类的名称。

IDL 的图形对象类如下: Container Objects : IDLgrScene, IDLgrView, IDLgrModel IDLgrViewgroup ,IDL_Container Graphical Atom Objects : IDLgrPlot, IDLgrPolyline, IDLgrPloygon, IDLgrContour, IDLgrSurface, IDLgrVolume, IDLgrImage, IDLgrAxis ,IDLgrText ,IDLgrLight Destination Objects : IDLgrWindow, IDLgrPrinter, IDLgrBuffer, IDLgrClipboard, IDLgrVRML Attrigute : (outside the hierarchy, be used when rendering graphic objects) IDLgrFont, IDLgrPalette, IDLgrSymbol Helper : (outside the hierarchy, alter data in useful ways or provide other services) IDLgrTessalator,Trackball Composite Objects : IDLgrColor,IDLgrLegend

Page 86: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

The Object Graphics Hierarchy ,对象图形的层次结构

Scene

View

Model

grAtom grAtom grAtom

Use if multi view

Can root hierarchy

Contain Graphic Atoms

Graphic Atom objects

Page 87: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

Create Hierarchy 对象图形场景必须以层次结构创建。基本的层次结构创建如下: 1. Creation of an IDLgrView object 2. Creation of an IDLgrModel object 3. Creation of a Graphical Atom 4. Add the Model to the View 5. Add Graphical Atom(s) to the Model 6. Creating a Destination Object 7. Drawing the View to the Destination Object

最简单的对象图形例程: oView=obj_new('IDLgrView', VIEWPLANE_RECT=[-10,-2,380,4]) oModel=obj_new('IDLgrModel') oPlot=obj_new('IDLgrSurface',sin(findgen(360)*!DtoR),THICK=3) oView->Add, oModel oModel->Add, oPlot oWindow=obj_new('IDLgrWindow', TITLE='The Simplest OG Plot') oWindow->Draw, oView

Page 88: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

将 IDLgrView或 IDLgrScenen嵌入 IDL的Widget 程序 在建立了对象图形层次结构之后,可以将它输出到一个合法的目标类对象,比如一个 Window。Widget_draw就可以成为一个这样的 Window。

基本方法 tlb=widget_base() draw=widget_draw(tlb ,uname='draw' ,GRAPHICS_LEVEL=2 $ ,xsize=512 ,ysize=512 ,retain=2) widget_control ,tlb ,/realize

widget_control ,draw ,get_value=oWin oWin->draw ,oView

注意: GRAPHICS_LEVEL=2和 retain=2

Page 89: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

图形对象操作概述

对象创建:任何一个对象必须从一个对象类中创建 oOBJ=Obj_new(‘IDLgrYyyyy’)

对象属性:每个对象都有唯一的一组属性描述对象的特点。可以在创建对象时指定,也可以在创建后修改。 oOBJ=Obj_new(‘IDLgrYyyyy’ ,color=[255,0,0] )

对象方法:每个对象都有一组自己的内建方法,用于操纵数据和属性。 oObj->GetProperty 获取对象的属性 oObj->SetProperty 设置对象的属性

oObj->add oObj->remove

对象注销:对象是驻留内存的,因此当一个图形对象不再使用时,应该注销,从内存中释放。在应用程序的开发中尤其重要。 obj_destroy ,oOBJ

Page 90: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

图形坐标 对象图形系统中的图形坐标是通过设置 IDLgrView 的属性实现的。

obj=OBJ_NEW('IDLgrView’ ,UNITS=0|1|2|3 ,DIMENSIONS=[width,height] ,LOCATION=[x, y] ,VIEWPLANE_RECT=[x,y,width,height] ,ZCLIP=[near,far] )

UNITS :设置坐标系 0:device(default) ,1:inches ,2:centimeters ,3:normal

VIEWPLANE_RECT和 ZCLIP :设置坐标系范围 当使用 normal坐标系时:

• 3个坐标轴的默认范围均为 -1~1• 应对该 view 下的 grAtom(s) 的数据进行坐标变换

DIMENSIONS和 LOCATION :设置图形的大小和位置

x

y

z

Page 91: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

图形变换 图形变换指对图形的旋转、平移和缩放。 对象图形系统中的图形变换是通过设置 IDLgrModel 的变换矩阵实现的。 IDLgrModel一经创建,便产生一个 4×4 的变换矩阵,图形的变换操作是通过重新设置这个矩阵的值实现的。

设置方法: 1. 通过 IDLgrModel的 rotate、 translate和 scale 方法设置。 2. 通过 IDLgrModel的 transform 属性设置。

恢复初始状态: oModel-> reset

Page 92: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

图形变换-旋转: 1. oModel-> Rotate ,[x,y,z] ,Angle

2. oModel-> GetProperty ,transform= t oModel-> SetProperty ,transform= t * newT

Rx = [[1.0, 0.0, 0.0, 0.0], $ [0.0, cosa, -sina, 0.0], $ [0.0, sina, cosa, 0.0], $ [0.0, 0.0, 0.0, 1.0]] Ry = [[ cosa, 0.0, sina, 0.0], $ [ 0.0, 1.0, 0.0, 0.0], $ [-sina, 0.0, cosa, 0.0], $ [ 0.0, 0.0, 0.0, 1.0]] Rz = [[cosa, -sina, 0.0, 0.0], $ [sina, cosa, 0.0, 0.0], $ [ 0.0, 0.0, 1.0, 0.0], $ [ 0.0, 0.0, 0.0, 1.0]]

Page 93: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

图形变换-平移: 1. oModel-> Translate, dx, dy, dz

2. oModel-> GetProperty ,transform= t oModel-> SetProperty ,transform= t * newT

transT = [[1.0, 0.0, 0.0, dx], $ [0.0, 1.0, 0.0, dy], $ [0.0, 0.0, 1.0, dz], $ [0.0, 0.0, 0.0, 1.0]]

Page 94: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

图形变换-比例缩放: 1. oModel-> Scale ,sx ,sy ,sz

2. oModel-> GetProperty ,transform= t oModel-> SetProperty ,transform= t * newT scaleT = [[ sx, 0.0, 0.0, 0.0], $ [0.0, sy, 0.0, 0.0], $ [0.0, 0.0, sz, 0.0], $ [0.0, 0.0, 0.0, 1.0]]

Page 95: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

grAtom 中数据的 normal 坐标转换 当 IDLgrView 使用 normal坐标时,应该对 grAtom(s) 中的数据进行坐标转换以适应新的坐标系。

oAtom=obj_new(‘IDLgrYyyy’ ,data )

Obj[i]->GetProperty, XRANGE=xr, YRANGE=yr, ZRANGE=zrxc = [ -xr[0]/(xr[1]=xr[0]), 1/(xr[1]-xr[0]) ]yc = [ -yr[0]/(yr[1]=yr[0]), 1/(yr[1]-yr[0]) ]yc = [ -zr[0]/(zr[1]=zr[0]), 1/(zr[1]-zr[0]) ]Obj[i]->SetProperty, XCOORD_CONV=xc, YCOORD_CONV=yc, ZCOORD_CONV=zc

事实上,在 grAtom内部的计算方法为: normalized=so+s1*data

上述公式的转换结果为为 0~ 1 ,如果 IDLgrView 中的坐标不是 0~ 1 ,则可以根据需要对 xc[0], yc[0], zc[0]进行计算,可以使图形在适当的位置显示。 如: data 的值域为 0~ 1 ,坐标为 -1~ 1 ,则 xc[0]=xc[0]-0.5 即可。

Page 96: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

Trackball Object 真正的交互式图形显示必须能让用户使用鼠标来操纵图形。

obj=OBJ_NEW('TrackBall’ ,Center ,Radius ,AXIS=0|1|2 )其中: center 为鼠标作用区域的中心点、 radius 为鼠标作用区域的半径,均为 device坐标。 axis 标识旋转轴, 0 , 1 , 2分别对应 x, y, z轴,默认 2 。注意:( 1) TrackBall为 Helper 类,既无父类也无子类。因此,不能加入到任何一种图形对象类,通常只做为 widget 的用户数据传递。 ( 2) TrackBall 的事件一般只通过 widget 的事件处理程序处理。

TrackBall事件处理一般方法:TLB: oTrack=obj_new('Trackball', [200,200], 200)EH: widget_control ,event.top ,get_uvalue=pState bHaveXform=(*pState).oTrack->Update(event,TRANSFORM=TrackXform) if (bHaveXform) then begin (*pState).oModel->GetProperty,TRANSFORM=ModelXform (*pState).oModel->SetProperty,TRANSFORM=ModelXform#TrackXform (*pState).oWindow->Draw, (*pState).oView endif

Page 97: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

Light Object 光源是 IDL图形对象 grAtom 类之一,它可以加入到对象图形的层次结构中,从而可以随对象图形的变换而变换(如:旋转、平移和缩放)。 IDL默认为环绕光,这会使 3D图形看起来象 2D图形一样。通过设置光源对象的属性,可以看到真正的 3D图形。

obj=OBJ_NEW(’IDLgrLight’ ,TYPE=0|1|2|3 ,LOCATION=[x,y,z],COLOR=[r,g,b])其中: TYPE 为光源类型。 0 为环绕光, 1 为点光源, 2 为平行光, 3 为聚光灯。 LOCATION 为光源位置; COLOR 为光源颜色。

多光源 由于光源可以随对象图形变换,因此为了从各个角度都能清楚地看到图形,就必须设置多个光源。一个 IDLgrView里最多可以放置 8 个光源。

让光源停在特定的位置 单独创建一个包含 IDLgrLight的 IDLgrModel ,就可以控制它的动作。

Page 98: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

Color Palettes Object 颜色的使用总是一件麻烦的事,在对象图形系统中,这个问题得到了较好的解决。 在对象图形系统中,无论以何种方式加载颜色表, IDL总是把颜色表的r, g, b 值拷贝到目标对象的颜色表中中。因此,索引表方式或真彩表方式的差别只是颜色的检索方式的差别,都是静态颜色模式,不会出现动态颜色模式。

创建颜色模板对象的两种方法: (1) obj=OBJ_NEW('IDLgrPalette', aRed, aGreen, aBlue) (2) obj=OBJ_NEW('IDLgrPalette') obj->loadct ,33注意:( 1) IDLgrPalette 不是 grAtom 类,因此不能加入到 IDLgrModel里。它只能用于目标类对象或用于 grAtom 类的 PALETTE 属性。(如 IDLgrImage) ( 2 )注意目标类对象的 color_model。

Page 99: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

Text and Font Objects 对图形输出而言,文本标注从来都是基本要求之一。 IDL提供高质量、可伸缩的文本用于输出。这些标注可以象图形一起加入层次结构,从而可以和其他图形一起重写、旋转、平移等。当然,也可以选择‘ ONGLASS’ ,这样你总可以在屏幕上看见它们。

IDLgrText oText=obj_new('IDLgrText', string ,FONT=oFont ,/ONGLASS $ ,LOCATION=[-1,0,0],COLOR=[0,255,0] $ ,ALIGNMENT=0.5 ,vertical_alignment=0.5) 缺省设置:左对齐,与 x轴平行,写在原点。 FONT 属性设置字体,但该字体必须是 IDLgrFont 对象。

IDLgrFont oFont = obj_new('IDLgrFont', ' 隶书 ', SIZE=36 ) 可以使用中文 TrueType 字体

Page 100: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

Outputting Objects 对象图形系统同样支持多种目标类输出,包括: printer ,图形文件等。

1. 输出到打印机 打印机是一个目标对象类,输出的一般方法如下:

oPrinter=Obj_New('IDLgrPrinter',/LANDSCAPE,PRINT_QUALITY=3) status=dialog_printersetup(oPrinter) if status eq 0 then return

oPrinter->Draw, oView ;suppose we have create a view oPrinter->NewDocument ;ouput and finish print job

2. 输出到图形文件 抓取当前 IDLgrWindow 的内容,输出到图形文件

;suppose we have create a window oWindowImage=oWindow->Read() ; Get the data from the image oWindowImage->GetProperty, DATA=img write_jpeg, 'og_out.jpg', img, TRUE = 1

Page 101: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -对象图形类(对象图形类( IDLgrYyyyIDLgrYyyy))

Images and Texture Mapping 将一幅地形图( image )覆盖在由高程数据形成的曲面( surface )上,是很有实用价值的。 IDLgrSurface和 IDLgrPolygon都具有将一幅地形图与高程数据曲面适当地组合的能力。

oImage=obj_new(‘ILDgrImage’ ,data )oSurface=obj_new(‘IDLgrSurface’ ,data ,texture_map=oImage )

Page 102: IDL  高级培训 基础篇

对象图形篇 -对象图形篇 -创建自己的图形对象类创建自己的图形对象类

在 IDL 引入了面向对象设计思想后,程序员使用 IDL 创建自己的图形对象类成为可能。

创建新的对象类的步骤 1. 为类命名 每当创建一个类对象时, IDL总是用对象类的名标识,因此类名必须唯一。 2. 定义类的属性( data) 一个对象的所有必要的信息必须在类的数据部分适当地定义。 对象类的数据定义使用 IDL 的命名结构,结构的名就是类名,并且使用objname__define.pro 存储。 3. 定义类的行为( methods) 一个对象类的行为通常称为方法,使用 IDL 的过程和函数定义。不同点在于命名和数据传递。 命名: objname::methodname 数据传递:自动 方法的定义既可以与数据定义使用一个文件;也可以为每一个方法单独使用一个文件,文件命名必须为 objname__method.pro

实例分析: imageobj__define.pro

Page 103: IDL  高级培训 基础篇

IDL IDL 高级培训高级培训

外部接口篇外部接口篇

IDL IDL 高级培训高级培训

外部接口篇外部接口篇

Page 104: IDL  高级培训 基础篇

接口篇 -接口篇 -概述概述

IDL提供了多种与外部语言混合编程接口工具

• spawn• IDLDrawWidget ActiveX control (Windows) • AppleScript (Mac)• Remote Procedure Calls (RPCs) (UNIX)• CALL_EXTERNAL • Callable IDL• Adding System Routines LINKIMAGE and Dynamically Loadable Module (DLM)

• ODBC

Page 105: IDL  高级培训 基础篇

接口篇 -接口篇 - spawnspawn

IDL 与外部接口工具中最简便地一种

spawn ,command ,result=var ,errresult=var ,/hide ,/nowait ,/noshell ,/log_output ,/null_stdin ,/stderr

(1) Windows 下环境下相当与在执行一个 DOS 命令,但无法返回信息。(2) 无选项时,弹出一个 DOS窗口(3) nowait ,不选,在程序中调用 spawn 时,直至命令完成才执行 spawn 的下一句。(4) hide ,不选,在程序中调用 spawn 时,会弹出一个 DOS窗口显示外部命令的执行情况。 选中,则将 DOS窗口最小化。(对 DOS 程序有用)(5) noshell ,不选,在程序中调用 spawn 时,会通过 DOS 命令行执行。 选中,则不经过命令行,直接运行。(对 windows 程序有用)

Page 106: IDL  高级培训 基础篇

接口篇 -接口篇 - Call_external

以共享库方式通过目标码进行传递,可调用任何语言的代码 (如 c和 Fortran) ,适合任何操作平台。

基本格式 result = CALL_EXTERNAL( Image ,Entry ,… ) image:共享库( Windows平台: DLL, UNIX平台: so) entry :调用名( Windows平台:函数)

缺点:数据在传递时数据大小和类型都必须已知,且不能传递虚拟变量。

Page 107: IDL  高级培训 基础篇

接口篇 -接口篇 - ActiveX

IDL提供了 windows平台下标准的 ActiveX 控件,使得我们可以从任意一种支持ActiveX嵌入的语言中使用 IDL 。只要遵守参数传递标准, IDL 的编程与在 IDL 环境下没有区别。 在不想放弃 IDL 的前提下,也许是 Windows平台下开发应用系统的最好的办法之一。

环境 \windows\system32\idldrawx2.ocx 需要 IDL支持。

以 Vb 调用 IDL 为例• 界面由 VB 设计,触发事件可由 VB或 IDL 控制。• 控件初始化• IDL 程序初始化

Page 108: IDL  高级培训 基础篇

接口篇 -接口篇 - ODBC

信息技术的发展,终于到了这样一个阶段: Everything is Over Database ! ,看来,不支持数据库是不行了。 IDL提供了支持 ODBC 的接口, DataMiner ,和完整的 Intersolv ODBC驱动,支持几乎所有的主流数据库系统。通过 DataMiner既可以使用标准 SQL 也可以使用 DataMiner的API 工具集对数据库操作而不必知道 SQL。

IDL DataMiner 的基本功能• Connect to a database management system (DBMS)• Query data from a DBMS• Get information about the available database tables in a DBMS• Access a table in a DBMS• Create a table in a DBMS• Delete a table in a DBMS• Perform standard SQL operations in the DBMS• Get information about the columns in a selected table• Add/Change/Delete records in a table

基于 ODBC 的应用程序架构• Database Application. call ODBC API to access a data source• Driver Manager. • Drivers. • Data Source.

测试在你的 IDL 环境下 ODBC 是否可用: status=DB_EXISTS()

Page 109: IDL  高级培训 基础篇

接口篇 -接口篇 - DataMiner API

创建表并追加数据

;creat a database object ,conect to DB and creat a new tableoDB = obj_new('IDLDBDatabase')oDB->Connect, DataSource ="IDLTRAINING"oDB->ExecuteSQL, "create table training( id integer" + $ ",x integer ,y integer, data image, name char(50))";creat a recordset ,append a recordoRS = obj_new('IDLdbRecordSet', oDB, table='training' )oRS->AddRecord, 1, 400, 400, BYTSCL(DIST(400)), 'first image';after working ,destroy objectobj_destroy ,oRSobj_destroy ,oDB

Page 110: IDL  高级培训 基础篇

接口篇 -接口篇 - DataMiner API

从已有表中读取数据

;creat a database object ,conect to DB and creat a new tableoDB = obj_new('IDLDBDatabase')oDB->Connect, DataSource ='IDLTRAINING';creat a recordset ,append a recordoRS = obj_new('IDLdbRecordSet', oDB, table='training')status=oRS->MoveCursor(/first)

;retrieve image data and informationX = oRS->GetField(1)Y = oRS->GetField(2)image = oRS->GetField(3)name = oRS->getField(4);after working ,destroy objectobj_destroy ,oRSobj_destroy ,oDB

;now we can use these data in IDLWINDOW, COLORS=-5, TITLE=name, XSIZE=x, YSIZE=yimage = REFORM(image, 400, 400)TVSCL, image

Page 111: IDL  高级培训 基础篇

接口篇 -接口篇 - DataMiner API

小结:• IDL 并不是一个有效的信息系统的界面工具,数据校验功能过弱。这就使得在写入数据库时预处理过于繁杂,效率不高。但从数据库读取数据非常简单,便于使用。• 空间数据的存取是 IDL 通过 ODBC 的瓶颈,往往如果能结合 ORACLE的 spatial功能,对于空间数据的管理不失为一个好办法。• 如果结合 VB 开发应用信息系统,应该是一个比较好的选择。