resterio融合tif

文章介绍了如何使用Python和QGIS工具对tif影像进行顺序融合,包括读取qlr文件获取图像顺序,重投影到特定坐标系并调整分辨率,最后进行tif图片的拼接。
摘要由CSDN通过智能技术生成

按照规定顺序融合tif,需要tif路径有序写入列表。

使用qgis打开各个影像,调整tif顺序,如下图所示选中所有文件(或选中需要合并的tif图层)导出为图层定义文件(.qlr文件),放到与当前工程文件(.qgz文件)相同目录下。(无序融合tif,直接os.listdir)

import os
import sys
import rasterio
from rasterio.merge import merge
from rasterio.warp import calculate_default_transform, reproject, Resampling
from rasterio.crs import CRS
from rasterio import Affine

def mk_dir(path,a=0):
    if os.path.exists(path):
        path=mk_dir(path.replace(f"_({a})","")+f"_({a+1})",a=a+1)
    else:
        os.makedirs(path)
    return path

def remove_dir(dir):
    import shutil
    if os.path.exists(dir):
        shutil.rmtree(dir)

def get_tifpath_list(folder):
    path_list=os.listdir(folder)
    tifpath_list=[folder+os.sep+i for i in path_list if ".tif"==i[-4:]]
    return tifpath_list

# 重投影,坐标系修改
def raster_resamping(path,save,_crs=False,ac=False):
    """
    :param path: 原始tif
    :param save: 输出tif
    :param _crs: 坐标系,默认False按照原始图像的坐标系
    :param ac: 输出分辨率(m),默认False按照原始图像分辨率
    :return:
    """

    if os.path.exists(save):
        print("文件已存在!!!",save)
        return save
    if _crs:
        dst_crs = CRS.from_epsg(_crs)

    with rasterio.open(path) as src:
        if not _crs:
            dst_crs = src.crs

        if not ac :
            ac=Affine.to_gdal(src.transform)[1]

        if src.crs == dst_crs and ac==Affine.to_gdal(src.transform)[1]:  # 坐标系和分辨率没有变化,跳过
            print("目标tif,与原tif一致,end!",path)
            return path

        try:
            transform, width, height = calculate_default_transform(
                src.crs,
                dst_crs,
                src.width,
                src.height,
                resolution=(ac,ac),  # 输出图像分辨率,单位m
                *src.bounds)
        except:
            print("计算错误!end!")
            return  # 计算错误跳过这张tif
        kwargs = src.meta.copy()
        kwargs.update(
            {"crs": dst_crs, "transform": transform, "width": width, "height": height, "compress": 'lzw'}
        )

        with rasterio.open(save, "w", **kwargs) as dst:
            for i in range(1, src.count + 1):
                reproject(
                    source=rasterio.band(src, i),
                    destination=rasterio.band(dst, i),
                    src_transform=src.transform,
                    src_crs=src.crs,
                    dst_transform=transform,
                    dst_crs=dst_crs,
                    resampling=Resampling.nearest
                )
        print("重投影已完成!!!",save)
        return save


# 读取.qlr文件获取tif顺序
def read_qlr(path):

    path_dirname=os.path.dirname(os.path.abspath(path))

    with open(path, "r", encoding='UTF-8') as f:
        res = f.read()
    from bs4 import BeautifulSoup

    soup = BeautifulSoup(res, 'html.parser')
    all = soup.find_all('layer-tree-layer')

    # 文件列表
    tifpath_list = []
    for li_all in all:
        tif_path = li_all.attrs["source"]
        if tif_path[-4:] == ".tif":
            if not os.path.exists(tif_path):
                tif_path=os.path.join(path_dirname,tif_path.split("./")[-1] ) # 将相对路径改为绝对路径
            tifpath_list.append(tif_path)

    return tifpath_list



def tif_stitch(tifpath_list, save):
    print(f"{len(tifpath_list)}张图,开始拼接tif!!!!!")

    src_files_to_mosaic = [rasterio.open(i) for i in tifpath_list]

    dst_data, out_trans = merge(src_files_to_mosaic)
    out_meta = src_files_to_mosaic[0].meta.copy()
    out_meta.update({"driver": "GTiff",
                     "height": dst_data.shape[1],
                     "width": dst_data.shape[2],
                     "transform": out_trans
                     }
                    )
    # 保存文件
    with rasterio.open(save, "w", **out_meta) as dest:
        dest.write(dst_data)

def main(path, save,_crs=False,pix=False):

    if os.path.exists(save):
        print("文件已存在!")
        return None
    # 读取.qlr文件获取tif顺序
    tifpath_list=read_qlr(path)

    # tifpath_list=get_tifpath_list(path)

    print(f"共{len(tifpath_list)}张图需要融合")
    # 重投影、坐标转换
    temp_files= mk_dir('temp')
    tifpath_list=[raster_resamping(i,f"{temp_files}/{os.path.basename(i)}",_crs=_crs, ac=pix) for i in tifpath_list if raster_resamping(i,f"{temp_files}/{os.path.basename(i)}",_crs=_crs, ac=pix) !=None]


    # 拼接tif
    tif_stitch(tifpath_list, save)

    # # 删除过程文件
    # remove_dir(temp_files)
    print("融合成功!!!!!!")


if __name__ == '__main__':
    # path = sys.argv[1] #  .qlr文件路径
    # save = sys.argv[2] # 保存文件地址

    path = r"D:\Desktop\demo_tif\demo.qlr"
    save = r"merge_demo.tif"
    main(path, save,_crs=3857,pix=0.1)










  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值