# -*- coding: utf-8 -*-

__author__ = 'wanger'
__description__ = '批量生成栅格数据元数据表格 EXCEL'
__date__ = '2024-11-25'
__copyright__ = '(C) 2024 by siwei'
__revision__ = '1.0'

from osgeo import gdal, osr
import openpyxl
from utils import *

# TODO 栅格数据文件夹
folder_path = 'E:\\projects\\遥感技术部需求\\批量生成元数据\\make\\data'
# TODO 元数据输出文件夹
output_path = 'E:\\projects\\遥感技术部需求\\批量生成元数据\\make\\metadata'
# TODO 元数据模板路径
templatepath = 'E:\\projects\\遥感技术部需求\\批量生成元数据\\make\\template\\template.xlsx'
# 获取元数据模板文件所在的目录
templatedirectory = os.path.dirname(os.path.abspath(templatepath))
# TODO 空间分析图层位置 默认在模板文件夹内有一个overlap.shp  点线面要素无所谓
overlapVectorPath = f"{templatedirectory}\\overlap.shp"
# 绑定需要从shp数据提取的信息
# data_gain_date 影像/数据获取时间
# data_resolution 影像分辨率/点云密度
overlapParams = {
    "data_resolution": "resolution",
    "data_gain_date": "gaindate"
}
# 遍历文件夹中的所有文件
for filename in os.listdir(folder_path):
    filepath = os.path.join(folder_path, filename)
    # 检查文件扩展名
    if filename.endswith('.img') or filename.endswith('.tif'):
        # filepath = 'E:\\projects\\遥感技术部需求\\批量生成元数据\\数据\\分幅成果\\DEM成果\\DEM\\NH48G053055DEMK.img'
        dataset = gdal.Open(filepath)
        # TODO 读取图号
        image_number, image_format = getImageNumberAndFormat(filepath)
        file_size = getFileSize(filepath)
        if dataset:
            # TODO 获取栅格数据的行数、列数
            grid_row = dataset.RasterYSize
            grid_col = dataset.RasterXSize
            # TODO 格网单元尺寸
            grid_size = 2
            # TODO波段数
            band_size = dataset.RasterCount
            # TODO 无效值 list 用逗号隔开
            nodata_list = []
            # TODO 计算高程记录的小数点位数
            decimal_number = None
            for band_index in range(1, dataset.RasterCount + 1):
                band = dataset.GetRasterBand(band_index)
                nodata_list.append(band.GetNoDataValue())
                stats = band.GetStatistics(True, True)  # 获取统计信息
                min_value, max_value = stats[0], stats[1]
                if min_value is not None and max_value is not None:
                    # 获取高程小数位数的最大可能值
                    decimal_number = max(len(str(min_value).split(".")[-1]),
                                         len(str(max_value).split(".")[-1])) if '.' in str(
                        min_value) else 0
            # TODO 获取栅格数据左上角标
            cornerpoint = getImageLeftTop(dataset)
            # 获取地理信息
            geo_transform = dataset.GetGeoTransform()
            # 获取投影信息
            projection = dataset.GetProjection()
            # 获取栅格数据的投影信息
            # 创建 SpatialReference 对象并加载投影信息
            spatial_ref = osr.SpatialReference()
            spatial_ref.ImportFromWkt(projection)
            # TODO 投影参数集合
            central_meridian = None
            ellipsoid_radius = None
            ellipsoid_flat = None
            geodetic_datum = None
            projection_name = None
            divided_into_zones = "无分带"
            with_number = "无代号"
            plane_coordinate_unit = "米"
            altitude_name = "正常高"
            altitude_benchmark = "1985国家高程基准"
            if spatial_ref.IsProjected():
                # TODO 中央子午线
                central_meridian = processingNumericalValues(spatial_ref.GetProjParm(osr.SRS_PP_CENTRAL_MERIDIAN))
                # TODO 椭球长半径
                ellipsoid_radius = processingNumericalValues(spatial_ref.GetSemiMajor())  # 长半轴
                # TODO 椭球扁率
                ellipsoid_flat = f"1/{spatial_ref.GetInvFlattening():.3f}"  # 反扁率（1/扁率）
                # TODO 所采用大地基准
                geodetic_datum = spatial_ref.GetAttrValue("DATUM")
                # TODO 地图投影名称
                projection_name = spatial_ref.GetAttrValue("PROJECTION")

                # TODO 分带方式（适用于 UTM）
                if geodetic_datum == "China_2000":
                    if projection.__contains__("-degree"):
                        number = projection.split("-degree")[0][-1:]
                        divided_into_zones = f'{number}度带'
                        with_number = int(central_meridian / int(number))
                elif spatial_ref.IsProjected() and "UTM" in projection:
                    zone = spatial_ref.GetUTMZone()
                    divided_into_zones = "UTM分带" if zone else "其他"
                    with_number = zone if zone else "N/A"
                # TODO 平面坐标单位
                plane_coordinate_unit = spatial_ref.GetLinearUnitsName()
                linear_units = spatial_ref.GetLinearUnits()  # 单位与米的换算关系

                # 高程系统（如果有）
                altitude_name = spatial_ref.GetAttrValue("VERT_CS")
                altitude_benchmark = spatial_ref.GetAttrValue("VERT_DATUM")

        metadatadict = {
            "image_number": image_number,
            "data_format": image_format,
            "data_volume": file_size,
            "grid_size": grid_size,
            "grid_row": grid_row,
            "grid_col": grid_col,
            "decimal_number": decimal_number,
            "nodata_number": ",".join(map(str, nodata_list)),
            "cornerpoint_lon": cornerpoint["lon"],
            "cornerpoint_lat": cornerpoint["lat"],
            "cornerpoint_x": cornerpoint["x"],
            "cornerpoint_y": cornerpoint["y"],
            "ellipsoid_radius": ellipsoid_radius,
            "ellipsoid_flat": ellipsoid_flat,
            "geodetic_datum": "2000国家大地坐标系" if geodetic_datum == "China_2000" else geodetic_datum,
            "projection_name": "高斯-克吕格投影" if projection_name == "Transverse_Mercator" else projection_name,
            "central_meridian": central_meridian,
            "divided_into_zones": divided_into_zones,
            "with_number": with_number,
            "plane_coordinate_unit": "米" if plane_coordinate_unit == "metre" else plane_coordinate_unit,
            "altitude_name": altitude_name,
            "altitude_benchmark": altitude_benchmark
        }
        # TODO 空间叠加
        for key in overlapParams:
            value = overlapParams[key]
            largest_feature = get_largest_overlapping_feature(raster_path=filepath, shp_path=overlapVectorPath)
            field_value = largest_feature[value]
            metadatadict[key] = field_value
        # 利用模板生成excel
        workbook = openpyxl.load_workbook(templatepath)
        sheet = workbook.active
        # 定义替换数据的字典
        replacements = {}
        for attr in metadatadict:
            key = f"<{attr}>"
            value = metadatadict[attr]
            replacements[key] = value
        # 遍历单元格，替换占位符
        for row in sheet.iter_rows():
            for cell in row:
                if isinstance(cell.value, str):  # 确保单元格内容是字符串
                    for placeholder, replacement in replacements.items():
                        if placeholder in cell.value:
                            # 替换占位符
                            cell.value = cell.value.replace(placeholder, str(replacement))
        # 保存修改后的文件
        workbook.save(f'{output_path}\\{image_number}.xlsx')
