microproduct-l-sar/atmosphericDelay-L-SAR/AtmosphericDelayAuxData.py

321 lines
13 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"""
@Project microproduct
@File AtmosphericAuxData.PY
@Function :辅助文件读写
@Author LMM
@Date 2021/09/3 14:39
@Version 1.0.0
"""
import os
import shutil
import cftime
import numpy as np
import netCDF4 as Nc
import math
from tool.algorithm.image.ImageHandle import ImageHandler
from osgeo import gdal, osr
import gc
import logging
logger = logging.getLogger("mylog")
class NcHandle:
"""
气象数据的检查
气象数据的读取、降维、转tif
"""
def __int__(self):
pass
@staticmethod
def check_nc(nc_infile):
"""
检查气象数据
nc_infile 气象数据路径
"""
nc_data_obj = Nc.Dataset(nc_infile)
keys = nc_data_obj.variables.keys() # 查看气象数据文件包含的变量列表
inform = nc_data_obj.variables
variables = ['longitude', 'latitude', 'level', 'time', 'z', 'r', 't']
if len(keys) < len(variables): # 检查缺少了哪种气象数据
logger.error("下载气象数据有误,缺少参数")
return False
else:
for var in variables:
if var not in keys:
logger.error("缺少气象数据:", inform[var].long_name)
return False
logger.info("variables check true !")
all_vars_units = [] # 检查气象数据单位是否正确
for key in keys:
all_vars_units.append(nc_data_obj.variables[key].units)
if key == "level":
if nc_data_obj.variables[key].units != "millibars":
logger.error("units errors", inform[key].long_name)
if key == "t":
if nc_data_obj.variables[key].units != "K":
logger.error("units errors", inform[key].long_name)
if key == "r":
if nc_data_obj.variables[key].units != "%":
logger.error("units errors", inform[key].long_name)
if key == "z":
if nc_data_obj.variables[key].units != "m**2 s**-2":
logger.error("units errors", inform[key].long_name)
logger.info("The units of variables check true !")
all_vars_shape = [] # 检查气象数据维数是否正确
for key in keys:
all_vars_shape.append(inform[key].shape)
if inform["level"].shape[0] != 37: # 检查level是否为37压力面
logger.error("shape errors", inform[key].long_name)
if inform["time"].shape[0] != 1: # 检查time是否只有一个时间点
logger.error("shape errors", inform[key].long_name)
if (inform["t"].shape[0]) != 1 or (inform["t"].shape[1]) != 37:
logger.error("shape errors", inform[key].long_name)
if inform["r"].shape[0] != 1 or inform["r"].shape[1] != 37:
logger.error("shape errors", inform[key].long_name)
if inform["z"].shape[0] != 1 or inform["z"].shape[1] != 37:
logger.error("shape errors", inform[key].long_name)
logger.info("The shape of variables check true !")
@staticmethod
def read_nc(nc_file):
"""
function: 从气象数据中读取数组
"""
nc_data_obj = Nc.Dataset(nc_file)
inform = nc_data_obj.variables
lon_array = inform['longitude'][:] # lon数组
lat_array = inform['latitude'][:] # lat数组
n_lat = len(lat_array) # 经线列数量
n_lon = len(lon_array) # 纬线行数量
lon_min, lat_max, lon_max, lat_min = [lon_array.min(), lat_array.max(), lon_array.max(), lat_array.min()]
lon_res = (lon_max - lon_min) / (float(n_lon) - 1) # 计算经度方向分辨率
lat_res = (lat_max - lat_min) / (float(n_lat) - 1) # 计算纬度方向分辨率
pre_level = np.array(inform["level"]) # pressure level in m 压力面
temp_array = np.array(inform["t"]) # temp--k (1,37,25,25)
rel_hum_array = np.array(inform["r"]) # relative_humidity--% (1,37,25,25)
geo_h_array = np.array(inform["z"]) # Geopotential--m**2 s**-2 (1,37,25,25)
return lon_array, lat_array, pre_level, temp_array, rel_hum_array, geo_h_array, n_lat, n_lon, lon_res, lat_res
def redu_dim(self, nc_file):
"""
function : 降低数组维度
output:
lon_array: (25)-->(1,25,37)
lat_array: (25)-->(1,25,37)
pre_level: (37)-->(25,25,37)
temp_array: (1,37,25,25)-->(25,25,37)
rel_hum_array: (1,37,25,25)-->(25,25,37)
geo_h_array: (1,37,25,25)-->(25,25,37)
"""
lon_array, lat_array, pre_level, temp_array, rel_hum_array, geo_h_array, n_lat,\
n_lon, lon_res, lat_res = self.read_nc(nc_file)
lat_01 = np.zeros((1, n_lat, 37), dtype=float)
lon_01 = np.zeros((1, n_lon, 37), dtype=float)
level_01 = np.zeros((n_lat, n_lon, 37), dtype=float)
temp_01 = np.zeros((n_lat, n_lon, 37), dtype=float)
rel_hum_01 = np.zeros((n_lat, n_lon, 37), dtype=float)
geo_h_01 = np.zeros((n_lat, n_lon, 37), dtype=float)
for i in range(0, 37):
lon_01[0, :, i] = lon_array
lat_01[0, :, i] = lat_array
# pre_level = pre_level/100
level_01[:, :, i] = level_01[:, :, i] + pre_level[i]
temp_01[0:n_lat, 0:n_lon, i] = temp_array[0, i, :, :]
rel_hum_01[0:n_lat, 0:n_lon, i] = rel_hum_array[0, i, :, :]
geo_h_01[:, :, i] = geo_h_array[0, i, :, :]
del lon_array, lat_array, pre_level, temp_array, rel_hum_array, geo_h_array
lon_array, lat_array, pre_level, temp_array, rel_hum_array, geo_h_array =\
lon_01, lat_01, level_01, temp_01, rel_hum_01, geo_h_01
return lon_array, lat_array, pre_level, temp_array, rel_hum_array, geo_h_array, lon_res, lat_res
def tran_tif(self, nc_file, out_path, str_name):
"""
function: 气象数据矩阵转成tiff数据
param: nc_infile 气象数据文件
param: out_path 输出的文件夹路径
param: str 气象数据名字
"""
lon_array, lat_array, pre_level, temp_array, rel_hum_array, geo_h_array,\
lon_res, lat_res = self.redu_dim(nc_file)
# im_bands, n_lat, n_lon = temp_array.shape
dst_srs = osr.SpatialReference()
dst_srs.ImportFromEPSG(4326) # 定义一个WGS84坐标系
im_proj = dst_srs.ExportToWkt()
im_geo = [lon_array[0, 0, 0], lon_res, 0, lat_array[0, 0, 0], 0, -lat_res]
# first_name = (nc_file.split("\\", -1)[-1]).split(".nc")[0]
# out_level_path = out_path+str_name+"_"+"level.tif"
# ImageHandler.write_era_into_img(out_level_path, im_proj, im_geo, pre_level)
out_temp_path = out_path+str_name+"_"+"temp.tif"
ImageHandler.write_era_into_img(out_temp_path, im_proj, im_geo, temp_array)
out_hum_path = out_path+str_name+"_"+"re_hum.tif"
ImageHandler.write_era_into_img(out_hum_path, im_proj, im_geo, rel_hum_array)
out_geo_h_path = out_path+str_name+"_"+"geo_h.tif"
ImageHandler.write_era_into_img(out_geo_h_path, im_proj, im_geo, geo_h_array)
def copy_tif(self, nc_tif_file, out_path, key_name):
"""
tif格式的气象数据1.识别文件夹中的气象参数2.复制气象参数至临时文件夹
param: nc_tif_file:存放气象数据的文件夹路径
param: out_path气象数据的复制路径
param: key_nameMasterNC/AuxiliaryNC
"""
filename = os.listdir(nc_tif_file)
for name in filename:
if "geo" in name:
geo_path = os.path.join(nc_tif_file, name)
out_path1 = os.path.join(out_path, key_name+"_geo_h.tif")
shutil.copy(geo_path, out_path1)
elif "hum" in name:
hum_path = os.path.join(nc_tif_file, name)
out_path2 = os.path.join(out_path, key_name+"_re_hum.tif")
shutil.copy(hum_path, out_path2)
elif "temp" in name:
temp_path = os.path.join(nc_tif_file, name)
out_path3 = os.path.join(out_path, key_name+"_temp.tif")
shutil.copy(temp_path, out_path3)
class ReadImage:
"""
读取dem影像, 并输出dem矩阵
读取主辅影像,并计算干涉相位图
"""
def __int__(self):
pass
@staticmethod
def read_dem(filename):
"""
function: 从input目录下读取dem,返回DEM对应的数值数组
param: fileName-- dem文件路径
"""
dem = ImageHandler().get_band_array(filename, 1)
# dem = np.array(Image.open(filename))
max_dem = math.ceil(np.max(dem) / 100) * 100 + 50 # 四舍五入向上取值
return dem, max_dem
@staticmethod
def read_lon_lat(filename):
"""
读取影像的经度,纬度
"""
lon = []
lat = []
im_scope = ImageHandler().get_scope(filename)
width, height = ImageHandler().get_img_width(filename), ImageHandler().get_img_height(filename) # 获取数据的宽度、高度
point_upleft, point_downleft = im_scope[1], im_scope[3] # 获取左上数据的[经度、纬度],右下数据的[经度、纬度]
geotran = ImageHandler().get_geotransform(filename)
pix_width, pix_hight = geotran[1], geotran[5] # 像元的宽度,像元的高度 # 获取像元的宽度和像元的高度
for i in range(0, width):
longitude = point_upleft[0] + i * pix_width
lon.append(longitude)
for j in range(0, height):
latitude = point_upleft[1] + j * pix_hight
lat.append(latitude)
lon = np.asarray(lon)
lat = np.asarray(lat)
lon_min, lat_max, lon_max, lat_min = [lon.min(), lat.max(), lon.max(), lat.min()]
n_lat = len(lat) # 经线列数量
n_lon = len(lon) # 纬线行数量
nncols = n_lat-1
nnrows = n_lon-1
lat_37 = np.zeros((1, n_lat, 37), dtype=float)
lon_37 = np.zeros((1, n_lon, 37), dtype=float)
for i in range(0, 37):
d = lon
lon_37[0, :, i] = d
e = lat
lat_37[0, :, i] = e
return lon, lat, lon_min, lat_max, lon_max, lat_min, n_lat, n_lon,\
nncols, nnrows, pix_width, pix_hight, lat_37, lon_37
@staticmethod
def read_phase(file1, file2, out_path):
"""
function 计算干涉相位
"""
f01_dataset = gdal.Open(file1) # 获取主影像波段
f01_width = f01_dataset.RasterXSize
f01_height = f01_dataset.RasterYSize
f01_bands = f01_dataset.RasterCount
img_pro = f01_dataset.GetProjection()
img_tra = f01_dataset.GetGeoTransform()
f01_bands1 = f01_dataset.GetRasterBand(1)
f01_bands2 = f01_dataset.GetRasterBand(2)
m_r_1 = f01_bands1.ReadAsArray(0, 0, f01_width, f01_height)
m_i_1 = f01_bands2.ReadAsArray(0, 0, f01_width, f01_height)
f02_dataset = gdal.Open(file2) # 获取辅影像波段
f02_width = f02_dataset.RasterXSize
f02_height = f02_dataset.RasterYSize
f02_bands = f02_dataset.RasterCount
f02_bands1 = f02_dataset.GetRasterBand(1)
f02_bands2 = f02_dataset.GetRasterBand(2)
a_r_1 = f02_bands1.ReadAsArray(0, 0, f02_width, f02_height)
a_i_1 = f02_bands2.ReadAsArray(0, 0, f02_width, f02_height)
real_int_ms = m_r_1 * a_r_1 + m_i_1 * a_i_1
imag_int_ms = m_i_1 * a_r_1 - m_r_1 * a_i_1
a = real_int_ms
b = imag_int_ms
fan1 = np.where(a <= 0)
a = np.where(a == 0, -9999, a)
phase1 = np.arctan(b / a)
phase1[fan1] = 0
del fan1
gc.collect()
fan2 = np.where(a == 0, 1, 0)
fan3 = np.where(b > 0, 1, 0)
phase2 = fan2 * fan3 * math.pi / 2
del fan2, fan3
gc.collect()
fan4 = np.where(a == 0, 1, 0)
fan5 = np.where(b < 0, 1, 0)
phase3 = fan4 * fan5 * (-math.pi / 2)
del fan4, fan5
gc.collect()
fan6 = np.where(a < 0, 1, 0)
fan7 = np.where(b >= 0, 1, 0)
a = np.where(a == 0, -9999, a)
phase4 = fan6 * fan7 * (np.arctan(b / a) + math.pi)
del fan6, fan7
gc.collect()
fan8 = np.where(a < 0, 1, 0)
fan9 = np.where(b < 0, 1, 0)
a = np.where(a == 0, -9999, a)
phase5 = fan8 * fan9 * (np.arctan(b / a) - math.pi)
del fan8, fan9
gc.collect()
phase = phase1 + phase2 + phase3 + phase4 + phase5
logger.info("Calculate phase complete !")
ImageHandler.write_era_into_img(out_path, img_pro, img_tra, phase)