microproduct/tool/algorithm/transforml1a/transHandle.py

1116 lines
53 KiB
Python
Raw 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.

from tool.algorithm.transforml1a import SAR_GEO as SAR_GEO
from tool.algorithm.image import ImageHandle
import numpy as np
import scipy
from scipy.interpolate import griddata, RegularGridInterpolator
import logging
import pyresample as pr
# 插值模块
from pyresample.bilinear import NumpyBilinearResampler
from pyresample import geometry
from pyresample.geometry import AreaDefinition
from osgeo import osr
import os
import math
os.environ['PROJ_LIB'] = r"D:\Anaconda\envs\micro\Lib\site-packages\osgeo\data\proj"
logger = logging.getLogger("mylog")
##############
# 多项式回归组件
##############
#
def griddata_geo(points, data, lon_grid, lat_grid, method, i, end_i):
grid_data = griddata(points, data, (lon_grid, lat_grid), method=method, )
grid_data = grid_data[:, :, 0]
return [i, end_i, grid_data]
def griddataBlock(start_x, len_x, start_y, len_y, grid_data_input, grid_x, grid_y, method):
grid_x = grid_x.reshape(-1)
grid_y = grid_y.reshape(-1)
grid_data_input = grid_data_input.reshape(-1)
x_list = np.array(list(range(len_x))) + start_x
y_list = np.array(list(range(len_y))) + start_y
x_grid, y_grid = np.meshgrid(x_list, y_list)
idx = np.argsort(grid_x)
grid_x = grid_x[idx].reshape(-1)
grid_y = grid_y[idx].reshape(-1)
grid_data_input = grid_data_input[idx].reshape(-1)
interp_func = RegularGridInterpolator((grid_x.reshape(-1), grid_y.reshape(-1)), grid_data_input.reshape(-1),
method='slinear', bounds_error=False, fill_value=np.nan)
grid_data = interp_func((x_grid, y_grid))
# grid_data = griddata(p, grid_data_input, (x_grid, y_grid), method=method)
grid_data = grid_data[:, :, 0]
return (x_grid, y_grid, grid_data)
class polyfit2d_U:
def __init__(self, x, y, z) -> None:
# 定义参数
X = np.ones((x.shape[0], 10))
X[:, 0] = 1
X[:, 1] = x
X[:, 2] = y
X[:, 3] = x * y
X[:, 4] = x ** 2
X[:, 5] = y ** 2
X[:, 6] = x * X[:, 5]
X[:, 7] = y * X[:, 4]
X[:, 8] = x ** 3
X[:, 9] = y ** 3
Y = z.reshape(-1, 1)
A = np.matmul(np.matmul(np.linalg.inv(np.matmul(X.T, X)), X.T), Y)
self.paras_fit = A
def fit(self, x, y):
X = np.ones((x.shape[0], 10))
X[:, 0] = 1
X[:, 1] = x
X[:, 2] = y
X[:, 3] = x * y
X[:, 4] = x ** 2
X[:, 5] = y ** 2
X[:, 6] = x * X[:, 5]
X[:, 7] = y * X[:, 4]
X[:, 8] = x ** 3
X[:, 9] = y ** 3
z = np.matmul(X, self.paras_fit)
return np.sum(z)
class TransImgL1A:
def __init__(self, ori_sim_path, roi, l1a_height, l1a_width):
self._begin_r, self._begin_c, self._end_r, self._end_c = 0, 0, 0, 0
self.ori2geo_img = None
self._mask = None
self.l1a_height = l1a_height
self.l1a_width = l1a_width
self._min_lon, self._max_lon, self._min_lat, self._max_lat = 0, 0, 0, 0
self.init_trans_para(ori_sim_path, roi)
def get_roi_points(self):
rowcol = np.where(self._mask == 1)
data = [(self._begin_r + row, self._begin_c + col) for (row, col) in zip(rowcol[0], rowcol[1])]
return data
def get_lonlat_points(self):
lon = self.ori2geo_img[0, :, :][np.where(self._mask == 1)]
lat = self.ori2geo_img[1, :, :][np.where(self._mask == 1)]
data = [(row, col) for (row, col) in zip(lon, lat)]
return data
######################
# 插值方法
######################
def init_trans_para(self, sim_ori_path, roi):
"""裁剪L1a_img --裁剪L1A影像
--- 修改 ori_sim 变换为 sim_ori
Args:
src_img_path (_type_): 原始L1A影像
cuted_img_path (_type_): 待裁剪对象
roi (_type_): 裁剪roi
"""
ori2geo_img_height = ImageHandle.ImageHandler.get_img_height(sim_ori_path)
ori2geo_img_width = ImageHandle.ImageHandler.get_img_width(sim_ori_path)
ori2geo_img = ImageHandle.ImageHandler.get_data(sim_ori_path)
ori2geo_gt = ImageHandle.ImageHandler.get_geotransform(sim_ori_path)
point_list = np.array(roi)
min_lon = np.nanmin(point_list[:, 0])
max_lon = np.nanmax(point_list[:, 0])
min_lat = np.nanmin(point_list[:, 1])
max_lat = np.nanmax(point_list[:, 1])
self._min_lon, self._max_lon, self._min_lat, self._max_lat = min_lon, max_lon, min_lat, max_lat
# 根据 min_lon max_lon
# 根据 min_lat max_lat
(x_min, y_min) = ImageHandle.ImageHandler.lat_lon_to_pixel(sim_ori_path, (min_lon, min_lat))
(x_max, y_max) = ImageHandle.ImageHandler.lat_lon_to_pixel(sim_ori_path, (max_lon, max_lat))
xmin = x_min if x_min < x_max else x_max
xmax = x_min if x_min > x_max else x_max
ymin = y_min if y_min < y_max else y_max
ymax = y_min if y_min > y_max else y_max
xmin = int(math.floor(xmin)) # 列号
xmax = int(math.ceil(xmax)) # 因为python 的索引机制
# xmax = int(math.ceil(xmax)) + 1 # 因为python 的索引机制
ymin = int(math.floor(ymin)) # 行号
ymax = int(math.ceil(ymax)) # 因为pytohn的索引机制
# ymax = int(math.ceil(ymax)) + 1 # 因为pytohn的索引机制
# 处理最大最小范围
xmin = 0 if 0 > xmin else xmin
ymin = 0 if 0 > ymin else ymin
xmax = xmax if ori2geo_img_width > xmax else ori2geo_img_width
ymax = ymax if ori2geo_img_height > ymax else ori2geo_img_height
# 判断条件
xmax = xmax + 1 if xmax == xmin else xmax
ymax = ymax + 1 if ymax == ymin else ymax
if ymax <= ymin or xmax <= xmin or ymax > ori2geo_img_height or xmax > ori2geo_img_width or xmin < 0 or ymin < 0 or xmin > ori2geo_img_width or ymin > ori2geo_img_height or ymax < 0 or xmax < 0:
msg = 'csv_roi:' + str(roi) + 'not in box,please revise csv data'
print(msg)
else:
r_arr = ori2geo_img[0, ymin:ymax, xmin:xmax]
c_arr = ori2geo_img[1, ymin:ymax, xmin:xmax]
# 构建坐标矩阵
ori2geo_mask_r_count = ymax - ymin
ori2geo_mask_c_count = xmax - xmin
lon_lat_arr = np.ones((2, ori2geo_mask_r_count, ori2geo_mask_c_count))
col_arr = np.arange(xmin, xmax) * np.ones((ori2geo_mask_r_count, ori2geo_mask_c_count))
row_arr = ((np.arange(ymin, ymax)) * np.ones((ori2geo_mask_c_count, ori2geo_mask_r_count))).T
img_geotrans = ori2geo_gt
lon_arr = img_geotrans[0] + img_geotrans[1] * col_arr + img_geotrans[2] * row_arr
lat_arr = img_geotrans[3] + img_geotrans[4] * col_arr + img_geotrans[5] * row_arr
lon_lat_arr[0, :, :] = lon_arr
lon_lat_arr[1, :, :] = lat_arr
# print("csv_roi:")
# print(roi)
r_min = np.floor(np.nanmin(r_arr)) # 获取 L1A 的行列号范围
r_max = np.ceil(np.nanmax(r_arr)) + 1
c_min = np.floor(np.nanmin(c_arr))
c_max = np.ceil(np.nanmax(c_arr)) + 1
# 判断是否越界
r_min = 0 if r_min < 0 else r_min
r_max = self.l1a_height if r_max > self.l1a_height else r_max
c_min = 0 if c_min < 0 else c_min
c_max = self.l1a_width if c_max > self.l1a_width else c_max
# 判断条件
r_max = r_max + 1 if r_min == r_max else r_max
c_max = c_max + 1 if c_min == c_max else c_max
if r_max <= r_min or c_max <= c_min or r_max > self.l1a_height or c_max > self.l1a_width or r_min < 0 or c_min < 0 or c_min > self.l1a_width or r_min > self.l1a_height or r_max < 0 or c_max < 0:
msg = 'csv_roi:' + str(roi) + 'not in box,please revise csv data'
else:
pass
mask_geo = SAR_GEO.cut_L1A_img(lon_lat_arr, point_list) # 在地理坐标系下裁剪对应影像
mask_geo = mask_geo.reshape(-1)
r_arr = r_arr.reshape(-1)
c_arr = c_arr.reshape(-1)
mask_geo_idx = np.where(mask_geo == 1)[0]
if mask_geo_idx.shape[0] == 0:
msg = 'csv_roi:' + str(roi) + 'not in box,please revise csv data'
print(msg)
else:
r_idx = r_arr[mask_geo_idx]
c_idx = c_arr[mask_geo_idx]
r_idx = r_idx - r_min # offset row
c_idx = c_idx - c_min # offset col
r_count = r_max - r_min # 行数
c_count = c_max - c_min # 列数
#
mask_l1a = np.zeros((int(r_count), int(c_count))) * np.nan # 创建目标大小的行列号
mask = SAR_GEO.gereratorMask(r_idx.astype(np.float64), c_idx.astype(np.float64).astype(np.float64),
mask_l1a) # 这个函数修改了
self._begin_r = int(r_min)
self._end_r = int(r_max)
self._begin_c = int(c_min)
self._end_c = int(c_max)
self._mask = mask
def cut_L1A(self, in_path, out_path):
img = ImageHandle.ImageHandler.get_data(in_path)
if len(img.shape) == 3:
cut_img = img[:, self._begin_r:self._end_r, self._begin_c:self._end_c]
cut_img[0, :, :] = cut_img[0, :, :] * self._mask
cut_img[1, :, :] = cut_img[1, :, :] * self._mask
ImageHandle.ImageHandler.write_img(out_path, '', [0, 0, 0, 0, 0, 0], cut_img)
else:
cut_img = img[self._begin_r:self._end_r + 1, self._begin_c:self._end_c + 1]
cut_img[:, :] = cut_img[:, :] * self._mask
cut_img[:, :] = cut_img[:, :] * self._mask
ImageHandle.ImageHandler.write_img(out_path, '', [0, 0, 0, 0, 0, 0], cut_img)
def cut_L1A_noMask(self, in_path, out_path):
img = ImageHandle.ImageHandler.get_data(in_path)
if len(img.shape) == 3:
cut_img = img[:, self._begin_r:self._end_r, self._begin_c:self._end_c]
cut_img[0, :, :] = cut_img[0, :, :]
cut_img[1, :, :] = cut_img[1, :, :]
ImageHandle.ImageHandler.write_img(out_path, '', [0, 0, 0, 0, 0, 0], cut_img)
else:
cut_img = img[self._begin_r:self._end_r + 1, self._begin_c:self._end_c + 1]
cut_img[:, :] = cut_img[:, :]
cut_img[:, :] = cut_img[:, :]
ImageHandle.ImageHandler.write_img(out_path, '', [0, 0, 0, 0, 0, 0], cut_img)
def grid_interp_to_station(self, all_data, station_lon, station_lat, method='linear'):
'''
func: 将等经纬度网格值 插值到 离散站点。使用griddata进行插值
inputs:
all_data,形式为:[grid_lon,grid_lat,data] 即[经度网格,纬度网格,数值网格]
station_lon: 站点经度
station_lat: 站点纬度。可以是 单个点,列表或者一维数组
method: 插值方法,默认使用 linear
'''
station_lon = np.array(station_lon).reshape(-1, 1)
station_lat = np.array(station_lat).reshape(-1, 1)
lon = all_data[0].reshape(-1, 1)
lat = all_data[1].reshape(-1, 1)
data = all_data[2].reshape(-1, 1)
points = np.concatenate([lon, lat], axis=1)
station_value = griddata(points, data, (station_lon, station_lat), method=method)
station_value = station_value[:, :, 0]
return station_value
#####################
# 当存在 ori2geo.tif
#####################
@staticmethod
def cut_L1a_img(src_img_path, cuted_img_path, roi):
"""裁剪L1a_img
Args:
src_img_path (_type_): 原始L1A影像
cuted_img_path (_type_): 待裁剪对象
roi (_type_): 裁剪roi
"""
ori2geo_img = ImageHandle.ImageHandler.get_data(src_img_path)
point_list = np.array(roi)
# 开始调用组件 计算
mask = SAR_GEO.cut_L1A_img(ori2geo_img.astype(np.float64), point_list)
#
ori2geo_img[0, :, :] = ori2geo_img[0, :, :] * mask
ori2geo_img[1, :, :] = ori2geo_img[1, :, :] * mask
ImageHandle.ImageHandler.write_img(cuted_img_path, '', [0, 0, 0, 0, 0, 0], ori2geo_img)
return ori2geo_img # 保存成影像
def tran_geo_to_l1a(self, geo_img_path, out_l1a_img_path, ori_sim_img_path, is_class=False):
"""裁剪后的有投影信息的影像(cover、ndvi)转换到L1A裁剪影像的尺寸
Args:
geo_img_path (_type_): _description_
out_l1a_img_path (_type_): _description_
ori_sim_img_path (_type_): _description_
geo_img_path:地理影像路径
out_l1a_img_path转换L1A坐标系图像路径
ori_sim_img_path裁剪后模拟影像路径
is_clss: 是否是 定性类产品
"""
inverse_gt = ImageHandle.ImageHandler.get_invgeotransform(geo_img_path)
ori2geo_tif = ImageHandle.ImageHandler.get_data(ori_sim_img_path)
height = ImageHandle.ImageHandler.get_img_height(geo_img_path)
width = ImageHandle.ImageHandler.get_img_width(geo_img_path)
# 计算投影
x = ori2geo_tif[0, :, :] # lon lat x,y
y = ori2geo_tif[1, :, :]
ori2geo_tif[0, :, :] = inverse_gt[0] + inverse_gt[1] * x + inverse_gt[2] * y # x
ori2geo_tif[1, :, :] = inverse_gt[3] + inverse_gt[4] * x + inverse_gt[5] * y # y
del x, y
geo_tif = ImageHandle.ImageHandler.get_data(geo_img_path) # 获取目标影像
ori2geo_tif_shape = ori2geo_tif.shape # height,width
if is_class:
ori2geo_tif = np.round(ori2geo_tif).astype(np.int32)
mask = (ori2geo_tif[0, :, :] >= 0) & (ori2geo_tif[0, :, :] < width) & (ori2geo_tif[1, :, :] >= 0) & (
ori2geo_tif[1, :, :] < height)
ori2geo_tif[0, :, :] = ori2geo_tif[0, :, :] * mask
ori2geo_tif[1, :, :] = ori2geo_tif[1, :, :] * mask
geo_tif_shape = geo_tif.shape
geo_tif_l1a = geo_tif[ori2geo_tif[1, :, :].reshape(-1), ori2geo_tif[0, :, :].reshape(-1)].reshape(
ori2geo_tif.shape[1], ori2geo_tif.shape[2]).astype(np.float32)
del ori2geo_tif, geo_tif
one_ids = np.where(mask == False)
geo_tif_l1a[one_ids[0], one_ids[1]] = np.nan
ImageHandle.ImageHandler.write_img(out_l1a_img_path, '', [0, 0, 0, 0, 0, 0], geo_tif_l1a)
# save_temp_L1A(out_l1a_img_path,geo_tif_l1a)
return geo_tif_l1a
else: # 数值性插值
mask = (ori2geo_tif[0, :, :] > 0) & (ori2geo_tif[0, :, :] < width - 1) & (ori2geo_tif[1, :, :] > 0) & (
ori2geo_tif[1, :, :] < height - 1)
one_ids = np.where(mask == 1)
x, y = np.meshgrid(np.arange(0, width), np.arange(0, height))
result_data = self.grid_interp_to_station([y.reshape(-1), x.reshape(-1), geo_tif.reshape(-1)],
ori2geo_tif[1, one_ids[0], one_ids[1]].reshape(-1),
ori2geo_tif[0, one_ids[0], one_ids[1]].reshape(-1),
method='linear').reshape(-1)
mask = mask.reshape(-1)
result_data_result = np.zeros((ori2geo_tif.shape[1], ori2geo_tif.shape[2]))
result_data_result[:, :] = np.nan
result_data_result = SAR_GEO.insert_data(result_data_result, one_ids[0].astype(np.int32),
one_ids[1].astype(np.int32), result_data)
ImageHandle.ImageHandler.write_img(out_l1a_img_path, '', [0, 0, 0, 0, 0, 0], result_data_result)
# save_temp_L1A(out_l1a_img_path,result_data_result)
return result_data_result
def tran_lonlats_to_rowcols(self, lonlats, ori_sim_img_path):
"""
功能:输入经纬度坐标,输出图像行列号
函数名称tran_lonlats_to_rowcols(lonlats,out_rowcols,ori_sim_img_path)
Lonlats:经纬度坐标,示例[[120.53, 31.5], [120.61, 31.5], [120.53, 31.45], [120.61, 31.45]]
out_rowcols:图像行列号,示例[[0, 0], [7000, 0], [7000, 8000], [0, 8000]]
ori_sim_img_path裁剪后模拟影像路径
"""
ori2geo_tif = ImageHandle.ImageHandler.get_data(ori_sim_img_path)
min_lon = np.nanmin(ori2geo_tif[0, :, :])
max_lon = np.nanmax(ori2geo_tif[0, :, :])
min_lat = np.nanmin(ori2geo_tif[1, :, :])
max_lat = np.nanmax(ori2geo_tif[1, :, :])
result = []
for i in range(len(lonlats)):
p = lonlats[i]
if min_lon > p[0] or max_lon < p[0] or min_lat > p[1] or max_lat < p[1]:
result.append([-1, -1])
continue
temp_x = np.square(ori2geo_tif[0, :, :] - p[0]) + np.square(ori2geo_tif[1, :, :] - p[1])
r_c_list = []
r_c = np.argmin(temp_x)
r_c = [r_c // temp_x.shape[1], r_c % temp_x.shape[1]]
r_c_list.append([r_c[0], r_c[1], ori2geo_tif[0, r_c[0], r_c[1]], ori2geo_tif[1, r_c[0], r_c[1]]])
# 插值
for i in range(r_c[0] - 3, r_c[0] + 3):
if i < 0 or i > temp_x.shape[0] - 1:
continue
for j in range(r_c[1] - 3, r_c[1] + 3):
if j < 0 or j > temp_x.shape[1] - 1:
continue
r_c_list.append([i, j, ori2geo_tif[0, i, j], ori2geo_tif[1, i, j]])
r_c_list = np.array(r_c_list)
points = r_c_list[:, 2:]
f_r = scipy.interpolate.interp2d(r_c_list[:, 2], r_c_list[:, 3], r_c_list[:, 0], kind='linear')
f_c = scipy.interpolate.interp2d(r_c_list[:, 2], r_c_list[:, 3], r_c_list[:, 1], kind='linear')
tar_get_r = f_r(p[0], p[1])[0]
tar_get_c = f_c(p[0], p[1])[0]
if tar_get_r < ori2geo_tif.shape[1] and tar_get_c < ori2geo_tif.shape[2] and tar_get_r>=0 and tar_get_c>=0:
lon_temp = ori2geo_tif[0, int(round(tar_get_r)), int(round(tar_get_c))]
lon_lat = ori2geo_tif[1, int(round(tar_get_r)), int(round(tar_get_c))]
# 增加条件筛选
result.append([tar_get_r, tar_get_c])
else:
result.append([-1, -1])
return result
def tran_lonlats_to_L1A_rowcols(self, meas_data, ori_sim_path, row, col):
lonlats = []
data_roi = []
rowcols = []
measdata_list = []
data_sim = ImageHandle.ImageHandler.get_all_band_array(ori_sim_path)
for data in meas_data:
lon = float(data[1])
lat = float(data[2])
if (lon > self._min_lon and lon < self._max_lon and lat > self._min_lat and lat < self._max_lat):
lonlats.append([lon, lat])
data_roi.append(data)
for lonlat in lonlats:
(x, y) = ImageHandle.ImageHandler.lat_lon_to_pixel(ori_sim_path, lonlat)
rowcols.append([x, y])
for data, rowcol in zip(data_roi, rowcols):
img_x = round(data_sim[round(rowcol[1]), round(rowcol[0]), 0])
img_y = round(data_sim[round(rowcol[1]), round(rowcol[0]), 1])
if (img_x > 0 and img_x < row and img_y > 0 and img_y < col):
measdata_list.append([img_x, img_y, float(data[3])])
# rowcols = self.tran_lonlats_to_rowcols(lonlats, ori_sim_path)
# measdata_list = []
# for data, rowcol in zip(data_roi, rowcols):
# if (rowcol[0] != -1 and rowcol[1] != -1):
# measdata_list.append(
# [round(rowcol[0]) - self._begin_r, round(rowcol[1]) - self._begin_c, float(data[3])])
return measdata_list
@staticmethod
def get_radius_of_influence(lalo_step, src_meta='radar2geo', ratio=3):
EARTH_RADIUS = 6378122.65 # m
"""Get radius of influence based on the lookup table resolution in lat/lon direction"""
if src_meta == "geo2radar":
# geo2radar
radius = 100e3
else:
# radar2geo
step_deg = max(np.abs(lalo_step))
step_m = step_deg * np.pi / 180.0 * EARTH_RADIUS
radius = step_m * ratio
return radius
def interp2d_station_to_grid(self, lon, lat, data, loc_range=[18, 54, 73, 135],
det_grid=1, method='linear', projCode=4326):
# 参考链接 https://blog.csdn.net/weixin_43718675/article/details/103497930
'''
func : 将站点数据插值到等经纬度格点
inputs:
lon: 站点的经度
lat: 站点的纬度
data: 对应经纬度站点的 气象要素值
loc_range: [lat_min,lat_max,lon_min,lon_max]。站点数据插值到loc_range这个范围
det_grid: 插值形成的网格空间分辨率
method: 所选插值方法,默认 0.125
return:
[lon_grid,lat_grid,data_grid]
'''
# step1: 先将 lon,lat,data转换成 n*1 的array数组
lon = np.array(lon).reshape(-1, 1)
lat = np.array(lat).reshape(-1, 1)
data = np.array(data).reshape(-1, 1)
# step2:确定插值区域的经纬度网格
lat_min = loc_range[0] # y
lat_max = loc_range[1] # y
lon_min = loc_range[2] # x
lon_max = loc_range[3] # x
gt = [0, 0, 0, 0, 0, 0]
gt[0] = lon_min # x
gt[1] = det_grid
gt[3] = lat_max # y
gt[5] = -det_grid
lat_count = int((lat_max - lat_min) / det_grid + 1) # y
lon_count = int((lon_max - lon_min) / det_grid + 1) # x
# 替换为pyresample 插值方法
proj_osr = osr.SpatialReference()
proj_osr.ImportFromEPSG(projCode)
projection = proj_osr.ExportToPROJJSON()
# lower_left_x、lower_left_y、upper_right_x、upper_right_y
target_def = AreaDefinition("id1", "WGS84", "proj_id", projection,
lon_count, lat_count, [lon_min, lat_min, lon_max, lat_max])
source_def = geometry.SwathDefinition(lons=lon, lats=lat)
lalo_step = [det_grid, -det_grid]
radius = TransImgL1A.get_radius_of_influence(lalo_step, src_meta='radar2geo')
result = pr.bilinear.resample_bilinear(data, source_def, target_def,
radius=radius, neighbours=32,
nprocs=8, fill_value=np.nan,
epsilon=0)
#
return result
def geocoding(self, ori_geo_tif, produc_arr, pixel_delta=1, method='linear'):
# 参考链接 https://blog.csdn.net/weixin_43718675/article/details/103497930
ori_geo_tif[np.isnan(ori_geo_tif)] = -1
lon_data = ori_geo_tif[0, :, :].reshape(-1)
lat_data = ori_geo_tif[1, :, :].reshape(-1)
idx = np.where(lat_data != -1)
lat_data = lat_data[idx]
lon_data = lon_data[idx]
idx = np.where(lon_data != -1)
lat_data = lat_data[idx]
lon_data = lon_data[idx]
# ###########################################
result = self.interp2d_station_to_grid(lon_data, lat_data, produc_arr,
[self._min_lat, self._max_lat, self._min_lon, self._max_lon],
det_grid=pixel_delta, method=method)
return result
def l1a_2_geo(self, ori_geo_path, l1a_produc_path, geo_produc_path, method='linear'):
ori_geo_tif = ImageHandle.ImageHandler.get_data(ori_geo_path)
# l1a_produc = ImageHandle.ImageHandler.get_data(l1a_produc_path)
l1a_produc = ImageHandle.ImageHandler.get_band_array(l1a_produc_path, 1)
pixel_delta_y = (self._max_lat - self._min_lat) / (self._end_r - self._begin_r) # 0.001
pixel_delta_x = (self._max_lon - self._min_lon) / (self._end_c - self._begin_c)
lon_data = ori_geo_tif[0, :, :].reshape(-1)
lat_data = ori_geo_tif[1, :, :].reshape(-1)
l1a_produc = l1a_produc.reshape(-1)
idx = np.logical_not(np.isnan(lon_data))
lat_data = lat_data[idx]
lon_data = lon_data[idx]
l1a_produc = l1a_produc[idx]
idx = np.logical_not(np.isnan(lat_data))
lat_data = lat_data[idx]
lon_data = lon_data[idx]
l1a_produc = l1a_produc[idx]
gt = [self._min_lon, pixel_delta_x, 0.0,
self._max_lat, 0.0, -pixel_delta_y]
[lat_min, lat_max, lon_min, lon_max] = [self._min_lat, self._max_lat, self._min_lon, self._max_lon]
lat_count = int((lat_max - lat_min) / pixel_delta_y + 1) # y
lon_count = int((lon_max - lon_min) / pixel_delta_x + 1) # x
# 获取地理坐标系统信息,用于选取需要的地理坐标系统
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326) # 定义输出的坐标系为"WGS 84"
proj = srs.ExportToWkt()
projection = srs.ExportToPROJJSON()
# lower_left_x、lower_left_y、upper_right_x、upper_right_y
target_def = AreaDefinition("id1", "WGS84", "proj_id", projection,
lon_count, lat_count, [lon_min, lat_min, lon_max, lat_max])
lon_data = lon_data.reshape(-1, 1)
lat_data = lat_data.reshape(-1, 1)
l1a_produc = l1a_produc.reshape(-1, 1)
source_def = geometry.SwathDefinition(lons=lon_data, lats=lat_data)
lalo_step = [pixel_delta_x, -pixel_delta_y]
radius = TransImgL1A.get_radius_of_influence(lalo_step, src_meta='radar2geo')
geo_produc = pr.bilinear.resample_bilinear(l1a_produc, source_def, target_def,
radius=radius, neighbours=32,
nprocs=8, fill_value=np.nan,
epsilon=0)
ImageHandle.ImageHandler.write_img(geo_produc_path, proj, gt, geo_produc, np.nan)
#
# def l1a_2_geo_int(self, ori_geo_path, l1a_produc_path, geo_produc_path, method='nearest'):
# ori_geo_tif = ImageHandle.ImageHandler.get_data(ori_geo_path)
# # l1a_produc = ImageHandle.ImageHandler.get_data(l1a_produc_path)
# l1a_produc = ImageHandle.ImageHandler.get_band_array(l1a_produc_path, 1)
# pixel_delta_y = (self._max_lat - self._min_lat) / (self._end_r - self._begin_r) # 0.001
# pixel_delta_x = (self._max_lon - self._min_lon) / (self._end_c - self._begin_c)
#
# lon_data = ori_geo_tif[0, :, :].reshape(-1)
# lat_data = ori_geo_tif[1, :, :].reshape(-1)
# l1a_produc = l1a_produc.reshape(-1)
# idx = np.logical_not(np.isnan(lon_data))
# lat_data = lat_data[idx]
# lon_data = lon_data[idx]
# l1a_produc = l1a_produc[idx]
# idx = np.logical_not(np.isnan(lat_data))
# lat_data = lat_data[idx]
# lon_data = lon_data[idx]
# l1a_produc = l1a_produc[idx]
#
# gt = [self._min_lon, pixel_delta_x, 0.0,
# self._max_lat, 0.0, -pixel_delta_y]
# [lat_min, lat_max, lon_min, lon_max] = [self._min_lat, self._max_lat, self._min_lon, self._max_lon]
# lat_count = int((lat_max - lat_min) / pixel_delta_y + 1) # y
# lon_count = int((lon_max - lon_min) / pixel_delta_x + 1) # x
#
# # 获取地理坐标系统信息,用于选取需要的地理坐标系统
# srs = osr.SpatialReference()
# srs.ImportFromEPSG(4326) # 定义输出的坐标系为"WGS 84"
# proj = srs.ExportToWkt()
#
# projection = srs.ExportToPROJJSON()
# # lower_left_x、lower_left_y、upper_right_x、upper_right_y
# target_def = AreaDefinition("id1", "WGS84", "proj_id", projection,
# lon_count, lat_count, [lon_min, lat_min, lon_max, lat_max])
# lon_data = lon_data.reshape(-1, 1)
# lat_data = lat_data.reshape(-1, 1)
# l1a_produc = l1a_produc.reshape(-1, 1)
# source_def = geometry.SwathDefinition(lons=lon_data, lats=lat_data)
# lalo_step = [pixel_delta_x, -pixel_delta_y]
# radius = TransImgL1A.get_radius_of_influence(lalo_step, src_meta='radar2geo')
# if method == 'linear':
# geo_produc = pr.bilinear.resample_bilinear(l1a_produc, source_def, target_def,
# radius=radius, neighbours=32,
# nprocs=8, fill_value=0,
# epsilon=0)
# elif method == 'nearest':
# geo_produc = pr.kd_tree.resample_nearest(source_def, l1a_produc, target_def, epsilon=0,
# radius_of_influence=50000,
# fill_value=0, nprocs=8
# )
# geo_produc = geo_produc[:,:,0]
# ImageHandle.ImageHandler.write_img(geo_produc_path, proj, gt, geo_produc)
@property
def mask(self):
return self._mask
class TransImgL1A_ori:
def __init__(self, ori_sim_path, roi):
self._begin_r, self._begin_c, self._end_r, self._end_c = 0, 0, 0, 0
self._mask = None
self._min_lon, self._max_lon, self._min_lat, self._max_lat = 0, 0, 0, 0
self.init_trans_para(ori_sim_path, roi)
def get_roi_points(self):
rowcol = np.where(self._mask == 1)
data = [(self._begin_r + row, self._begin_c + col) for (row, col) in zip(rowcol[0], rowcol[1])]
return data
######################
# 插值方法
######################
def init_trans_para(self, ori_sim_path, roi):
"""裁剪L1a_img
Args:
src_img_path (_type_): 原始L1A影像
cuted_img_path (_type_): 待裁剪对象
roi (_type_): 裁剪roi
"""
ori2geo_img = ImageHandle.ImageHandler.get_data(ori_sim_path)
point_list = np.array(roi)
min_lon = np.nanmin(point_list[:, 0])
max_lon = np.nanmax(point_list[:, 0])
min_lat = np.nanmin(point_list[:, 1])
max_lat = np.nanmax(point_list[:, 1])
self._min_lon, self._max_lon, self._min_lat, self._max_lat = min_lon, max_lon, min_lat, max_lat
r_c_list = np.where(
(ori2geo_img[0, :, :] >= min_lon) & (ori2geo_img[0, :, :] <= max_lon)
& (ori2geo_img[1, :, :] >= min_lat) & (ori2geo_img[1, :, :] <= max_lat)) #
if len(r_c_list) == 0 or r_c_list[0] == [] or r_c_list[1] == [] or np.array(r_c_list).size == 0:
msg = 'csv_roi:' + str(roi) + 'not in box,please revise csv data'
print(msg)
else:
# print("csv_roi:")
# print(roi)
r_min = np.nanmin(r_c_list[0])
r_max = np.nanmax(r_c_list[0])
c_min = np.nanmin(r_c_list[1])
c_max = np.nanmax(r_c_list[1])
ori2geo_img = ori2geo_img[:, r_min:r_max + 1, c_min:c_max + 1]
# 开始调用组件 计算
mask = SAR_GEO.cut_L1A_img(ori2geo_img.astype(np.float64), point_list)
self._begin_r = r_min
self._end_r = r_max
self._begin_c = c_min
self._end_c = c_max
self._mask = mask
def cut_L1A(self, in_path, out_path):
img = ImageHandle.ImageHandler.get_data(in_path)
if len(img.shape) == 3:
cut_img = img[:, self._begin_r:self._end_r + 1, self._begin_c:self._end_c + 1]
cut_img[0, :, :] = cut_img[0, :, :] * self._mask
cut_img[1, :, :] = cut_img[1, :, :] * self._mask
ImageHandle.ImageHandler.write_img(out_path, '', [0, 0, 0, 0, 0, 0], cut_img)
else:
cut_img = img[self._begin_r:self._end_r + 1, self._begin_c:self._end_c + 1]
cut_img[:, :] = cut_img[:, :] * self._mask
cut_img[:, :] = cut_img[:, :] * self._mask
ImageHandle.ImageHandler.write_img(out_path, '', [0, 0, 0, 0, 0, 0], cut_img)
def grid_interp_to_station(self, all_data, station_lon, station_lat, method='linear'):
'''
func: 将等经纬度网格值 插值到 离散站点。使用griddata进行插值
inputs:
all_data,形式为:[grid_lon,grid_lat,data] 即[经度网格,纬度网格,数值网格]
station_lon: 站点经度
station_lat: 站点纬度。可以是 单个点,列表或者一维数组
method: 插值方法,默认使用 linear
'''
station_lon = np.array(station_lon).reshape(-1, 1)
station_lat = np.array(station_lat).reshape(-1, 1)
lon = all_data[0].reshape(-1, 1)
lat = all_data[1].reshape(-1, 1)
data = all_data[2].reshape(-1, 1)
points = np.concatenate([lon, lat], axis=1)
station_value = griddata(points, data, (station_lon, station_lat), method=method)
station_value = station_value[:, :, 0]
return station_value
#####################
# 当存在 ori2geo.tif
#####################
@staticmethod
def cut_L1a_img(src_img_path, cuted_img_path, roi):
"""裁剪L1a_img
Args:
src_img_path (_type_): 原始L1A影像
cuted_img_path (_type_): 待裁剪对象
roi (_type_): 裁剪roi
"""
ori2geo_img = ImageHandle.ImageHandler.get_data(src_img_path)
point_list = np.array(roi)
# 开始调用组件 计算
mask = SAR_GEO.cut_L1A_img(ori2geo_img.astype(np.float64), point_list)
#
ori2geo_img[0, :, :] = ori2geo_img[0, :, :] * mask
ori2geo_img[1, :, :] = ori2geo_img[1, :, :] * mask
ImageHandle.ImageHandler.write_img(cuted_img_path, '', [0, 0, 0, 0, 0, 0], ori2geo_img)
return ori2geo_img # 保存成影像
def tran_geo_to_l1a(self, geo_img_path, out_l1a_img_path, ori_sim_img_path, is_class=False):
"""裁剪后的有投影信息的影像(cover、ndvi)转换到L1A裁剪影像的尺寸
Args:
geo_img_path (_type_): _description_
out_l1a_img_path (_type_): _description_
ori_sim_img_path (_type_): _description_
geo_img_path:地理影像路径
out_l1a_img_path转换L1A坐标系图像路径
ori_sim_img_path裁剪后模拟影像路径
is_clss: 是否是 定性类产品
"""
inverse_gt = ImageHandle.ImageHandler.get_invgeotransform(geo_img_path)
ori2geo_tif = ImageHandle.ImageHandler.get_data(ori_sim_img_path)
height = ImageHandle.ImageHandler.get_img_height(geo_img_path)
width = ImageHandle.ImageHandler.get_img_width(geo_img_path)
# 计算投影
x = ori2geo_tif[0, :, :] # lon lat x,y
y = ori2geo_tif[1, :, :]
ori2geo_tif[0, :, :] = inverse_gt[0] + inverse_gt[1] * x + inverse_gt[2] * y # x
ori2geo_tif[1, :, :] = inverse_gt[3] + inverse_gt[4] * x + inverse_gt[5] * y # y
del x, y
geo_tif = ImageHandle.ImageHandler.get_data(geo_img_path) # 获取目标影像
ori2geo_tif_shape = ori2geo_tif.shape # height,width
if is_class:
ori2geo_tif = np.round(ori2geo_tif).astype(np.int32)
mask = (ori2geo_tif[0, :, :] >= 0) & (ori2geo_tif[0, :, :] < width) & (ori2geo_tif[1, :, :] >= 0) & (
ori2geo_tif[1, :, :] < height)
ori2geo_tif[0, :, :] = ori2geo_tif[0, :, :] * mask
ori2geo_tif[1, :, :] = ori2geo_tif[1, :, :] * mask
geo_tif_shape = geo_tif.shape
geo_tif_l1a = geo_tif[ori2geo_tif[1, :, :].reshape(-1), ori2geo_tif[0, :, :].reshape(-1)].reshape(
ori2geo_tif.shape[1], ori2geo_tif.shape[2]).astype(np.float32)
del ori2geo_tif, geo_tif
one_ids = np.where(mask == False)
geo_tif_l1a[one_ids[0], one_ids[1]] = np.nan
ImageHandle.ImageHandler.write_img(out_l1a_img_path, '', [0, 0, 0, 0, 0, 0], geo_tif_l1a)
# save_temp_L1A(out_l1a_img_path,geo_tif_l1a)
return geo_tif_l1a
else: # 数值性插值
mask = (ori2geo_tif[0, :, :] > 0) & (ori2geo_tif[0, :, :] < width - 1) & (ori2geo_tif[1, :, :] > 0) & (
ori2geo_tif[1, :, :] < height - 1)
one_ids = np.where(mask == 1)
x, y = np.meshgrid(np.arange(0, width), np.arange(0, height))
result_data = self.grid_interp_to_station([y.reshape(-1), x.reshape(-1), geo_tif.reshape(-1)],
ori2geo_tif[1, one_ids[0], one_ids[1]].reshape(-1),
ori2geo_tif[0, one_ids[0], one_ids[1]].reshape(-1),
method='linear').reshape(-1)
mask = mask.reshape(-1)
result_data_result = np.zeros((ori2geo_tif.shape[1], ori2geo_tif.shape[2]))
result_data_result[:, :] = np.nan
result_data_result = SAR_GEO.insert_data(result_data_result, one_ids[0].astype(np.int32),
one_ids[1].astype(np.int32), result_data)
ImageHandle.ImageHandler.write_img(out_l1a_img_path, '', [0, 0, 0, 0, 0, 0], result_data_result)
# save_temp_L1A(out_l1a_img_path,result_data_result)
return result_data_result
def tran_lonlats_to_rowcols(self, lonlats, ori_sim_img_path):
"""
功能:输入经纬度坐标,输出图像行列号
函数名称tran_lonlats_to_rowcols(lonlats,out_rowcols,ori_sim_img_path)
Lonlats:经纬度坐标,示例[[120.53, 31.5], [120.61, 31.5], [120.53, 31.45], [120.61, 31.45]]
out_rowcols:图像行列号,示例[[0, 0], [7000, 0], [7000, 8000], [0, 8000]]
ori_sim_img_path裁剪后模拟影像路径
"""
ori2geo_tif = ImageHandle.ImageHandler.get_data(ori_sim_img_path)
min_lon = np.nanmin(ori2geo_tif[0, :, :])
max_lon = np.nanmax(ori2geo_tif[0, :, :])
min_lat = np.nanmin(ori2geo_tif[1, :, :])
max_lat = np.nanmax(ori2geo_tif[1, :, :])
result = []
for i in range(len(lonlats)):
p = lonlats[i]
if min_lon > p[0] or max_lon < p[0] or min_lat > p[1] or max_lat < p[1]:
result.append([-1, -1])
continue
temp_x = np.square(ori2geo_tif[0, :, :] - p[0]) + np.square(ori2geo_tif[1, :, :] - p[1])
r_c_list = []
r_c = np.argmin(temp_x)
r_c = [r_c // temp_x.shape[1], r_c % temp_x.shape[1]]
r_c_list.append([r_c[0], r_c[1], ori2geo_tif[0, r_c[0], r_c[1]], ori2geo_tif[1, r_c[0], r_c[1]]])
# 插值
for i in range(r_c[0] - 3, r_c[0] + 3):
if i < 0 or i > temp_x.shape[0] - 1:
continue
for j in range(r_c[1] - 3, r_c[1] + 3):
if j < 0 or j > temp_x.shape[1] - 1:
continue
r_c_list.append([i, j, ori2geo_tif[0, i, j], ori2geo_tif[1, i, j]])
r_c_list = np.array(r_c_list)
points = r_c_list[:, 2:]
f_r = scipy.interpolate.interp2d(r_c_list[:, 2], r_c_list[:, 3], r_c_list[:, 0], kind='linear')
f_c = scipy.interpolate.interp2d(r_c_list[:, 2], r_c_list[:, 3], r_c_list[:, 1], kind='linear')
tar_get_r = f_r(p[0], p[1])[0]
tar_get_c = f_c(p[0], p[1])[0]
if tar_get_r < ori2geo_tif.shape[1] and tar_get_c < ori2geo_tif.shape[
2] and tar_get_r >= 0 and tar_get_c >= 0:
lon_temp = ori2geo_tif[0, int(round(tar_get_r)), int(round(tar_get_c))]
lon_lat = ori2geo_tif[1, int(round(tar_get_r)), int(round(tar_get_c))]
# 增加条件筛选
result.append([tar_get_r, tar_get_c])
else:
result.append([-1, -1])
return result
def tran_lonlats_to_L1A_rowcols(self, meas_data, ori_sim_path):
lonlats = []
data_roi = []
for data in meas_data:
lon = float(data[1])
lat = float(data[2])
if (lon > self._min_lon and lon < self._max_lon and lat > self._min_lat and lat < self._max_lat):
lonlats.append([lon, lat])
data_roi.append(data)
rowcols = self.tran_lonlats_to_rowcols(lonlats, ori_sim_path)
measdata_list = []
for data, rowcol in zip(data_roi, rowcols):
if (rowcol[0] != -1 and rowcol[1] != -1):
measdata_list.append(
[round(rowcol[0]) - self._begin_r, round(rowcol[1]) - self._begin_c, float(data[3])])
return measdata_list
@staticmethod
def get_radius_of_influence(lalo_step, src_meta='radar2geo', ratio=3):
EARTH_RADIUS = 6378122.65 # m
"""Get radius of influence based on the lookup table resolution in lat/lon direction"""
if src_meta == "geo2radar":
# geo2radar
radius = 100e3
else:
# radar2geo
step_deg = max(np.abs(lalo_step))
step_m = step_deg * np.pi / 180.0 * EARTH_RADIUS
radius = step_m * ratio
return radius
def interp2d_station_to_grid(self, lon, lat, data, loc_range=[18, 54, 73, 135],
det_grid=1, method='linear', projCode=4326):
# 参考链接 https://blog.csdn.net/weixin_43718675/article/details/103497930
'''
func : 将站点数据插值到等经纬度格点
inputs:
lon: 站点的经度
lat: 站点的纬度
data: 对应经纬度站点的 气象要素值
loc_range: [lat_min,lat_max,lon_min,lon_max]。站点数据插值到loc_range这个范围
det_grid: 插值形成的网格空间分辨率
method: 所选插值方法,默认 0.125
return:
[lon_grid,lat_grid,data_grid]
'''
# step1: 先将 lon,lat,data转换成 n*1 的array数组
lon = np.array(lon).reshape(-1, 1)
lat = np.array(lat).reshape(-1, 1)
data = np.array(data).reshape(-1, 1)
# step2:确定插值区域的经纬度网格
lat_min = loc_range[0] # y
lat_max = loc_range[1] # y
lon_min = loc_range[2] # x
lon_max = loc_range[3] # x
gt = [0, 0, 0, 0, 0, 0]
gt[0] = lon_min # x
gt[1] = det_grid
gt[3] = lat_max # y
gt[5] = -det_grid
lat_count = int((lat_max - lat_min) / det_grid + 1) # y
lon_count = int((lon_max - lon_min) / det_grid + 1) # x
# 替换为pyresample 插值方法
proj_osr = osr.SpatialReference()
proj_osr.ImportFromEPSG(projCode)
projection = proj_osr.ExportToPROJJSON()
# lower_left_x、lower_left_y、upper_right_x、upper_right_y
target_def = AreaDefinition("id1", "WGS84", "proj_id", projection,
lon_count, lat_count, [lon_min, lat_min, lon_max, lat_max])
source_def = geometry.SwathDefinition(lons=lon, lats=lat)
lalo_step = [det_grid, -det_grid]
radius = TransImgL1A.get_radius_of_influence(lalo_step, src_meta='radar2geo')
result = pr.bilinear.resample_bilinear(data, source_def, target_def,
radius=radius, neighbours=32,
nprocs=8, fill_value=np.nan,
epsilon=0)
#
return result
def geocoding(self, ori_geo_tif, produc_arr, pixel_delta=1, method='linear'):
# 参考链接 https://blog.csdn.net/weixin_43718675/article/details/103497930
ori_geo_tif[np.isnan(ori_geo_tif)] = -1
lon_data = ori_geo_tif[0, :, :].reshape(-1)
lat_data = ori_geo_tif[1, :, :].reshape(-1)
idx = np.where(lat_data != -1)
lat_data = lat_data[idx]
lon_data = lon_data[idx]
idx = np.where(lon_data != -1)
lat_data = lat_data[idx]
lon_data = lon_data[idx]
# ###########################################
result = self.interp2d_station_to_grid(lon_data, lat_data, produc_arr,
[self._min_lat, self._max_lat, self._min_lon, self._max_lon],
det_grid=pixel_delta, method=method)
return result
def l1a_2_geo(self, ori_geo_path, l1a_produc_path, geo_produc_path, method='linear'):
ori_geo_tif = ImageHandle.ImageHandler.get_data(ori_geo_path)
# l1a_produc = ImageHandle.ImageHandler.get_data(l1a_produc_path)
l1a_produc = ImageHandle.ImageHandler.get_band_array(l1a_produc_path, 1)
pixel_delta_y = (self._max_lat - self._min_lat) / (self._end_r - self._begin_r) # 0.001
pixel_delta_x = (self._max_lon - self._min_lon) / (self._end_c - self._begin_c)
lon_data = ori_geo_tif[0, :, :].reshape(-1)
lat_data = ori_geo_tif[1, :, :].reshape(-1)
l1a_produc = l1a_produc.reshape(-1)
idx = np.logical_not(np.isnan(lon_data))
lat_data = lat_data[idx]
lon_data = lon_data[idx]
l1a_produc = l1a_produc[idx]
idx = np.logical_not(np.isnan(lat_data))
lat_data = lat_data[idx]
lon_data = lon_data[idx]
l1a_produc = l1a_produc[idx]
gt = [self._min_lon, pixel_delta_x, 0.0,
self._max_lat, 0.0, -pixel_delta_y]
[lat_min, lat_max, lon_min, lon_max] = [self._min_lat, self._max_lat, self._min_lon, self._max_lon]
lat_count = int((lat_max - lat_min) / pixel_delta_y + 1) # y
lon_count = int((lon_max - lon_min) / pixel_delta_x + 1) # x
# 获取地理坐标系统信息,用于选取需要的地理坐标系统
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326) # 定义输出的坐标系为"WGS 84"
proj = srs.ExportToWkt()
projection = srs.ExportToPROJJSON()
# lower_left_x、lower_left_y、upper_right_x、upper_right_y
target_def = AreaDefinition("id1", "WGS84", "proj_id", projection,
lon_count, lat_count, [lon_min, lat_min, lon_max, lat_max])
lon_data = lon_data.reshape(-1, 1)
lat_data = lat_data.reshape(-1, 1)
l1a_produc = l1a_produc.reshape(-1, 1)
source_def = geometry.SwathDefinition(lons=lon_data, lats=lat_data)
lalo_step = [pixel_delta_x, -pixel_delta_y]
radius = TransImgL1A.get_radius_of_influence(lalo_step, src_meta='radar2geo')
# geo_produc = pr.bilinear.NumpyBilinearResampler(source_def, target_def, neighbours=32, radius_of_influence=radius, epsilon=0).resample(l1a_produc)
geo_produc = pr.bilinear.resample_bilinear(l1a_produc, source_def, target_def,
radius=radius, neighbours=32,
nprocs=80, fill_value=0,
epsilon=0)
# geo_produc = pr.bilinear.resample_bilinear(l1a_produc, source_def, target_def,
# radius=radius, neighbours=32,
# nprocs=8, fill_value=np.nan,
# epsilon=0)
ImageHandle.ImageHandler.write_img(geo_produc_path, proj, gt, geo_produc, '0')
def l1a_2_geo_int(self, ori_geo_path, l1a_produc_path, geo_produc_path, method='nearest'):
ori_geo_tif = ImageHandle.ImageHandler.get_data(ori_geo_path)
# l1a_produc = ImageHandle.ImageHandler.get_data(l1a_produc_path)
l1a_produc = ImageHandle.ImageHandler.get_band_array(l1a_produc_path, 1)
pixel_delta_y = (self._max_lat - self._min_lat) / (self._end_r - self._begin_r) # 0.001
pixel_delta_x = (self._max_lon - self._min_lon) / (self._end_c - self._begin_c)
lon_data = ori_geo_tif[0, :, :].reshape(-1)
lat_data = ori_geo_tif[1, :, :].reshape(-1)
l1a_produc = l1a_produc.reshape(-1)
idx = np.logical_not(np.isnan(lon_data))
lat_data = lat_data[idx]
lon_data = lon_data[idx]
l1a_produc = l1a_produc[idx]
idx = np.logical_not(np.isnan(lat_data))
lat_data = lat_data[idx]
lon_data = lon_data[idx]
l1a_produc = l1a_produc[idx]
gt = [self._min_lon, pixel_delta_x, 0.0,
self._max_lat, 0.0, -pixel_delta_y]
[lat_min, lat_max, lon_min, lon_max] = [self._min_lat, self._max_lat, self._min_lon, self._max_lon]
lat_count = int((lat_max - lat_min) / pixel_delta_y + 1) # y
lon_count = int((lon_max - lon_min) / pixel_delta_x + 1) # x
# 获取地理坐标系统信息,用于选取需要的地理坐标系统
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326) # 定义输出的坐标系为"WGS 84"
proj = srs.ExportToWkt()
projection = srs.ExportToPROJJSON()
# lower_left_x、lower_left_y、upper_right_x、upper_right_y
target_def = AreaDefinition("id1", "WGS84", "proj_id", projection,
lon_count, lat_count, [lon_min, lat_min, lon_max, lat_max])
lon_data = lon_data.reshape(-1, 1)
lat_data = lat_data.reshape(-1, 1)
l1a_produc = l1a_produc.reshape(-1, 1)
source_def = geometry.SwathDefinition(lons=lon_data, lats=lat_data)
lalo_step = [pixel_delta_x, -pixel_delta_y]
radius = TransImgL1A.get_radius_of_influence(lalo_step, src_meta='radar2geo')
if method == 'linear':
geo_produc = pr.bilinear.resample_bilinear(l1a_produc, source_def, target_def,
radius=radius, neighbours=32,
nprocs=8, fill_value=0,
epsilon=0)
elif method == 'nearest':
geo_produc = pr.kd_tree.resample_nearest(source_def, l1a_produc, target_def, epsilon=0,
radius_of_influence=50000,
fill_value=0, nprocs=8
)
geo_produc = geo_produc[:,:,0]
ImageHandle.ImageHandler.write_img(geo_produc_path, proj, gt, geo_produc)
@property
def mask(self):
return self._mask
if __name__ == '__main__':
# ori_sim_path = r"I:\坐标转换\坐标转换接口\L1A数据l1a_img_path数据\RPC_ori_sim.tif"
# roi_Extend = [[120.53, 31.5], [120.61, 31.5], [120.61, 31.45], [120.53, 31.45]]
# conver_path = r"I:\坐标转换\坐标转换接口\裁剪后辅助数据geo_img_path数据\Covering_cut.tif"
# ndvi_path = r"I:\坐标转换\坐标转换接口\裁剪后辅助数据geo_img_path数据\NDVI_cut.tif"
# out_path = r"I:\坐标转换\SAR2GEO\test"
#
# tr = TransImgL1A(ori_sim_path,roi_Extend)
# tr.l1a_2_geo("I:/cut.tif", "I:/salinity.tif", "I:/salinity_geo2.tif")
ori_sim = r"D:\micro\LWork\AtmosphericDelay\Temporary\cut\ori_sim.tif"
product_tif = r"D:\micro\LWork\AtmosphericDelay\Temporary\apsWork\master_ztd\dlosout.tiff"
result = r"D:\micro\LWork\AtmosphericDelay\Temporary\apsWork\master_ztd\dlosout_geo.tiff"
method = 'linear'
scopes = ImageHandle.ImageHandler().get_scopes(ori_sim)
# """
# 31.14;31.50;120.34;120.75
# """
# # roi_Extend = [[102.12, 33.879], [102.327, 33.879], [102.327, 33.66], [102.12, 31.45]]
# ori_sim_data = ImageHandle.ImageHandler.get_data(ori_sim)
# lon = ori_sim_data[0, :, :]
# lat = ori_sim_data[1, :, :]
# min_lon = np.nanmin(lon)
# max_lon = np.nanmax(lon)
# min_lat = np.nanmin(lat)
# max_lat = np.nanmax(lat)
# print(np.nanmin(lon))
# print(np.nanmax(lon))
# print(np.nanmin(lat))
# print(np.nanmax(lat))
#
# # roi_Extend = [[min_lon, max_lat], [max_lon, max_lat], [min_lon, min_lat], [max_lon, min_lat]]
# roi_Extend = [[116.17328, 43.727577], [116.652504, 43.727577], [116.652504, 44.119164], [116.17328, 44.119164]]
# # roi_Extend = [[108.51960117899473, 38.192443138079895], [109.62308480328566, 38.192443138079895], [109.62308480328566, 37.69300142375064], [108.51960117899473, 37.69300142375064]]
tr = TransImgL1A_ori(ori_sim, scopes)
tr.l1a_2_geo(ori_sim, product_tif, result, method)
pass
"""
import numpy as np
from pyresample import kd_tree, geometry
area_def = geometry.AreaDefinition('areaD', 'Europe (3km, HRV, VTC)', 'areaD',
{'a': '6378144.0', 'b': '6356759.0',
'lat_0': '50.00', 'lat_ts': '50.00',
'lon_0': '8.00', 'proj': 'stere'},
800, 800,
[-1370912.72, -909968.64,
1029087.28, 1490031.36])
data = np.fromfunction(lambda y, x: y*x, (50, 10))
lons = np.fromfunction(lambda y, x: 3 + x, (50, 10))
lats = np.fromfunction(lambda y, x: 75 - y, (50, 10))
swath_def = geometry.SwathDefinition(lons=lons, lats=lats)
result = kd_tree.resample_nearest(swath_def, data,area_def, radius_of_influence=50000, epsilon=0.5)
"""