123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- # -*- coding: utf-8 -*-
- __author__ = 'wanger'
- __description__ = '按照掩膜范围裁剪栅格数据'
- __date__ = '2024-11-25'
- __copyright__ = '(C) 2024 by siwei'
- __revision__ = '1.0'
- import os
- import subprocess
- import math
- from qgis._core import QgsRasterFileWriter, QgsProcessingParameterFolderDestination
- from qgis.core import (
- QgsVectorLayer,
- QgsRasterLayer,
- QgsFeature,
- QgsGeometry
- )
- import processing
- from PyQt5.QtCore import QFileInfo
- from qgis.analysis import QgsRasterCalculator, QgsRasterCalculatorEntry
- 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 ClipRasterByMaskProcessingAlgorithm(QgsProcessingAlgorithm):
- INPUT_SHP = 'INPUT_SHP'
- INPUT_RASTER = 'INPUT_RASTER'
- OUTPUT = 'OUTPUT'
- def tr(self, string):
- return QCoreApplication.translate('Processing', string)
- def createInstance(self):
- return ClipRasterByMaskProcessingAlgorithm()
- def name(self):
- return 'cliprasterbymask'
- 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_SHP,
- '网格数据',
- extension='shp'
- ))
- self.addParameter(QgsProcessingParameterFile(
- self.INPUT_RASTER,
- '栅格数据',
- extension='tif'
- ))
- # 通过 setExtensions 方法设置多个扩展名
- # self.parameter(self.INPUT_RASTER).setExtensions(['tif', 'img']) # 支持 .shp, .csv, .txt
- self.addParameter(QgsProcessingParameterFolderDestination(self.OUTPUT, '输出文件夹'))
- # 执行
- def processAlgorithm(self, parameters, context, feedback):
- input_shp = self.parameterAsString(parameters, self.INPUT_SHP, context)
- input_raster = self.parameterAsOutputLayer(parameters, self.INPUT_RASTER, context)
- output_raster = self.parameterAsString(parameters, self.OUTPUT, context)
- # 输入Shapefile路径
- # input_shp = "E:\\projects\\遥感技术部需求\\裁剪栅格\\data\\grid_extent.shp"
- # 输入栅格数据路径
- # input_raster = "D:\\gisdata\\tif\\unnamed_卫图_Level_12.tif"
- # 输出裁剪后的栅格路径
- # output_raster = "E:\\projects\\遥感技术部需求\\裁剪栅格\\output\\"
- # 加载输入Shapefile和栅格数据
- vector_layer = QgsVectorLayer(input_shp, "vector_layer", "ogr")
- raster_layer = QgsRasterLayer(input_raster, "raster_layer")
- fields = vector_layer.fields()
- # 获取分辨率(像素大小)
- pixel_width = raster_layer.rasterUnitsPerPixelX()
- pixel_height = raster_layer.rasterUnitsPerPixelY()
- # 遍历输入图层的所有要素,并为每个要素保存一个单独的Shapefile文件
- total = 0
- for idx, feature in enumerate(vector_layer.getFeatures()):
- # 获取当前要素的几何数据
- geometry = feature.geometry()
- key = feature["新图号"]
- extent = geometry.boundingBox()
- # 创建一个新的 Shapefile 文件名,可以使用索引或 ID 来命名
- # output_shp = os.path.join(output_raster, f"{key}.shp")
- #
- # # 创建输出shapefile
- # writer = QgsVectorFileWriter(output_shp, 'UTF-8', fields, QgsWkbTypes.MultiPolygon, vector_layer.crs(),
- # 'ESRI Shapefile')
- # writer.addFeature(feature)
- #
- # # 完成写入并关闭输出文件
- # del writer
- # 使用QGIS的processing模块进行栅格裁剪
- # params = {
- # 'INPUT': raster_layer, # 输入栅格
- # 'MASK': output_shp, # 用于裁剪的矢量图层
- # 'OUTPUT': f"{output_raster}\\{key}.tif", # 输出裁剪后的栅格文件
- # 'CROP_TO_CUTLINE': True
- # }
- # 调用 clipRasterByExtent 进行裁剪
- # vector_layer_cur = QgsVectorLayer(output_shp, 'Shapefile Layer')
- # params = {
- # 'INPUT': input_raster,
- # 'EXTENT': vector_layer_cur.extent(),
- # 'PROJWIN': vector_layer_cur.extent(),
- # 'OUTPUT': f"{output_raster}\\{key}.tif"
- # }
- # extent = vector_layer_cur.extent()
- # 计算裁剪范围的整数倍,确保裁剪范围对齐
- minX = extent.xMinimum()
- maxX = extent.xMaximum()
- minY = extent.yMinimum()
- maxY = extent.yMaximum()
- # 通过对齐最大值,确保裁剪范围完整
- maxX_aligned = maxX + pixel_width
- maxY_aligned = maxY + pixel_width
- minX_aligned = minX - pixel_width
- minY_aligned = minY - pixel_width
- # maxX_aligned = math.ceil(maxX / pixel_width) * pixel_width + pixel_width
- # maxY_aligned = math.ceil(maxY / pixel_height) * pixel_height + pixel_width
- # minX_aligned = math.floor(minX / pixel_width) * pixel_width - pixel_width
- # minY_aligned = math.floor(minY / pixel_height) * pixel_height - pixel_width
- # extent_cur = f'{minX},{extent.yMaximum()},{extent.xMaximum()},{minY}' # 裁剪范围:minX,maxY,maxX,minY
- # extent_cur = f'524101.737 3310956.7264999966 530229.7547000019 3306243.2199' # 裁剪范围:minX,maxY,maxX,minY
- # print(extent_cur)
- # 设置 gdal_translate 命令和参数
- gdal_translate_cmd = [
- 'gdal_translate', # GDAL 工具名称
- '-projwin', str(minX_aligned), str(maxY_aligned), str(maxX_aligned), str(minY_aligned),
- # 裁剪范围(minX, maxY, maxX, minY)
- '-of', 'GTiff', # 输出格式为 GeoTIFF
- input_raster, # 输入栅格文件路径
- f"{output_raster}\\{key}.tif" # 输出文件路径
- ]
- print(gdal_translate_cmd)
- # 运行命令
- try:
- subprocess.run(gdal_translate_cmd, check=True)
- print("gdal_translate 执行成功!")
- total = total + 1
- except subprocess.CalledProcessError as e:
- print(f"gdal_translate 执行失败: {e}")
- # 3. 调用 `gdal:translate` 进行裁剪
- # parameters = {
- # 'INPUT': input_raster, # 输入栅格
- # 'OUTPUT': f"{output_raster}\\{key}.tif", # 输出路径
- # 'PROJWIN': extent_cur, # 裁剪范围 (左下右上)
- # # 'TARGET_CRS': 'EPSG:4544' # 可选:指定目标坐标系统(如果需要)
- # }
- # print(parameters)
- # 4. 运行工具
- # processing.run('gdal:translate', parameters)
- # 执行裁剪操作
- # processing.run('gdal:cliprasterbyextent', params)
- # processing.run('gdal:cliprasterbymasklayer', params)
- # print(f"Cropped raster saved to {output_raster}")
- return {
- "状态": f"处理成功,共裁剪出{total}块栅格数据。"
- }
|