Expand_Grid.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. from qgis.PyQt.QtCore import QCoreApplication
  8. from qgis._core import QgsRectangle, QgsProcessingParameterVectorDestination, \
  9. QgsVectorFileWriter, QgsWkbTypes, QgsProcessingParameterNumber, QgsProcessingParameterBoolean, QgsGeometry, \
  10. QgsFeature
  11. from qgis.core import (QgsVectorLayer,
  12. QgsProcessingAlgorithm,
  13. QgsProcessingParameterFile)
  14. class ExpandGridProcessingAlgorithm(QgsProcessingAlgorithm):
  15. INPUT = 'INPUT'
  16. OUTPUT = 'OUTPUT'
  17. tolerance = 'tolerance'
  18. expanded = 'expanded'
  19. resolution = 'resolution'
  20. def tr(self, string):
  21. return QCoreApplication.translate('Processing', string)
  22. def createInstance(self):
  23. return ExpandGridProcessingAlgorithm()
  24. def name(self):
  25. return 'expandGrid'
  26. def displayName(self):
  27. return self.tr('网格数据外扩')
  28. def group(self):
  29. return self.tr('栅格裁剪')
  30. def groupId(self):
  31. return 'rasterclip'
  32. def shortHelpString(self):
  33. return self.tr("遍历输入shp数据要素获取四至坐标点并按照指定距离外扩数据框,保存到输出文件夹。")
  34. def initAlgorithm(self, config=None):
  35. self.addParameter(QgsProcessingParameterFile(
  36. self.INPUT,
  37. '网格数据',
  38. extension='shp'
  39. ))
  40. # 栅格分辨率
  41. self.addParameter(QgsProcessingParameterNumber(self.resolution,
  42. self.tr('栅格分辨率'),
  43. QgsProcessingParameterNumber.Double
  44. ))
  45. # 创建一个参数,提示用户输入一个小数值
  46. self.addParameter(QgsProcessingParameterNumber(self.tolerance,
  47. self.tr('外扩距离(米)'),
  48. QgsProcessingParameterNumber.Double
  49. ))
  50. self.addParameter(QgsProcessingParameterBoolean(self.expanded,
  51. self.tr('是否外扩'),
  52. defaultValue=True))
  53. self.addParameter(QgsProcessingParameterVectorDestination(self.OUTPUT,
  54. self.tr('输出位置')))
  55. # 执行
  56. def processAlgorithm(self, parameters, context, feedback):
  57. input_shp = self.parameterAsString(parameters, self.INPUT, context)
  58. output_shp = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
  59. expand_distance = self.parameterAsDouble(parameters, self.tolerance, context)
  60. resolution = self.parameterAsDouble(parameters, self.resolution, context)
  61. print(f"expand_distance:{expand_distance}")
  62. expanded = self.parameterAsBoolean(parameters, self.expanded, context)
  63. print(f"expanded:{expanded}")
  64. if expanded == False:
  65. expand_distance = 0
  66. print(f"expanded:{expanded}")
  67. # 加载输入shapefile
  68. input_layer = QgsVectorLayer(input_shp, "input_layer", "ogr")
  69. if not input_layer.isValid():
  70. print(f"Failed to load input shapefile: {input_shp}")
  71. return {
  72. "状态": "处理失败!",
  73. "原因": f"Failed to load input shapefile: {input_shp}"
  74. }
  75. else:
  76. # 获取输入图层的字段信息
  77. fields = input_layer.fields()
  78. # 创建输出shapefile
  79. writer = QgsVectorFileWriter(output_shp, 'UTF-8', fields, QgsWkbTypes.MultiPolygon, input_layer.crs(),
  80. 'ESRI Shapefile')
  81. # 检查文件是否成功创建
  82. if writer.hasError() != QgsVectorFileWriter.NoError:
  83. print(f"Error creating output shapefile: {output_shp}")
  84. return {
  85. "状态": "处理失败!",
  86. "原因": f"Error creating output shapefile: {output_shp}"
  87. }
  88. else:
  89. # 遍历输入shapefile中的要素
  90. for feature in input_layer.getFeatures():
  91. # 获取要素的geometry和extent
  92. geometry = feature.geometry()
  93. extent = geometry.boundingBox() # 获取要素的extent(bounding box)
  94. # TODO 创建新的扩展后的QgsRectangle
  95. rings = None
  96. try:
  97. rings = geometry.asPolygon()
  98. except Exception as e:
  99. rings = geometry.asMultiPolygon()
  100. rings = rings[0]
  101. finally:
  102. print("读取完成")
  103. print("开始计算")
  104. ring = rings[0]
  105. p1 = ring[0]
  106. p2 = ring[1]
  107. p3 = ring[2]
  108. p4 = ring[3]
  109. ymax = int((max(p1.y(), p2.y(), p3.y(), p4.y()) + expand_distance) / resolution) * resolution
  110. xmin = int((min(p1.x(), p2.x(), p3.x(), p4.x()) - expand_distance) / resolution) * resolution
  111. ymin = int((min(p1.y(), p2.y(), p3.y(), p4.y()) - expand_distance) / resolution) * resolution
  112. xmax = int((max(p1.x(), p2.x(), p3.x(), p4.x()) + expand_distance) / resolution) * resolution
  113. print(f"{xmin},{ymin},{xmax},{ymax}")
  114. expanded_extent = QgsRectangle(xmin, ymin, xmax, ymax)
  115. # 使用extent创建一个新的几何(矩形geometry)
  116. new_geometry = QgsGeometry.fromRect(expanded_extent)
  117. # 创建一个新的要素,并将新几何设置到要素中
  118. new_feature = QgsFeature(fields) # 创建新的空要素,使用相同的字段定义
  119. new_feature.setGeometry(new_geometry) # 设置新的几何(extent)
  120. # 复制原始要素的属性到新的要素
  121. new_feature.setAttributes(feature.attributes()) # 将原要素的属性复制到新要素
  122. # 将修改后的要素添加到输出shapefile
  123. writer.addFeature(new_feature)
  124. # 完成写入并关闭输出文件
  125. del writer
  126. print(f"Features copied from {input_shp} to {output_shp} with modified extent.")
  127. return {
  128. "状态": "处理成功"
  129. }