# -*- coding: UTF-8 -*- """ @Project :microproduct @File :SoilMoistureMain.py @Author :SHJ @Contact: @Date :2021/7/26 17:11 @Version :1.0.0 修改历史: [修改序列] [修改日期] [修改者] [修改内容] 1 2022-6-30 石海军 1.使用cover_roi_id来选取ROI区域; 2.内部处理使用地理坐标系(4326); """ import glob from osgeo import osr from tool.algorithm.algtools.PreProcess import PreProcess as pp from tool.algorithm.transforml1a.transHandle import TransImgL1A from tool.algorithm.xml.AlgXmlHandle import ManageAlgXML, CheckSource,InitPara # 导入xml文件读取与检查文件 from tool.algorithm.image.ImageHandle import ImageHandler from tool.algorithm.algtools.logHandler import LogHandler from SurfaceRoughnessAlg import MoistureAlg as alg from tool.algorithm.block.blockprocess import BlockProcess from tool.algorithm.algtools.MetaDataHandler import MetaDataHandler from tool.algorithm.xml.AnalysisXml import xml_extend from tool.algorithm.xml.CreateMetaDict import CreateMetaDict, CreateProductXml, OrthoAzimuth from tool.config.ConfigeHandle import Config as cf from tool.algorithm.xml.CreatMetafile import CreateMetafile from tool.algorithm.algtools.ROIAlg import ROIAlg as roi from SurfaceRoughnessXmlInfo import CreateDict, CreateStadardXmlFile from tool.algorithm.algtools.filter.lee_Filter import Filter from tool.file.fileHandle import fileHandle from SurfaceRoughnessTool import SoilMoistureTool import logging import os import shutil import datetime import numpy as np import sys import multiprocessing cover_id_list = [] threshold_of_ndvi_min = 0 threshold_of_ndvi_max = 0 multiprocessing_num = int(cf.get('multiprocessing_num')) tar = r'-' + cf.get('tar') productLevel = cf.get('productLevel') if cf.get('debug') == 'True': DEBUG = True else: DEBUG = False file =fileHandle(DEBUG) EXE_NAME = cf.get('exe_name') soil_moisture_value_min = float(cf.get('product_value_min')) soil_moisture_value_max = float(cf.get('product_value_max')) pixelspace=float(cf.get('pixelspace')) LogHandler.init_log_handler('run_log\\' + EXE_NAME) logger = logging.getLogger("mylog") # env_str = os.path.split(os.path.realpath(__file__))[0] env_str =os.path.dirname(os.path.abspath(sys.argv[0])) os.environ['PROJ_LIB'] = env_str class MoistureMain: """ 土壤水分处理主函数 """ def __init__(self, alg_xml_path): self.alg_xml_path = alg_xml_path self.imageHandler = ImageHandler() self.__alg_xml_handler = ManageAlgXML(alg_xml_path) self.__check_handler = CheckSource(self.__alg_xml_handler) self.__workspace_path, self.__out_para = None, None self.__input_paras, self.__output_paras, self.__processing_paras, self.__preprocessed_paras = {},{},{},{} # 参考影像路径 self.__ref_img_path = '' # 宽/列数,高/行数 self.__cols, self.__rows = 0, 0 # 坐标系 self.__proj = '' # 影像投影变换矩阵 self.__geo = [0, 0, 0, 0, 0, 0] self.name = '' def check_source(self): """ 检查算法相关的配置文件,图像,辅助文件是否齐全 """ env_str = os.getcwd() logger.info("sysdir: %s", env_str) if self.__check_handler.check_alg_xml() is False: return False if self.__check_handler.check_run_env() is False: return False input_para_names = ['box', 'DualPolarSAR'] if self.__check_handler.check_input_paras(input_para_names) is False: return False self.__workspace_path = self.__alg_xml_handler.get_workspace_path() self.__create_work_space() self.__input_paras = self.__alg_xml_handler.get_input_paras() self.__processing_paras = InitPara.init_processing_paras(self.__input_paras, self.__workspace_preprocessing_path) self.__processing_paras.update(self.get_tar_gz_inf(self.__processing_paras["sar_path0"])) SrcImageName = os.path.split(self.__input_paras["DualPolarSAR"]['ParaValue'])[1].split('.tar.gz')[0] result_name = SrcImageName + tar + ".tar.gz" self.__out_para = os.path.join(self.__workspace_path, EXE_NAME, 'Output', result_name) self.__alg_xml_handler.write_out_para("SurfaceRoughnessProduct", self.__out_para) #写入输出参数 logger.info('check_source success!') logger.info('progress bar: 10%') return True def get_tar_gz_inf(self, tar_gz_path): para_dic = {} self.name = os.path.split(tar_gz_path)[1].rstrip('.tar.gz') name = os.path.split(tar_gz_path)[1].rstrip('.tar.gz') file_dir = os.path.join(self.__workspace_preprocessing_path, name + '\\') file.de_targz(tar_gz_path, file_dir) # 元文件字典 # para_dic.update(InitPara.get_meta_dic(InitPara.get_meta_paths(file_dir, name), name)) para_dic.update(InitPara.get_meta_dic_new(InitPara.get_meta_paths(file_dir, name), name)) para_dic.update({'incXML': InitPara.get_incidence_xml_paths(file_dir, name)[0]}) # tif路径字典 parameter_path = os.path.join(file_dir, "orth_para.txt") para_dic.update({"paraMeter": parameter_path}) pol_dic = InitPara.get_polarization_mode(InitPara.get_tif_paths(file_dir, name)) flag_list = [0, 0, 0, 0] for key, in_tif_path in pol_dic.items(): # 获取极化类型 if 'HH' == key: para_dic.update({'HH': in_tif_path}) flag_list[0] = 1 elif 'HV' == key: para_dic.update({'HV': in_tif_path}) # 如果没有VV,用HV代替 flag_list[1] = 1 elif 'VV' == key: para_dic.update({'VV': in_tif_path}) flag_list[2] = 1 elif 'VH' == key: para_dic.update({'VH': in_tif_path}) flag_list[3] = 1 elif 'inc_angle' == key: para_dic.update({'inc_angle': in_tif_path}) elif 'ori_sim' == key: para_dic.update({'ori_sim': in_tif_path}) elif 'sim_ori' == key: para_dic.update({'sim_ori': in_tif_path}) elif 'LocalIncidenceAngle' == key: para_dic.update({'LocalIncidenceAngle': in_tif_path}) elif 'inci_Angle-ortho' == key: para_dic.update({'inci_Angle-ortho': in_tif_path}) elif 'LocalIncidentAngle-ortho' == key: para_dic.update({'LocalIncidentAngle-ortho': in_tif_path}) if flag_list != [1, 1, 1, 1]: raise Exception('There are not tar_gz path: HH、HV(VV)、IncidenceAngle in path:', tar_gz_path) self.processinfo = flag_list return para_dic def __create_work_space(self): """ 删除原有工作区文件夹,创建新工作区文件夹 """ self.__workspace_preprocessing_path = self.__workspace_path + EXE_NAME + r'\Temporary\preprocessing''\\' self.__workspace_preprocessed_path = self.__workspace_path + EXE_NAME + r'\Temporary\preprocessed''\\' self.__workspace_processing_path = self.__workspace_path + EXE_NAME + r'\Temporary\processing''\\' self.__workspace_block_tif_path = self.__workspace_path + EXE_NAME + r'\Temporary\blockTif''\\' self.__workspace_block_tif_processed_path = self.__workspace_path + EXE_NAME + r'\Temporary\blockTifProcessed''\\' self.__product_dic = self.__workspace_processing_path + 'product\\' path_list = [self.__workspace_preprocessing_path, self.__workspace_preprocessed_path, self.__workspace_processing_path, self.__workspace_block_tif_path, self.__workspace_block_tif_processed_path, self.__product_dic] file.creat_dirs(path_list) logger.info('create new workspace success!') def preprocess_handle(self): """ 预处理 """ # para_names = [] # p = pp() # self.__preprocessed_paras, scopes_roi = p.preprocessing_oh2004(para_names, self.__processing_paras, # self.__workspace_preprocessing_path, self.__workspace_preprocessed_path) para_names_geo = ['Covering', 'NDVI', 'sim_ori'] p = pp() p.check_img_projection(self.__workspace_preprocessing_path, para_names_geo, self.__processing_paras) # 计算roi scopes = () # scopes += (self.imageHandler.get_scope_ori_sim(self.__processing_paras['ori_sim']),) scopes += (xml_extend(self.__processing_paras['META']).get_extend(),) scopes += p.box2scope(self.__processing_paras['box']) # 计算图像的轮廓,并求相交区域 intersect_shp_path = self.__workspace_preprocessing_path + 'IntersectPolygon.shp' scopes_roi = p.cal_intersect_shp(intersect_shp_path, para_names_geo, self.__processing_paras, scopes) # 裁剪 # 裁剪图像:裁剪微波图像,裁剪其他图像 cutted_img_paths = p.cut_imgs(self.__workspace_preprocessing_path, para_names_geo, self.__processing_paras, intersect_shp_path) self.__preprocessed_paras.update(cutted_img_paths) l1a_width = ImageHandler.get_img_width(self.__processing_paras['HH']) l1a_height = ImageHandler.get_img_height(self.__processing_paras['HH']) self._tr = TransImgL1A(self.__processing_paras['sim_ori'], scopes_roi, l1a_height, l1a_width) # 裁剪图像 out_inc = os.path.join(self.__workspace_preprocessing_path, 'inc_angle.tif') ImageHandler.get_inc_angle(self.__processing_paras['incXML'], l1a_height, l1a_width, out_inc) self.__processing_paras.update({'inc_angle': out_inc}) para_names_l1a = ["HH", "VV", "HV", "VH"] for name in para_names_l1a: out_path = os.path.join(self.__workspace_preprocessed_path, name + "_preprocessed.tif") self._tr.cut_L1A(self.__processing_paras[name], out_path) self.__preprocessed_paras.update({name: out_path}) out_path = os.path.join(self.__workspace_preprocessed_path, "inc_angle" + "_preprocessed.tif") self._tr.cut_L1A_noMask(self.__processing_paras["inc_angle"], out_path) self.__preprocessed_paras.update({"inc_angle": out_path}) logger.info('preprocess_handle success!') self.__cols = self.imageHandler.get_img_width(self.__preprocessed_paras['HH']) self.__rows = self.imageHandler.get_img_height(self.__preprocessed_paras['HH']) logger.info('progress bar: 40%') def create_roi(self): """ 计算ROI掩膜 :return: 掩膜路径 """ processing_path = self.__workspace_processing_path # 利用角度为nan生成Mask pp.check_LocalIncidenceAngle(self.__preprocessed_paras['LocalIncidenceAngle'], self.__preprocessed_paras['LocalIncidenceAngle']) angle_nan_mask_path = processing_path + 'angle_nan_mask.tif' roi.trans_tif2mask(angle_nan_mask_path, self.__preprocessed_paras['LocalIncidenceAngle'], np.nan) # 利用影像的有效范围生成MASK tif_mask_path = processing_path + 'tif_mask.tif' roi.trans_tif2mask(tif_mask_path, self.__preprocessed_paras['HH'], 0, 0) # 0,0修改为np.nan tif_zero_mask_path = processing_path + 'tif_mask_zero.tif' roi.trans_tif2mask(tif_zero_mask_path, self.__preprocessed_paras['HH'], np.nan) # 利用cover计算植被覆盖范围 cover_mask_path = processing_path + 'cover_mask.tif' #alg.trans_tif2mask(cover_mask_path, self.__preprocessed_paras['Covering'], threshold_of_cover_min, threshold_of_cover_max) cover_id_list = list(self.__processing_paras['CoveringIDs'].split(';')) cover_id_list = [int(num) for num in cover_id_list] roi.trans_cover2mask(cover_mask_path, self.__preprocessed_paras["Covering"], cover_id_list) # 利用NDVI计算裸土范围该指数的输出值在 -1.0 和 1.0 之间,大部分表示植被量, # 负值主要根据云、水和雪而生成 # 接近零的值则主要根据岩石和裸土而生成。 # 较低的(小于等于 0.1)NDVI 值表示岩石、沙石或雪覆盖的贫瘠区域。 # 中等值(0.2 至 0.3)表示灌木丛和草地 # 较高的值(0.6 至 0.8)表示温带雨林和热带雨林。 ndvi_mask_path = processing_path + 'ndvi_mask.tif' ndvi_scope = list(self.__processing_paras['NDVIScope'].split(';')) threshold_of_ndvi_min = float(ndvi_scope[0]) threshold_of_ndvi_max = float(ndvi_scope[1]) roi.trans_tif2mask(ndvi_mask_path, self.__preprocessed_paras['NDVI'], threshold_of_ndvi_min, threshold_of_ndvi_max) logger.info('create masks success!') # 利用覆盖范围和裸土范围 生成MASK bare_land_mask_path = processing_path + 'bare_land_mask.tif' roi.combine_mask(bare_land_mask_path, cover_mask_path, ndvi_mask_path) roi.combine_mask(bare_land_mask_path, bare_land_mask_path, tif_mask_path) roi.combine_mask(bare_land_mask_path, bare_land_mask_path, tif_zero_mask_path) roi.combine_mask(bare_land_mask_path, bare_land_mask_path, angle_nan_mask_path) logger.info('combine_mask success!') # 计算roi区域 roi.cal_roi(self.__preprocessed_paras['LocalIncidenceAngle'], self.__preprocessed_paras['LocalIncidenceAngle'], bare_land_mask_path, background_value=1) shutil.copyfile(bare_land_mask_path, self.__workspace_preprocessed_path + 'mask.tif') logger.info('create ROI image success!') return bare_land_mask_path def resampleImgs(self, refer_img_path): ndvi_rampling_path = self.__workspace_processing_path + "ndvi.tif" pp.resampling_by_scale(self.__preprocessed_paras["NDVI"], ndvi_rampling_path, refer_img_path) self.__preprocessed_paras["NDVI"] = ndvi_rampling_path cover_rampling_path = self.__workspace_processing_path + "cover.tif" pp.resampling_by_scale(self.__preprocessed_paras["Covering"], cover_rampling_path, refer_img_path) self.__preprocessed_paras["Covering"] = cover_rampling_path def calInterpolation_bil_Wgs84_rc_sar_sigma(self, parameter_path, dem_rc, in_sar, out_sar): ''' # std::cout << "mode 11"; # std::cout << "SIMOrthoProgram.exe 11 in_parameter_path in_rc_wgs84_path in_ori_sar_path out_orth_sar_path"; ''' exe_path = r".\baseTool\x64\Release\SIMOrthoProgram.exe" exe_cmd = r"set PROJ_LIB=.\baseTool\x64\Release; & {0} {1} {2} {3} {4} {5}".format(exe_path, 11, parameter_path, dem_rc, in_sar, out_sar) print(exe_cmd) print(os.system(exe_cmd)) print("==========================================================================") def process_handle(self,start): """ 算法主处理函数 :return: True or False """ tem_folder = self.__workspace_path + EXE_NAME + r"\Temporary""\\" soilOh2004 = SoilMoistureTool(self.__workspace_preprocessed_path, self.__workspace_processing_path, self.__cols, self.__rows, self.__preprocessed_paras['inc_angle'], self.__processing_paras['Origin_META']) result = soilOh2004.soil_oh2004() logger.info('progress bar: 80%') product_temp_path = os.path.join(tem_folder, 'SurfaceRoughnessProduct_temp.tif') tif_files = list(glob.glob(os.path.join(result, '*.tif'))) for tif_file in tif_files: if 'oh2004_s' in os.path.basename(tif_file): shutil.copy(tif_file, product_temp_path) product_geo_path = os.path.join(tem_folder, 'SurfaceRoughnessProduct_geo.tif') self.calInterpolation_bil_Wgs84_rc_sar_sigma(self.__processing_paras['paraMeter'], self.__preprocessed_paras['sim_ori'], product_temp_path, product_geo_path) # self.inter_Range2Geo(self.__preprocessed_paras['ori_sim'], product_temp_path, product_geo_path, pixelspace) # self._tr.l1a_2_geo_int(self.__preprocessed_paras['ori_sim'], product_temp_path, product_geo_path, 'linear') # # hh_geo_path = self.__workspace_processing_path + "hh_geo.tif" # self._tr.l1a_2_geo_int(self.__preprocessed_paras['ori_sim'], self.__preprocessed_paras['HH'], hh_geo_path, 'linear') self.resampleImgs(product_geo_path) para_names = ['Covering', 'NDVI'] bare_land_mask_path = roi().roi_process(para_names, self.__workspace_processing_path + "/roi/", self.__processing_paras, self.__preprocessed_paras) SrcImageName = os.path.split(self.__input_paras["DualPolarSAR"]['ParaValue'])[1].split('.tar.gz')[0] + tar + '.tif' product_path = os.path.join(self.__product_dic, SrcImageName) # 获取影像roi区域 roi.cal_roi(product_path, product_geo_path, bare_land_mask_path, background_value=-9999) # 生成快视图 self.imageHandler.write_quick_view(product_path) # 生成元文件案例 xml_path = "./model_meta.xml" image_path = product_path out_path1 = os.path.join(tem_folder, "trans_geo_projcs.tif") out_path2 = os.path.join(tem_folder, "trans_projcs_geo.tif") # par_dict = CreateDict(image_path, self.processinfo, out_path1, out_path2).calu_nature(start) # model_xml_path = os.path.join(tem_folder, "creat_standard.meta.xml") # 输出xml路径 # # id_min = 0 # id_max = 1000 # threshold_of_ndvi_min = 0 # threshold_of_ndvi_max = 1 # set_threshold = [id_max, id_min, threshold_of_ndvi_min, threshold_of_ndvi_max] # CreateStadardXmlFile(xml_path, self.alg_xml_path, par_dict, set_threshold, model_xml_path).create_standard_xml() # SrcImagePath = self.__input_paras["DualPolarSAR"]['ParaValue'] paths = SrcImagePath.split(';') SrcImageName=os.path.split(paths[0])[1].split('.tar.gz')[0] # if len(paths) >= 2: # for i in range(1, len(paths)): # SrcImageName=SrcImageName+";"+os.path.split(paths[i])[1].split('.tar.gz')[0] # meta_xml_path = self.__product_dic + EXE_NAME + "Product.meta.xml" # CreateMetafile(self.__processing_paras['META'], self.alg_xml_path, model_xml_path, meta_xml_path).process(SrcImageName) # 文件夹打包 model_path = "./product.xml" meta_xml_path = os.path.join(self.__product_dic, SrcImageName + tar + ".meta.xml") para_dict = CreateMetaDict(image_path, self.__processing_paras['Origin_META'], self.__workspace_processing_path, out_path1, out_path2).calu_nature() Azimuth_incidence = OrthoAzimuth.read_Azimuth_incidence(self.__processing_paras['META']) para_dict.update({"imageinfo_ProductName": "地表粗糙度"}) para_dict.update({"imageinfo_ProductIdentifier": "SurfaceRoughness"}) para_dict.update({"imageinfo_ProductLevel": productLevel}) para_dict.update({"ProductProductionInfo_BandSelection": "1,2"}) para_dict.update({"ObservationGeometry_SatelliteAzimuth": Azimuth_incidence}) CreateProductXml(para_dict, model_path, meta_xml_path).create_standard_xml() temp_folder = os.path.join(self.__workspace_path, EXE_NAME, 'Output') out_xml = os.path.join(temp_folder, os.path.basename(meta_xml_path)) if os.path.exists(temp_folder) is False: os.mkdir(temp_folder) # CreateProductXml(para_dict, model_path, out_xml).create_standard_xml() shutil.copy(meta_xml_path, out_xml) file.make_targz(self.__out_para, self.__product_dic) logger.info('process_handle success!') logger.info('progress bar: 100%') def del_temp_workspace(self): """ 临时工作区 """ if DEBUG is False: path = self.__workspace_path + EXE_NAME + r'\Temporary' if os.path.exists(path): file.del_folder(path) if __name__ == '__main__': multiprocessing.freeze_support() start = datetime.datetime.now() try: if len(sys.argv) < 2: xml_path = 'SurfaceRoughness.xml' else: xml_path = sys.argv[1] main_handler = MoistureMain(xml_path) if main_handler.check_source() is False: raise Exception('check_source() failed!') if main_handler.preprocess_handle() is False: raise Exception('preprocess_handle() failed!') if main_handler.process_handle(start) is False: raise Exception('process_handle() failed!') logger.info('successful production of ' + EXE_NAME + ' products!') except Exception: logger.exception('run-time error!') finally: main_handler.del_temp_workspace() pass end = datetime.datetime.now() msg = 'running use time: %s ' % (end - start) logger.info(msg)