IDL 9.2 新特性介绍

IDL9.2主要包括以下新增功能和改进功能。

新增功能:

  • 支持BZIP2格式
  • 用于IDL和ENVI的嵌入式Python语言
  • FILE_HASH功能
  • HttpRequest类型:PATCH
  • 串行端口通信
  • 全新Windows命令行界面
  • Tab键补全功能

更新功能:

  • 改进ASDF格式数据支持
  • CREATE_STRUCT函数新增PRESERVE_CASE关键字
  • HttpRequest新增用于下载和加载文件的简化API
  • IDL Package Manager(IPM)支持IDL/ENVI Repository门户、新版API和发布功能
  • ISA函数新增STRICT_ARRAY关键字
  • 物理常量数值更新
  • Python::获取属性方法
  • 支持超大整数属性的矢量文件
  • SORT函数新增STABLE关键字
  • VS Code 的 IDL 扩展
  • MAKE_RT增强功能
  • 数组和结构体创建中的尾逗号
  • WIDGET_INFO函数新增SCREENSHOT关键字
  • WIDGET_TABLE优化对滚动条和选择事件的操作
  • WIDGET_TABLE支持格式字符串在行列中重复使用
  • FILE_POLL_INPUT支持Windows管道配合使用
  • FFT在arm64架构的MAC电脑上更新实施

IDL 9.2新特性

1 新增功能

1.1 支持BZIP2格式

IDL现在支持以BZIP2格式压缩和解压文件。细节参阅BZIP_COMPRESS和BZIP_UNCOMPRESS。

1.2 用于IDL和ENVI的Python包

IDL现在附带了一个功能齐全的 Python 发行版。自带Python包含了一系列实用的软件包,例如 numpy、pandas、regex、urllib3、h5py 以及 envipyengine。您可以轻松地将新软件包安装到用户专属的安装文件夹中。

新增的Python包移除了配置IDL-Python桥的过程。当执行第一个Python命令时,IDL会自动加载内置的Python程序。例如:

IDL> pd = Python.Import('pandas')
% Python is embedded version 3.13.
% Loaded DLM: PYTHON313.
% PYTHON_INIT: C:\Program Files\NV5\IDL92\bin\bin.x86_64\idl-python313.
IDL> dates = pd.date_range("20130101", periods=3)
IDL> df = pd.dataframe(randomu(seed, 4, 3), index = dates, columns = ["A", "B", "C", "D"])
IDL> print, df
A         B         C         D
2013-01-01  0.647128  0.954983  0.171173  0.664392
2013-01-02  0.251179  0.635682  0.986357  0.125033
2013-01-03  0.003626  0.229533  0.639266  0.297249

内置的Python还引入了一个全新的PyUtils类,支持通过熟悉的pip命令轻松地添加或删除软件包。例如,可以安装用于有效解析HTML和XML文件的Beautiful Soup软件包:

IDL> PyUtils.PipInstall, 'beautifulsoup4'
Looking in indexes: https://pypi.python.org/simple
Collecting beautifulsoup4
Installing collected packages: beautifulsoup4
Successfully installed beautifulsoup4-4.13.3
Package beautifulsoup4 successfully installed in C:\Users\myusername\.idl\idl\python_idlx_x.

安装好之后,我们就可以尝试用这个软件包了:

IDL> bs4 = Python.Import('bs4')
IDL> myhtml = '<html><title>IDL is great</title></html>'
IDL> soup = bs4.BeautifulSoup(myhtml, 'html.parser')
IDL> print, soup.title.string
IDL is great

IDL9.2仍然支持其它Python版本,以便用户选择自己的安装版本也可以正常使用。PyUtils类可以用于获取其它兼容的安装版本。例如,如果想要使用自行安装的Python3.13版本,可以调用新的PyUtils.Load方法来选择合适的Python桥接库。例如:

IDL> PyUtils.Load, 'python313'  ; your Python is 3.13

细节参阅Python Bridge和PyUtils Class。

1.3 FILE_HASH功能

IDL新增FILE_HASH函数,可以计算出文件或数组文件的加密哈希值。加密哈希值可以有效确保文件包含所有预期的字节数,不会被篡改损坏。此新增函数可以计算出MD5、SHA-1、SHA-2 (256 bit)和SHA-2 (512 bit)的哈希值。例如:

IDL> file = filepath('hdf5_test.h5', subdir=['examples', 'data'])
IDL> print, file_hash(file)
69121a6aa9bc4eed8bdbd668f98d5503
IDL> print, file_hash(file, /SHA256)
74e416059b19e63581f9d8d03266081ed6a9a9a18fa44c2e41709ff7a7c20dba

细节参阅FILE_HASH。

1.4 HttpRequest类型新增PATCH方法

HttpRequest类(在IDL9.0中引进)新增:PATCH方法,支持向服务器发送PATCH请求。与POST和PUT请求不同,PATCH请求允许更新服务器上的已有资源。

例如,上传一个名为“helloworld.txt”的文件,该文件中包含的文字为“Hello World”:

IDL> data = hash("name", "patched file", "file", "@helloworld.txt")
IDL> response = HttpRequest.Patch('https://httpbin.org/patch', multipart = data)
IDL> response.status
200
IDL> response.json()
{
  "args": {
  },
  "data": "",
  "files": {
    "file": "Hello World\r\n"
  },
  "form": {
    "name": "patched file"
  },
  ...
}

细节参阅HttpRequest。

1.5 串行端口通信

使用全新的内置Python桥,IDL现在支持通过pyserial包与串行端口进行通信。例如,可以安装Python包:

pyutils.pipinstall, 'pyserial'

接下来,将串行设备接入电脑。然后,在IDL中导入pyserial库,并获取可用端口的列表:

serial = Python.import('serial')
ports = Python.import('serial.tools.list_ports')
com_ports = ports.comports()
foreach p, com_ports do print, p.device

在 Windows 系统中,将输出COM2 或 COM3 这样的端口名称。而在 Linux 和 Mac 系统中,端口名称则会显示为/dev/ttyUSB0 。

一旦识别到正确的端口,就可以连接到该端口并开始进行通信。

例如,这里将Arduino连接到Windows机器进行字符串的来回传递:

serial = Python.import('serial')
arduino = serial.Serial(port="COM3", baudrate=9600, timeout=0.1)
wait, 2 ; give time to connect
!null = arduino.write(byte("hello"))
wait, 0.05
data = arduino.readline()
print, data
!null = arduino.close()

完整示例请参阅Serial Port Communication via Python Bridge。

1.6 全新Windows命令行界面

在Windows系统上,IDL命令行界面已经完全重写。新的命令行具有以下附加功能:

  • 优化输出大量数据流时的性能
  • 利用彩色文本显示IDL或ENVI提示、信息消息和报错消息。

image

提示:要使用新版Windows命令行界面,可以直接运行idl.exe应用程序,或者将IDL的bin目录添加到系统路径中,并在Windows或bash命令行中运行idl。

1.7 Tab键补全功能

在新版Windows命令行中按下“TAB”键将会实现自动补全功能,优先借助IDL命令历史记录(如果存在匹配的命令),如果没有匹配的命令,IDL会尝试匹配本地系统上的文件名。

举个文件路径自动补全的例子,假设系统中有两个文件夹目录结构:

dir1/
  subdir/
    myimage.jpeg
dir2/

在 IDL 命令行中输入:

IDL> read_jpeg, "./dir

按下TAB键,IDL将输出:

dir1/  dir2/

如果您继续输入“1/”,然后再按一次TAB键,IDL 将自动补全剩余的子文件夹路径:

IDL> read_jpeg, "./dir1/subdir/

再次按下“TAB”键后,文件路径就会被完整填写:

IDL> read_jpeg, ".\dir1\subdir\myimage.jpeg

如果该子目录中有多个文件,那么IDL将会一次性输出所有文件,此时您就可以继续输入并按TAB键来缩小选择范围。

2 功能更新

2.1 改进ASDF格式数据支持

IDL对ASDF(Advanced Scientific Data Format)的支持已改进,新增以下功能:

  • 处理具有不同字节顺序的文件
  • 支持以步长读取文件
  • 支持读取流式文件
  • 支持读写结构体数组
  • 支持读写ASCII类型数据
  • 支持BZIP2数据压缩

更多细节请参阅ASDF_PARSE和ASDF_WRITE。

2.2 CREATE_STRUCT函数新增PRESERVE_CASE关键字

默认情况下,无论使用大括号{}还是使用CREATE_STRUCT函数来创建 IDL 结构,标签名称都会自动转换为大写形式。在CREATE_STRUCT函数中,可以使用新增的PRESERVE_CASE关键字来保持小写字母不变。例如:

IDL> a = create_struct('tag1', 1.0, 'TaG2', 2, /preserve_case)
IDL> help, a
  ** Structure <b5161400>, 2 tags, length=8, data length=6, refs=1:
  tag1            FLOAT           1.00000
  TaG2            INT              2
   
IDL> print, tag_names(a)
tag1 TaG2

注释:

1、在 IDL 中,可以使用任何大写或小写子母的组合来引用结构体中的标签名称;所有标签名称的匹配都是不区分大小写的。这一点始终适用,即便是在处理大小写混合标签名称的结构数组时也是如此。例如:

IDL> a = create_struct('tag1', 1.0, 'TaG2', 2, /preserve_case)
IDL> print, a.TAG1, a.tag1, a.TAG2, a.tag2
1.00000    1.00000    2    2
IDL> arr = replicate(a, 10)
IDL> arr[5] = {TAG1: 2.0, TAG2: 3}
IDL> print, tag_names(arr[5])
tag1 TaG2

2、使用大括号{}创建的结构体通常采用大写字母标签,不论IDL 代码中实际使用的是哪种大小写形式。此特点保持不变。例如:

IDL> b = {tag1: 3.14, Tag2: 5}
IDL> help, b

** Structure <83e80910>, 2 tags, length=8, data length=6, refs=1:

TAG1   FLOAT 3.14000

TAG2  INT   5

3、由于标签匹配不区分大小写,因此不能创建两个标签名称仅大小写不同的结构。例如,尝试创建标签名称为“tag1”和“TAG1”的结构将会报错。

2.3 HttpRequest提供了简洁的 API 用于下载和上传文件

HttpRequest类(在 IDL 9.0 中引入)允许发送GET、POST、PUT和DELETE请求到HTTP或HTTPS服务器上。在IDL 9.2中下载和上传文件会更简便。

首先,GET、POST和PUT方法有了一个新的关键字FILENAME。设置这个关键字,将会下载对文件的响应,而不是以字节数组或字符串的形式返回数据。此操作可以直接从一个 URL下载大型文件到本地文件系统中的某个文件中。例如:

response = HttpRequest.Get('https://httpbin.org/', FILENAME='c:/temp/result.txt')
print, response.status_code
print, file_lines('c:/temp/result.txt')

接下来,对于 POST 和 PUT 方法,当上传的文件是多部分表单的一部分时,可以使用快捷方式“@filepath”来指定文件,而无需创建 IDL 结构。例如:

multipart = hash("name", "David Stern", "resume", "@c:/myplainresume.txt")
a = HttpRequest.Post(url, multipart=multipart)

这些新功能的细节请参阅HttpRequest。

2.4 IDL Package Manager(IPM)支持IDL/ENVI Repository门户、新版API和发布功能

IDL Package Manager(IPM)已采用了静态方法重写。重写后提供了一个更简洁的API,并且与HttpRequest等其他IDL类保持了一致的风格。

IPM 还新增了Publish功能,可以将IDL包上传至远程服务器。

除此之外,增加了一个新的IDL/ENVI Repository读取器。此功能可以在IDL中创建、上传和安装IDL或者ENVI软件包。例如,如果你的服务器URL是myrepository.com,端口8000,软件包名称为ExtractAttributes,那么以下代码将会在服务器上创建并上传这个包,然后再下载并安装。

url = 'http://myrepository.com:8000/'
packagename = 'ExtractAttributes'
dir = getenv('HOME') + '/' + packagename

IPM.Create, dir, $
  name = packagename, $
  display_name = "Extract Attributes", $
  description = "Extracts the attributes table of a shapefile.", $
  tags = ["Vector"], $
  version = '1.0.0', $
  author = "David Stern", $
  dependencies = [{ $
    name: "DumpVectorTable", $
    version: ">=1.0.0"}, $
    { $
    name: "ReadShapefile", $
    version: "<2.0"} $
    ], $
  url = url

现在添加所有需求文件,将新创建的软件包上传至服务器:

IPM.Publish, dir, destination = 'http://myrepository.com:8000/'

要测试软件包,可以进行安装操作:

IPM.Install, 'http://myrepository.com:8000/', name='ExtractAttributes', version='1.0.0'

IDL输出:

Package: ExtractAttributes, Version: 1.0.0 installed
Package: DumpVectorTable, Version: 1.2.0 installed
Package: ReadShapefile, Version: 1.9.0 installed

细节请参阅IPM。

2.5 ISA函数新增STRICT_ARRAY关键字

ISA函数目前有/ARRAY关键字。这对于检查一个变量是否可索引非常有用,比如常规的 IDL 数组、列表或者哈希值。

现在ISA新增了STRICT_ARRAY关键字,只有当变量确为IDL数组或者结构体时才会返回“真”。例如,一个哈希值或列表将会返回“假”,但是由哈希值和列表组成的对象数组将会返回“真”。

细节请参阅ISA。

2.6 物理常量数值更新

!CONST系统变量包含了最常见的物理常量。

在2019年,千克、安培、开尔文和摩尔这四个国际单位制的基本单位基于自然物理常数重新定义,替代了人造物品作为基本单位。这是通过为普朗克常数(h)、基本电荷(e)、玻尔兹曼常数(kB)和阿伏伽德罗常数(NA)设定精确的数值来实现的。由于重新定义,这些物理常量有了新的数值:

名称

描述

旧值

新值

alpha

Fine structure constant

7.2973525698 x 10-3

7.2973525643 x 10-3

e

Elementary charge

1.602176565 x 10-19 C

1.602176634 x 10-19 C

eps0

Vacuum electric permittivity

8.854187817 x 10-12 F/m

8.8541878188 x 10-12 F/m

F

Faraday constant

96485.3365 C/mol

96485.33212 C/mol

G

Gravitation constant

6.67428 x 10-11 m3/kg/s2

6.67430 x 10-11 m3/kg/s2

h

Planck constant

6.62606957 x 10-34 J s

6.62607015 x 10-34 J s

hbar

h/(2π)

1.054571726 x 10-34 J s

1.054571817 x 10-34 J s

k

Boltzmann constant

1.3806488 x 10-23 J/K

1.380649 x 10-23 J/K

me

Electron mass

9.10938291 x 10-31 kg

9.1093837139 x 10-31 kg

mn

Neutron mass

1.674927351 x 10-27 kg

1.67492750056 x 10-27 kg

mp

Proton mass

1.672621777 x 10-27 kg

1.67262192595 x 10-27 kg

mu0

Vacuum magnetic permeability

1.2566370614 x 10-6 N/A2

1.25663706127 x 10-6 N/A2

n0

Loschmidt constant

2.6867805 x 1025 m-3

2.686780111 x 1025 m-3

Na

Avogadro constant

6.02214129 x 1023 mol-1

6.02214076 x 1023 mol-1

parsec

Parsec distance

3.0856775814671912 x 1016 m

3.0856775814913673 x 1016 m

R

Molar gas constant

8.3144621 J/mol/K

8.3144626181532395 J/mol/K

re

Classical electron radius

2.8179403267 x 10-15 m

2.8179403205 x 10-15 m

rydberg

Rydberg constant

10973731.568539 m-1

10973731.568157 m-1

sigma

Stefan-Boltzmann constant

5.670373 x 10-8 W/m2/K4

5.670374419 x 10-8 W/m2/K4

u

Atomic mass constant

1.660538921 x 10-27 kg

1.66053906892 x 10-27 kg

Vm

Molar volume, ideal gas at STP

22.413968 x 10-3 m3/mol

22.41396954 x 10-3 m3/mol

虽然这些数值大多数可以通过合适的实验室设备来验证,但我们正满怀期待地等待着使用IDL的勇士们从他们的探险之旅归来,以测量新的秒差距距离。

有关详细信息,请参阅!CONST系统变量。

2.7 Python::Getattr方法

IDL-to-Python桥增加了一个新的静态法——Python::GetAttr。Python::GetAttr静态方法从 Python 对象中获取属性。GetAttr方法在将属性指定为字符串时,或者使用WRAP关键字将属性作为Python对象返回而不是转换为IDL类型时非常有用。

示例

创建Pandas DataFrame并获取“shape”属性,该属性会给出每一个维度的长度。

np = python.import('numpy')
pd = python.import('pandas')
arr = (np.random).randn(6,4)
dates = pd.date_range("20130101", periods=6)
df = pd.dataframe(arr, index = dates, columns = ["A", "B", "C", "D"])
print, `shape = ${df.shape}`   ; use dot notation
shape = Python.getattr(df, 'shape', /wrap)
help, shape
print, shape

IDL 输出:

shape = [6,4]
SHAPE           PYTHON  <ID=837>  <class 'tuple'>
(6, 4)

请注意,在调用 GetAttr 时,使用WRAP关键字可直接返回 Python 元组,无需进行任何转换。

细节请参阅Python::GetAttr。

2.8 支持超大整数属性的矢量文件

在IDL9.2之前的版本,如果ESRI shapefile包含整型属性,那么该属性的值总是会被读取为32位的整数。这与 ESRI shapefile限制整数存储位数在32位内的规范一致。然而,某些shapefile中可能存在超出合理取值范围(-2147483648 到 2147483647)的整数值。在这些情况下,IDL现在将会把这些属性域转化为IDL DOUBLE格式。注意,如果接下来将这些属性值写入一个新的shapefile,格式会自动转为Double,这是符合ESRI规范的并且允许这些文件能够顺利地与其他工具共同使用。

2.9 SORT函数新增STABLE关键字

默认情况下,对具有相同元素的数组调用 SORT 函数时,返回的索引会以任意顺序排列。现在,SORT 函数新增了一个名为 STABLE 的关键字,它将保持相同元素的顺序:

a = [4.0, 3.5, 7.0, 1.0, 1.1, 7.0, 7.0] ; the 7.0 values are identical
indices = sort(a)
indices_stable = sort(a, /stable)
print, `${indices}`
print, `${indices_stable}`

IDL输出:

[3, 4, 1, 0, 5, 6, 2] ; note the arbitrary order of the indices 5,6,2
[3, 4, 1, 0, 2, 5, 6] ; the values equal to 7.0 are now in order 2,5,6

同样地,如果对一个IDL变量使用::Sort方法,现在可以指定STABLE关键字,使INDICES 关键字中返回的值按照正确的顺序排列:

a = [4.0, 3.5, 7.0, 1.0, 1.1, 7.0, 7.0]
astable = a.sort(indices = indices_stable, /stable)
print, `${indices_stable}` ; the results are the same as above

细节请参阅SORT函数和IDL_Variable::Sort方法。

2.10 VS Code 的 IDL 扩展

VSCode 的IDL扩展可在 Visual Studio Code 中免费获取。此扩展可以轻易地从VS Code扩展网页中下载并安装。包含以下新增功能:

  • 全面的调试支持,包括停止程序执行的功能。
  • 一个 IDL 教程,包含一系列互动式 IDL 笔记本,引导用户学习 IDL 语言。

细节访问IDL for VSCode 页面。

2.11 MAKE_RT增强功能

MAKE_RT已经过优化,能够生成一个规模小得多的版本。新增了三个关键字:

  • BROWSER——默认情况下,MAKE_RT 不会包含用于 IDL 浏览器组件所需的文件。设置此关键字以包含这些文件。
  • PYTHON——默认情况下,MAKE_RT 不会将自带的 Python 包含在 IDL 二进制文件夹中。设置此关键字以包含这些文件。
  • VERBOSE——设置此关键字可以打印每一个被复制文件的完整路径。

MAKE_RT现在利用CLI_PROGRESS展示进度条。

IDL> make_rt,'helloWorld','C:\Users\<User>\IDLWorkspace\make_rt_copy_trgt'

IDL输出:

8.0% [###-------------------------------------] Filtering files
61.3% [########################----------------] Copying files
etc...

所有增加功能的细节请参阅MAKE_RT。

2.12 数组和结构体创建中的末尾逗号

现在,当创建新的数组时,一系列值末尾的逗号会被忽略。例如:

a = [ $
  [10:19], $
  [20:29], $
  [30:39], $ ; this trailing comma is now ignored
]

可以轻松地添加第四行:

a = [ $
  [10:19], $
  [20:29], $
  [30:39], $
  [40:49], $ ; new row, did not have to touch the third row
]

同样地,对结构体进行操作:

a = { $
  field1: 1, $
  field2: "2", $
  field3: 3.0, $ ; this trailing comma is now ignored
}

可以轻松地添加第四行:

a = { $
  field1: 1, $
  field2: "2", $
  field3: 3.0, $
  field4: "four", $ ; new row, did not have to touch the third row
}

此功能使得在代码中修改现有数组或结构变得更加简便,只需添加一行即可,无需担心缺少逗号的问题。是否添加尾随逗号(或不添加)完全是可选的,对创建的数组或结构及其内部数据均无影响。

2.13 WIDGET_INFO函数新增SCREENSHOT关键字

SCREENSHOT这一关键字使WIDGET_INFO能够返回指定组件的[M,N,3]字节大小的图像。几乎所有的组件都可以被捕获,包括顶层基组件、子基组件、浏览器组件以及其他组件。但只有菜单栏、菜单、菜单项和树形组件节点这几种组件无法被指定。图像可用于自动化测试、报告生成等用途。

细节参阅WIDGET_INFO函数。

2.14 WIDGET_TABLE优化对滚动条和选择事件的操作

WIDGET_TABLE函数现在仅在必要时才添加滚动条,否则滚动条会被隐藏。现在可以将 X_SCROLL_SIZE 设置为0或Y_SCROLL_SIZE设置为0来隐藏水平或垂直方向的滚动条。

WIDGET_TABLE新增WHEEL_EVENTS关键字,在使用鼠标滚轮滚动表单组件时能够生成滚轮事件。

WIDGET_TABLE新增EXTEND_SELECTION关键字,在点击行或列标题时改变选择事件的值。此关键字能够区分用户是在表格内部点击还是在行或列标题上点击所引发的不同事件。

WIDGET_TABLE现在可以为列标题和行标题设置前景色和背景色。通过使用-1可以对标题单元格进行索引。

细节参阅WIDGET_TABLE。

2.15 WIDGET_TABLE支持格式字符串在行列中重复使用

WIDGET_TABLE 函数新增REPEAT_FORMAT关键字。如果设置了此关键字,并且FORMAT关键字所指定的向量或数组小于表格的大小,那么该格式数组将会在额外的行或列中重复排列。

通过将FORMAT设置为一个字符串向量,并结合使用REPEAT_FORMAT关键字,可以轻易地为整个表格设置格式,这样表格中的每一行都将具有相同的格式。

细节参阅WIDGET_TABLE。

2.16 FILE_POLL_INPUT支持Windows管道配合使用

FILE_POLL_INPUT函数现在支持Windows管道、Windows sockets接口和Unix文件描述符。这种功能的一个应用场景是:当IDL启动了一个子进程,并让其通过stdin和stdout进行读写操作时:

spawn, command, unit = pipe, /noshell

现在,IDL 能够检查子进程是否具有可供读取的数据:

result = file_poll_input(pipe, timeout = double)

此功能使得 IDL 应用程序避免阻塞式读取,从而保持活跃状态。如果结果为1,那么 IDL 应用程序就可以安全地进行读取(至少读取一个字节),而无需因可能永远不会到来的数据或在未知的时间才出现的数据而进行阻塞等待。

细节参阅FILE_POLL_INPUT。

2.17 FFT在arm64架构的MAC电脑上更新

Arm64 Mac的IDL现已附带了Arm性能库25.04版本。该版本为一维数据提供了性能提升。

posted @ 2025-08-28 15:34  ENVI-IDL技术殿堂  阅读(161)  评论(0)    收藏  举报