173 lines
6.6 KiB
Python
173 lines
6.6 KiB
Python
#!/usr/bin/env python3
|
||
|
||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
# LAMP License
|
||
#
|
||
# Author: chenzenghui
|
||
# time: 2023.06.04
|
||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
# 自定义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)
|
||
demImage.initImage(outname,'write',width,type="float")
|
||
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())
|