IDL&python学习——实现根据有经纬度坐标的excel/csv表格提取相应影像的像元值

6 篇文章 0 订阅

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

平时在做遥感应用的时候经常会拿监测站点数据和遥感影像进行对比,然后做一些拟合什么的,本博客就是实现从有经纬度数据的excel/csv表格中提取相应影像的像元值。

示例表格数据:

IdXY
1108.9805453490034.49123985970
2109.5183035360036.41146489150
3110.0179903470033.55611168450
4107.8883727470032.75899224750
5107.7812970020033.97251736050
6109.7324550270037.55360617420
7108.2571892030037.17289241330
8109.0900005550033.68698203980
9109.9232084840035.62469610990
10107.9333842180034.81270504160
11110.0481301870035.53844064840
12108.3091407680033.82205610950
13108.8778319490034.01241299000

 

Python实现过程:

# encoding: utf-8
# author:三十二号星期八
# date :2021/2/1
import gdal
import os
import pandas as pd

def get_location_data(location,tif_files):
    f=tif_files
    print(f)
    tif_name = os.path.basename(f).split('_')[0]
    raster: gdal.Dataset = gdal.Open(f)
    geotransform = raster.GetGeoTransform()
    #获取栅格影像的左上角起始坐标,像元大小
    xOrigin = geotransform[0]
    yOrigin = geotransform[3]
    pixelWidth = geotransform[1]
    pixelHeight = geotransform[5]
    #创建一个空的数组,把for循环里面得到的值放到这个数组里面
    data = []
    for index, row in location.iterrows():
        long_value = row["X"]
        lat_value = row["Y"]
        print(lat_value)
        print(yOrigin)
        coord_x = long_value
        coord_y = lat_value
        #主要思路就是计算该坐标与该tif起始坐标差了多少行和列
        loc_x = int((float(coord_x) - xOrigin) / pixelWidth)
        loc_y = int((float(coord_y) - yOrigin) / pixelHeight)
        print(loc_y)
        #知道了多少行和列,就直接读这个行列对应数像元的数值大小,并把读到的数值追加到data这个空数组里面
        data_value = raster.GetRasterBand(1).ReadAsArray(loc_x, loc_y, 1, 1)[0, 0]
        data.append(data_value)
    location['NDVI_'+tif_name] = data
    print(location)
    return location

if __name__ == '__main__':
    excel_data = pd.read_excel(r'G:\0test\test\xj.xlsx')
    test_tif =r'G:\0test\test\xj.tif'
    out_data = get_location_data(excel_data,test_tif)
    #输出为另一个表格
    xls_name = r'G:\0test\test\location_value.xlsx'
    out_data.to_excel(xls_name)

IDL实现过程:

ps: IDL正常读取excel数据较难,所以我把测试的excel转成了csv格式,便于读取。

;encoding:GB2312
;author:YX
;date:2021-2-1
pro read_csv_value
compile_opt idl2
e=envi(/headless)
fn='G:\0test\test\xj.csv'
raster=e.openraster('G:\0test\test\xj.tif')
raster_data=raster.GetData()
data = read_csv(fn,count=nl,header=header)
LeftPoint_arr=raster.SPATIALREF.TIE_POINT_MAP
PIXEL_SIZE=raster.SPATIALREF.PIXEL_SIZE
minX=LeftPoint_arr[0]
maxY=LeftPoint_arr[1]
;同样创建一个空数组,存放数据
anglevalue_arr=make_array(4,nl)

for i=0,nl-1 do begin
  ;读取csv里面经纬度数值
  loc_X=data.field2[i]
  loc_Y=data.field3[i]
  ;计算该坐标对应的行列号
  sample=floor((loc_X-minX)/PIXEL_SIZE[0])
  line=floor((maxY-loc_Y)/PIXEL_SIZE[1])
  ;获取该行列号对应的栅格值
  anglevalue=raster_data[sample,line]
  ;把经纬度和对应的栅格值放到上面创建的三维数组里面
  anglevalue_arr[0,i]=i
  anglevalue_arr[1,i]=loc_X
  anglevalue_arr[2,i]=loc_Y
  anglevalue_arr[3,i]=anglevalue
endfor
;定义输出csv的header
header=['ID','X','Y','xj_tif_value']
;输出
write_csv,'G:\0test\test\IDL_location.csv',anglevalue_arr,header=header
end

结果,左边为python结果,右边为IDL结果

                                                                  

在这个过程中发现了两个小细节:

第一个小细节是计算该经纬度对应那一列的时候,在python里面是 

loc_y = int((float(coord_y) - yOrigin) / pixelHeight)

在IDL里面为:

line=floor((maxY-loc_Y)/PIXEL_SIZE[1])

python里面读取列方向的像元大小时,读出来是个负值,所以必须用低纬减去高纬(影像左上角的起始纬度),而在IDL里面读取列方向的像元大小时,读出来是个正值,所以要影像左上角的起始纬度减去表格的纬度,也就是高纬减低纬。

第二个小细节,就如下图所示,arcmap_value那一列字段的值是在arcmap里面用Spatial analyst——提取分析——值提取至点,这个工具提取出来的,但提取出来的值和IDL和Python里面的有几个不一样,右图是在arcmap里面识别出来的值,又和代码提出来的是一样样的。。。

                                          

所以,有没有人能解答一下这个疑惑呢?抱拳了~

  • 9
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三十二号星期八

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值