Relief.py 6.77 KB
Newer Older
xuebingbing's avatar
xuebingbing committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
# -*- coding: utf-8 -*-

"""
***************************************************************************
    Relief.py
    ---------------------
    Date                 : December 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__ = 'December 2016'
__copyright__ = '(C) 2016, Alexander Bruy'

import os

from qgis.PyQt.QtGui import QIcon, QColor

from qgis.analysis import QgsRelief
from qgis.core import (QgsProcessingParameterDefinition,
                       QgsProcessingParameterRasterLayer,
                       QgsProcessingParameterNumber,
                       QgsProcessingParameterBoolean,
                       QgsProcessingParameterRasterDestination,
                       QgsProcessingParameterFileDestination,
                       QgsRasterFileWriter,
                       QgsProcessingException)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm

pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]


class ParameterReliefColors(QgsProcessingParameterDefinition):

    def __init__(self, name='', description='', parent=None, optional=True):
        super().__init__(name, description, None, optional)
        self.parent = parent
        self.setMetadata({'widget_wrapper': 'processing.algs.qgis.ui.ReliefColorsWidget.ReliefColorsWidgetWrapper'})

    def type(self):
        return 'relief_colors'

    def clone(self):
        return ParameterReliefColors(self.name(), self.description(), self.parent,
                                     self.flags() & QgsProcessingParameterDefinition.FlagOptional)

    @staticmethod
    def valueToColors(value):
        if value is None:
            return None

        if value == '':
            return None

        if isinstance(value, str):
            return value.split(';')
        else:
            return ParameterReliefColors.colorsToString(value)

    @staticmethod
    def colorsToString(colors):
        s = ''
        for c in colors:
            s += '{:f}, {:f}, {:d}, {:d}, {:d};'.format(c[0],
                                                        c[1],
                                                        c[2],
                                                        c[3],
                                                        c[4])
        return s[:-1]


class Relief(QgisAlgorithm):

    INPUT = 'INPUT'
    Z_FACTOR = 'Z_FACTOR'
    AUTO_COLORS = 'AUTO_COLORS'
    COLORS = 'COLORS'
    OUTPUT = 'OUTPUT'
    FREQUENCY_DISTRIBUTION = 'FREQUENCY_DISTRIBUTION'

    def icon(self):
        return QIcon(os.path.join(pluginPath, 'images', 'dem.png'))

    def group(self):
        return self.tr('Raster terrain analysis')

    def groupId(self):
        return 'rasterterrainanalysis'

    def __init__(self):
        super().__init__()

    def initAlgorithm(self, config=None):
        self.addParameter(QgsProcessingParameterRasterLayer(self.INPUT,
                                                            self.tr('Elevation layer')))
        self.addParameter(QgsProcessingParameterNumber(self.Z_FACTOR,
                                                       self.tr('Z factor'), type=QgsProcessingParameterNumber.Double,
                                                       minValue=0.00, defaultValue=1.0))
        self.addParameter(QgsProcessingParameterBoolean(self.AUTO_COLORS,
                                                        self.tr('Generate relief classes automatically'),
                                                        defaultValue=False))
        self.addParameter(ParameterReliefColors(self.COLORS,
                                                self.tr('Relief colors'),
                                                self.INPUT,
                                                True))
        self.addParameter(QgsProcessingParameterRasterDestination(self.OUTPUT,
                                                                  self.tr('Relief')))
        self.addParameter(QgsProcessingParameterFileDestination(self.FREQUENCY_DISTRIBUTION,
                                                                self.tr('Frequency distribution'),
                                                                'CSV files (*.csv)',
                                                                optional=True,
                                                                createByDefault=False))

    def name(self):
        return 'relief'

    def displayName(self):
        return self.tr('Relief')

    def processAlgorithm(self, parameters, context, feedback):
        inputFile = self.parameterAsRasterLayer(parameters, self.INPUT, context).source()
        zFactor = self.parameterAsDouble(parameters, self.Z_FACTOR, context)
        automaticColors = self.parameterAsBoolean(parameters, self.AUTO_COLORS, context)
        outputFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)
        frequencyDistribution = self.parameterAsFileOutput(parameters, self.FREQUENCY_DISTRIBUTION, context)

        outputFormat = QgsRasterFileWriter.driverForExtension(os.path.splitext(outputFile)[1])

        relief = QgsRelief(inputFile, outputFile, outputFormat)

        if automaticColors:
            reliefColors = relief.calculateOptimizedReliefClasses()
        else:
            colors = ParameterReliefColors.valueToColors(parameters[self.COLORS])
            if colors is None or len(colors) == 0:
                raise QgsProcessingException(
                    self.tr('Specify relief colors or activate "Generate relief classes automatically" option.'))

            reliefColors = []
            for c in colors:
                v = c.split(',')
                color = QgsRelief.ReliefColor(QColor(int(v[2]), int(v[3]), int(v[4])),
                                              float(v[0]),
                                              float(v[1]))
                reliefColors.append(color)

        relief.setReliefColors(reliefColors)
        relief.setZFactor(zFactor)
        if frequencyDistribution:
            relief.exportFrequencyDistributionToCsv(frequencyDistribution)
        relief.processRaster(feedback)

        return {self.OUTPUT: outputFile, self.FREQUENCY_DISTRIBUTION: frequencyDistribution}