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

__author__ = 'wanger'
__description__ = '处理网格数据  遍历要素获取四至坐标点  按照指定距离外扩数据框'
__date__ = '2024-11-25'
__copyright__ = '(C) 2024 by siwei'
__revision__ = '1.0'


from qgis.PyQt.QtCore import QCoreApplication
from qgis._core import QgsRectangle, QgsProcessingParameterVectorDestination, \
    QgsVectorFileWriter, QgsWkbTypes, QgsProcessingParameterNumber, QgsProcessingParameterBoolean, QgsGeometry, \
    QgsFeature
from qgis.core import (QgsVectorLayer,
                       QgsProcessingAlgorithm,
                       QgsProcessingParameterFile)


class ExpandGridProcessingAlgorithm(QgsProcessingAlgorithm):
    INPUT = 'INPUT'
    OUTPUT = 'OUTPUT'
    tolerance = 'tolerance'
    expanded = 'expanded'
    resolution = 'resolution'

    def tr(self, string):
        return QCoreApplication.translate('Processing', string)

    def createInstance(self):
        return ExpandGridProcessingAlgorithm()

    def name(self):
        return 'expandGrid'

    def displayName(self):
        return self.tr('网格数据外扩')

    def group(self):
        return self.tr('栅格裁剪')

    def groupId(self):
        return 'rasterclip'

    def shortHelpString(self):
        return self.tr("遍历输入shp数据要素获取四至坐标点并按照指定距离外扩数据框，保存到输出文件夹。")

    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterFile(
            self.INPUT,
            '网格数据',
            extension='shp'
        ))
        # 栅格分辨率
        self.addParameter(QgsProcessingParameterNumber(self.resolution,
                                                       self.tr('栅格分辨率'),
                                                       QgsProcessingParameterNumber.Double
                                                       ))
        # 创建一个参数，提示用户输入一个小数值
        self.addParameter(QgsProcessingParameterNumber(self.tolerance,
                                                       self.tr('外扩距离（米）'),
                                                       QgsProcessingParameterNumber.Double
                                                       ))
        self.addParameter(QgsProcessingParameterBoolean(self.expanded,
                                                        self.tr('是否外扩'),
                                                        defaultValue=True))
        self.addParameter(QgsProcessingParameterVectorDestination(self.OUTPUT,
                                                                  self.tr('输出位置')))

    # 执行
    def processAlgorithm(self, parameters, context, feedback):
        input_shp = self.parameterAsString(parameters, self.INPUT, context)
        output_shp = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
        expand_distance = self.parameterAsDouble(parameters, self.tolerance, context)
        resolution = self.parameterAsDouble(parameters, self.resolution, context)
        print(f"expand_distance:{expand_distance}")
        expanded = self.parameterAsBoolean(parameters, self.expanded, context)
        print(f"expanded:{expanded}")
        if expanded == False:
            expand_distance = 0
        print(f"expanded:{expanded}")
        # 加载输入shapefile
        input_layer = QgsVectorLayer(input_shp, "input_layer", "ogr")
        if not input_layer.isValid():
            print(f"Failed to load input shapefile: {input_shp}")
            return {
                "状态": "处理失败！",
                "原因": f"Failed to load input shapefile: {input_shp}"
            }
        else:
            # 获取输入图层的字段信息
            fields = input_layer.fields()
            # 创建输出shapefile
            writer = QgsVectorFileWriter(output_shp, 'UTF-8', fields, QgsWkbTypes.MultiPolygon, input_layer.crs(),
                                         'ESRI Shapefile')
            # 检查文件是否成功创建
            if writer.hasError() != QgsVectorFileWriter.NoError:
                print(f"Error creating output shapefile: {output_shp}")
                return {
                    "状态": "处理失败！",
                    "原因": f"Error creating output shapefile: {output_shp}"
                }
            else:
                # 遍历输入shapefile中的要素
                for feature in input_layer.getFeatures():
                    # 获取要素的geometry和extent
                    geometry = feature.geometry()
                    extent = geometry.boundingBox()  # 获取要素的extent（bounding box）
                    # TODO 创建新的扩展后的QgsRectangle
                    rings = None
                    try:
                        rings = geometry.asPolygon()
                    except Exception as e:
                        rings = geometry.asMultiPolygon()
                        rings = rings[0]
                    finally:
                        print("读取完成")
                    print("开始计算")
                    ring = rings[0]
                    p1 = ring[0]
                    p2 = ring[1]
                    p3 = ring[2]
                    p4 = ring[3]
                    ymax = int((max(p1.y(), p2.y(), p3.y(), p4.y()) + expand_distance) / resolution) * resolution
                    xmin = int((min(p1.x(), p2.x(), p3.x(), p4.x()) - expand_distance) / resolution) * resolution
                    ymin = int((min(p1.y(), p2.y(), p3.y(), p4.y()) - expand_distance) / resolution) * resolution
                    xmax = int((max(p1.x(), p2.x(), p3.x(), p4.x()) + expand_distance) / resolution) * resolution
                    print(f"{xmin},{ymin},{xmax},{ymax}")
                    expanded_extent = QgsRectangle(xmin, ymin, xmax, ymax)
                    # 使用extent创建一个新的几何（矩形geometry）
                    new_geometry = QgsGeometry.fromRect(expanded_extent)
                    # 创建一个新的要素，并将新几何设置到要素中
                    new_feature = QgsFeature(fields)  # 创建新的空要素，使用相同的字段定义
                    new_feature.setGeometry(new_geometry)  # 设置新的几何（extent）
                    # 复制原始要素的属性到新的要素
                    new_feature.setAttributes(feature.attributes())  # 将原要素的属性复制到新要素
                    # 将修改后的要素添加到输出shapefile
                    writer.addFeature(new_feature)
                # 完成写入并关闭输出文件
                del writer
                print(f"Features copied from {input_shp} to {output_shp} with modified extent.")
        return {
            "状态": "处理成功"
        }
