FishNet.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. # -*- coding: utf-8 -*-
  2. __author__ = 'wanger'
  3. __description__ = '处理渔网数据 判断网格是否为自由 增加标签'
  4. __date__ = '2024-11-25'
  5. __copyright__ = '(C) 2024 by siwei'
  6. __revision__ = '1.0'
  7. import os
  8. from PyQt5.QtCore import QVariant
  9. from qgis.PyQt.QtCore import QCoreApplication
  10. from qgis._core import QgsSpatialIndex, QgsField, QgsRectangle
  11. from qgis.core import (QgsVectorLayer,
  12. QgsProcessingAlgorithm,
  13. QgsProcessingParameterFile)
  14. class FishNetProcessingAlgorithm(QgsProcessingAlgorithm):
  15. INPUT = 'INPUT'
  16. def tr(self, string):
  17. return QCoreApplication.translate('Processing', string)
  18. def createInstance(self):
  19. return FishNetProcessingAlgorithm()
  20. def name(self):
  21. return 'makeFishNet'
  22. def displayName(self):
  23. return self.tr('网格数据预处理')
  24. def group(self):
  25. return self.tr('栅格元数据生成')
  26. def groupId(self):
  27. return 'metadata'
  28. def shortHelpString(self):
  29. return self.tr("将输入的网格数据进行检查,将接边自由的要素做标记。")
  30. def initAlgorithm(self, config=None):
  31. self.addParameter(QgsProcessingParameterFile(
  32. self.INPUT,
  33. '网格数据',
  34. extension='shp' # 设置文件过滤器,只允许选择shp文件
  35. ))
  36. def cacl(self, neighbors):
  37. if len(neighbors) == 0:
  38. return "自由"
  39. else:
  40. return None
  41. # 执行
  42. def processAlgorithm(self, parameters, context, feedback):
  43. shp_file_path = self.parameterAsString(parameters, self.INPUT, context)
  44. # 检查文件路径是否有效
  45. if not os.path.exists(shp_file_path):
  46. feedback.reportError(f"指定的文件路径 {shp_file_path} 不存在!")
  47. return {}
  48. # 加载Shapefile为QgsVectorLayer
  49. layer = QgsVectorLayer(shp_file_path, "Vector Layer", 'ogr')
  50. layer.startEditing()
  51. grid_width = 100 # 替换为实际网格宽度
  52. grid_height = 100 # 替换为实际网格高度
  53. if layer.featureCount() > 0:
  54. # 获取第一个要素
  55. feature = next(layer.getFeatures())
  56. geom = feature.geometry()
  57. # 获取要素的边界矩形(bounding box)
  58. bounds = geom.boundingBox()
  59. # 计算宽度和高度
  60. grid_width = bounds.width()
  61. grid_height = bounds.height()
  62. print(f"网格宽度:{grid_width}")
  63. print(f"网格高度:{grid_height}")
  64. else:
  65. print("图层没有任何要素!")
  66. return {
  67. "状态": "图层没有任何要素!"
  68. }
  69. # 为图层添加邻居字段
  70. layer.startEditing()
  71. for field in ["east", "west", "south", "north"]:
  72. if field not in [f.name() for f in layer.fields()]:
  73. layer.dataProvider().addAttributes([QgsField(field, QVariant.String)])
  74. layer.updateFields()
  75. # 创建空间索引
  76. spatial_index = QgsSpatialIndex(layer)
  77. # 设置误差值 过滤掉仅仅是边线重叠的数据
  78. tolerance = grid_width if grid_width < grid_height else grid_height
  79. tolerance = tolerance / 5
  80. print(f"网格边界容差:{tolerance}")
  81. # 遍历图层中的所有要素
  82. for feature in layer.getFeatures():
  83. geom = feature.geometry()
  84. extent = geom.boundingBox()
  85. # 获取网格宽度和高度
  86. width = grid_width
  87. height = grid_height
  88. # 构造东西南北方向的矩形
  89. west_extent = QgsRectangle(extent.xMinimum() - width + tolerance, extent.yMinimum() + tolerance,
  90. extent.xMinimum() - tolerance,
  91. extent.yMaximum() - tolerance)
  92. east_extent = QgsRectangle(extent.xMaximum() + tolerance, extent.yMinimum() + tolerance,
  93. extent.xMaximum() + width - tolerance,
  94. extent.yMaximum() - tolerance)
  95. south_extent = QgsRectangle(extent.xMinimum() + tolerance, extent.yMinimum() - height + tolerance,
  96. extent.xMaximum() - tolerance,
  97. extent.yMinimum() - tolerance)
  98. north_extent = QgsRectangle(extent.xMinimum() + tolerance, extent.yMaximum() + tolerance,
  99. extent.xMaximum() - tolerance,
  100. extent.yMaximum() + height - tolerance)
  101. # 查询每个方向是否有其他网格
  102. west_neighbors = spatial_index.intersects(west_extent)
  103. east_neighbors = spatial_index.intersects(east_extent)
  104. south_neighbors = spatial_index.intersects(south_extent)
  105. north_neighbors = spatial_index.intersects(north_extent)
  106. neighbor_geometries = {
  107. "north": self.cacl(north_neighbors),
  108. "south": self.cacl(south_neighbors),
  109. "west": self.cacl(west_neighbors),
  110. "east": self.cacl(east_neighbors)
  111. }
  112. for direction, value in neighbor_geometries.items():
  113. feature[direction] = value
  114. layer.updateFeature(feature)
  115. # 保存编辑
  116. layer.commitChanges()
  117. print("邻居计算完成!")
  118. return {
  119. "状态": "处理成功"
  120. }