ENVI IDL:如何将txt文本文件转化为GeoTIFF文件?

news2024/12/23 3:59:08

01 前言

此处的文本文件形式如下:

在这里插入图片描述

里面包含了众多点位信息(不是站点数据),我们需要依据上述点的经纬度信息放到对应位置的像素点位置,放置完后如下:

在这里插入图片描述

可以发现,还存在部分缺失值,我们还需要进行缺失值的填补。

02 文本文件的读取

IDL读取文本文件还是不够方便,稍微封装了一下。

;+
;   函数用途:
;       用于读取文本文件
;   函数参数:
;       txt_path: 文本文件的路径
;       ds: 读取的输出数据集(不含表头)
;       header(关键字参数): 读取的输出表头
;       separator(关键字参数): 分隔符,默认空白符 
;-
pro read_txt, txt_path, ds, header=header, separator=separator
    if ~keyword_set(separator) then separator = " "
        
    ; 读取和检索
    openr, 1, txt_path  ; 打开文本文件
    ; 是否指定输出的header
    if ~arg_present(header) then begin
        skip_lun, 1, 0
    endif else begin
        header = ''
        readf, 1, header  ; 读取表头
        header = strsplit(header, separator, /extract)
    endelse
    ; 读取和处理数据集
    ds = strarr(file_lines(txt_path) - 1)
    readf, 1, ds
    ds = list(ds, /extract)  ; 字符串数组转化为列表
    ds = ds.map(lambda(e, separator: double(strsplit(e, separator, /extract))), separator)
    ds = ds.toarray()  ; 列表转化为数组
    
    free_lun, 1
end

还好,算是可以用的程度了。

03 栅格矩阵的放置

于是乎,我们开始进行文件的读取和转数组。

pro txt_to_tiff
    ; 准备
    in_path = 'D:\Objects\JuniorFallTerm\IDLProgram\Experiments\ExperimentalData\Week6\2013_year_aop.txt'
    out_dir = 'D:\Objects\JuniorFallTerm\IDLProgram\Experiments\ExperimentalData\Week6\out_tif_by_txt_me\'
    if ~file_test(out_dir, /directory) then file_mkdir, out_dir
    out_res = 0.18d
    out_res_half = out_res / 2.0d

    ; 读取和检索
    read_txt, in_path, ds, header=header
    lon = ds[*, 0]
    lat = ds[*, 1]
    ds = ds[*, 2:*]
    header = header[2:*]
    lon_min = min(lon) - out_res_half
    lon_max = max(lon) + out_res_half
    lat_min = min(lat) - out_res_half
    lat_max = max(lat) + out_res_half
    cols = ceil((lon_max - lon_min) / out_res)
    rows = ceil((lat_max - lat_min) / out_res)
    lon_cols = floor((lon - lon_min) / out_res)
    lat_rows = floor((lat_max - lat) / out_res)
    foreach header_ele, header, header_ix do begin
        target = make_array(cols, rows, value=!values.F_NAN)
        target[lon_cols, lat_rows] = ds[*, header_ix]
        
        ; 填充
        window_interp, target, target_interp, interp=2
        
        ; 输出
        out_path = out_dir + header_ele + '.tiff'
        write_img, out_path, target_interp, out_res, lon_min, lat_max
    endforeach
end

在循环中,可以发现,使用了自定义的window_interp函数对target栅格矩阵进行缺失值的填补。

关于window_interp函数的定义由于封装的比较多,叠的比较层数比较多,阅读稍微有困难。学python的时候我是真的讨厌那些一个简单的功能的非要定义一个类,类又叠类,方法重组,来回找实现方法,来回折腾,本身功能不算特别复杂,但是被这么一折腾反而给阅读代码带来困难。

然而,我现在还是成为了他们。But 我将尽量让代码的逻辑清晰可见,不过分抽象,如有必要我抽出部分功能进行整合,避免使用过于复杂的代码框架搭建简单的功能。

以下是关于填补缺失值的封装函数,主要基于滑动窗口实现,包括滑动窗口均值填补和最近邻填补。
涉及自定义函数:window_interppaddinginterp_nearestmeshgrid

;+
;   函数用途:
;       用于对二维数组进行边界填充
;   函数参数:
;       array: 用于边界填充的数组
;       pad_size: 单边(上下左右)填充的大小
;       pad_value(关键字参数: NAN): 填充的数值
;-
function padding, array, pad_size, pad_value=pad_value
    if ~keyword_set(pad_value) then pad_value = !values.F_NAN
    
    ; 获取基本信息
    ds_size = size(array, /dimensions)
    ds_type = size(array, /type)
    ds_size += pad_size * 2
    
    ; pad
    pad_array = make_array(ds_size, type=ds_type, value=pad_value)
    pad_array[pad_size:(ds_size[0] - pad_size - 1), $
        pad_size:(ds_size[1] - pad_size - 1)] = array
        
    return, pad_array
end

;+
;   函数用途:
;       用于生成行列号格网矩阵
;   函数参数:
;       cols_n: 列数
;       rows_n: 行数
;-
function meshgrid, cols_n, rows_n
    window_cols = rebin(findgen(cols_n, 1), cols_n, rows_n)
    window_rows = rebin(findgen(1, rows_n), cols_n, rows_n)
    
    return, list(window_cols, window_rows)
end

function interp_nearest, window_ds
    ; 获取数组尺寸
    window_size = size(window_ds, /dimensions)
    cols_n = window_size[0]
    rows_n = window_size[1]
    
    ; 生成行列号矩阵
    cols_rows = meshgrid(cols_n, rows_n)
    cols = cols_rows[0]
    rows = cols_rows[1]
    
    ; 计算距离矩阵
    center_col = cols_n / 2
    center_row = rows_n / 2
    distance = sqrt((cols - center_col) ^ 2.0 +(rows - center_row) ^ 2.0)
    invalid_pos = where(finite(window_ds, /nan))
    distance[invalid_pos] = !values.F_NAN
    
    interp_value = (window_ds[where(distance eq min(distance, /nan))])[0]
    
    return, interp_value
end

;+
;   函数用途:
;       该函数用于对栅格矩阵中缺失值基于滑动窗口进行填充
;   函数参数:
;       dataset: 需要进行填补的栅格矩阵
;       dataset_interp: 输出的经填补好的栅格矩阵
;       window_size(默认: 3): 窗口大小(奇数)
;       interp: 填充的方法(1: 窗口均值; 2: 最近邻)
;-
pro window_interp, dataset, dataset_interp, window_size = window_size, interp = interp
    ds_size = size(dataset, /dimensions)
    ds_type = size(dataset, /type)
    
    ; 边界填充
    if ~keyword_set(window_size) then window_size = 3
    padding_size = window_size / 2
    ds_size += padding_size * 2
    dataset_pad = padding(dataset, padding_size)
    dataset_interp = padding(dataset, padding_size)
    
    ; 插值
    for col_ix=padding_size, ds_size[0] - padding_size - 1 do begin
        for row_ix=padding_size, ds_size[1] - padding_size - 1 do begin
            ; 若不是NAN跳过
            if ~finite(dataset_pad[col_ix, row_ix], /nan) then continue
            
            ; 取窗口数组
            window_ds = dataset_pad[col_ix-padding_size: col_ix+padding_size, $
                row_ix-padding_size: row_ix+padding_size]
            if (where(~finite(window_ds, /nan), /null) eq !null) then continue  ; 若窗口内均为NAN则跳过
            
            ; 插值
            if interp eq 1 then interp_value = mean(window_ds, /nan)
            if interp eq 2 then interp_value = interp_nearest(window_ds)
            
            ; 赋值
            dataset_interp[col_ix, row_ix] = interp_value
        endfor
    endfor
    
    ; no padding
    dataset_interp = dataset_interp[padding_size:(ds_size[0] - padding_size - 1), $
        padding_size:(ds_size[1] - padding_size - 1)]
end

还有write_img熬,自带的write_tiff每次都得自己写地理结构体,也稍微封装了一下。

;+
;   函数用途:
;       用于输出tiff文件(封装write_tiff)
;   函数参数:
;       img_path: tiff文件的输出路径
;       img: 栅格矩阵
;       out_res: 输出分辨率
;       ul_x: 左上角格点的左上角位置的X坐标
;       ul_y: 左上角格点的左上角位置的Y坐标
;-
pro write_img, img_path, img, out_res, ul_x, ul_y
    ; 地理结构体
    geo_info={$
        MODELPIXELSCALETAG: [out_res, out_res, 0.0], $  ; 分辨率
        MODELTIEPOINTTAG: [0.0, 0.0, 0.0, ul_x, ul_y, 0.0], $  ; 角点信息
        GTMODELTYPEGEOKEY: 2, $  ; 设置为地理坐标系
        GTRASTERTYPEGEOKEY: 1, $  ; 像素的表示类型, 北上图像(North-Up)
        GEOGRAPHICTYPEGEOKEY: 4326, $  ; 地理坐标系为WGS84
        GEOGCITATIONGEOKEY: 'GCS_WGS_1984', $
        GEOGANGULARUNITSGEOKEY: 9102}  ; 单位为度
        
    ; 输出
    write_tiff, img_path, img, geotiff=geo_info, /float
end

时间精力有限,不再详细说明,Bye~.

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

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

相关文章

C++八股文

第一章 编译内存相关 1.1 main函数之前和之后执行的代码 main函数之前 设置栈指针 初始化静态变量和全局变量(即.data内容);将未初始化的全局变量赋值:short、int、long初始化为0,bool初始化为false,指针…

Python使用SQLAlchemy操作sqlite

Python使用SQLAlchemy操作sqlite sqllite1. SQLite的简介2. 在 Windows 上安装 SQLite3. 使用SQLite创建数据库3.1 命令行创建数据库3.2 navicat连接数据库 4.sqlite的数据类型存储类SQLite Affinity 类型Boolean 数据类型Date 与 Time 数据类型 5. 常用的sql语法**创建表(CREA…

程序员职业生涯规划:多领域路线图一网打尽 | 开源日报 No.72

kamranahmedse/developer-roadmap Stars: 244.4k License: NOASSERTION 这是一个互动的路线图,指南和其他教育内容,旨在帮助开发人员在他们的职业生涯中成长。 提供多个不同领域 (如前端、后端、DevOps 等) 的路线图路线图可交互,并提供了详…

MySQL中外键的使用及外键约束策略

一、外键约束的概念 外键约束(FOREIGN KEY,缩写FK是数据库设计的一个概念,它确保在两个表之间的关系保持数据的一致性和完整性。 外键是指表中的某个字段的依赖于另一张表中某个字段的值,而被依赖的字段必须具有主键约束或者唯一约束&#…

适用于初学者的 .NET MAUI

适用于初学者的 .NET MAUI | Microsoft Learn 记录微软Learn中用到的代码。文章比较粗糙,大部分是项目代码粘贴。想详细学习的可到上面的链接学习,代码可以从这里复制后直接运行。 练习中一共有两个页面: 1、MainPage.xaml 用于添加列表中的…

网络安全之认识托管威胁检测与响应(MDR)

随着数字化转型加速,企业的IT环境日益复杂,面临的网络安全威胁也在不断增加。传统的防御措施已经无法有效应对新型威胁,而且很多企业缺乏专业的网络安全团队和技术手段,导致大量的安全事件未能及时被发现和处理。 在这种背景下&a…

如何安装Node.js? 创建Vue脚手架

1.进入Node.js官网,点击LTS版本进行下载 Node.js (nodejs.org)https://nodejs.org/en 2.然后一直【Next】即可 3.打开【cmd】,输入【node -v】注意node和-v中间的空格 查看已安装的Node.js的版本号,如果可以看到版本号,则安装成功 创建Vue脚手…

Flutter实践一:package组织

1.架构概览 为了降低Flutter工程里lib的复杂度,应尽量拆分一些代码成为独立的package。如图: 我们将通用的组件、领域模型、API、features、存储、repository等抽取成了单独的package。这时lib只剩下多国语言、基本的页面、路由等代码了: 这…

Flutter笔记:使用Flutter构建响应式PC客户端/Web页面-案例

Flutter笔记 使用Flutter构建响应式PC客户端/Web页面-案例 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/detai…

Python基础入门例程53-NP53 前10个偶数(循环语句)

最近的博文: Python基础入门例程52-NP52 累加数与平均值(循环语句)-CSDN博客 Python基础入门例程51-NP51 列表的最大与最小(循环语句)-CSDN博客 Python基础入门例程50-NP50 程序员节(循环语句)-CSDN博客 目录 最近的博文: 描…

TCSVT(IEEE Transactions on Circuits and Systems for Video Technology)期刊投稿指南

目录 TCSVT 期刊简介 TCSVT 期刊影响因子和分区​ 期刊官方网站 期刊投稿网址 投稿指南网址 稿件格式要求 稿件提交指南 A. 提交稿件 B. 手稿格式 C. 摘要指南 D. 提交图形的指南 E. 页面和彩色图形费用 TCSVT 期刊简介 IEEE Transactions on Circuits and Systems…

RGB颜色空间与BMP格式图片

RGB颜色空间 RGB可以分为两大类:一种是索引形式,一种是像素形式: 索引形式:存储每个像素在调色板中的索引 RGB1:每个像素用1bit表示,调色板中只包含两种颜色(黑白)RGB4&#xff1a…

恒源云之oss上传数据、云台下载数据

目录 一、本地cmd上传数据二、使用云平台下载数据 一、本地cmd上传数据 需要下载恒源云客户端oss需要先将数据(代码、数据集)压缩成zip文件。 本地cmd打开oss,测试是否安成功 oss输入oss命令,并正确输入账号密码 oss login在个人…

按键编程 pal库和标准库

按钮的电路设计 电路的搭建 原理与编程 创建了两个变量 用来捕捉按键的状态 先让两个变量都为1 previous和current都为1 (按键没按下) 然后让current去捕捉按键的状态通过读gpioA的pin0 如果为0就是按键按下 如果为1就是按键没按下 然后赋值给current …

U-Boot 图形化配置及其原理

目录 U-Boot 图形化配置体验menuconfig 图形化配置原理make menuconfig 过程分析Kconfig 语法简介 添加自定义菜单 在前两章中我们知道uboot 可以通过mx6ull_alientek_emmc_defconfig 来配置,或者通过文件mx6ull_alientek_emmc.h 来配置uboot。还有另外一种配置uboo…

理解快速排序

理解快速排序 首先了解以下快速排序 快速排序(QuickSort)是一种常用的排序算法,属于比较排序算法的一种。它是由英国计算机科学家Tony Hoare于1960年提出的,是一种分而治之(divide and conquer)的算法。 …

systemd-timesyncd

介绍 systemd-timesyncd 是一个用于跨网络同步系统时钟的守护服务。它实现了一个 SNTP 客户端。与NTP的复杂实现相比,这个服务简单的多,它只专注于从远程服务器查询然后同步到本地时钟。除非你打算为客户端提供 NTP 服务器或者连接本地硬件时钟&#xff…

Keras实现图注意力模型GAT

简介:本文实现了一个GAT图注意力机制的网络层,可以在Keras中像调用Dense网络层、Input网络层一样直接搭积木进行网络组合。 一,基本展示 如下图所示,我们输入邻接矩阵和节点特征矩阵之后,可以直接调用myGraphAttention…

第90步 深度学习图像分割:U-Net建模

基于WIN10的64位系统演示 一、写在前面 从这一期开始,我们杀个回马枪,继续学习深度学习图像分割系列,以为4090上岗了。 图像分割是计算机视觉的一个重要任务,目的是将数字图像分割成多个部分或区域,这些部分通常对应…

大话IEC104 规约

2. iec104 协议的帧结构 iec104 基于TCP/IP 传输,是一个应用层协议, 其帧结构被称为 APDU,APDU 一般由 APCI 和 ASDU组成。 2.1 APDU (Application Protocol Data Unit) APDU 被称为应用协议数据单元,也就是一个iec104 的协议帧…