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

__author__ = 'wanger'
__description__ = '处理渔网数据  判断网格是否为自由 增加标签'
__date__ = '2024-11-25'
__copyright__ = '(C) 2024 by siwei'
__revision__ = '1.0'

import os

from PyQt5.QtCore import QVariant

from qgis.PyQt.QtCore import QCoreApplication
from qgis._core import QgsSpatialIndex, QgsField, QgsRectangle
from qgis.core import (QgsVectorLayer,
                       QgsProcessingAlgorithm,
                       QgsProcessingParameterFile)


class FishNetProcessingAlgorithm(QgsProcessingAlgorithm):
    INPUT = 'INPUT'

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

    def createInstance(self):
        return FishNetProcessingAlgorithm()

    def name(self):
        return 'makeFishNet'

    def displayName(self):
        return self.tr('网格数据预处理')

    def group(self):
        return self.tr('栅格元数据生成')

    def groupId(self):
        return 'metadata'

    def shortHelpString(self):
        return self.tr("将输入的网格数据进行检查，将接边自由的要素做标记。")

    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterFile(
            self.INPUT,
            '网格数据',
            extension='shp'  # 设置文件过滤器，只允许选择shp文件
        ))

    def cacl(self, neighbors):
        if len(neighbors) == 0:
            return "自由"
        else:
            return None

    # 执行
    def processAlgorithm(self, parameters, context, feedback):
        shp_file_path = self.parameterAsString(parameters, self.INPUT, context)
        # 检查文件路径是否有效
        if not os.path.exists(shp_file_path):
            feedback.reportError(f"指定的文件路径 {shp_file_path} 不存在！")
            return {}
        # 加载Shapefile为QgsVectorLayer
        layer = QgsVectorLayer(shp_file_path, "Vector Layer", 'ogr')
        layer.startEditing()
        grid_width = 100  # 替换为实际网格宽度
        grid_height = 100  # 替换为实际网格高度
        if layer.featureCount() > 0:
            # 获取第一个要素
            feature = next(layer.getFeatures())
            geom = feature.geometry()
            # 获取要素的边界矩形（bounding box）
            bounds = geom.boundingBox()
            # 计算宽度和高度
            grid_width = bounds.width()
            grid_height = bounds.height()
            print(f"网格宽度：{grid_width}")
            print(f"网格高度：{grid_height}")
        else:
            print("图层没有任何要素！")
            return {
                "状态": "图层没有任何要素！"
            }
        # 为图层添加邻居字段
        layer.startEditing()
        for field in ["east", "west", "south", "north"]:
            if field not in [f.name() for f in layer.fields()]:
                layer.dataProvider().addAttributes([QgsField(field, QVariant.String)])
        layer.updateFields()
        # 创建空间索引
        spatial_index = QgsSpatialIndex(layer)
        # 设置误差值 过滤掉仅仅是边线重叠的数据
        tolerance = grid_width if grid_width < grid_height else grid_height
        tolerance = tolerance / 5
        print(f"网格边界容差：{tolerance}")
        # 遍历图层中的所有要素
        for feature in layer.getFeatures():
            geom = feature.geometry()
            extent = geom.boundingBox()
            # 获取网格宽度和高度
            width = grid_width
            height = grid_height
            # 构造东西南北方向的矩形
            west_extent = QgsRectangle(extent.xMinimum() - width + tolerance, extent.yMinimum() + tolerance,
                                       extent.xMinimum() - tolerance,
                                       extent.yMaximum() - tolerance)
            east_extent = QgsRectangle(extent.xMaximum() + tolerance, extent.yMinimum() + tolerance,
                                       extent.xMaximum() + width - tolerance,
                                       extent.yMaximum() - tolerance)
            south_extent = QgsRectangle(extent.xMinimum() + tolerance, extent.yMinimum() - height + tolerance,
                                        extent.xMaximum() - tolerance,
                                        extent.yMinimum() - tolerance)
            north_extent = QgsRectangle(extent.xMinimum() + tolerance, extent.yMaximum() + tolerance,
                                        extent.xMaximum() - tolerance,
                                        extent.yMaximum() + height - tolerance)
            # 查询每个方向是否有其他网格
            west_neighbors = spatial_index.intersects(west_extent)
            east_neighbors = spatial_index.intersects(east_extent)
            south_neighbors = spatial_index.intersects(south_extent)
            north_neighbors = spatial_index.intersects(north_extent)
            neighbor_geometries = {
                "north": self.cacl(north_neighbors),
                "south": self.cacl(south_neighbors),
                "west": self.cacl(west_neighbors),
                "east": self.cacl(east_neighbors)
            }
            for direction, value in neighbor_geometries.items():
                feature[direction] = value
            layer.updateFeature(feature)
        # 保存编辑
        layer.commitChanges()
        print("邻居计算完成！")
        return {
            "状态": "处理成功"
        }
