5公里范围内 经纬度判断_「技能技巧」Python根据经纬度批量提取遥感图像光谱信息...

以下代码,可以根据经纬度批量提取遥感影像光谱反射率信息,其实也就是提取特定经纬度的像元值。我找了一幅遥感影像,实验了一下,效果还是可以的,分享一下,如需自取。

实验材料:

1.一幅(也可多幅,不需拼接)经过辐射定标和QUAC大气校正的遥感影像(Landsat8,ENVI处理),包含DAT文件和HDR头文件;

2.一个包含经纬度信息的csv文件(虚拟的点);

如下图所示:

5公里范围内 经纬度判断_「技能技巧」Python根据经纬度批量提取遥感图像光谱信息..._第1张图片
5公里范围内 经纬度判断_「技能技巧」Python根据经纬度批量提取遥感图像光谱信息..._第2张图片

接下来,运行文章末尾的代码,运行过程和结果如下图

5公里范围内 经纬度判断_「技能技巧」Python根据经纬度批量提取遥感图像光谱信息..._第3张图片

将record文件内的提取内容经过整理后,与ENVI提取的光谱曲线对比,结果一致,如下所示,其中只提取了4个点,因为第5个点是在图像外,被过滤掉了

5公里范围内 经纬度判断_「技能技巧」Python根据经纬度批量提取遥感图像光谱信息..._第4张图片
5公里范围内 经纬度判断_「技能技巧」Python根据经纬度批量提取遥感图像光谱信息..._第5张图片

注意事项:

1.代码运行过程中对存在于图像边缘的点可能会存在范围上的误判,不过一般不影响结果。对于出现范围误判的点,在结果文件中会有“AN ERROR”字样出现,对个别误判的,手动查一下即可,一般没什么意义。本例中没有误判点,没法演示;

2.代码运行结果文件中包含有很多信息,包括从哪个图像提取了哪些点等等,对于冗余信息,利用excel可以很简单的处理掉,不再赘述;

3.代码运行过程中有很多‘Info:’信息,多关注信息有利于掌握代码运行规律;

4.代码已给出,使用可自取。有任何问题咱们可以一起探讨,

鄙人邮箱:[email protected]

公众号:科研萌新

以下是完整代码:

# -*- coding: utf-8 -*-"""@author:ai wo zhong hua"""from osgeo import gdalfrom osgeo import osrimport osimport numpy as npimport pandas as pdimport timegdal.AllRegister#find all files which end with '.dat'def Filenames(path):    f_num = 0    file_list = os.listdir(path)    filenames = []    for f in file_list:        if f.endswith('.dat'):            filenames.append(f)            f_num += 1        else:            pass    print('Info: {} files with suffix .dat were found.'.format(f_num))    return filenames# xy coordinate to lon-lat coordinatedef XY2Lonlat(gcs,pcs,x,y):    ct = osr.CoordinateTransformation(pcs,gcs)    lon,lat,_ = ct.TransformPoint(x,y)    return lon,lat#lon-lat coordinate to  xy coordinatedef Lonlat2XY(gcs,pcs,lon,lat):    ct = osr.CoordinateTransformation(gcs,pcs)    coor = ct.TransformPoint(lon,lat)    #coor[0] is lon,coor[1] is lat    return coor[0],coor[1]# xy coord to row-coldef XY2Rowcol(extend,x,y):    '''    Pay particular attention to whether x and y represent longitude     or latitude and how they relate to the index of rows and columns.    this is very important!    '''    c1 = extend[4] * (x - extend[0]) - extend[1] * (y - extend[3])    c2 = extend[2] * extend[4] - extend[5] * extend[1]    c = c1 / c2    r = (x - extend[0] - c * extend[2]) / extend[1]    row = int(np.floor(r))    col = int(np.floor(c))#    print(extend,c,r,x,y)    return col,row    #return the x-y coord about image top-left and low-rightdef RectCoor(extend,xsize,ysize):    lefttop_x = extend[0]    lefttop_y = extend[3]    lowright_x = extend[0] + ysize * extend[1] + xsize * extend[2]    lowright_y = extend[3] + ysize * extend[4] + xsize * extend[5]    return lefttop_x,lefttop_y,lowright_x,lowright_y# read the lon-lat file,return a list of all lon-lat#Determine whether the point is within the range of the imagedef ReadCoordFile(filename,lp_lon,lp_lat,lt_lon,lt_lat):    data = pd.read_csv(filename)    points = []    p = 0    total_point = len(data.iloc[:,0])    for n in range(total_point):        #determine the longitude        if data.iloc[n,0] >= lp_lon and data.iloc[n,0] <= lt_lon:            #determine the latitude            if data.iloc[n,1] >= lt_lat and data.iloc[n,1] <= lp_lat:                points.append(('{:.8f}'.format(data.iloc[n,0]),'{:.8f}'.format(data.iloc[n,1]),                               str(data.iloc[n,2])))                p += 1            else:                pass        else:            pass    print('Info: {0} points totally,{1} points in the image range.'.format(total_point,p))    return points#main functiondef main(dat_file_path,csv_file_path):    for file in Filenames(dat_file_path):        print('Info: Running: {}'.format(file))        stime = time.time()        dataset = gdal.Open(dat_file_path + '/' + file)        Bands = dataset.RasterCount #bands number        Xsize = dataset.RasterXSize #columns        Ysize = dataset.RasterYSize #rows#        pixel_nums = Xsize * Ysize        datatransform = dataset.GetGeoTransform()        projection = dataset.GetProjection()        pcs = osr.SpatialReference()        pcs.ImportFromWkt(projection)        gcs = pcs.CloneGeogCS()                #get image range:top-left and low-right        lefttop_x,lefttop_y,lowright_x,lowright_y = RectCoor(datatransform,                                                             Xsize,Ysize)        lefttop_lon,lefttop_lat = XY2Lonlat(gcs,pcs,lefttop_x,lefttop_y)        lowright_lon,lowright_lat = XY2Lonlat(gcs,pcs,lowright_x,lowright_y)        #        print(lefttop_lon,lefttop_lat,lowright_lon,lowright_lat)        #points that fit the range,return a list        points_list = ReadCoordFile(csv_file_path,lefttop_lon,                                    lefttop_lat,lowright_lon,lowright_lat)                if points_list:            with open(dat_file_path + '/record.txt','a') as record:                record.write(file + '')                record.write('name'+','+'lon'+','+'lat'+','+'0.443'+','+'0.4826'+','+'0.5613'+','                             +'0.6546'+','+'0.8646'+','+'1.609'+','+'2.201'+'')                for point in points_list:                    print('Info: Running {}...'.format(point))                    px,py = Lonlat2XY(gcs,pcs,float(point[0]),float(point[1]))                    row,col = XY2Rowcol(datatransform,px,py)                    record.write(str(point[2]) + ','+str(point[0])+','+str(point[1]))                    try:                         for i in range(1,Bands+1):                            datarray = dataset.GetRasterBand(i).ReadAsArray()                            record.write(','+str(datarray[row,col]))                    except Exception as e:                        print('ERROR: An error occurred,been recorded in txt:')                        print('ERROR: {}'.format(e))                        record.write(','+'AN ERROR'+'')                        continue                    record.write('')            pass        else:            print('Info: {} not contain any point.'.format(file))        etime = time.time()        print('Info: Processed Time: {:.4}s'.format(etime - stime))    passif __name__ == '__main__':    dat_file_path = 'E:/test'    csv_file_path = 'E:/test/lonlat.csv'    starttime = time.time()    main(dat_file_path,csv_file_path)    endtime = time.time()    proc_time = endtime - starttime    print('------Complete Successfully!------')    print(' Total Time: {:.4}s'.format(proc_time))

你可能感兴趣的:(5公里范围内,经纬度判断)