2023-04-11 08:33:59 +00:00
#!/usr/bin/env python3
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# LAMP License
#
# Author: chenzenghui
2023-06-04 02:25:30 +00:00
# time: 2023.06.04
2023-04-11 08:33:59 +00:00
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 自定义dem管理
# 1. 创建二进制文件 ENVI hdr
# 2. 读取文件构建.vrt .xml
import argparse
import isce
from ctypes import cdll , c_char_p , c_int , byref
from array import array
import struct
import zipfile
import os
import sys
import math
import urllib . request , urllib . parse , urllib . error
from isce import logging
from iscesys . Component . Component import Component
from isceobj . Image import createDemImage
from osgeo import gdal , osr , ogr
import xml . etree . ElementTree as ET
from html . parser import HTMLParser
import time
class DEM2ISCE ( Component ) :
def dem_merged ( self , 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 = in_dem_path #[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拼接成一张大图
out_DEM = out_dem_path
gdal . Warp ( out_DEM ,
dem_file_paths ,
format = " ENVI " ,
dstSRS = spatialproj ,
dstNodata = self . _NoDataValue ,
outputType = gdal . GDT_Float32 )
time . sleep ( 3 )
return out_DEM
#this method also create an actual DeimImage object that is returned by the getImage() method
def createXmlMetadata ( self , outname ) :
demImage = self . createImage ( outname )
demImage . renderHdr ( )
def getDemWidth ( self , outname ) :
gdal . AllRegister ( )
dataset = gdal . Open ( outname )
width = dataset . RasterXSize
del dataset
return width
def getDemHeight ( self , outname ) :
gdal . AllRegister ( )
dataset = gdal . Open ( outname )
height = dataset . RasterYSize
del dataset
return height
def getGeotransform ( self , outname ) :
gdal . AllRegister ( )
dataset = gdal . Open ( outname )
geotransform = dataset . GetGeoTransform ( )
del dataset
return geotransform
def createImage ( self , outname ) :
demImage = createDemImage ( )
width = self . getDemWidth ( outname )
height = self . getDemHeight ( outname )
2023-12-06 09:44:22 +00:00
demImage . initImage ( outname , ' write ' , width , type = " float " )
2023-04-11 08:33:59 +00:00
length = demImage . getLength ( )
# 获取分辨率
geotransform = self . getGeotransform ( outname )
dictProp = { ' METADATA_LOCATION ' : outname + ' .xml ' , ' REFERENCE ' : self . _reference , ' Coordinate1 ' : { ' size ' : width , ' startingValue ' : geotransform [ 0 ] , ' delta ' : geotransform [ 1 ] } , ' Coordinate2 ' : { ' size ' : length , ' startingValue ' : geotransform [ 3 ] , ' delta ' : geotransform [ 5 ] } , ' FILE_NAME ' : outname }
#no need to pass the dictionaryOfFacilities since init will use the default one
demImage . init ( dictProp )
self . _image = demImage
return demImage
def setFillingValue ( self , val ) :
self . _fillingValue = val
def setNoDataValue ( self , val ) :
self . _NoDataValue = val
def stitchDems ( self , source , outname ) :
import glob
# 合并数据
self . dem_merged ( source , outname )
self . createXmlMetadata ( outname )
family = ' DEM2ISCE '
def __init__ ( self , family = ' ' , name = ' ' ) :
self . _extension = ' .tif '
self . _zip = ' .zip '
#to make it working with other urls, make sure that the second part of the url
#it's /srtm/version2_1/SRTM(1,3)
self . _filters = { ' region1 ' : [ ' Region ' ] , ' region3 ' : [ ' Africa ' , ' Australia ' , ' Eurasia ' , ' Islands ' , ' America ' ] , ' fileExtension ' : [ ' .hgt.zip ' ] }
self . _remove = [ ' .jpg ' ]
self . _metadataFilename = ' fileDem.dem '
self . _createXmlMetadata = None
self . _createRscMetadata = None
self . _regionList = { ' 1 ' : [ ] , ' 3 ' : [ ] }
##self._keepDems = False
self . _fillingFilename = ' filling.hgt ' # synthetic tile to cover holes
##self._fillingValue = -32768 # fill the synthetic tile with this value
##self._noFilling = False
self . _failed = ' failed '
self . _succeded = ' succeded '
self . _image = None
self . _reference = ' EGM96 '
super ( DEM2ISCE , self ) . __init__ ( family if family else self . __class__ . family , name = name )
# logger not defined until baseclass is called
if not self . logger :
self . logger = logging . getLogger ( ' isce.contrib.demUtils.DEM2ISCE ' )
def getImage ( self ) :
return self . _image
# DEM转换主流程
def processDEM2ISCE ( name , source_path , target_path , fillvalue , noDataValue ) :
ds = DEM2ISCE ( name = name )
# 构建
ds . setFillingValue ( fillvalue )
ds . setNoDataValue ( noDataValue )
ds . stitchDems ( source_path , target_path )
def main ( ) :
#if not argument provided force the --help flag
if ( len ( sys . argv ) == 1 ) :
sys . argv . append ( ' -h ' )
# Use the epilog to add usage examples
epilog = ' 将格式为tif 的DEM 转换为ISCE 支持的DEM格式: \n \n '
epilog + = ' Usage examples: \n \n '
epilog + = ' DEM2ISCE.py -s /mnt/d/codestorage/isce2/青海省.tif -o /mnt/d/codestorage/isce2/青海省_wgs84 -fillvalue -9999 -Nodata -9999 \n \n '
#set the formatter_class=argparse.RawDescriptionHelpFormatter otherwise it splits the epilog lines with its own default format
parser = argparse . ArgumentParser ( formatter_class = argparse . RawDescriptionHelpFormatter , epilog = epilog )
parser . add_argument ( ' -s ' , ' --source ' , type = str , default = " /mnt/d/codestorage/isce2/青海省.tif " , dest = ' source_path ' , help = ' 输入dem,格式为tif ' )
parser . add_argument ( ' -o ' , ' --outpath ' , type = str , default = ' /mnt/d/codestorage/isce2/青海省_wgs84 ' , dest = ' outpath ' , help = ' 输出isce 支持的DEM ' )
parser . add_argument ( ' -fillvalue ' , ' --fillvalue ' , type = float , default = - 9999 , dest = ' fillvalue ' , help = ' 空值填充 ' )
parser . add_argument ( ' -Nodata ' , ' --Nodata ' , type = float , default = - 9999 , dest = ' Nodatavalue ' , help = ' 无效值填充 ' )
args = parser . parse_args ( )
processDEM2ISCE ( " DEM2ISCE " , args . source_path , args . outpath , args . fillvalue , args . Nodatavalue )
return - 1
if __name__ == ' __main__ ' :
sys . exit ( main ( ) )