全國所有縣的12.5m分辨率DEM數據制作與分享


1.背景介紹

我網盤里有12.5m的全球分辨率數據,但是沒有分縣級單位裁剪的DEM數據。每一次使用都非常麻煩。

2.簡介

數字高程模型(Digital Elevation Model),簡稱DEM,是通過有限的地形高程數據實現對地面地形的數字化模擬。
目前能獲取到的最高的DEM數據是12.5m分辨率的ALOS衛星數據。原始數據下載網址為:https://urs.earthdata.nasa.gov.

3.數據制作

3.1 流程圖

總體思路是:全國12.5m的DEM數據篩選、按縣級單位進行裁剪、鑲嵌,結果數據后處理。

3.1數據准備工作

首先是下載數據,篩選出中國區的范圍。

3.2 DEM按省份、地級市、縣裁剪

3.2.1 腳本進行裁剪

使用python的RasterIO模塊進行單景的DEM讀取,使用Geooandas模塊操作省份矢量裁剪。這里暫時只放重要的裁剪腳本:

#裁剪函數
def clip(pathDir,shpdata,rasterfile):
    for i in tqdm(range(len(pathDir))):
        # 讀入柵格文件
        rasterfile = files_path+"\\"+pathDir[i]
        rasterdata = rio.open(rasterfile)
        #獲取柵格信息
        profile = rasterdata.profile
        #標識符
        note = pathDir[i]
        # 投影變換,使矢量數據與柵格數據投影參數一致
        shpdata = shpdata.to_crs(rasterdata.crs)
        # 按照所有矢量進行循環裁剪
        for j in range(0, len(shpdata)):
        try:
                # 獲取矢量數據的features
                geo = shpdata.geometry[j]
                #獲取該要素的屬性信息
                data_shp_name=shpdata.全稱[j]
                #文件保存位置的文件夾 各省
                data_filepath=str(data_shp_name)
                feature = [geo.__geo_interface__]
                # 通過feature裁剪柵格影像
                out_image, out_transform = rio.mask.mask(rasterdata, feature, all_touched=True, crop=True, nodata=0)
                profile.update(
                    height=out_image.shape[1],
                    width=out_image.shape[2],
                    shape=(out_image.shape[1],out_image.shape[2]),
                    nodata=0,
                    bounds=[],
                    transform=out_transform,
                    )
                # 定義要創建的目錄
                mkpath = "目錄名"
                # 檢測目錄是否存在
                mkdir(mkpath)
                # 文件名字
                name="文件名"
                with rasterio.open(name, mode='w', **profile) as dst:
                    dst.write(out_image)
        except:
                pass
                

裁剪后的影像單個縣會出現多張影像,因此需要進行鑲嵌。

3.2 DEM按縣級單位進行鑲嵌

遍歷所有地區的文件夾,鑲嵌使用gdal庫的Warp函數。

#鑲嵌一個文件夾中的所有文件
import os
from osgeo import gdal, gdalconst
import rasterio as rio
import rasterio.mask
import rasterio
from tqdm import tqdm

tifPath = '待鑲嵌文件的目錄'  # 待融合的圖像所在的文件夾

tifPaths_folder = os.listdir(tifPath)

# 循環目錄
for path in tqdm(tifPaths_folder):
    DEM_SMALL_PATH = os.path.join(tifPath, path)
    for (pathname, dirs, files) in os.walk(DEM_SMALL_PATH):
        son_Paths_file=files
    # 如果影像數量大於一
    if len(son_Paths_file) >= 2:
        DEM_SMALL_PATH2=DEM_SMALL_PATH+"\\"
        # 循環子目錄,進行鑲嵌
        #循環同一個文件下的tif文件
        inputFiles = []
        for path_small in son_Paths_file:
            # 每一個柵格的路徑
            son_Paths_PATH = os.path.join(DEM_SMALL_PATH2, path_small)
            #讀取影像
            inputrasfile = gdal.Open(son_Paths_PATH, gdal.GA_ReadOnly)  # 讀取影像

            inputProj = inputrasfile.GetProjection()  # 獲取坐標系


            inputFiles.append(inputrasfile)  # 推入列表

            options = gdal.WarpOptions(srcSRS=inputProj,  # 輸入坐標系
                                       dstSRS=inputProj,  # 輸出坐標系
                                       format='GTiff',  # 圖像格式
                                       resampleAlg=gdalconst.GRIORA_NearestNeighbour,  # 重采樣算法,這里是雙線性內插
                                       # dstNodata=Nodata,  # 缺省值
                                       #    cutlineLayer=outline,  # 輸出范圍,這里可以是一個外輪廓shp數據
                                       outputType=gdalconst.GDT_Int16)  # 數據類型,這里是有符號32位整型

        #輸出文件名
        outputfilePath =DEM_SMALL_PATH+"\\"+path+"_DEM"+"_12.5分辨率_ALOS數據"+".tif"
        #寫柵格
        gdal.Warp(outputfilePath, inputFiles, options=options)  # 圖像鑲嵌

3.3 數據后處理

主要是使用python腳本,對每一個省份文件夾中的結果影像進行重命名,並刪除多余的切片文件。這一步需要添加一個判定函數,判定是否為鑲嵌文件,
是則保留,不是則刪除。

# 刪除非融合的原始文件  並將單個影像重新命名
import os
# 待融合的圖像所在的文件夾
tifPath = '存儲縣級DEM的目錄'  # 待融合的圖像所在的文件夾

tifPaths_folder = os.listdir(tifPath)

# 循環目錄
for path in tifPaths_folder:
    DEM_SMALL_PATH = os.path.join(tifPath, path)
    for (pathname, dirs, files) in os.walk(DEM_SMALL_PATH):
        son_Paths_file=files
        # 如果影像數量大於一
        if len(son_Paths_file) >= 2:
            DEM_SMALL_PATH2=DEM_SMALL_PATH+"\\"
            # 循環子目錄,進行鑲嵌
            #循環同一個文件下的tif文件
            inputFiles = []
            for path_small in son_Paths_file:
                #判定不是鑲嵌影像,刪除
                if path_small.replace("_DEM_30m分辨率_ASTER數據.tif","")!=path:
                    # 每一個柵格的路徑
                    son_Paths_PATH = os.path.join(DEM_SMALL_PATH2, path_small)
                    os.remove(son_Paths_PATH)
        else:
            for (pathname, dirs, files) in os.walk(DEM_SMALL_PATH):
                son_Paths_file = files
            for path_small in son_Paths_file:
                DEM_SMALL_PATH2 = DEM_SMALL_PATH + "\\"
                son_Paths_PATH = os.path.join(DEM_SMALL_PATH2, path_small)
                new_name=DEM_SMALL_PATH2+path+"_DEM_12.5分辨率_ALOS數據.tif"
                os.rename(son_Paths_PATH,new_name)

4.結果展示

裁剪得到了全國2700多個縣12.5m的DEM影像。以加載四川省-資陽市-樂至縣的DEM數據為例。

首先選擇對應的省份、市,然后找到縣,下載數據,加載到arcgis中:

5.總結

1.使用gdal、geopandas可以很方面地使用矢量裁剪柵格。
2.此次鑲嵌的范圍只是基於縣的,沒有超出gdal默認的鑲嵌范圍,因此不需要設置輸出影像的范圍大小。如果輸出范圍過大,是需要設置輸出范圍的。
3.數據鑲嵌后,需要設置一個函數,批量刪除文件夾中的中間文件,參考節3.3;
4.針對全國的DEM數據分縣的裁剪,算法不是問題,電腦的算力才是主要問題。

6.數據分享

需要哪個縣的DEM數據,請在評論區留言,我會在12個小時內回復。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM