157 lines
5.6 KiB
Python
157 lines
5.6 KiB
Python
"""
|
||
@Project :microproduct
|
||
@File :DEMJoint
|
||
@Function :主函数
|
||
@Author :LMM
|
||
@Date :2021/10/19 14:39
|
||
@Version :1.0.0
|
||
"""
|
||
from osgeo import gdal, osr
|
||
import os
|
||
import numpy as np
|
||
|
||
|
||
class DEMProcess:
|
||
"""
|
||
DEM拼接、重采样
|
||
"""
|
||
def __init__(self):
|
||
pass
|
||
|
||
@staticmethod
|
||
def get_extent(fn):
|
||
'''
|
||
原文链接:https://blog.csdn.net/XBR_2014/article/details/85255412
|
||
'''
|
||
ds = gdal.Open(fn)
|
||
rows = ds.RasterYSize
|
||
cols = ds.RasterXSize
|
||
# 获取图像角点坐标
|
||
gt = ds.GetGeoTransform()
|
||
minx = gt[0]
|
||
maxy = gt[3]
|
||
maxx = gt[0] + gt[1] * rows
|
||
miny = gt[3] + gt[5] * cols
|
||
return (minx, maxy, maxx, miny)
|
||
|
||
@staticmethod
|
||
def img_mosaic(in_files, out_dem_path):
|
||
# 通过两两比较大小,将最终符合条件的四个角点坐标保存
|
||
# 即为拼接图像的四个角点坐标
|
||
minX, maxY, maxX, minY = DEMProcess.get_extent(in_files[0])
|
||
for fn in in_files[1:]:
|
||
minx, maxy, maxx, miny = DEMProcess.get_extent(fn)
|
||
minX = min(minX, minx)
|
||
maxY = max(maxY, maxy)
|
||
maxX = max(maxX, maxx)
|
||
minY = min(minY, miny)
|
||
|
||
# 获取输出图像的行列数
|
||
in_ds = gdal.Open(in_files[0])
|
||
bands_num = in_ds.RasterCount
|
||
gt = in_ds.GetGeoTransform()
|
||
rows = int((maxX - minX) / abs(gt[5]))
|
||
cols = int((maxY - minY) / gt[1])
|
||
|
||
# 判断栅格数据的数据类型
|
||
datatype = gdal.GDT_UInt16
|
||
|
||
# 创建输出图像
|
||
driver = gdal.GetDriverByName('GTiff')
|
||
out_dem = os.path.join(out_dem_path, 'mosaic0.tif')
|
||
out_ds = driver.Create(out_dem, cols, rows, bands_num, datatype)
|
||
out_ds.SetProjection(in_ds.GetProjection())
|
||
|
||
gt = list(in_ds.GetGeoTransform())
|
||
gt[0], gt[3] = minX, maxY
|
||
out_ds.SetGeoTransform(gt)
|
||
|
||
for fn in in_files:
|
||
in_ds = gdal.Open(fn)
|
||
x_size = in_ds.RasterXSize
|
||
y_size = in_ds.RasterYSize
|
||
trans = gdal.Transformer(in_ds, out_ds, [])
|
||
success, xyz = trans.TransformPoint(False, 0, 0)
|
||
x, y, z = map(int, xyz)
|
||
for i in range(1, bands_num + 1):
|
||
data = in_ds.GetRasterBand(i).ReadAsArray()
|
||
out_band = out_ds.GetRasterBand(i)
|
||
out_data = out_band.ReadAsArray(x, y, x_size, y_size)
|
||
data = np.maximum(data, out_data)
|
||
out_band.WriteArray(data, x, y)
|
||
|
||
del in_ds, out_band, out_ds
|
||
|
||
@staticmethod
|
||
def dem_clip(OutFilePath, DEMFilePath, SelectArea):
|
||
'''
|
||
根据选择范围裁剪DEM,并输出
|
||
agrs:
|
||
outFilePath:裁剪DEM输出地址
|
||
DEMFilePath:被裁减DEM地址
|
||
SelectArea:list [(xmin,ymax),(xmax,ymin)] 框选范围 左上角,右下角
|
||
'''
|
||
DEM_ptr = gdal.Open(DEMFilePath)
|
||
DEM_GeoTransform = DEM_ptr.GetGeoTransform() # 读取影像的投影变换
|
||
DEM_InvGeoTransform = gdal.InvGeoTransform(DEM_GeoTransform)
|
||
SelectAreaArrayPoints = [gdal.ApplyGeoTransform(DEM_InvGeoTransform, p[0], p[1]) for p in SelectArea]
|
||
SelectAreaArrayPoints = list(map(lambda p: (int(p[0]), int(p[1])), SelectAreaArrayPoints)) # 确定坐标
|
||
|
||
[(ulx, uly), (brx, bry)] = SelectAreaArrayPoints
|
||
rowCount, colCount = bry - uly, brx - ulx
|
||
|
||
# 输出DEM的桌面坐标转换
|
||
Out_Transfrom = list(DEM_GeoTransform)
|
||
Out_Transfrom[0] = SelectArea[0][0]
|
||
Out_Transfrom[3] = SelectArea[0][1]
|
||
|
||
# 构建输出DEM
|
||
Bands_num = DEM_ptr.RasterCount
|
||
gtiff_driver = gdal.GetDriverByName('GTiff')
|
||
datatype = gdal.GDT_UInt16
|
||
out_dem = gtiff_driver.Create(OutFilePath, colCount, rowCount, Bands_num, datatype)
|
||
out_dem.SetProjection(DEM_ptr.GetProjection())
|
||
out_dem.SetGeoTransform(Out_Transfrom)
|
||
|
||
for i in range(1, Bands_num + 1):
|
||
data_band = DEM_ptr.GetRasterBand(i)
|
||
out_band = out_dem.GetRasterBand(i)
|
||
data = data_band.ReadAsArray(ulx, uly, colCount, rowCount)
|
||
out_band.WriteArray(data)
|
||
del out_dem
|
||
|
||
@staticmethod
|
||
def dem_resample(in_dem_path, out_dem_path):
|
||
'''
|
||
DEM重采样函数,默认坐标系为WGS84
|
||
agrs:
|
||
in_dem_path: 输入的DEM文件夹路径
|
||
meta_file_path: 输入的xml元文件路径
|
||
out_dem_path: 输出的DEM文件夹路径
|
||
'''
|
||
# 读取文件夹中所有的DEM
|
||
dem_file_paths=[os.path.join(in_dem_path,dem_name) for dem_name in os.listdir(in_dem_path) if dem_name.find(".tif")>=0 and dem_name.find(".tif.")==-1]
|
||
spatialreference=osr.SpatialReference()
|
||
spatialreference.SetWellKnownGeogCS("WGS84") # 设置地理坐标,单位为度 degree # 设置投影坐标,单位为度 degree
|
||
spatialproj=spatialreference.ExportToWkt() # 导出投影结果
|
||
# 将DEM拼接成一张大图
|
||
mergeFile =gdal.BuildVRT(os.path.join(out_dem_path,"mergeDEM.tif"), dem_file_paths)
|
||
out_DEM=os.path.join(out_dem_path,"mosaic.tif")
|
||
gdal.Warp(out_DEM,
|
||
mergeFile,
|
||
format="GTiff",
|
||
dstSRS=spatialproj,
|
||
dstNodata=-9999,
|
||
outputType=gdal.GDT_Float32)
|
||
return out_DEM
|
||
|
||
|
||
# if __name__ == "__main__":
|
||
# DEMProcess = DEMProcess()
|
||
# in_dem_path = r'F:\大气延迟\out_dem'
|
||
# out_dem_path = r'F:\大气延迟\out_dem'
|
||
# DEMProcess.dem_resample(in_dem_path, out_dem_path)
|
||
|
||
|
||
|