ENVI IDL:如何解析XML文件(以Landsat9-MTL.xml文件为例)

news2025/3/16 17:07:15

01 前言

我们原本是打算对Landsat9文件进行辐射定标,但是辐射定标的参数在MTL文件中,从文件中查看参数直接复制到IDL中固然可行,但是当我们对Landsat9文件进行批量辐射定标时,这种方法就将失效了。因此我们需要自动从MTL文件中读取相关参数,这里的相关参数实际上只包含两个参数(对于一个波段),一个是比例系数,一个是偏置量。

对于Landsat9,给出三种MTL形式:
在这里插入图片描述
这里我们只讨论txt文本文件和XML文件的解析和提取。

02 通过XML文件获取定标参数

需要使用到IDL的IDLffXMLDOMDocument类,以及类的方法getelementsbytagname,getfirstchild,GetNodeValue

getelementsbytagname方法通过指定标签名得到满足要求的所有标签(类似列表形式返回:IDLffXMLDOMNodeList);
getfirstchild获取节点的第一个子节点;
GetNodeValue获取节点的值;

由于getelementsbytagname方法获取返回的值是一个类似列表的形式,当我们指定的标签名在XML文件中唯一时,那么实际上列表元素仅有一个元素,需要通过.item(0)取出第一个元素(其依旧是一个对象)。

由于我们的定标参数类似下方:
在这里插入图片描述

但是需要注意,在另外一个标签也有相同节点名称:

在这里插入图片描述

上面有两个辐射定标的参数,第一个是Level2级别的辐射定标,最终获取的是地表反射率或者地表温度(我们使用这个);而第二个是用于级别 1(L1)的辐射定标,即将传感器捕获的原始数字数据转换为辐射亮度值。因此,我们需要进行两次getelementsbytagname方法,第一次是获取到节点LEVEL2_SURFACE_REFLECTANCE_PARAMETERS,再用一次该方法从该节点下检索各个满足要求的子节点(各个波段的比例系数和偏置量节点)。

接着从获取的指定子节点中得到所有值。

所以我们的代码应该这么写:

pro L9_C2_calibration
    ; 准备
    xml_path = 'D:\Objects\JuniorFallTerm\IDLProgram\Experiments\ExperimentalData\Week8\LC09_L2SP_130039_20220311_20220314_02_T1_MTL.xml'
    xml = IDLffXMLDOMDocument(filename=xml_path)
    
    ; 获取level2
    level2 = xml.getelementsbytagname('LEVEL2_SURFACE_REFLECTANCE_PARAMETERS')
    level2 = level2.item(0)
    b1 = level2.getelementsbytagname('REFLECTANCE_MULT_BAND_1')
    b1 = b1.item(0)
    print, double((b1.getfirstchild()).getnodevalue())
    
    ; 销毁对象
    obj_destroy, b1
    obj_destroy, level2
    obj_destroy, xml
end

输出结果:

在这里插入图片描述

(PS:说实话,IDL的XML对象真的不好用,太底层了,不如python,但是好处就是你可以更自由的自己写一些高级函数进行封装得到自己想要的方法)

封装了一下,函数如下:

;+
;   函数用途:
;       用于获取指定路径节点的值
;   函数参数:
;       xml_path: xml文件的路径
;       tags_name: 各个节点的名称(数组形式), 按父-子顺序排列
;-
function xml_get_value, xml_path, tags_name
    xml = idlffxmldomdocument(filename=xml_path)  ; 实例化一个XML对象
    
    cur_tag = xml
    foreach tag_name, tags_name do begin
        cur_tag = cur_tag.getelementsbytagname(tag_name)
        cur_tag = cur_tag.item(0)
    endforeach
    
    return, (cur_tag.getfirstchild()).getnodevalue()
end

如果你的节点相对路径如下:

LEVEL2_SURFACE_REFLECTANCE_PARAMETERS\REFLECTANCE_MAXIMUM_BAND_1
即:
在这里插入图片描述
那么获取值如下:

a = xml_get_value(xml_path, ['LEVEL2_SURFACE_REFLECTANCE_PARAMETERS', 'REFLECTANCE_MULT_BAND_1'])
print, a

在这里插入图片描述

但是需要注意,我并没有设置任何错误机制,如果你的路径错误或者不正确等问题会导致返回值为NULL甚至直接报错;另外需要注意,我这里假定所有节点在其父节点中唯一,也就是不考虑父节点下存在多个相同名称的子节点。另外确保你的相对路径唯一,如果你仅仅传入[REFLECTANCE_MAXIMUM_BAND_1]而非上述形式,那么通过前文知,多个标签Tag下存在该节点名称,那么函数会自动取第一个匹配的值。

03 通过文本文件获取定标参数

这就是通过字符串截取等方式去取值,这里就是拿各种字符串操作函数来回折腾,总体思路还是前面如此。这里给出代码:

    ; 准备
    txt_path = 'D:\Objects\JuniorFallTerm\IDLProgram\Experiments\ExperimentalData\Week8\LC09_L2SP_130039_20220311_20220314_02_T1_MTL.txt'
    
    openr, 1, txt_path
    txt_content = strarr(file_lines(txt_path))
    readf, 1, txt_content
    level2_pos = where(strmatch(txt_content, '*LEVEL2_SURFACE_REFLECTANCE_PARAMETERS*'))
    calibration_content = txt_content[level2_pos[0]:level2_pos[1]]
    band_sc_pos = where(strmatch(calibration_content, '*REFLECTANCE_MULT_BAND_1*'))
    band_sc = (strsplit(calibration_content[band_sc_pos], '=', /extract))[-1]
    print, band_sc
    free_lun, 1

运行结果如下:

在这里插入图片描述
在这里插入图片描述

注意,上述两种方法得到的结果均为字符串,需要转化为double等数值类型。

当然,其实还有其他方法,例如在IDL中调用python模块(XML内置模块),前提是你安装python解释器。这里也贴出代码:

ET = python.import('xml.etree.ElementTree')
tree = ET.parse(xml_path)
root = tree.getroot()
finds = root.find('./LEVEL2_SURFACE_REFLECTANCE_PARAMETERS/REFLECTANCE_MULT_BAND_1')
print, finds.text

输出结果:

在这里插入图片描述

最后贴一个对Landsat9各个波段辐射定标的完整代码(取定标参数使用方法1):

; @Author	: ChaoQiezi
; @Time		: 20231111-上午10:24:06
; @Email	: chaoqiezi.one@qq.com

; 该程序用于 对Landsat9 C2(第二版次算法)的一级产品进行辐射定标并输出为TIFF文件

;+
;   函数用途:
;       用于获取指定路径节点的值
;   函数参数:
;       xml_path: xml文件的路径
;       tags_name: 各个节点的名称(数组形式), 按父-子顺序排列
;-
function xml_get_value, xml_path, tags_name, double=double
    xml = idlffxmldomdocument(filename=xml_path)  ; 实例化一个XML对象
    
    cur_tag = xml
    foreach tag_name, tags_name do begin
        cur_tag = cur_tag.getelementsbytagname(tag_name)
        cur_tag = cur_tag.item(0)
    endforeach
    
    value = (cur_tag.getfirstchild()).getnodevalue()
    if keyword_set(double) then return, double(value)
    
    return, value
end

pro L9_C2_calibration
    ; 准备
    in_dir = 'D:\Objects\JuniorFallTerm\IDLProgram\Experiments\ExperimentalData\Week8\'
    out_dir = in_dir + 'out_me\'
    if ~file_test(out_dir, /directory) then file_mkdir, out_dir
    xml_path = in_dir + 'LC09_L2SP_130039_20220311_20220314_02_T1_MTL.xml'
    level2_name = 'LEVEL2_SURFACE_REFLECTANCE_PARAMETERS'
    mult_name = 'REFLECTANCE_MULT_BAND_'
    add_name = 'REFLECTANCE_ADD_BAND_'
    img_wildcard = '*T1_SR_B'
    
    for band_ix = 1, 7 do begin
        cur_mult_name = mult_name + strtrim(band_ix, 1)
        cur_add_name = add_name + strtrim(band_ix, 1)
        cur_img_name = img_wildcard + strtrim(band_ix, 1) + '.tif'
        scale = xml_get_value(xml_path, [level2_name, cur_mult_name], /double)
        add = xml_get_value(xml_path, [level2_name, cur_add_name], /double)
        
        ; 读取影像文件和定标
        cur_img_path = (file_search(in_dir+cur_img_name))[0]
        cur_img = double(read_tiff(cur_img_path, geotiff=geo_info, dot_range=range))
        cur_img[where(cur_img eq 0.0, /null)] = !values.F_NAN
        cur_img = cur_img * scale + add
        
        ; 输出
        cur_out_path = out_dir + file_basename(cur_img_path)
        write_tiff, cur_out_path, cur_img, geotiff=geo_info, /double
    endfor    
end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1197086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSM框架Demo: 简朴博客系统

文章目录 1. 前端页面效果2. 项目创建3. 前期配置3.1. 创建数据库数据表3.2. 配置文件 4. 创建实体类5. 统一处理5.1. 统一返回格式处理5.2. 统一异常处理 6. 全局变量7. Session工具类8. 登录拦截器9. 密码加盐加密10. 线程池组件11. dao层11.1. UserMapper11.2. ArticleMappe…

jenkins分步式构建环境(agent)

rootjenkins:~# netstat -antp|grep 50000 tcp6 0 0 :::50000 ::😗 LISTEN 5139/java 1.52 安装Jenkins rootubuntu20:~# dpkg -i jenkins_2.414.3_all.deb 配置各种类型的Agent的关键之处在于启动Agent的方式 ◼ JNLP Agent对应着“通过Java Web启动代理”这种方…

人工智能基础——Python:Pillow与图像处理

人工智能的学习之路非常漫长,不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心,我为大家整理了一份600多G的学习资源,基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

SPSS:卡方检验(交叉表)

第一步 打开SPSS软件,在工具栏中选中【打开-文件-数据】,然后选择一份要打开的数据表(如图所示)。 第二步 在工具栏中找到【分析-描述统计-交叉表】打开交叉表对话框(如图所示)。 第三步 接着将【行-列】相关变量放在对应对话框中(如图所示)。 第四步 在…

2023年03月 Python(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 运行下列程序,输出的结果是?( ) def wenhao(name = zhejiang): print(hello + name) wenhao

《软件工程与计算》期末考试真题范例及答案

今天分享一套针对《软件工程与计算》这本书的真题案例,有关《软件工程与计算》23章内容的重点知识整理,已经总结在了博客专栏中,有需要的自行阅读: 《软件工程与计算》啃书总结https://blog.csdn.net/jsl123x/category_12468792.…

git基础知识

1.git的必要配置 所有的配置文件,其实都保存在本地! 查看所有配置 git config -l 即把 系统配置(system)和当前用户(global)配置都 列出来 以直接编辑配置文件,通过命令设置后会响应到这里。 注意: 如果…

男科医院服务预约小程序的作用是什么

医院的需求度从来都很高,随着技术发展,不少科目随之衍生出新的医院的,比如男科医院、妇科医院等,这使得目标群体更加精准,同时也赋能用户可以快速享受到服务。 当然相应的男科医院在实际经营中也面临痛点:…

【图像分类】【深度学习】【Pytorch版本】GoogLeNet(InceptionV1)模型算法详解

【图像分类】【深度学习】【Pytorch版本】GoogLeNet(InceptionV1)模型算法详解 文章目录 【图像分类】【深度学习】【Pytorch版本】GoogLeNet(InceptionV1)模型算法详解前言GoogLeNet(InceptionV1)讲解Inception结构InceptionV1结构1x1卷积的作用辅助分类器 GoogLeNet(Inceptio…

(论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking

文献阅读笔记(分层卷积特征) 简介 题目 Hierarchical Convolutional Features for Visual Tracking 作者 Chao Ma, Jia-Bin Huang, Xiaokang Yang and Ming-Hsuan Yang 原文链接 arxiv.org/pdf/1707.03816.pdf 关键词 Hierarchical convolution…

华为防火墙双机热备配置案例(无vrrp)

思路: IP和路由、ospf要两台防火墙单配,hrp不会同步 其它zone和策略会同步,只在master上配就行了 FW_A主要配置: hrp enable hrp interface GigabitEthernet1/0/2 remote 172.16.0.2 interface GigabitEthernet1/0/0 undo shut…

Qt 自定义按钮 区分点按与长按信号,适配触摸事件

Qt 自定义按钮 区分点按与长按信号 适配触摸事件 效果 使用示例 // 点按connect(ui.btnLeft, &JogButton::stepclicked, this, &MainWindow::btnLeft_clicked);// 长按开始connect(ui.btnLeft, &JogButton::continueOn, this, &MainWindow::slotJogLeftOn);//…

【Springboot】基于注解式开发Springboot-Vue3整合Mybatis-plus实现分页查询

系列文章目录 文章目录 系列文章目录系统版本实现功能操作步骤1. 新建Mybatis的全局分页配置文件2. 编写OrderMapper :继承Mybatis-plus提供的BaseMapper3. 编写OrderServiceImpl,实现OrderService4. 编写OrdersController 控制类 发送接口请求测试 系统版本 后端&…

Antd React Form.Item内部是自定义组件怎么自定义返回值

在线演示https://stackblitz.com/edit/stackblitz-starters-xwtwyz?filesrc%2FSelfTreeSelect.tsx 需求 当我们点击提交,需要返回用户名和选中树的id信息,但是,我不关要返回树的id信息,还需要返回选中树的名称 //默认返回的 {userName:梦洁,treeInfo:leaf1-value } //但是需…

MySQL中的json使用注意

MySQL中json是一种重要的数据类型 好的点在于其不必事先定义列得名称啥的 不过不要将明显的关系型数据作为json来存储,例如用户余额、姓名、身份证等,这些是用户必须包含的数据 json适合存储的是给每个用户(或者物品)打的标签&…

红黑树的模拟实现

一、介绍 1. 概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍&#xff0c…

超级有效的12个远程团队管理技巧

前言 随着远程办公的兴起,虚拟管理团队已成为新常态。尽管混合和远程工作正在成为新常态,但管理远程团队也面临着一系列挑战。本文我们将为您提供 12个技巧,帮助您成功管理远程团队并改善协作。此外,我们将讨论定期接触点的重要性…

前端通过导入editor.md库实现markdown功能

小王学习录 今日摘录前言jquery下载editor下载editor和jquery的导入初始化editor总结 今日摘录 满招损,谦受益 前言 要想通过editor.md实现markdown的功能,需要经过如下四步: 下载editor.md到本地将本地editor导入到前端代码中编写少量代…

【分布式】tensorflow 1 分布式代码实战与说明;单个节点上运行 2 个分布式worker工作线程

tensorflow.python.framework.errors_impl.UnknowError: Could not start gRPC server 1. tf分布式 一台电脑服务器server是一个节点,包含了多个GPU。首先分布式的方式就是让多台电脑上的gpu共同干活。 分布式工作分为两个部分,parameter server&#…

Practice01-Qt6.0设置文本颜色、格式等。

Qt6.0学习,在此做个记录,方便日后查找复习 本次项目用到的控件有:复选框,单选按钮。文本编辑框。 项目目录结构: 项目运行效果图: 实现的功能: 勾选Underline、Italic,Bold时&…