# -*- coding: UTF-8 -*- """ @Project :microproduct @File :BackscatteringMain.py @Function :后向散射 @Author :KHZ @Contact: @Date :2021/9/1 @Version :1.0.0 """ import logging from tool.algorithm.algtools.logHandler import LogHandler from tool.algorithm.block.blockprocess import BlockProcess from tool.algorithm.xml.AlgXmlHandle import ManageAlgXML, CheckSource from tool.algorithm.xml.AnalysisXml import DictXml from tool.algorithm.xml.CreateMetaDict import CreateMetaDict, CreateProductXml from tool.algorithm.image.ImageHandle import ImageHandler from tool.algorithm.algtools.PreProcess import PreProcess as pp from BackScatteringAlg import IndirectOrthorectification, DEMProcess,rpc_correction,getRCImageRC,get_RPC_lon_lat,getRCImageRC2 from BackScatteringAlg import ScatteringAlg as alg from tool.config.ConfigeHandle import Config as cf import os import glob import datetime import shutil import tarfile import sys if cf.get('debug') == 'True': DEBUG = True else: DEBUG = False EXE_NAME = cf.get('exe_name') tar = cf.get('target') productLevel = cf.get('productLevel') 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 ScatteringMain: """ 后向散射系数主函数 """ 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 = None self.__task_id = None self.__input_paras = {} self.__output_paras = {} self.__in_processing_paras = {} self.__out_para = None self.__preprocessed_paras = {} self.__tif_names_list = [] self.__feature_name_list = [] def check_source(self): """ 检查算法相关的配置文件,图像,辅助文件是否齐全 """ 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 = ["SLC","DEM"] 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.__task_id = self.__alg_xml_handler.get_task_id() self.__input_paras = self.__alg_xml_handler.get_input_paras() self.__in_processing_paras = self.__init_processing_paras(self.__input_paras, self.__workspace_preprocessing_path) SrcImageName = os.path.split(self.__input_paras["SLC"]['ParaValue'])[1].split('.tar.gz')[0] # AlgorithmName = self.__alg_xml_handler.get_algorithm_name() # TaskId = self.__alg_xml_handler.get_task_id() result_name = SrcImageName + "-" + tar + ".tar.gz" # out_name = os.path.splitext(os.path.splitext(os.path.basename(self.__input_paras['SLC']['ParaValue']))[0])[0] # self.__out_para = os.path.join(self.__workspace_path, EXE_NAME, 'Output', "BackScatteringProduct.tar.gz") self.__out_para = os.path.join(self.__workspace_path, EXE_NAME, 'Output', result_name) self.__alg_xml_handler.write_out_para("BackScatteringProduct", self.__out_para) # 写入输出参数 logger.info('check_source success!') logger.info('progress bar: 30%') return True def __init_processing_paras(self, names, out_path): """ :param names:字典列表,每个字典为一个输入产品的配置信息 """ processing_paras = {} for name in names: para = self.__input_paras[name] if para is None: logger.error(name + "is None!") return False if para['ParaType'] == 'File': if para['DataType'] == 'File': processing_paras.update({name: para['ParaValue']}) # if para['DataType'] == 'csv': # para_value_list = para['ParaValue'].split(";") # if len(para_value_list) == 1: # para_path = para['ParaValue'] # processing_paras.update({name: para_path}) # else: # for n, para_value in zip(range(len(para_value_list)), para_value_list): # processing_paras.update({'feature'+str(n): para_value}) # self.__feature_name_list.append('feature'+str(n)) elif para['DataType'] == 'tar.gz': paths = para['ParaValue'].split(';') for path in paths: tar_gz_dic = self.__dec_tar_gz(path, self.__workspace_preprocessing_path) processing_paras.update(tar_gz_dic) elif para['DataType'] == 'zip': # temp_para = para['ParaValue'].split(".")[0] para_value_list = para['ParaValue'].split(";") if len(para_value_list) == 1: para_path = para['ParaValue'] if para_path != 'empty' and para_path != '': file_path = BlockProcess.unzip_file(para_path, out_path) processing_paras.update({name: os.path.dirname(file_path)}) else: file_path = DEMProcess.unzip_file(para['ParaValue'], out_path) processing_paras.update({name: file_path}) elif para['DataType'] == 'tif' or para['DataType'] == 'tiff': # 新增修改dem数据为文件绝对路径 if para['ParaValue'] != 'empty' and para['ParaValue'] != 'Empty' and para['ParaValue'] != '': para_path_list = para['ParaValue'].split(";") if len(para_path_list) != 0: dem_path = os.path.join(self.__workspace_origin_path, para['ParaName']) if os.path.exists(dem_path) is False: os.mkdir(dem_path) for file_path in para_path_list: tif_name = os.path.basename(file_path) shutil.copy(file_path, os.path.join(dem_path, tif_name)) para_path = os.path.join(self.__workspace_origin_path, para['ParaName']) processing_paras.update({name: para_path}) else: para_path = para['ParaValue'] processing_paras.update({name: para_path}) elif para['ParaType'] == 'Value': if para['DataType'] == 'float': value = float(para['ParaValue']) elif para['DataType'] == 'int': value = int(para['ParaValue']) else: # 默认string value = para['ParaValue'] processing_paras.update({name: value}) return processing_paras def __dec_tar_gz(self, tar_gz_path, out_dir): """ 解压.tar_gz格式景影像文件 :param tar_gz_path:.tar_gz文件路径 :param out_dir:输出文件夹 :return para_dic:全极化影像路径 """ # 创建文件夹 name = os.path.split(tar_gz_path)[1].rstrip('.tar.gz') file_dir = os.path.join(out_dir, name + '\\') if os.path.exists(file_dir) is False: os.makedirs(file_dir) # 解压 t = tarfile.open(tar_gz_path) t.extractall(path=file_dir) # 获取文件夹内的文件 para_dic = {} # if os.path.exists(file_dir + name + '\\'): # meta_xml_paths = list(glob.glob(os.path.join(file_dir + name, '*.meta.xml'))) # para_dic.update({'SLC': file_dir + name}) # else: # meta_xml_paths = list(glob.glob(os.path.join(file_dir, '*.meta.xml'))) # para_dic.update({'SLC': file_dir}) if os.path.exists(file_dir + name + '\\'): meta_xml_paths = list(glob.glob(os.path.join(file_dir + name, '*.xml'))) if os.path.exists(meta_xml_paths[0]): print(meta_xml_paths[0]) para_dic.update({'META': meta_xml_paths[0]}) para_dic.update({'SLC': file_dir + name}) else: meta_xml_paths = list(glob.glob(os.path.join(file_dir, '*.xml'))) if os.path.exists(meta_xml_paths[0]): print(meta_xml_paths[0]) para_dic.update({'SLC': file_dir}) para_dic.update({'META': meta_xml_paths[0]}) if meta_xml_paths == []: raise Exception('there is not .meta.xml in path: ', file_dir + '\\') # para_dic.update({'META': meta_xml_paths[0]}) self.image_meta_xml = meta_xml_paths return para_dic def __create_work_space(self): """ 删除原有工作区文件夹,创建新工作区文件夹 """ self.__workspace_preprocessing_path = os.path.join(self.__workspace_path, EXE_NAME, "Temporary", "preprocessing") # self.__workspace_path + EXE_NAME + r"\Temporary\preprocessing""\\" self.__workspace_preprocessed_path = os.path.join(self.__workspace_path, EXE_NAME, "Temporary", "preprocessed") # self.__workspace_path + EXE_NAME + r"\Temporary\preprocessed""\\" self.__workspace_processing_path = os.path.join(self.__workspace_path, EXE_NAME, "Temporary","processing\\") #self.__workspace_path + EXE_NAME + r"\Temporary\processing""\\" self.__workspace_origin_path = os.path.join(self.__workspace_path, EXE_NAME, "Temporary", "origin") path_list = [self.__workspace_preprocessing_path, self.__workspace_preprocessed_path, self.__workspace_processing_path, self.__workspace_origin_path] for path in path_list: if os.path.exists(path): if DEBUG is True: continue self.del_floder(path) os.makedirs(path) else: os.makedirs(path) logger.info('create new workspace success!') def del_file(self, path_data): """ 只删除文件,不删除文件夹 """ if DEBUG is True: return for i in os.listdir(path_data): # os.listdir(path_data)#返回一个列表,里面是当前目录下面的所有东西的相对路径 file_data = os.path.join(path_data, i) # path_data + "\\" + i # 当前文件夹的下面的所有东西的绝对路径 if os.path.isfile(file_data) is True: # os.path.isfile判断是否为文件,如果是文件,就删除.如果是文件夹.递归给del_file. os.remove(file_data) else: self.del_file(file_data) @staticmethod def del_floder(dic): """ 删除整个文件夹 """ if DEBUG is True: return if os.path.isdir(dic): shutil.rmtree(dic) @staticmethod def make_targz(output_filename, source_dir): """ 一次性打包整个根目录。空子目录会被打包。 如果只打包不压缩,将"w:gz"参数改为"w:"或"w"即可。 :param output_filename:输出压缩包的完整路径,eg:'E:\test.tar.gz' :param source_dir:需要打包的跟目录,eg: 'E:\testFfile\'打包文件夹里面的所有文件,'E:\testFfile'打包文件夹 """ dir = os.path.split(output_filename)[0] if os.path.exists(dir) is False: os.makedirs(dir) with tarfile.open(output_filename, "w:gz") as tar: tar.add(source_dir, arcname=os.path.basename(source_dir)) def del_temp_workspace(self): """ 临时工作区 """ if DEBUG is True: return path = os.path.join(self.__workspace_path, EXE_NAME, "Temporary") # self.__workspace_path + EXE_NAME + r"\Temporary" if os.path.exists(path): self.del_floder(path) def process_sim_ori(self, sim_ori): scopes = () scopes += (DictXml(self.__in_processing_paras['META']).get_extend(),) intersect_polygon = pp().intersect_polygon(scopes) if intersect_polygon is None: raise Exception('create intersect shp fail!') shp_path = os.path.join(self.__workspace_preprocessed_path, 'IntersectPolygon.shp') if pp().write_polygon_shp(shp_path, intersect_polygon, 4326) is False: raise Exception('create intersect shp fail!') sim_ori_process = os.path.join(self.__workspace_preprocessed_path, 'sim_ori_process.tif') pp().cut_img(sim_ori_process, sim_ori, shp_path) return sim_ori_process def process_handle(self,start): in_tif_paths = list(glob.glob(os.path.join(self.__in_processing_paras['SLC'], '*.tif'))) if in_tif_paths == []: in_tif_paths = list(glob.glob(os.path.join(self.__in_processing_paras['SLC'], '*.tiff'))) hh_flag, hv_flag, vh_flag, vv_flag, angle_flag = 0, 0, 0, 0, 0 for in_tif_path in in_tif_paths: if 'HH' in os.path.basename(in_tif_path): hh_flag = 1 elif 'HV' in os.path.basename(in_tif_path): hv_flag = 1 elif 'VH' in os.path.basename(in_tif_path): vh_flag = 1 elif 'VV' in os.path.basename(in_tif_path): vv_flag = 1 self.processinfo=[hh_flag, hv_flag, vh_flag, vv_flag] ref_tif_path = "" meta_file_path = self.__in_processing_paras['META'] rpc_path=None ####################### # RD ###################### # 2.2 生成局地入射角 path2 = env_str print("path2:" + path2) Orthorectification = IndirectOrthorectification(os.path.join(path2,"config.yaml")) Orthorectification.IndirectOrthorectification(self.__in_processing_paras["SLC"], self.__workspace_processing_path) # 改动1 # 2.3 输出结果 # 3 处理RD # 合并DEM Orth_Slc=[] in_dem_path = self.__in_processing_paras['DEM'] meta_file_path = self.__in_processing_paras['META'] # .meta文件路径 out_dem_path = self.__workspace_preprocessing_path dem_merged_path=DEMProcess.dem_merged(in_dem_path, meta_file_path, out_dem_path) # 生成TestDEM\mergedDEM_VRT.tif in_slc_path=None for slc_path in in_tif_paths: if slc_path.find(".tiff")>0 and (slc_path.find("_HH_")>0 or slc_path.find("_VV_")>0): in_slc_path=slc_path break # 获取校正模型后 Orthorectification.preCaldem_sar_rc(dem_merged_path,in_slc_path,self.__workspace_preprocessing_path,self.__workspace_processing_path.replace("\\","\\\\")) # 初步筛选坐标范围 logger.info('progress bar: 40%') # clip_dem_reample_path=os.path.join(self.__workspace_preprocessing_path, "SAR_dem.tiff") # infooption=gdal.InfoOptions("-json") # clip_dem_tif_info=gdal.Info(clip_dem_reample_path,options=infooption) # dem_merged_info=gdal.Info(dem_merged_path,options=infooption) # sampling_f=clip_dem_tif_info['size'][0]/dem_merged_info['size'][0] # 处理RD 的结果 out_dir_path=self.__workspace_processing_path.replace("\\","\\\\") this_outSpace_path = out_dir_path this_out_dem_slantRange_path = os.path.join(out_dir_path, "dem_slantRange.tiff") # out_dir_path + "\\" + "dem_slantRange.tiff"#// 地形斜距 this_out_plant_slantRange_path = os.path.join(out_dir_path, "flat_slantRange.tiff") # out_dir_path + "\\" + "flat_slantRange.tiff"#// 平地斜距 # 保留结果 if(os.path.exists(this_out_dem_slantRange_path)): os.remove(this_out_dem_slantRange_path) if(os.path.exists(this_out_plant_slantRange_path)): os.remove(this_out_plant_slantRange_path) this_out_dem_rc_path = os.path.join(out_dir_path, "WGS_SAR_map.tiff") # out_dir_path + "\\" + "WGS_SAR_map.tiff"#// 经纬度与行列号映射 if(os.path.exists(this_out_dem_rc_path)): os.remove(this_out_dem_rc_path) this_out_sar_sim_path = out_dir_path + "\\" + "sar_sim.tiff" if (os.path.exists(this_out_sar_sim_path)): os.remove(this_out_sar_sim_path) this_out_sar_sim_wgs_path = out_dir_path + "\\" + "sar_sim_wgs.tiff" # // 经纬度与行列号映射 if (os.path.exists(this_out_sar_sim_wgs_path)): os.remove(this_out_sar_sim_wgs_path) this_out_incidence_path = os.path.join(out_dir_path, "incidentAngle.tiff") # out_dir_path + "\\" + "incidentAngle.tiff"#// 入射角 this_out_localIncidenct_path = os.path.join(out_dir_path, "localIncidentAngle.tiff") # out_dir_path + "\\" + "localIncidentAngle.tiff"#// 局地入射角 if(os.path.exists(this_out_incidence_path)): shutil.move(this_out_incidence_path,os.path.join(out_dir_path, "inc_angle.tif")) # out_dir_path + "\\" + "inc_angle.tif") if(os.path.exists(this_out_localIncidenct_path)): shutil.move(this_out_localIncidenct_path, os.path.join(out_dir_path, "LocalIncidenceAngle.tif")) # out_dir_path + "\\" + "LocalIncidenceAngle.tif") this_out_inc_angle_rpc_path = os.path.join(out_dir_path, "RD_incidentAngle.tiff") # out_dir_path + "\\" + "RD_incidentAngle.tiff"#// 局地入射角 this_out_local_inc_angle_rpc_path = os.path.join(out_dir_path, "RD_localIncidentAngle.tiff") # out_dir_path + "\\" + "RD_localIncidentAngle.tiff"#// 局地入射角 if(os.path.exists(this_out_inc_angle_rpc_path)): os.remove(this_out_inc_angle_rpc_path) if(os.path.exists(this_out_local_inc_angle_rpc_path)): os.remove(this_out_local_inc_angle_rpc_path) this_out_ori_sim_tiff = os.path.join(out_dir_path, "RD_ori_sim.tif") # out_dir_path + "\\" + "RD_ori_sim.tif"#// 局地入射角 this_in_rpc_lon_lat_path = this_out_ori_sim_tiff this_out_sim_ori_tiff = os.path.join(out_dir_path, "RD_sim_ori.tif") this_in_rpc_x_y_path = this_out_sim_ori_tiff # this_in_rpc_x_y_path_pro = self.process_sim_ori(this_in_rpc_x_y_path) parameter_path = os.path.join(self.__workspace_processing_path, "orth_para.txt") for in_tif_path in in_tif_paths: # out_tif_path = os.path.join(self.__workspace_preprocessing_path,os.path.splitext(os.path.basename(in_tif_path))[0]) + r"_lin.tif" out_tif_path = os.path.join(self.__workspace_preprocessing_path,os.path.splitext(os.path.basename(in_tif_path))[0]) + r"_lin.tif" if ('HH' in os.path.basename(in_tif_path)) or ('HV' in os.path.basename(in_tif_path)) or ('VH' in os.path.basename(in_tif_path)) or ('VV' in os.path.basename(in_tif_path)): alg.sar_backscattering_coef(in_tif_path, meta_file_path, out_tif_path) # 构建RPC # 查找RPC rpc_path=in_tif_path.replace(".tiff",".rpc") if os.path.exists(in_tif_path.replace(".tiff",".rpc")) else in_tif_path.replace(".tiff",".rpb") if not os.path.exists(rpc_path): logger.error('rpc not found!') # db->地理编码 # lin_tif_path = os.path.join(self.__workspace_processing_path, # os.path.splitext(os.path.basename(in_tif_path))[0]) + r"-cal.tif" # Orthorectification.calInterpolation_cubic_Wgs84_rc_sar_sigma(parameter_path, this_in_rpc_x_y_path, # out_tif_path, # lin_tif_path) # 线性->地理编码->db lin_tif_path=os.path.join(self.__workspace_preprocessing_path,os.path.splitext(os.path.basename(in_tif_path))[0]) + r"-lin_geo.tif" # Orthorectification.calInterpolation_cubic_Wgs84_rc_sar_sigma(parameter_path, this_in_rpc_x_y_path_pro, # out_tif_path, # lin_tif_path) Orthorectification.calInterpolation_bil_Wgs84_rc_sar_sigma(parameter_path, this_in_rpc_x_y_path, out_tif_path, lin_tif_path) tempout_tif_path = os.path.join(self.__workspace_processing_path, os.path.splitext(os.path.basename(in_tif_path))[0]) + r"-" + tar + r".tif" alg.lin_to_db(lin_tif_path, tempout_tif_path) #线性值转回DB值 # 移动RPC #rpc_correction(in_tif_path,rpc_path,out_tif_path,dem_tif_file = None) # Orthorectification.inter_Range2Geo(this_in_rpc_lon_lat_path,out_tif_path,tempout_tif_path,Orthorectification.heightspace) self.imageHandler.write_quick_view(tempout_tif_path, color_img=False) # self.imageHandler.write_quick_view(lin_tif_path, color_img=False) else: shutil.copy(in_tif_path,self.__workspace_processing_path) ref_tif_path = tempout_tif_path # ref_tif_path = lin_tif_path # 构建行列号映射表 #out_rpc_rc_path = os.path.join(self.__workspace_processing_path,"RPC_ori_sim.tif") #getRCImageRC(in_tif_path,out_rpc_rc_path,rpc_path) logger.info('progress bar: 90%') if(os.path.exists(this_in_rpc_lon_lat_path)): os.remove(this_in_rpc_lon_lat_path) # if (os.path.exists(this_in_rpc_x_y_path)): # os.remove(this_in_rpc_x_y_path) # out_mate_file_path = os.path.join(self.__workspace_processing_path,os.path.split(meta_file_path)[1].rstrip('.meta.xml') + '_DB.meta.xml') out_mate_file_path = os.path.join(self.__workspace_processing_path,os.path.basename(meta_file_path)) shutil.copy(meta_file_path, out_mate_file_path) if ref_tif_path != "": # xml_path = "./model_meta.xml" tem_folder = os.path.join(self.__workspace_path, EXE_NAME, "Temporary") image_path = ref_tif_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_standa5rd.meta.xml") # 输出xml路径 # CreateStadardXmlFile(xml_path, par_dict, model_xml_path).create_standard_xml() # SrcImageName = os.path.split(self.__input_paras["SLC"]['ParaValue'])[1].split('.tar.gz')[0] # meta_xml_path = os.path.join(self.__workspace_processing_path, SrcImageName + "-cal.meta.xml") # CreateMetafile(self.image_meta_xml[0], self.alg_xml_path, model_xml_path,meta_xml_path).process(SrcImageName) model_path = "./product.xml" meta_xml_path = os.path.join(self.__workspace_processing_path, SrcImageName + "-" + tar + ".meta.xml") para_dict = CreateMetaDict(image_path, self.__in_processing_paras['META'], self.__workspace_processing_path, out_path1, out_path2).calu_nature() para_dict.update({"imageinfo_ProductName": "后向散射系数"}) para_dict.update({"imageinfo_ProductIdentifier": "BackScattering"}) para_dict.update({"imageinfo_ProductLevel": productLevel}) para_dict.update({"ProductProductionInfo_BandSelection": "1,2"}) para_dict.update({"ProductProductionInfo_AuxiliaryDataDescription": "DEM"}) para_dict.update({"MetaInfo_UnitDes": "DB"}) # 设置单位 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) self.make_targz(self.__out_para, self.__workspace_processing_path) logger.info('process_handle finished!') logger.info('progress bar: 100%') return True if __name__ == '__main__': start = datetime.datetime.now() try: if len(sys.argv)<2: xml_path = 'BackScattering-S-SAR.xml' else: xml_path = sys.argv[1] ScatteringMain = ScatteringMain(xml_path) if not ScatteringMain.check_source(): raise Exception('check_source() failed!') if not ScatteringMain.process_handle(start): raise Exception('process_handle() failed!') logger.info('successful production of backscattering products!') except Exception: logger.exception("run-time error!") finally: ScatteringMain.del_temp_workspace() # pass end = datetime.datetime.now() msg = 'running use time: %s ' % (end - start) logger.info(msg)