|
@@ -0,0 +1,141 @@
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
+
|
|
|
+__author__ = 'wanger'
|
|
|
+__description__ = '处理网格数据 遍历要素获取四至坐标点 按照指定距离外扩数据框'
|
|
|
+__date__ = '2024-11-25'
|
|
|
+__copyright__ = '(C) 2024 by siwei'
|
|
|
+__revision__ = '1.0'
|
|
|
+import processing
|
|
|
+import os
|
|
|
+
|
|
|
+from PyQt5.QtCore import QVariant
|
|
|
+
|
|
|
+from qgis.PyQt.QtCore import QCoreApplication
|
|
|
+from qgis._core import QgsSpatialIndex, QgsField, QgsRectangle, QgsProcessingParameterVectorDestination, \
|
|
|
+ QgsVectorFileWriter, QgsWkbTypes, QgsProcessingParameterNumber, QgsProcessingParameterBoolean, QgsGeometry, \
|
|
|
+ QgsFeature
|
|
|
+from qgis.core import (QgsProcessing,
|
|
|
+ QgsVectorLayer,
|
|
|
+ QgsFeatureSink,
|
|
|
+ QgsProcessingException,
|
|
|
+ QgsProcessingAlgorithm,
|
|
|
+ QgsProcessingParameterFile,
|
|
|
+ QgsProcessingParameterFeatureSource,
|
|
|
+ QgsProcessingParameterFeatureSink)
|
|
|
+from qgis import processing
|
|
|
+
|
|
|
+
|
|
|
+class ExpandGridProcessingAlgorithm(QgsProcessingAlgorithm):
|
|
|
+ INPUT = 'INPUT'
|
|
|
+ OUTPUT = 'OUTPUT'
|
|
|
+ tolerance = 'tolerance'
|
|
|
+ expanded = 'expanded'
|
|
|
+
|
|
|
+ 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.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)
|
|
|
+ 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)
|
|
|
+ # 对extent进行外扩
|
|
|
+ # 使用 grow 方法来将bounding box外扩100米
|
|
|
+ # if expanded == False:
|
|
|
+ # extent.grow(expand_distance) # 扩展100米
|
|
|
+ # print(f"Feature ID: {feature.id()}, Extent: {extent}")
|
|
|
+ # 获取四至坐标
|
|
|
+ minX = extent.xMinimum()
|
|
|
+ maxX = extent.xMaximum()
|
|
|
+ minY = extent.yMinimum()
|
|
|
+ maxY = extent.yMaximum()
|
|
|
+ # 手动扩展extent,向四个方向扩展100米
|
|
|
+ expanded_minX = minX - expand_distance # 向左扩展
|
|
|
+ expanded_maxX = maxX + expand_distance # 向右扩展
|
|
|
+ expanded_minY = minY - expand_distance # 向下扩展
|
|
|
+ expanded_maxY = maxY + expand_distance # 向上扩展
|
|
|
+ # 创建新的扩展后的QgsRectangle
|
|
|
+ expanded_extent = QgsRectangle(expanded_minX, expanded_minY, expanded_maxX, expanded_maxY)
|
|
|
+ # 使用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 {
|
|
|
+ "状态": "处理成功"
|
|
|
+ }
|