ENVI_IDL:批量拼接Modis Swath的逐日数据并输出为Geotiff格式

简介: ENVI_IDL:批量拼接Modis Swath的逐日数据并输出为Geotiff格式

1. 实验内容:

批量拼接Modis Swath的逐日数据并输出为Geotiff格式

另外这里需要说一下:

有一个新的函数或许你没有学过: uniq()函数——》字面意思就是获取唯一值的索引,但是这个唯一值有点不一样。


函数解释:首先函数会返回一个数组arr


传入一个数组array,依次检索数组array的元素,每检索一个元素,获取该元素在array的索引。若检索下一个元素时,下一个元素与之前的元素不一样,那么函数会将上一个元素的索引放入到数组arr中;若检索下一个元素时,下一个元素与之前的元素一样,那么函数会继续检索下一个元素。怎么说呢?我举几个例子吧?



如果最后你还是没有理解uniq函数的意思,那么我只能说我解释不够好,你可以去官网查看该函数的解释。

最后,如果你已经理解了uniq函数,那么你可能会困惑这个函数的鸡肋,更会觉得代码里面使用uniq函数是否是不对的,这里我一开始也是比较纳闷的,但是需要多理解。最后对于代码uniq函数我只解释一点,代码可以使用uniq函数完全是因为重复值都是相邻的,如果不相邻,那么也是不可以用uniq函数的。


2. 编程

pro week_five_homework
  ; 本程序主要解决如何实现Modis Swath产品的每天数据的拼接(如果数据有重叠就均值处理)
  ; 路径
  in_path = 'D:/IDL_program/experiment_data/chapter_3/modis_swath/geo_out'
  out_path = 'D:/IDL_program/experiment_data/chapter_3/modis_swath/mosaic'
  if file_test(out_path, /DIRECTORY) eq 0 then begin
    ; 没有该目录就创建
    file_mkdir, out_path
  endif
  ; 如何寻找一天的数据不一定只有一张tiff文件,可能有多张,如何找到
  ; 获取in_path下所有tiff文件的绝对路径
  file_path_array = file_search(in_path, '*.tiff')  ; 在in_path目录下寻找tiff文件,以数组形式返回找到的所有文件的绝对路径
  ; 获取所有tiff文件的名称
  file_name_array = file_basename(file_path_array)
  ; 获取所有tiff文件中名称的日期
  file_date_array = strmid(file_name_array, 10, 7)
  ; 获取不重复日期的最后一个索引(也许你听的有点别扭,但你可以仔细阅读uniq()函数就明白了)
  file_date_uniq = uniq(file_date_array)  ; 这里如果你了解了uniq()函数的作用,那么你会疑惑,why?这是因为我们获取的时候,相同日期就是连在一起的, 所以可以得到唯一值
  ; 获取不重复日期的总个数
  file_date_count = n_elements(file_date_uniq)
  ; 输出tiff文件的分辨率(x、y均是一样的)
  out_resolution = 0.03
  ; 循环进行每天数据的拼接
  for file_date_i = 0, file_date_count - 1 do begin
    ; 获取in_path中该循环日期下的所有文件的路径(以数组形式返回)
    today_file_path_array = file_search(in_path, '*A' + file_date_array[file_date_uniq[file_date_i]] + '*.tiff')
    ; 该日期下的所有文件的个数
    today_file_count = n_elements(today_file_path_array)
    ; 由于file_search()函数若只有一个匹配结果,那么不会返回数组而是返回str,所以上面的n_elemen()函数对于str返回0
    ; 所以这里做一点改变
    if today_file_count eq 0 then begin
      today_file_count = 1
      today_file_path_array = [today_file_path_array]
    endif
    ; 获取这一天的所有文件的最大最小经纬度
    ; 预设值
    lon_min = 9999.0
    lon_max = -9999.0
    lat_min = 9999.0
    lat_max = -9999.0
    for today_file_i = 0, today_file_count - 1 do begin
      ; 获取该文件的路径
      today_file_path = today_file_path_array[today_file_i]
      ; 获取该文件的数据
      today_file_data = read_tiff(today_file_path, geotiff=geo_info)  ; 同时获取该tiff文件的地理信息(返回给了变量geo_info)
      ; 该数据的size
      today_file_data_size = size(today_file_data)
      ; 获取该数据的空间分辨率
      today_file_resolution = geo_info.(0)
      ; 获取该数据左上角点的地理信息
      today_file_loc = geo_info.(1)
      ; 获取该数据左上角点的经纬度坐标
      temp_lon_min = today_file_loc[3]
      temp_lat_max = today_file_loc[4]
      temp_lon_max = temp_lon_min + today_file_resolution[0] * today_file_data_size[1]
      temp_lat_min = temp_lat_max - today_file_resolution[1] * today_file_data_size[2]
      ; 如果有更大或更小的经纬度,那么替换
      if temp_lon_min lt lon_min then lon_min = temp_lon_min
      if temp_lat_max gt lat_max then lat_max = temp_lat_max
      if temp_lon_max gt lon_max then lon_max = temp_lon_max
      if temp_lat_min lt lat_min then lat_min = temp_lat_min
    endfor
    ; today所有的文件需要的行列数
    today_col = ceil((lon_max - lon_min) / out_resolution)
    today_row = ceil((lat_max - lat_min) / out_resolution)
    ; 下面这些是不需要的
;    ; 经纬度box初始化
;    today_lon_box = fltarr(today-col, today_row)
;    today_lat_box = fltarr(today-col, today_row)
;    ; 初始化值设定
;    today_lon_box[*, *] = -9999.0
;    today_lat_box[*, *] = -9999.0
    ; 装数据的sum_box初始化
    today_data_box = fltarr(today_col, today_row)
    ; num_box初始化
    today_data_num_box = fltarr(today_col, today_row)
    ; 循环获取该日期下的所有文件的数据并进行拼接
    for today_file_i = 0, today_file_count - 1 do begin
      ; 获取该文件路径
      today_file_path = today_file_path_array[today_file_i]
      ; 获取该文件的数据
      today_file_data = read_tiff(today_file_path, geotiff=geo_info)
      ; 该数据的size
      today_file_data_size = size(today_file_data)
      ; 获取该数据的空间分辨率
      today_file_resolution = geo_info.(0)
      ; 获取该数据左上角点的地理信息
      today_file_loc = geo_info.(1)
      ; 获取该数据左上角点的经纬度坐标
      temp_lon_min = today_file_loc[3]
      temp_lat_max = today_file_loc[4]
      ; 初始化行列数
      today_data_col_box = fltarr(today_file_data_size[1], today_file_data_size[2])
      today_data_row_box = fltarr(today_file_data_size[1], today_file_data_size[2])
      ; 该数据的在大box中的行列数
      for x_i = 0, today_file_data_size[1] - 1 do begin
        today_data_col_box[x_i, *] = ((temp_lon_min + today_file_resolution[0] * x_i) - lon_min) / out_resolution
      endfor
      for y_i = 0, today_file_data_size[2] - 1 do begin
        today_data_row_box[*, y_i] = (lat_max - (temp_lat_max - today_file_resolution[1] * y_i)) / out_resolution
      endfor
      ; 求和 和 频次 计入
      today_data_box[today_data_col_box, today_data_row_box] += today_file_data
      today_data_num_box[today_data_col_box, today_data_row_box] += (today_file_data gt 0)
    endfor
    ; 均值运算
    ; today_data_num_box优化
    today_data_num_box = (today_data_num_box gt 0) * today_data_num_box + (today_data_num_box eq 0)
    ; 运算
    today_data_aver_box = today_data_box / today_data_num_box
    ; 地理信息填写
    geo_info={$
      MODELPIXELSCALETAG:[out_resolution,out_resolution,0.0],$
      MODELTIEPOINTTAG:[0.0,0.0,0.0,lon_min,lat_max,0.0],$
      GTMODELTYPEGEOKEY:2,$
      GTRASTERTYPEGEOKEY:1,$
      GEOGRAPHICTYPEGEOKEY:4326,$
      GEOGCITATIONGEOKEY:'GCS_WGS_1984',$
      GEOGANGULARUNITSGEOKEY:9102,$
      GEOGSEMIMAJORAXISGEOKEY:6378137.0,$
      GEOGINVFLATTENINGGEOKEY:298.25722}
    ; 输出
    write_tiff, out_path + '/aver_' + file_date_array[file_date_uniq[file_date_i]] + '.tiff', today_data_aver_box, geotiff=geo_info, /float
  endfor
end


运行结果:



某一张拼接效果:



最后我想说的是,由于这次想睡觉,时间比较紧,所以代码肯定有很多冗余的部分,譬如,如果某一天tiff文件只有一个,那么我没有输出也是直接进入循环。最后的图片虽然大致是一样的,但是还是有很小的偏移,我就懒得改动了,相信你们可以自己直接输出!


目录
相关文章
|
1月前
GEE——Google dynamic world中在影像导出过程中无法完全导出较大面积影像的解决方案(投影的转换)EPSG:32630和EPSG:4326的区别
GEE——Google dynamic world中在影像导出过程中无法完全导出较大面积影像的解决方案(投影的转换)EPSG:32630和EPSG:4326的区别
59 0
|
1月前
|
定位技术 Python
Python ArcPy将多个文件夹内大量遥感影像批量四等分裁剪或切割为N×M个部分
Python ArcPy将多个文件夹内大量遥感影像批量四等分裁剪或切割为N×M个部分
Python ArcPy将多个文件夹内大量遥感影像批量四等分裁剪或切割为N×M个部分
|
1月前
|
存储 定位技术
ASD光谱仪.asd格式光谱曲线文件转换为.txt格式的方法
ASD光谱仪.asd格式光谱曲线文件转换为.txt格式的方法
|
1月前
|
XML 定位技术 数据格式
ENVI感兴趣区(ROI)文件由XML格式转换为ROI格式的方法
ENVI感兴趣区(ROI)文件由XML格式转换为ROI格式的方法
113 1
|
11月前
|
存储 C语言 索引
ENVI IDL:熟悉IDL语法+输出多幅TIFF影像的MAX文件和MEAN文件
ENVI IDL:熟悉IDL语法+输出多幅TIFF影像的MAX文件和MEAN文件
243 0
|
11月前
成信大ENVI_IDL第二周实验内容:提取所有MODIS气溶胶产品中AOD+详细解析
成信大ENVI_IDL第二周实验内容:提取所有MODIS气溶胶产品中AOD+详细解析
162 0
|
11月前
成信大ENVI_IDL第三周课堂内容1:读取OMI数据(HDF5文件)以及输出+解析
成信大ENVI_IDL第三周课堂内容1:读取OMI数据(HDF5文件)以及输出+解析
131 0
|
10月前
|
算法 Linux Python
SGAT丨基于R语言tidyverse的vcf转txt文件算法,SNP位点判断与自动校正,染色体格式替换
SGAT丨基于R语言tidyverse的vcf转txt文件算法,SNP位点判断与自动校正,染色体格式替换
|
10月前
|
Linux Shell 数据格式
Linux脚本丨批量提取VCF文件指定样本数据
Linux脚本丨批量提取VCF文件指定样本数据
|
10月前
|
算法 Linux Python
SGAT丨hapmap 格式hmp.txt文件转换,基因型和表型文件样品关联筛选提取的快速方法
SGAT丨hapmap 格式hmp.txt文件转换,基因型和表型文件样品关联筛选提取的快速方法