mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			190 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			190 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# -*- coding: utf-8 -*-
 | 
						|
 | 
						|
"""
 | 
						|
***************************************************************************
 | 
						|
    TinInterpolation.py
 | 
						|
    ---------------------
 | 
						|
    Date                 : October 2016
 | 
						|
    Copyright            : (C) 2016 by Alexander Bruy
 | 
						|
    Email                : alexander dot bruy at gmail dot com
 | 
						|
***************************************************************************
 | 
						|
*                                                                         *
 | 
						|
*   This program is free software; you can redistribute it and/or modify  *
 | 
						|
*   it under the terms of the GNU General Public License as published by  *
 | 
						|
*   the Free Software Foundation; either version 2 of the License, or     *
 | 
						|
*   (at your option) any later version.                                   *
 | 
						|
*                                                                         *
 | 
						|
***************************************************************************
 | 
						|
"""
 | 
						|
 | 
						|
__author__ = 'Alexander Bruy'
 | 
						|
__date__ = 'October 2016'
 | 
						|
__copyright__ = '(C) 2016, Alexander Bruy'
 | 
						|
 | 
						|
import os
 | 
						|
import math
 | 
						|
 | 
						|
from qgis.PyQt.QtGui import QIcon
 | 
						|
 | 
						|
from qgis.core import (QgsProcessingUtils,
 | 
						|
                       QgsProcessing,
 | 
						|
                       QgsProcessingParameterEnum,
 | 
						|
                       QgsProcessingParameterNumber,
 | 
						|
                       QgsProcessingParameterExtent,
 | 
						|
                       QgsProcessingParameterDefinition,
 | 
						|
                       QgsProcessingParameterRasterDestination,
 | 
						|
                       QgsWkbTypes,
 | 
						|
                       QgsProcessingParameterFeatureSink,
 | 
						|
                       QgsProcessingException,
 | 
						|
                       QgsCoordinateReferenceSystem)
 | 
						|
from qgis.analysis import (QgsInterpolator,
 | 
						|
                           QgsTinInterpolator,
 | 
						|
                           QgsGridFileWriter)
 | 
						|
 | 
						|
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
 | 
						|
from processing.algs.qgis.ui.InterpolationWidgets import ParameterInterpolationData, ParameterPixelSize
 | 
						|
 | 
						|
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
 | 
						|
 | 
						|
 | 
						|
class TinInterpolation(QgisAlgorithm):
 | 
						|
    INTERPOLATION_DATA = 'INTERPOLATION_DATA'
 | 
						|
    METHOD = 'METHOD'
 | 
						|
    PIXEL_SIZE = 'PIXEL_SIZE'
 | 
						|
    COLUMNS = 'COLUMNS'
 | 
						|
    ROWS = 'ROWS'
 | 
						|
    EXTENT = 'EXTENT'
 | 
						|
    OUTPUT = 'OUTPUT'
 | 
						|
    TRIANGULATION = 'TRIANGULATION'
 | 
						|
 | 
						|
    def icon(self):
 | 
						|
        return QIcon(os.path.join(pluginPath, 'images', 'interpolation.png'))
 | 
						|
 | 
						|
    def group(self):
 | 
						|
        return self.tr('Interpolation')
 | 
						|
 | 
						|
    def groupId(self):
 | 
						|
        return 'interpolation'
 | 
						|
 | 
						|
    def __init__(self):
 | 
						|
        super().__init__()
 | 
						|
 | 
						|
    def initAlgorithm(self, config=None):
 | 
						|
        self.METHODS = [self.tr('Linear'),
 | 
						|
                        self.tr('Clough-Toucher (cubic)')
 | 
						|
                        ]
 | 
						|
 | 
						|
        self.addParameter(ParameterInterpolationData(self.INTERPOLATION_DATA,
 | 
						|
                                                     self.tr('Input layer(s)')))
 | 
						|
        self.addParameter(QgsProcessingParameterEnum(self.METHOD,
 | 
						|
                                                     self.tr('Interpolation method'),
 | 
						|
                                                     options=self.METHODS,
 | 
						|
                                                     defaultValue=0))
 | 
						|
        self.addParameter(QgsProcessingParameterExtent(self.EXTENT,
 | 
						|
                                                       self.tr('Extent'),
 | 
						|
                                                       optional=False))
 | 
						|
        pixel_size_param = ParameterPixelSize(self.PIXEL_SIZE,
 | 
						|
                                              self.tr('Output raster size'),
 | 
						|
                                              layersData=self.INTERPOLATION_DATA,
 | 
						|
                                              extent=self.EXTENT,
 | 
						|
                                              minValue=0.0,
 | 
						|
                                              default=0.1)
 | 
						|
        self.addParameter(pixel_size_param)
 | 
						|
 | 
						|
        cols_param = QgsProcessingParameterNumber(self.COLUMNS,
 | 
						|
                                                  self.tr('Number of columns'),
 | 
						|
                                                  optional=True,
 | 
						|
                                                  minValue=0, maxValue=10000000)
 | 
						|
        cols_param.setFlags(cols_param.flags() | QgsProcessingParameterDefinition.FlagHidden)
 | 
						|
        self.addParameter(cols_param)
 | 
						|
 | 
						|
        rows_param = QgsProcessingParameterNumber(self.ROWS,
 | 
						|
                                                  self.tr('Number of rows'),
 | 
						|
                                                  optional=True,
 | 
						|
                                                  minValue=0, maxValue=10000000)
 | 
						|
        rows_param.setFlags(rows_param.flags() | QgsProcessingParameterDefinition.FlagHidden)
 | 
						|
        self.addParameter(rows_param)
 | 
						|
 | 
						|
        self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT,
 | 
						|
                                                                  self.tr('Interpolated')))
 | 
						|
 | 
						|
        triangulation_file_param = QgsProcessingParameterFeatureSink(self.TRIANGULATION,
 | 
						|
                                                                     self.tr('Triangulation'),
 | 
						|
                                                                     type=QgsProcessing.TypeVectorLine,
 | 
						|
                                                                     optional=True)
 | 
						|
        triangulation_file_param.setCreateByDefault(False)
 | 
						|
        self.addParameter(triangulation_file_param)
 | 
						|
 | 
						|
    def name(self):
 | 
						|
        return 'tininterpolation'
 | 
						|
 | 
						|
    def displayName(self):
 | 
						|
        return self.tr('TIN interpolation')
 | 
						|
 | 
						|
    def processAlgorithm(self, parameters, context, feedback):
 | 
						|
        interpolationData = ParameterInterpolationData.parseValue(parameters[self.INTERPOLATION_DATA])
 | 
						|
        method = self.parameterAsEnum(parameters, self.METHOD, context)
 | 
						|
        bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
 | 
						|
        pixel_size = self.parameterAsDouble(parameters, self.PIXEL_SIZE, context)
 | 
						|
        output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
 | 
						|
 | 
						|
        columns = self.parameterAsInt(parameters, self.COLUMNS, context)
 | 
						|
        rows = self.parameterAsInt(parameters, self.ROWS, context)
 | 
						|
        if columns == 0:
 | 
						|
            columns = max(math.ceil(bbox.width() / pixel_size), 1)
 | 
						|
        if rows == 0:
 | 
						|
            rows = max(math.ceil(bbox.height() / pixel_size), 1)
 | 
						|
 | 
						|
        if interpolationData is None:
 | 
						|
            raise QgsProcessingException(
 | 
						|
                self.tr('You need to specify at least one input layer.'))
 | 
						|
 | 
						|
        layerData = []
 | 
						|
        layers = []
 | 
						|
        crs = QgsCoordinateReferenceSystem()
 | 
						|
        for i, row in enumerate(interpolationData.split('::|::')):
 | 
						|
            v = row.split('::~::')
 | 
						|
            data = QgsInterpolator.LayerData()
 | 
						|
 | 
						|
            # need to keep a reference until interpolation is complete
 | 
						|
            layer = QgsProcessingUtils.variantToSource(v[0], context)
 | 
						|
            data.source = layer
 | 
						|
            data.transformContext = context.transformContext()
 | 
						|
            layers.append(layer)
 | 
						|
            if not crs.isValid():
 | 
						|
                crs = layer.sourceCrs()
 | 
						|
 | 
						|
            data.valueSource = int(v[1])
 | 
						|
            data.interpolationAttribute = int(v[2])
 | 
						|
            if data.valueSource == QgsInterpolator.ValueAttribute and data.interpolationAttribute == -1:
 | 
						|
                raise QgsProcessingException(self.tr('Layer {} is set to use a value attribute, but no attribute was set'.format(i + 1)))
 | 
						|
 | 
						|
            if v[3] == '0':
 | 
						|
                data.sourceType = QgsInterpolator.SourcePoints
 | 
						|
            elif v[3] == '1':
 | 
						|
                data.sourceType = QgsInterpolator.SourceStructureLines
 | 
						|
            else:
 | 
						|
                data.sourceType = QgsInterpolator.SourceBreakLines
 | 
						|
            layerData.append(data)
 | 
						|
 | 
						|
        if method == 0:
 | 
						|
            interpolationMethod = QgsTinInterpolator.Linear
 | 
						|
        else:
 | 
						|
            interpolationMethod = QgsTinInterpolator.CloughTocher
 | 
						|
 | 
						|
        (triangulation_sink, triangulation_dest_id) = self.parameterAsSink(parameters, self.TRIANGULATION, context,
 | 
						|
                                                                           QgsTinInterpolator.triangulationFields(), QgsWkbTypes.LineString, crs)
 | 
						|
 | 
						|
        interpolator = QgsTinInterpolator(layerData, interpolationMethod, feedback)
 | 
						|
        if triangulation_sink is not None:
 | 
						|
            interpolator.setTriangulationSink(triangulation_sink)
 | 
						|
 | 
						|
        writer = QgsGridFileWriter(interpolator,
 | 
						|
                                   output,
 | 
						|
                                   bbox,
 | 
						|
                                   columns,
 | 
						|
                                   rows)
 | 
						|
 | 
						|
        writer.writeFile(feedback)
 | 
						|
        return {self.OUTPUT: output, self.TRIANGULATION: triangulation_dest_id}
 |