Beispiel #1
0
def mmi_ramp(raster_layer):
    """Generate an mmi ramp using standardised range of 1-12

    A standarised range is used so that two shakemaps of different
    intensities can be properly compared visually with colours stretched
    accross the same range.

    The colours used are the 'standard' colours commonly shown for the
    mercalli scale e.g. on wikipedia and other sources.

    :param raster_layer: A raster layer that will have an mmi style applied.
    :type raster_layer: QgsRasterLayer
    """

    items = []
    for class_max in range(1, 13):
        colour = QtGui.QColor(mmi_colour(class_max))
        label = '%i' % class_max
        ramp_item = QgsColorRampShader.ColorRampItem(class_max, colour, label)
        items.append(ramp_item)

    raster_shader = QgsRasterShader()
    ramp_shader = QgsColorRampShader()
    ramp_shader.setColorRampType(QgsColorRampShader.INTERPOLATED)
    ramp_shader.setColorRampItemList(items)
    raster_shader.setRasterShaderFunction(ramp_shader)
    band = 1
    renderer = QgsSingleBandPseudoColorRenderer(
        raster_layer.dataProvider(),
        band,
        raster_shader)
    raster_layer.setRenderer(renderer)
Beispiel #2
0
def createRasterShader(fields, mode = "rgb", scale = "float"):
    shader = QgsRasterShader()
    colRamp = QgsColorRampShader()
    colRamp.setColorRampType(QgsColorRampShader.INTERPOLATED)
    
    ramp = []
    col = QColor()
    
    for line in fields:
        val = float(line[0])
        txt = unicode(line[1])
       
        if mode == "rgb" or mode == "rnd":
            if scale != "float":
                color = [float(x)/255.0 for x in line[2:6]]
            col.setRgbF(*color)
            
        elif mode == "hsv":
            if scale != "float":
                color = [float(x)/float(y) for x,y in zip(line[2:6], [360, 100, 100, 255])]
            col.setHsvF(*color)
            
        elif mode == "hex":
            col.setNamedColor(str(line[2]))

        ramp.append(QgsColorRampShader.ColorRampItem(val, col, txt))
    
    colRamp.setColorRampItemList(ramp)
    shader.setRasterShaderFunction(colRamp)
    
    return(shader)
 def aggregate_layers(self, layers, d):
     aggregation = self.frequency.itemData(self.frequency.currentIndex())
     month = str(d.month)
     month = month if len(month) == 2 else '0' + month
     day = str(d.day)
     day = day if len(day) == 2 else '0' + day
     filtered_layers = filter(lambda x: '.tif' in x, layers)
     datasets = []
     file_name = None
     for l in filtered_layers:
         datasets.append(Dataset(l))
     sum = datasets[0]
     for i in range(1,len(datasets)-1):
         sum += datasets[i]
     if aggregation == 'SUM':
         Env.overwrite = True
         avg = sum
         file_name = self.download_folder.text() + '/' + str(d.year) + '_' + month + '_' + day + '_SUM.tif'
         avg.save(file_name)
     elif aggregation == 'AVG':
         Env.overwrite = True
         avg = sum
         avg /= len(datasets)
         file_name = self.download_folder.text() + '/' + str(d.year) + '_' + month + '_' + day + '_AVG.tif'
         avg.save(file_name)
     if self.add_to_canvas.isChecked() is True:
         self.bar.pushMessage(None, str(file_name), level=QgsMessageBar.INFO)
         title = None
         if aggregation == 'SUM':
             title = self.tr('TRMM Aggregate (Sum): ') + str(d.year) + '-' + str(month) + '-' + str(day)
         elif aggregation == 'AVG':
             title = self.tr('TRMM Aggregate (Average): ') + str(d.year) + '-' + str(month) + '-' + str(day)
         rl = self.iface.addRasterLayer(file_name, title)
         fcn = QgsColorRampShader()
         fcn.setColorRampType(QgsColorRampShader.INTERPOLATED)
         lst = [
             QgsColorRampShader.ColorRampItem(0, QColor(247, 251, 255, 0), '< 2.6 [mm]'),
             QgsColorRampShader.ColorRampItem(2.6, QColor(222, 235, 247), '< 5.2 [mm]'),
             QgsColorRampShader.ColorRampItem(5.2, QColor(199, 220, 239), '< 7.8 [mm]'),
             QgsColorRampShader.ColorRampItem(7.8, QColor(162, 203, 226), '< 10.4 [mm]'),
             QgsColorRampShader.ColorRampItem(10.4, QColor(114, 178, 215), '< 13 [mm]'),
             QgsColorRampShader.ColorRampItem(13, QColor(73, 151, 201), '< 15.6 [mm]'),
             QgsColorRampShader.ColorRampItem(15.6, QColor(40, 120, 184), '< 18 [mm]'),
             QgsColorRampShader.ColorRampItem(18, QColor(13, 87, 161), '< 20 [mm]'),
             QgsColorRampShader.ColorRampItem(20, QColor(8, 48, 107), '>= 20 [mm]')
         ]
         fcn.setColorRampItemList(lst)
         shader = QgsRasterShader()
         shader.setRasterShaderFunction(fcn)
         renderer = QgsSingleBandPseudoColorRenderer(rl.dataProvider(), 1, shader)
         rl.setRenderer(renderer)
         rl.triggerRepaint()
def setRamp(layer, iface):
    
    renderer = layer.renderer()
    provider = layer.dataProvider()
    extent = layer.extent()
    
    ver = provider.hasStatistics(1, QgsRasterBandStats.All)
    
    stats = provider.bandStatistics(1, QgsRasterBandStats.All,extent, 0)
    
    if ver is not False:
        print "minimumValue = ", stats.minimumValue
    
        print "maximumValue = ", stats.maximumValue
    
    if (stats.minimumValue < 0):
        min = 0  
    
    else: 
        min= stats.minimumValue
    
    max = stats.maximumValue
    range = max - min
    add = range//2
    interval = min + add
    
    colDic = {'red':'#ff0000', 'yellow':'#ffff00','blue':'#0000ff'}
    
    valueList =[min, interval, max]
    
    lst = [ QgsColorRampShader.ColorRampItem(valueList[0], QColor(colDic['red'])), 
            QgsColorRampShader.ColorRampItem(valueList[1], QColor(colDic['yellow'])), 
            QgsColorRampShader.ColorRampItem(valueList[2], QColor(colDic['blue']))]
    
    myRasterShader = QgsRasterShader()
    myColorRamp = QgsColorRampShader()
    
    myColorRamp.setColorRampItemList(lst)
    myColorRamp.setColorRampType(QgsColorRampShader.INTERPOLATED)
    myRasterShader.setRasterShaderFunction(myColorRamp)
    
    myPseudoRenderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 
                                                        layer.type(),  
                                                        myRasterShader)
    
    layer.setRenderer(myPseudoRenderer)
    
    layer.triggerRepaint()
Beispiel #5
0
def displaced_people_style(layer):
    """Simple style to display a displaced count with a binary style.

    :param layer: The layer to style.
    :type layer: QgsRasterLayer
    """
    color_ramp = QgsColorRampShader()
    color_ramp.setColorRampType(QgsColorRampShader.INTERPOLATED)
    color_ramp.setColorRampItemList(legend_raster_displaced)

    shader = QgsRasterShader()
    shader.setRasterShaderFunction(color_ramp)

    renderer = QgsSingleBandPseudoColorRenderer(
        layer.dataProvider(), 1, shader)

    layer.setRenderer(renderer)
Beispiel #6
0
    def loadLabelImage(imagepath, labeldescriptor = None):
        """
        Load a labeled single band raster in the canvas

        Keyword arguments:
        imagepath -- the path to the image
        labeldescriptor -- a dictionnary for label (int) to tuple (QColor, QString) conversion
        """
        if imagepath is None:
            return

        name = os.path.splitext( os.path.basename(imagepath) )[0]
        qgslayer = QgsRasterLayer(imagepath, name)
        if not qgslayer.isValid():
            QtGui.QMessageBox.critical(None,
                                       u"Erreur",
                                       u"Impossible de charger la couche %s" % unicode(imagepath))

        QgsMapLayerRegistry.instance().addMapLayer(qgslayer)

        qgslayer.setDrawingStyle('SingleBandPseudoColor')

        colorlist = []
        max_label = 0
        for label in sorted(labeldescriptor.keys()):
            color = labeldescriptor[label][0]
            labeltxt = labeldescriptor[label][1]
            colorlist.append(QgsColorRampShader.ColorRampItem(label, color, labeltxt))
            if labeltxt > max_label:
                max_label = labeltxt

        s = QgsRasterShader()
        c = QgsColorRampShader()
        c.setColorRampType(QgsColorRampShader.INTERPOLATED)
        c.setColorRampItemList(colorlist)
        s.setRasterShaderFunction(c)
        ps = QgsSingleBandPseudoColorRenderer(qgslayer.dataProvider(), 1, s)
        qgslayer.setRenderer(ps)

        for bandNo in range(1,qgslayer.dataProvider().bandCount()+1):
            qgslayer.dataProvider().setUseSrcNoDataValue( bandNo, False )

        QGisLayers.iface.legendInterface().refreshLayerSymbology(qgslayer)
        if hasattr(qgslayer, "setCacheImage"):
            qgslayer.setCacheImage(None)
        qgslayer.triggerRepaint()
    def testShaderCrash(self):
        """Check if we assign a shader and then reassign it no crash occurs."""
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage

        myRasterShader = QgsRasterShader()
        myColorRampShader = QgsColorRampShader()
        myColorRampShader.setColorRampType(QgsColorRampShader.Interpolated)
        myItems = []
        myItem = QgsColorRampShader.ColorRampItem(10, QColor('#ffff00'), 'foo')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(100, QColor('#ff00ff'),
                                                  'bar')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(1000, QColor('#00ff00'),
                                                  'kazam')
        myItems.append(myItem)
        myColorRampShader.setColorRampItemList(myItems)
        myRasterShader.setRasterShaderFunction(myColorRampShader)
        myPseudoRenderer = QgsSingleBandPseudoColorRenderer(
            myRasterLayer.dataProvider(), 1, myRasterShader)
        myRasterLayer.setRenderer(myPseudoRenderer)

        return
        # ####### works first time #############

        myRasterShader = QgsRasterShader()
        myColorRampShader = QgsColorRampShader()
        myColorRampShader.setColorRampType(QgsColorRampShader.Interpolated)
        myItems = []
        myItem = QgsColorRampShader.ColorRampItem(10, QColor('#ffff00'), 'foo')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(100, QColor('#ff00ff'),
                                                  'bar')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(1000, QColor('#00ff00'),
                                                  'kazam')
        myItems.append(myItem)
        myColorRampShader.setColorRampItemList(myItems)
        myRasterShader.setRasterShaderFunction(myColorRampShader)
        # ####### crash on next line (fixed now)##################
        myPseudoRenderer = QgsSingleBandPseudoColorRenderer(
            myRasterLayer.dataProvider(), 1, myRasterShader)
        myRasterLayer.setRenderer(myPseudoRenderer)
Beispiel #8
0
    def testSingleBandPseudoColorRenderer_Interpolated(self):
        # get min and max of the band to renderer
        bandNo = 3
        stats = self.raster_layer.dataProvider().bandStatistics(bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max)
        minValue = stats.minimumValue
        maxValue = stats.maximumValue
        # create shader for the renderer
        shader = QgsRasterShader(minValue, maxValue)
        colorRampShaderFcn = QgsColorRampShader(minValue, maxValue)
        colorRampShaderFcn.setColorRampType(QgsColorRampShader.Interpolated)
        colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous)
        colorRampShaderFcn.setClip(True)
        items = []
        for index in range(10):
            items.append(QgsColorRampShader.ColorRampItem(index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)),
                                                          "{}".format(index)))
        colorRampShaderFcn.setColorRampItemList(items)
        shader.setRasterShaderFunction(colorRampShaderFcn)
        # create instance to test
        rasterRenderer = QgsSingleBandPseudoColorRenderer(self.raster_layer.dataProvider(), bandNo, shader)
        self.raster_layer.setRenderer(rasterRenderer)

        # do test
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertNoOpacity(root)
        self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo))
        # check ColorMapEntry classes
        colorMap = root.elementsByTagName('sld:ColorMap')
        colorMap = colorMap.item(0).toElement()
        self.assertFalse(colorMap.isNull())
        self.assertEqual(colorMap.attribute('type'), 'ramp')
        colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry')
        self.assertEqual(colorMapEntries.count(), 10)
        for index in range(colorMapEntries.count()):
            colorMapEntry = colorMapEntries.at(index).toElement()
            self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('opacity'), '')
            self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index))
    def testSingleBandPseudoColorRenderer_Interpolated(self):
        # get min and max of the band to renderer
        bandNo = 3
        stats = self.raster_layer.dataProvider().bandStatistics(bandNo, QgsRasterBandStats.Min | QgsRasterBandStats.Max)
        minValue = stats.minimumValue
        maxValue = stats.maximumValue
        # create shader for the renderer
        shader = QgsRasterShader(minValue, maxValue)
        colorRampShaderFcn = QgsColorRampShader(minValue, maxValue)
        colorRampShaderFcn.setColorRampType(QgsColorRampShader.Interpolated)
        colorRampShaderFcn.setClassificationMode(QgsColorRampShader.Continuous)
        colorRampShaderFcn.setClip(True)
        items = []
        for index in range(10):
            items.append(QgsColorRampShader.ColorRampItem(index, QColor('#{0:02d}{0:02d}{0:02d}'.format(index)), "{}".format(index)))
        colorRampShaderFcn.setColorRampItemList(items)
        shader.setRasterShaderFunction(colorRampShaderFcn)
        # create instance to test
        rasterRenderer = QgsSingleBandPseudoColorRenderer(self.raster_layer.dataProvider(), bandNo, shader)
        self.raster_layer.setRenderer(rasterRenderer)

        # do test
        dom, root = self.rendererToSld(self.raster_layer.renderer())
        self.assertNoOpacity(root)
        self.assertChannelBand(root, 'sld:GrayChannel', '{}'.format(bandNo))
        # check ColorMapEntry classes
        colorMap = root.elementsByTagName('sld:ColorMap')
        colorMap = colorMap.item(0).toElement()
        self.assertFalse(colorMap.isNull())
        self.assertEqual(colorMap.attribute('type'), 'ramp')
        colorMapEntries = colorMap.elementsByTagName('sld:ColorMapEntry')
        self.assertEqual(colorMapEntries.count(), 10)
        for index in range(colorMapEntries.count()):
            colorMapEntry = colorMapEntries.at(index).toElement()
            self.assertEqual(colorMapEntry.attribute('quantity'), '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('label'), '{}'.format(index))
            self.assertEqual(colorMapEntry.attribute('opacity'), '')
            self.assertEqual(colorMapEntry.attribute('color'), '#{0:02d}{0:02d}{0:02d}'.format(index))
Beispiel #10
0
    def categoraize_raster_layer(self, layer=None, layer_name=None):
        """
        """
        if not layer:
            layer = self.get_layer_by_name(layer_name)
        if not layer:
            return

        fnc = QgsColorRampShader()
        fnc.setColorRampType(QgsColorRampShader.Discrete)
        fnc.setColorRampItemList([
            QgsColorRampShader.ColorRampItem(0, QColor(0, 0, 0, 0), '-'),
            QgsColorRampShader.ColorRampItem(1, QColor(187, 187, 187), '1 - Cloud'),
            QgsColorRampShader.ColorRampItem(2, QColor(255, 255, 26), '2 - Subsurface'),
            QgsColorRampShader.ColorRampItem(3, QColor(247, 126, 60), '3 - Surface'),
            QgsColorRampShader.ColorRampItem(4, QColor(0, 0, 0), '4 - NoData')
        ])

        shader = QgsRasterShader()
        shader.setRasterShaderFunction(fnc)

        renderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 1, shader)
        layer.setRenderer(renderer)
    def render(self):
        t_0 = self.dlg.threshold_0_slider.value() / (10.0**self.precision)
        t_1 = self.dlg.threshold_1_slider.value() / (10.0**self.precision)
        t_2 = self.dlg.threshold_2_slider.value() / (10.0**self.precision)
        base = self.dlg.base_slider.value() / (10.0**self.precision)
        lst = [
            QgsColorRampShader.ColorRampItem(t_0 - base, self.CLEAR),
            QgsColorRampShader.ColorRampItem(t_0, self.t_0_COLOR),
            QgsColorRampShader.ColorRampItem(t_1, self.t_1_COLOR),
            QgsColorRampShader.ColorRampItem(t_2, self.t_2_COLOR),
        ]
        self.fcn = QgsColorRampShader()
        self.fcn.setColorRampType(QgsColorRampShader.Interpolated)
        self.fcn.setColorRampItemList(lst)
        self.shader = QgsRasterShader()

        self.shader.setRasterShaderFunction(self.fcn)

        self.renderer = QgsSingleBandPseudoColorRenderer(
            self.layer.dataProvider(), 1, self.shader)

        self.layer.setRenderer(self.renderer)
        self.layer.triggerRepaint()
Beispiel #12
0
def mmi_ramp_roman(raster_layer):
    """Generate an mmi ramp using range of 1-10 on roman.

    A standarised range is used so that two shakemaps of different
    intensities can be properly compared visually with colours stretched
    accross the same range.

    The colours used are the 'standard' colours commonly shown for the
    mercalli scale e.g. on wikipedia and other sources.

    :param raster_layer: A raster layer that will have an mmi style applied.
    :type raster_layer: QgsRasterLayer

    .. versionadded:: 4.0
    """

    items = []
    sorted_mmi_scale = sorted(
        earthquake_mmi_scale['classes'], key=itemgetter('value'))
    for class_max in sorted_mmi_scale:
        colour = class_max['color']
        label = '%s' % class_max['key']
        ramp_item = QgsColorRampShader.ColorRampItem(
            class_max['value'], colour, label)
        items.append(ramp_item)

    raster_shader = QgsRasterShader()
    ramp_shader = QgsColorRampShader()
    ramp_shader.setColorRampType(QgsColorRampShader.INTERPOLATED)
    ramp_shader.setColorRampItemList(items)
    raster_shader.setRasterShaderFunction(ramp_shader)
    band = 1
    renderer = QgsSingleBandPseudoColorRenderer(
        raster_layer.dataProvider(),
        band,
        raster_shader)
    raster_layer.setRenderer(renderer)
Beispiel #13
0
def mmi_ramp_roman(raster_layer):
    """Generate an mmi ramp using range of 1-10 on roman.

    A standarised range is used so that two shakemaps of different
    intensities can be properly compared visually with colours stretched
    accross the same range.

    The colours used are the 'standard' colours commonly shown for the
    mercalli scale e.g. on wikipedia and other sources.

    :param raster_layer: A raster layer that will have an mmi style applied.
    :type raster_layer: QgsRasterLayer

    .. versionadded:: 4.0
    """

    items = []
    sorted_mmi_scale = sorted(
        earthquake_mmi_scale['classes'], key=itemgetter('value'))
    for class_max in sorted_mmi_scale:
        colour = class_max['color']
        label = '%s' % class_max['key']
        ramp_item = QgsColorRampShader.ColorRampItem(
            class_max['value'], colour, label)
        items.append(ramp_item)

    raster_shader = QgsRasterShader()
    ramp_shader = QgsColorRampShader()
    ramp_shader.setColorRampType(QgsColorRampShader.INTERPOLATED)
    ramp_shader.setColorRampItemList(items)
    raster_shader.setRasterShaderFunction(ramp_shader)
    band = 1
    renderer = QgsSingleBandPseudoColorRenderer(
        raster_layer.dataProvider(),
        band,
        raster_shader)
    raster_layer.setRenderer(renderer)
Beispiel #14
0
def style_land_cover_lc_target(outfile):
    layer_lc_target = iface.addRasterLayer(
        outfile,
        QtGui.QApplication.translate('LDMPPlugin', 'Land cover (target)'))
    if not layer_lc_target.isValid():
        log('Failed to add layer')
        return None
    fcn = QgsColorRampShader()
    fcn.setColorRampType(QgsColorRampShader.EXACT)
    lst = [
        QgsColorRampShader.ColorRampItem(
            1, QtGui.QColor('#a50f15'),
            QtGui.QApplication.translate('LDMPPlugin', 'Cropland')),
        QgsColorRampShader.ColorRampItem(
            2, QtGui.QColor('#006d2c'),
            QtGui.QApplication.translate('LDMPPlugin', 'Forest land')),
        QgsColorRampShader.ColorRampItem(
            3, QtGui.QColor('#d8d800'),
            QtGui.QApplication.translate('LDMPPlugin', 'Grassland')),
        QgsColorRampShader.ColorRampItem(
            4, QtGui.QColor('#08519c'),
            QtGui.QApplication.translate('LDMPPlugin', 'Wetlands')),
        QgsColorRampShader.ColorRampItem(
            5, QtGui.QColor('#54278f'),
            QtGui.QApplication.translate('LDMPPlugin', 'Settlements')),
        QgsColorRampShader.ColorRampItem(
            6, QtGui.QColor('#252525'),
            QtGui.QApplication.translate('LDMPPlugin', 'Other land'))
    ]
    fcn.setColorRampItemList(lst)
    shader = QgsRasterShader()
    shader.setRasterShaderFunction(fcn)
    pseudoRenderer = QgsSingleBandPseudoColorRenderer(
        layer_lc_target.dataProvider(), 1, shader)
    layer_lc_target.setRenderer(pseudoRenderer)
    layer_lc_target.triggerRepaint()
    iface.legendInterface().refreshLayerSymbology(layer_lc_target)
Beispiel #15
0
def style_prod_state_init(outfile):
    # Significance layer
    layer = iface.addRasterLayer(
        outfile,
        QtGui.QApplication.translate('LDMPPlugin',
                                     'Productivity state (initial)'))
    if not layer.isValid():
        return None
    fcn = QgsColorRampShader()
    fcn.setColorRampType(QgsColorRampShader.EXACT)
    lst = [
        QgsColorRampShader.ColorRampItem(
            -2, QtGui.QColor(0, 0, 0),
            QtGui.QApplication.translate('LDMPPlugin', 'No data')),
        QgsColorRampShader.ColorRampItem(
            -1, QtGui.QColor(153, 51, 4),
            QtGui.QApplication.translate('LDMPPlugin',
                                         'Potentially degraded')),
        QgsColorRampShader.ColorRampItem(
            0, QtGui.QColor(246, 246, 234),
            QtGui.QApplication.translate('LDMPPlugin', 'Stable')),
        QgsColorRampShader.ColorRampItem(
            2, QtGui.QColor(58, 77, 214),
            QtGui.QApplication.translate('LDMPPlugin', 'Water')),
        QgsColorRampShader.ColorRampItem(
            3, QtGui.QColor(192, 105, 223),
            QtGui.QApplication.translate('LDMPPlugin', 'Urban land cover'))
    ]
    fcn.setColorRampItemList(lst)
    shader = QgsRasterShader()
    shader.setRasterShaderFunction(fcn)
    pseudoRenderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 1,
                                                      shader)
    layer.setRenderer(pseudoRenderer)
    layer.triggerRepaint()
    iface.legendInterface().refreshLayerSymbology(layer)
Beispiel #16
0
def style_prod_perf(outfile):
    layer_perf = iface.addRasterLayer(
        outfile,
        QtGui.QApplication.translate('LDMPPlugin',
                                     'Productivity performance (degradation)'))
    if not layer_perf.isValid():
        log('Failed to add layer')
        return None
    fcn = QgsColorRampShader()
    fcn.setColorRampType(QgsColorRampShader.EXACT)
    #TODO The GPG doesn't seem to allow for possibility of improvement...?
    lst = [
        QgsColorRampShader.ColorRampItem(
            -1, QtGui.QColor(153, 51, 4),
            QtGui.QApplication.translate('LDMPPlugin', 'Degradation')),
        QgsColorRampShader.ColorRampItem(
            0, QtGui.QColor(246, 246, 234),
            QtGui.QApplication.translate('LDMPPlugin', 'Stable')),
        QgsColorRampShader.ColorRampItem(
            1, QtGui.QColor(0, 140, 121),
            QtGui.QApplication.translate('LDMPPlugin', 'Improvement')),
        QgsColorRampShader.ColorRampItem(
            2, QtGui.QColor(58, 77, 214),
            QtGui.QApplication.translate('LDMPPlugin', 'Water')),
        QgsColorRampShader.ColorRampItem(
            3, QtGui.QColor(192, 105, 223),
            QtGui.QApplication.translate('LDMPPlugin', 'Urban land cover'))
    ]
    fcn.setColorRampItemList(lst)
    shader = QgsRasterShader()
    shader.setRasterShaderFunction(fcn)
    pseudoRenderer = QgsSingleBandPseudoColorRenderer(
        layer_perf.dataProvider(), 1, shader)
    layer_perf.setRenderer(pseudoRenderer)
    layer_perf.triggerRepaint()
    iface.legendInterface().refreshLayerSymbology(layer_perf)
    def __init__(self, layer):
        self.colDic = {'tan':'#ffebb0', 'green':'#267300', 'brown':'#734d00', 'white':'#ffffff',
                                'red':'#e60000', 'light gray':'#f0f0f0', 'blue':'#004cab'}
        self.shader = QgsRasterShader()
        self.ramp = QgsColorRampShader()
        self.colLst = []
        self.valLst = []
        self.labLst = []
        self.opacity = 1.0

        self.layer = layer
        self.provider = layer.dataProvider()
        extent = layer.extent()
        self.ver = self.provider.hasStatistics(1, QgsRasterBandStats.All)
        self.stats = self.provider.bandStatistics(1, QgsRasterBandStats.All, extent, 0)
Beispiel #18
0
    def test_setRenderer(self):
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        layer = QgsRasterLayer(myPath, myBaseName)

        self.rendererChanged = False
        layer.rendererChanged.connect(self.onRendererChanged)

        rShader = QgsRasterShader()
        r = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 1, rShader)

        layer.setRenderer(r)
        assert self.rendererChanged
        assert layer.renderer() == r
    def testShaderCrash(self):
        """Check if we assign a shader and then reassign it no crash occurs."""
        myPath = os.path.join(unitTestDataPath('raster'),
                              'band1_float32_noct_epsg4326.tif')
        myFileInfo = QFileInfo(myPath)
        myBaseName = myFileInfo.baseName()
        myRasterLayer = QgsRasterLayer(myPath, myBaseName)
        myMessage = 'Raster not loaded: %s' % myPath
        assert myRasterLayer.isValid(), myMessage

        myRasterShader = QgsRasterShader()
        myColorRampShader = QgsColorRampShader()
        myColorRampShader.setColorRampType(QgsColorRampShader.INTERPOLATED)
        myItems = []
        myItem = QgsColorRampShader.ColorRampItem(10,
                                                  QtGui.QColor('#ffff00'), 'foo')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(100,
                                                  QtGui.QColor('#ff00ff'), 'bar')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(1000,
                                                  QtGui.QColor('#00ff00'), 'kazam')
        myItems.append(myItem)
        myColorRampShader.setColorRampItemList(myItems)
        myRasterShader.setRasterShaderFunction(myColorRampShader)
        myPseudoRenderer = QgsSingleBandPseudoColorRenderer(
            myRasterLayer.dataProvider(), 1,  myRasterShader)
        myRasterLayer.setRenderer(myPseudoRenderer)

        return
        ######## works first time #############

        myRasterShader = QgsRasterShader()
        myColorRampShader = QgsColorRampShader()
        myColorRampShader.setColorRampType(QgsColorRampShader.INTERPOLATED)
        myItems = []
        myItem = QgsColorRampShader.ColorRampItem(10,
                                                  QtGui.QColor('#ffff00'), 'foo')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(100,
                                                  QtGui.QColor('#ff00ff'), 'bar')
        myItems.append(myItem)
        myItem = QgsColorRampShader.ColorRampItem(1000,
                                                  QtGui.QColor('#00ff00'), 'kazam')
        myItems.append(myItem)
        myColorRampShader.setColorRampItemList(myItems)
        myRasterShader.setRasterShaderFunction(myColorRampShader)
        ######## crash on next line (fixed now)##################
        myPseudoRenderer = QgsSingleBandPseudoColorRenderer(
            myRasterLayer.dataProvider(), 1,  myRasterShader)
        myRasterLayer.setRenderer(myPseudoRenderer)
Beispiel #20
0
def style_land_cover_lc_change(outfile):
    layer_lc_change = iface.addRasterLayer(
        outfile, QtGui.QApplication.translate('LDMPPlugin',
                                              'Land cover change'))
    if not layer_lc_change.isValid():
        log('Failed to add layer')
        return None
    fcn = QgsColorRampShader()
    fcn.setColorRampType(QgsColorRampShader.EXACT)
    lst = [
        QgsColorRampShader.ColorRampItem(11, QtGui.QColor(246, 246, 234),
                                         'Croplands-Croplands'),
        QgsColorRampShader.ColorRampItem(12, QtGui.QColor('#de2d26'),
                                         'Croplands-Forest land'),
        QgsColorRampShader.ColorRampItem(13, QtGui.QColor('#fb6a4a'),
                                         'Croplands-Grassland'),
        QgsColorRampShader.ColorRampItem(14, QtGui.QColor('#fc9272'),
                                         'Croplands-Wetlands'),
        QgsColorRampShader.ColorRampItem(15, QtGui.QColor('#fcbba1'),
                                         'Croplands-Settlements'),
        QgsColorRampShader.ColorRampItem(16, QtGui.QColor('#fee5d9'),
                                         'Croplands-Other land'),
        QgsColorRampShader.ColorRampItem(22, QtGui.QColor(246, 246, 234),
                                         'Forest land-Forest land'),
        QgsColorRampShader.ColorRampItem(21, QtGui.QColor('#31a354'),
                                         'Forest land-Croplands'),
        QgsColorRampShader.ColorRampItem(23, QtGui.QColor('#74c476'),
                                         'Forest land-Grassland'),
        QgsColorRampShader.ColorRampItem(24, QtGui.QColor('#a1d99b'),
                                         'Forest land-Wetlands'),
        QgsColorRampShader.ColorRampItem(25, QtGui.QColor('#c7e9c0'),
                                         'Forest land-Settlements'),
        QgsColorRampShader.ColorRampItem(26, QtGui.QColor('#edf8e9'),
                                         'Forest land-Other land'),
        QgsColorRampShader.ColorRampItem(33, QtGui.QColor(246, 246, 234),
                                         'Grassland-Grassland'),
        QgsColorRampShader.ColorRampItem(31, QtGui.QColor('#727200'),
                                         'Grassland-Croplands'),
        QgsColorRampShader.ColorRampItem(32, QtGui.QColor('#8b8b00'),
                                         'Grassland-Forest land'),
        QgsColorRampShader.ColorRampItem(34, QtGui.QColor('#a5a500'),
                                         'Grassland-Wetlands'),
        QgsColorRampShader.ColorRampItem(35, QtGui.QColor('#bebe00'),
                                         'Grassland-Settlements'),
        QgsColorRampShader.ColorRampItem(36, QtGui.QColor('#d8d800'),
                                         'Grassland-Other land'),
        QgsColorRampShader.ColorRampItem(44, QtGui.QColor(246, 246, 234),
                                         'Wetlands-Wetlands'),
        QgsColorRampShader.ColorRampItem(41, QtGui.QColor('#3182bd'),
                                         'Wetlands-Croplands'),
        QgsColorRampShader.ColorRampItem(42, QtGui.QColor('#6baed6'),
                                         'Wetlands-Forest land'),
        QgsColorRampShader.ColorRampItem(43, QtGui.QColor('#9ecae1'),
                                         'Wetlands-Grassland'),
        QgsColorRampShader.ColorRampItem(45, QtGui.QColor('#c6dbef'),
                                         'Wetlands-Settlements'),
        QgsColorRampShader.ColorRampItem(46, QtGui.QColor('#eff3ff'),
                                         'Wetlands-Other land'),
        QgsColorRampShader.ColorRampItem(55, QtGui.QColor(246, 246, 234),
                                         'Settlements-Settlements'),
        QgsColorRampShader.ColorRampItem(51, QtGui.QColor('#756bb1'),
                                         'Settlements-Croplands'),
        QgsColorRampShader.ColorRampItem(52, QtGui.QColor('#9e9ac8'),
                                         'Settlements-Forest land'),
        QgsColorRampShader.ColorRampItem(53, QtGui.QColor('#bcbddc'),
                                         'Settlements-Grassland'),
        QgsColorRampShader.ColorRampItem(54, QtGui.QColor('#dadaeb'),
                                         'Settlements-Wetlands'),
        QgsColorRampShader.ColorRampItem(56, QtGui.QColor('#f2f0f7'),
                                         'Settlements-Other land'),
        QgsColorRampShader.ColorRampItem(66, QtGui.QColor(246, 246, 234),
                                         'Other land-Other land'),
        QgsColorRampShader.ColorRampItem(61, QtGui.QColor('#636363'),
                                         'Other land-Croplands'),
        QgsColorRampShader.ColorRampItem(62, QtGui.QColor('#969696'),
                                         'Other land-Forest land'),
        QgsColorRampShader.ColorRampItem(63, QtGui.QColor('#bdbdbd'),
                                         'Other land-Grassland'),
        QgsColorRampShader.ColorRampItem(64, QtGui.QColor('#d9d9d9'),
                                         'Other land-Wetlands'),
        QgsColorRampShader.ColorRampItem(65, QtGui.QColor('#f7f7f7'),
                                         'Other land-Settlements')
    ]
    fcn.setColorRampItemList(lst)
    shader = QgsRasterShader()
    shader.setRasterShaderFunction(fcn)
    pseudoRenderer = QgsSingleBandPseudoColorRenderer(
        layer_lc_change.dataProvider(), 1, shader)
    layer_lc_change.setRenderer(pseudoRenderer)
    layer_lc_change.triggerRepaint()
    layer_lc_change.triggerRepaint()
    iface.legendInterface().refreshLayerSymbology(layer_lc_change)
    def processAlgorithm(self, parameters, context, feedback):
        feedback = QgsProcessingMultiStepFeedback(1, feedback)
        results = {}
        outputs = {}

        # Pfade definieren + Timestamp
        timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
        temp_path = str(parameters[self.TEMP]) + '/temp_' + str(timestamp)
        final_path = str(parameters[self.TEMP]) + '/final_' + str(timestamp)

        if not os.path.exists(temp_path):
            os.makedirs(temp_path)
        if not os.path.exists(final_path):
            os.makedirs(final_path)

        #feedback.pushInfo(str(parameters[self.INPUT_extent]))

        ## Cell Size und EPSG-Code
        raster_cs = gdal.Open(str(parameters[self.INPUT_ALS_new]))
        gt_cs = raster_cs.GetGeoTransform()
        proj = osr.SpatialReference(wkt=raster_cs.GetProjection())
        cs = gt_cs[1]
        epsg = proj.GetAttrValue('AUTHORITY', 1)
        srs = osr.SpatialReference()
        srs.ImportFromEPSG(int(epsg))

        ## Buffer
        buffer = out = temp_path + '/' + 'extent.shp'
        alg_params = {
            'DISSOLVE': False,
            'DISTANCE': -0.1,
            'END_CAP_STYLE': 2,
            'INPUT': str(parameters[self.INPUT_Shape]),
            'JOIN_STYLE': 1,
            'MITER_LIMIT': 2,
            'SEGMENTS': 1,
            'OUTPUT': buffer
        }
        processing.run('native:buffer',
                       alg_params,
                       context=context,
                       feedback=feedback,
                       is_child_algorithm=True)

        ## Clip Rasters
        out_new = temp_path + '/' + 'dhm_new.tif'
        out_old = temp_path + '/' + 'dhm_old.tif'
        alg_params = {
            'ALPHA_BAND': False,
            'CROP_TO_CUTLINE': True,
            'DATA_TYPE': 0,
            'EXTRA': '',
            'INPUT': str(parameters[self.INPUT_ALS_new]),
            'KEEP_RESOLUTION': False,
            'MASK': str(buffer),
            'MULTITHREADING': False,
            'NODATA': None,
            'OPTIONS': '',
            'SET_RESOLUTION': False,
            'SOURCE_CRS': QgsCoordinateReferenceSystem('EPSG:' + str(epsg)),
            'TARGET_CRS': QgsCoordinateReferenceSystem('EPSG:' + str(epsg)),
            'X_RESOLUTION': None,
            'Y_RESOLUTION': None,
            'OUTPUT': out_new
        }
        processing.run('gdal:cliprasterbymasklayer',
                       alg_params,
                       context=context,
                       feedback=feedback,
                       is_child_algorithm=True)

        alg_params = {
            'ALPHA_BAND': False,
            'CROP_TO_CUTLINE': True,
            'DATA_TYPE': 0,
            'EXTRA': '',
            'INPUT': str(parameters[self.INPUT_ALS_old]),
            'KEEP_RESOLUTION': False,
            'MASK': str(buffer),
            'MULTITHREADING': False,
            'NODATA': None,
            'OPTIONS': '',
            'SET_RESOLUTION': False,
            'SOURCE_CRS': QgsCoordinateReferenceSystem('EPSG:' + str(epsg)),
            'TARGET_CRS': QgsCoordinateReferenceSystem('EPSG:' + str(epsg)),
            'X_RESOLUTION': None,
            'Y_RESOLUTION': None,
            'OUTPUT': out_old
        }
        processing.run('gdal:cliprasterbymasklayer',
                       alg_params,
                       context=context,
                       feedback=feedback,
                       is_child_algorithm=True)

        ## Cell Size/ Extent
        raster_cs = gdal.Open(out_new)
        gt_cs = raster_cs.GetGeoTransform()
        cs = gt_cs[1]

        del raster_cs
        del gt_cs

        dtm_clip_gdal = gdal.Open(out_new)
        format = "GTiff"
        driver = gdal.GetDriverByName(format)
        band1 = dtm_clip_gdal.GetRasterBand(1)
        im = Image.open(out_new)
        pix = im.load()
        gt = dtm_clip_gdal.GetGeoTransform()
        feedback.pushInfo(str(gt))
        width = dtm_clip_gdal.RasterXSize
        height = dtm_clip_gdal.RasterYSize
        minx = gt[0]
        miny = gt[3] + width * gt[4] + height * gt[5]
        maxx = gt[0] + width * gt[1] + height * gt[2]
        maxy = gt[3]
        extent = str(minx) + "," + str(maxx) + "," + str(miny) + "," + str(
            maxy)
        extent2 = (minx, maxx, miny, maxy)
        feedback.pushInfo(str(extent))
        feedback.pushInfo(str(width))
        feedback.pushInfo(str(height))

        # Create empty grids
        grid_diff = np.zeros(shape=(width, height), dtype=np.float32)
        grid_diff_uc = np.zeros(shape=(width, height), dtype=np.float32)

        ## DOD
        out2_old = temp_path + '/' + 'diff.tif'

        ##Rasters to Arrays
        new_rds = gdal.Open(out_new)
        format = "GTiff"
        driver1 = gdal.GetDriverByName(format)
        band_new = new_rds.GetRasterBand(1)
        im_new = Image.open(out_new)
        pix_new = im_new.load()

        old_rds = gdal.Open(out_old)
        format = "GTiff"
        driver2 = gdal.GetDriverByName(format)
        band_old = old_rds.GetRasterBand(1)
        im_old = Image.open(out_old)
        pix_old = im_old.load()

        for row in range(0, width):
            for col in range(0, height):
                val_new = pix_new[row, col]
                val_old = pix_old[row, col]
                if val_new > -9999.0:
                    val_diff = val_new - val_old
                    #feedback.pushInfo(str(val_new))
                    grid_diff[row, col] = val_diff

        grid_diff = np.flip(grid_diff, 1)
        grid_diff = np.rot90(grid_diff)
        imsave = Image.fromarray(grid_diff, mode='F')
        imsave.save(out2_old, "TIFF")

        ## Add Spatial Reference
        out2 = final_path + '/' + 'diff.tif'

        src_ds = gdal.Open(out2_old)
        format = "GTiff"
        driver = gdal.GetDriverByName(format)

        dst_ds = driver.CreateCopy(out2, src_ds, 0)
        dst_ds.SetGeoTransform(gt)
        srs = osr.SpatialReference()
        srs.ImportFromEPSG(int(epsg))
        dest_wkt = srs.ExportToWkt()
        dst_ds.SetProjection(dest_wkt)

        # Close files
        dst_ds = None
        src_ds = None

        ## ----------------------------------------------------------------------------------------------------------##
        ## ChangeDetection (Uncertainty Model)
        sel = self.SELECTIONS[self.parameterAsEnum(parameters, self.SELECTION,
                                                   context)]
        if str(sel) == str('UncertaintyModel'):
            feedback.pushInfo(str(sel))
            out_uc = temp_path + '/' + 'dhm_uc.tif'
            alg_params = {
                'ALPHA_BAND': False,
                'CROP_TO_CUTLINE': True,
                'DATA_TYPE': 0,
                'EXTRA': '',
                'INPUT': str(parameters[self.INPUT_UC]),
                'KEEP_RESOLUTION': False,
                'MASK': str(buffer),
                'MULTITHREADING': False,
                'NODATA': None,
                'OPTIONS': '',
                'SET_RESOLUTION': False,
                'SOURCE_CRS':
                QgsCoordinateReferenceSystem('EPSG:' + str(epsg)),
                'TARGET_CRS':
                QgsCoordinateReferenceSystem('EPSG:' + str(epsg)),
                'X_RESOLUTION': None,
                'Y_RESOLUTION': None,
                'OUTPUT': out_uc
            }
            processing.run('gdal:cliprasterbymasklayer',
                           alg_params,
                           context=context,
                           feedback=feedback,
                           is_child_algorithm=True)

            del (out_uc)

            analyse = open(final_path + '/' + 'change_detection_UC.txt', "w")
            analyse_csv = open(final_path + '/' + 'change_detection_UC.csv',
                               "w")
            analyse_csv.write(
                " ; AOI [m2]; Detectable Change [m2]; Detectable Change [%]; Surface Lowering [m2]; Surface Raising [m2]; Surface Lowering [m3]; Surface Raising [m3]; Volume of Difference [m3]; Net Volume of Difference [m3]"
                + "\n")

            ##Rasters to Arrays
            out_uc = temp_path + '/' + 'dhm_uc.tif'

            diff_rds = gdal.Open(out2)
            format = "GTiff"
            driver3 = gdal.GetDriverByName(format)
            band_diff = diff_rds.GetRasterBand(1)
            im_diff = Image.open(out2)
            pix_diff = im_diff.load()

            uc_rds = gdal.Open(out_uc)
            format = "GTiff"
            driver4 = gdal.GetDriverByName(format)
            band_uc = uc_rds.GetRasterBand(1)
            im_uc = Image.open(out_uc)
            pix_uc = im_uc.load()

            ## Classification1 - 0 % 0.1
            countAOI = 0
            countPosGes = 0
            countNegGes = 0
            countPos = 0
            countNeg = 0
            countPosArea = 0
            countNegArea = 0
            countPosAreaGes = 0
            countNegAreaGes = 0
            countAcc = 0
            countCell = 0
            countCellVol = 0

            for row in range(0, width):
                for col in range(0, height):
                    diff = pix_diff[row, col]
                    if diff > -9999.0 and diff < 100:
                        countAOI = countAOI + (cs * cs)
                    if diff < 0 and diff > -100:
                        volNegGes = cs * cs * (abs(diff))
                        countNegGes = countNegGes + volNegGes
                        countNegAreaGes = countNegAreaGes + (cs * cs)
                    if diff > 0 and diff < 100:
                        volPosGes = cs * cs * (abs(diff))
                        countPosGes = countPosGes + volPosGes
                        countPosAreaGes = countPosAreaGes + (cs * cs)
                    if diff < -0.1 and diff > -100:  # 0.1 m ist der Standardfehler zwischen den 2 Modellen
                        volNeg = cs * cs * (
                            abs(diff) - 0.1
                        )  # -0.1 Standardfehler wird bei GCD-Tool nicht abgezogen
                        countNeg = countNeg + volNeg
                        countNegArea = countNegArea + (cs * cs)
                        countAcc = countAcc + (cs * cs * 0.1)
                    if diff > 0.1 and diff < 100:
                        volPos = cs * cs * (diff - 0.1)
                        countPos = countPos + (volPos)
                        countPosArea = countPosArea + (cs * cs)
                        countAcc = countAcc + (cs * cs * 0.1)
                    if diff < 0 and diff > -0.1:
                        countCell = countCell + 1
                        countCellVol = countCellVol + (cs * cs * abs(diff))
                        #print countCell
                    if diff > 0 and diff < 0.1:
                        countCell = countCell + 1
                        countCellVol = countCellVol + (cs * cs * abs(diff))

            analyse.write("Total Area [m2] of Interest: " + str(countAOI) +
                          "\n")
            analyse.write("Total Area [km2] of Interest: " +
                          str(countAOI / 1000000) + "\n")
            analyse.write("\n")
            analyse.write("Total Area [m2] of Detectable Change: " +
                          str(countPosAreaGes + countNegAreaGes) + "\n")
            analyse.write(
                "Total Area of Interest [%] with Detectable Change: " +
                str(((countPosAreaGes + countNegAreaGes) / countAOI) * 100) +
                "\n")
            analyse.write("Total Area [m2] of Surface Lowering: " +
                          str(countNegAreaGes) + "\n")
            analyse.write("Total Area [m2] of Surface Raising: " +
                          str(countPosAreaGes) + "\n")
            analyse.write("Total Volume [m3] of Surface Lowering: " +
                          str(countNegGes) + "\n")
            analyse.write("Total Volume [m3] of Surface Raising: " +
                          str(countPosGes) + "\n")
            analyse.write("Total Volume [m3] of Difference: " +
                          str(countPosGes + countNegGes) + "\n")
            analyse.write("Total Net Volume [m3] of Difference: " +
                          str(countPosGes - countNegGes) + "\n")
            analyse.write("\n")
            analyse.write("\n")

            analyse_csv.write(
                "0.0; " + str(countAOI) + "; " +
                str(countPosAreaGes + countNegAreaGes) + "; " +
                str(((countPosAreaGes + countNegAreaGes) / countAOI) * 100) +
                "; " + str(countNegAreaGes) + "; " + str(countPosAreaGes) +
                "; " + str(countNegGes) + "; " + str(countPosGes) + "; " +
                str(countPosGes + countNegGes) + "; " +
                str(countPosGes - countNegGes) + "\n")
            net_v_0 = countPosGes - countNegGes
            sr_0 = countPosGes
            sl_0 = countNegGes

            analyse.write("Analysis with Threshold of +/- 0.1" + "\n")
            analyse.write(
                "Thresholded (0.1) Area [m2] of Detectable Change: " +
                str(countPosArea + countNegArea) + "\n")
            analyse.write(
                "Thresholded (0.1) Area [km2] of Detectable Change: " +
                str((countPosArea + countNegArea) / 1000000) + "\n")
            analyse.write(
                "Thresholded (0.1) Area of Interest [%] with Detectable Change: "
                + str(((countPosArea + countNegArea) / countAOI) * 100) + "\n")
            analyse.write("Thresholded (0.1) Area [m2] of Surface Lowering: " +
                          str(countNegArea) + "\n")
            analyse.write(
                "Thresholded (0.1) Area [km2] of Surface Lowering: " +
                str(countNegArea / 1000000) + "\n")
            analyse.write("Thresholded (0.1) Area [m2] of Surface Raising: " +
                          str(countPosArea) + "\n")
            analyse.write("Thresholded (0.1) Area [km2] of Surface Raising: " +
                          str(countPosArea / 1000000) + "\n")
            analyse.write(
                "Thresholded (0.1) Volume [m3] of Surface Lowering: " +
                str(countNeg) + "\n")
            analyse.write(
                "Thresholded (0.1) Volume [m3] of Surface Raising: " +
                str(countPos) + "\n")
            analyse.write("Thresholded (0.1) Volume [m3] of Difference: " +
                          str(countPos + countNeg) + "\n")
            analyse.write("Thresholded (0.1) Net Volume [m3] of Difference: " +
                          str(countPos - countNeg) + "\n")
            analyse.write("\n")
            analyse.write("\n")
            analyse.write(
                "Volume [m3] of Error within Threshold of -0.1 and 0.1: " +
                str(countAcc) + "\n")
            analyse.write("Count of Cells within -0.1 and 0.1: " +
                          str(countCell) + "\n")
            analyse.write("Volume [m3] of Cells between -0.1 and 0.1: " +
                          str(countCellVol) + "\n")
            analyse.write(
                "Percent [%] of Error of Cells between -0.1 and 0.1: " +
                str((countCellVol / (countPosGes + countNegGes)) * 100) + "\n")
            analyse.write("\n")
            analyse.write("\n")

            analyse_csv.write("0.1; " + str(countAOI) + "; " +
                              str(countPosArea + countNegArea) + "; " +
                              str(((countPosArea + countNegArea) / countAOI) *
                                  100) + "; " + str(countNegArea) + "; " +
                              str(countPosArea) + "; " + str(countNeg) + "; " +
                              str(countPos) + "; " + str(countPos + countNeg) +
                              "; " + str(countPos - countNeg) + "\n")
            net_v_1 = countPos - countNeg
            sr_1 = countPos
            sl_1 = countNeg

            del countPos
            del countNeg
            del countPosArea
            del countNegArea
            del countAcc
            del countCell
            del countCellVol

            ## Classification2 - 0.3
            countPos = 0
            countNeg = 0
            countPosArea = 0
            countNegArea = 0
            countAcc = 0
            countCell = 0
            countCellVol = 0

            for row in range(0, width):
                for col in range(0, height):
                    diff = pix_diff[row, col]
                    ES = pix_uc[row, col]
                    ES2 = abs(ES)
                    if diff < -0.3 and diff > -100:  # 0.1 ist der Standardfehler zwischen den 2 Modellen
                        volNeg = cs * cs * (abs(diff) - 0.3)
                        countNeg = countNeg + volNeg
                        countNegArea = countNegArea + (cs * cs)
                        countAcc = countAcc + (cs * cs * 0.3)
                    if diff > 0.3 and diff < 100:
                        volPos = cs * cs * (diff - 0.3)
                        countPos = countPos + (volPos)
                        countPosArea = countPosArea + (cs * cs)
                        countAcc = countAcc + (cs * cs * 0.3)
                    if diff < 0 and diff > -0.3:
                        countCell = countCell + 1
                        countCellVol = countCellVol + (cs * cs * abs(diff))
                    if diff > 0 and diff < 0.3:
                        countCell = countCell + 1
                        countCellVol = countCellVol + (cs * cs * diff)

            analyse.write("Analysis with Threshold of +/- 0.3" + "\n")
            analyse.write(
                "Thresholded (0.3) Area [m2] of Detectable Change: " +
                str(countPosArea + countNegArea) + "\n")
            analyse.write(
                "Thresholded (0.3) Area [km2] of Detectable Change: " +
                str((countPosArea + countNegArea) / 1000000) + "\n")
            analyse.write(
                "Thresholded (0.3) of Interest [%] with Detectable Change: " +
                str(((countPosArea + countNegArea) / countAOI) * 100) + "\n")
            analyse.write("Thresholded (0.3) Area [m2] of Surface Lowering: " +
                          str(countNegArea) + "\n")
            analyse.write(
                "Thresholded (0.3) Area [km2] of Surface Lowering: " +
                str(countNegArea / 1000000) + "\n")
            analyse.write("Thresholded (0.3) Area [m2] of Surface Raising: " +
                          str(countPosArea) + "\n")
            analyse.write("Thresholded (0.3) Area [km2] of Surface Raising: " +
                          str(countPosArea / 1000000) + "\n")
            analyse.write(
                "Thresholded (0.3) Volume [m3] of Surface Lowering: " +
                str(countNeg) + "\n")
            analyse.write(
                "Thresholded (0.3) Volume [m3] of Surface Raising: " +
                str(countPos) + "\n")
            analyse.write("Thresholded (0.3) Volume [m3] of Difference: " +
                          str(countPos + countNeg) + "\n")
            analyse.write("Thresholded (0.3) Net Volume [m3] of Difference: " +
                          str(countPos - countNeg) + "\n")
            analyse.write("\n")
            analyse.write(
                "Volume [m3] of Error within Threshold of -0.3 and 0.3: " +
                str(countAcc) + "\n")
            analyse.write("Count of Cells within -0.3 and 0.3: " +
                          str(countCell) + "\n")
            analyse.write("Volume [m3] of Cells between -0.3 and 0.3: " +
                          str(countCellVol) + "\n")
            analyse.write(
                "Percent [%] of Error of Cells between -0.3 and 0.3: " +
                str((countCellVol / (countPosGes + countNegGes)) * 100) + "\n")
            analyse.write("\n")
            analyse.write("\n")

            analyse_csv.write("0.3; " + str(countAOI) + "; " +
                              str(countPosArea + countNegArea) + "; " +
                              str(((countPosArea + countNegArea) / countAOI) *
                                  100) + "; " + str(countNegArea) + "; " +
                              str(countPosArea) + "; " + str(countNeg) + "; " +
                              str(countPos) + "; " + str(countPos + countNeg) +
                              "; " + str(countPos - countNeg) + "\n")
            net_v_2 = countPos - countNeg
            sr_2 = countPos
            sl_2 = countNeg

            del countPos
            del countNeg
            del countPosArea
            del countNegArea
            del countAcc
            del countCell
            del countCellVol

            ## Classification3 - UC
            countAOI = 0
            countPosGes = 0
            countNegGes = 0
            countPos = 0
            countNeg = 0
            countPosArea = 0
            countNegArea = 0
            countES = 0
            countESneg = 0
            countESpos = 0
            countAcc = 0
            countCell = 0
            countCellVol = 0
            for row in range(0, width):
                for col in range(0, height):
                    diff = pix_diff[row, col]
                    ES = pix_uc[row, col]
                    ES2 = abs(ES)
                    if diff > -9999.0 and diff < 100:
                        countAOI = countAOI + (cs * cs)
                    if diff < -ES2 and diff > -100.0:
                        grid_diff_uc[row, col] = diff + ES2
                        volESneg = cs * cs * (abs(diff) - ES2)
                        countESneg = countESneg + volESneg
                        countNegArea = countNegArea + (cs * cs)
                        countAcc = countAcc + (cs * cs * ES2)
                    if diff > ES2 and diff < 100:
                        grid_diff_uc[row, col] = diff - ES2
                        volESpos = cs * cs * (diff - ES2)
                        countESpos = countESpos + volESpos
                        countPosArea = countPosArea + (cs * cs)
                        countAcc = countAcc + (cs * cs * 0.1)
                    if diff < 0 and diff > -ES2:
                        grid_diff_uc[row, col] = 0.0
                        countCell = countCell + 1
                        countCellVol = countCellVol + (cs * cs * abs(diff))
                        #print countCell
                    if diff > 0 and diff < ES2:
                        grid_diff_uc[row, col] = 0.0
                        countCell = countCell + 1
                        countCellVol = countCellVol + (cs * cs * abs(diff))

            analyse.write("Analysis including Uncertainty Analysis" + "\n")
            analyse.write("Thresholded Area [m2] of Detectable Change: " +
                          str(countPosArea + countNegArea) + "\n")
            analyse.write(
                "Thresholded Area of Interest [%] with Detectable Change: " +
                str(((countPosArea + countNegArea) / countAOI) * 100) + "\n")
            analyse.write("Thresholded Volume [m3] of Surface Lowering: " +
                          str(countESneg) + "\n")
            analyse.write("Thresholded Volume [m3] of Surface Raising: " +
                          str(countESpos) + "\n")
            analyse.write("Total Volume [m3] of Difference: " +
                          str(countESpos + countESneg) + "\n")
            analyse.write("Total Net Volume [m3] of Difference: " +
                          str(countESpos - countESneg) + "\n")
            analyse.write("\n")
            analyse.write("\n")
            analyse.write("Volume [m3] of Error within Threshold of UC: " +
                          str(countAcc) + "\n")
            analyse.write("Count of Cells within UC: " + str(countCell) + "\n")
            analyse.write("Volume [m3] of Cells between UC: " +
                          str(countCellVol) + "\n")
            analyse.write("Percent [%] of Error of Cells between UC: " +
                          str((countCellVol /
                               (countESpos + countESneg)) * 100) + "\n")
            analyse.write("\n")
            analyse.write("\n")

            analyse_csv.write("UC; " + str(countAOI) + "; " +
                              str(countPosArea + countNegArea) + "; " +
                              str(((countPosArea + countNegArea) / countAOI) *
                                  100) + "; ; ; " + str(countESneg) + "; " +
                              str(countESpos) + "; " +
                              str(countESpos + countESneg) + "; " +
                              str(countESpos - countESneg) + "\n")
            net_v_3 = countESpos - countESneg
            sr_3 = countESpos
            sl_3 = countESneg

            ## BarChart
            plotdata = pd.DataFrame(
                {
                    'surface raising': [sr_0, sr_1, sr_2, sr_3],
                    'surface lowering': [-sl_0, -sl_1, -sl_2, -sl_3]
                },
                index=['raw', '0.1 m', '0.3 m', 'UC model'])
            New_Colors = ['silver', 'dimgrey']
            rcParams['font.family'] = 'sans-serif'
            rcParams['font.sans-serif'] = ['Verdana']
            plotdata.plot(kind="bar",
                          stacked=True,
                          width=0.5,
                          color=New_Colors,
                          align='center',
                          widtH=0.5)
            #plt.xticks(np.arange(0, 4, step=1))
            plt.xticks(rotation=5, horizontalalignment="center")
            #plt.yticks(rotation=0, horizontalalignment="center")
            plt.title('volume changes [m3]', fontsize=10)
            plt.xlabel('threshold', fontsize=10)
            #plt.ylabel('volume changes [m3]', fontsize=10)
            #plt.ylabel('net volume [m3]', fontsize=10)
            plt.grid(True)

            plt.savefig(final_path + '/' + 'change_detection_plot.png')

            ## Grid UC
            out3 = temp_path + '/' + 'diff_uc_old.tif'
            out4 = final_path + '/' + 'diff_uc.tif'
            grid_diff_uc = np.flip(grid_diff_uc, 1)
            grid_diff_uc = np.rot90(grid_diff_uc)
            imsave = Image.fromarray(grid_diff_uc, mode='F')
            imsave.save(out3, "TIFF")

            ## Raster georeferenzieren
            src_ds = gdal.Open(out3)
            format = "GTiff"
            driver = gdal.GetDriverByName(format)

            dst_ds = driver.CreateCopy(out4, src_ds, 0)
            dst_ds.SetGeoTransform(gt)
            srs = osr.SpatialReference()
            srs.ImportFromEPSG(int(epsg))
            dest_wkt = srs.ExportToWkt()
            dst_ds.SetProjection(dest_wkt)

            # Close files
            dst_ds = None
            src_ds = None

        ## ----------------------------------------------------------------------------------------------------------##
        ## ChangeDetection (Threshold)
        sel = self.SELECTIONS[self.parameterAsEnum(parameters, self.SELECTION,
                                                   context)]
        if str(sel) == str('Threshold'):
            feedback.pushInfo(str(sel))

            val = (parameters[self.INPUT_threshold])

            analyse = open(
                final_path + '/' + 'change_detection_' + str(val) + '.txt',
                "w")
            analyse_csv = open(
                final_path + '/' + 'change_detection_' + str(val) + '.csv',
                "w")
            analyse_csv.write(
                " ; AOI [m2]; Detectable Change [m2]; Detectable Change [%]; Surface Lowering [m2]; Surface Raising [m2]; Surface Lowering [m3]; Surface Raising [m3]; Volume of Difference [m3]; Net Volume of Difference [m3]"
                + "\n")

            ##Rasters to Arrays
            #out_uc = temp_path + '/' + 'dhm_uc.tif'

            diff_rds = gdal.Open(out2)
            format = "GTiff"
            driver3 = gdal.GetDriverByName(format)
            band_diff = diff_rds.GetRasterBand(1)
            im_diff = Image.open(out2)
            pix_diff = im_diff.load()

            ## Classification1 - Threshold
            countAOI = 0
            countPosGes = 0
            countNegGes = 0
            countPos = 0
            countNeg = 0
            countPosArea = 0
            countNegArea = 0
            countPosAreaGes = 0
            countNegAreaGes = 0
            countAcc = 0
            countCell = 0
            countCellVol = 0

            for row in range(0, width):
                for col in range(0, height):
                    diff = pix_diff[row, col]
                    if diff > -9999.0 and diff < 100:
                        countAOI = countAOI + (cs * cs)
                    if diff < 0 and diff > -100:
                        volNegGes = cs * cs * (abs(diff))
                        countNegGes = countNegGes + volNegGes
                        countNegAreaGes = countNegAreaGes + (cs * cs)
                    if diff > 0 and diff < 100:
                        volPosGes = cs * cs * (abs(diff))
                        countPosGes = countPosGes + volPosGes
                        countPosAreaGes = countPosAreaGes + (cs * cs)
                    if diff < -val and diff > -100:
                        grid_diff_uc[row, col] = diff + val
                        volNeg = cs * cs * (abs(diff) - val)
                        countNeg = countNeg + volNeg
                        countNegArea = countNegArea + (cs * cs)
                        countAcc = countAcc + (cs * cs * val)
                    if diff > val and diff < 100:
                        grid_diff_uc[row, col] = diff - val
                        volPos = cs * cs * (diff - val)
                        countPos = countPos + (volPos)
                        countPosArea = countPosArea + (cs * cs)
                        countAcc = countAcc + (cs * cs * val)
                    if diff < 0 and diff > -val:
                        grid_diff_uc[row, col] = 0.0
                        countCell = countCell + 1
                        countCellVol = countCellVol + (cs * cs * abs(diff))
                        #print countCell
                    if diff > 0 and diff < val:
                        grid_diff_uc[row, col] = 0.0
                        countCell = countCell + 1
                        countCellVol = countCellVol + (cs * cs * abs(diff))

            analyse.write("Total Area [m2] of Interest: " + str(countAOI) +
                          "\n")
            analyse.write("Total Area [km2] of Interest: " +
                          str(countAOI / 1000000) + "\n")
            analyse.write("\n")
            analyse.write("Total Area [m2] of Detectable Change: " +
                          str(countPosAreaGes + countNegAreaGes) + "\n")
            analyse.write(
                "Total Area of Interest [%] with Detectable Change: " +
                str(((countPosAreaGes + countNegAreaGes) / countAOI) * 100) +
                "\n")
            analyse.write("Total Area [m2] of Surface Lowering: " +
                          str(countNegAreaGes) + "\n")
            analyse.write("Total Area [m2] of Surface Raising: " +
                          str(countPosAreaGes) + "\n")
            analyse.write("Total Volume [m3] of Surface Lowering: " +
                          str(countNegGes) + "\n")
            analyse.write("Total Volume [m3] of Surface Raising: " +
                          str(countPosGes) + "\n")
            analyse.write("Total Volume [m3] of Difference: " +
                          str(countPosGes + countNegGes) + "\n")
            analyse.write("Total Net Volume [m3] of Difference: " +
                          str(countPosGes - countNegGes) + "\n")
            analyse.write("\n")
            analyse.write("\n")

            analyse_csv.write(
                "0.0; " + str(countAOI) + "; " +
                str(countPosAreaGes + countNegAreaGes) + "; " +
                str(((countPosAreaGes + countNegAreaGes) / countAOI) * 100) +
                "; " + str(countNegAreaGes) + "; " + str(countPosAreaGes) +
                "; " + str(countNegGes) + "; " + str(countPosGes) + "; " +
                str(countPosGes + countNegGes) + "; " +
                str(countPosGes - countNegGes) + "\n")
            net_v_0 = countPosGes - countNegGes
            sr_0 = countPosGes
            sl_0 = countNegGes

            analyse.write("Analysis with Threshold of +/- 0.1" + "\n")
            analyse.write(
                "Thresholded (0.1) Area [m2] of Detectable Change: " +
                str(countPosArea + countNegArea) + "\n")
            analyse.write(
                "Thresholded (0.1) Area [km2] of Detectable Change: " +
                str((countPosArea + countNegArea) / 1000000) + "\n")
            analyse.write(
                "Thresholded (0.1) Area of Interest [%] with Detectable Change: "
                + str(((countPosArea + countNegArea) / countAOI) * 100) + "\n")
            analyse.write("Thresholded (0.1) Area [m2] of Surface Lowering: " +
                          str(countNegArea) + "\n")
            analyse.write(
                "Thresholded (0.1) Area [km2] of Surface Lowering: " +
                str(countNegArea / 1000000) + "\n")
            analyse.write("Thresholded (0.1) Area [m2] of Surface Raising: " +
                          str(countPosArea) + "\n")
            analyse.write("Thresholded (0.1) Area [km2] of Surface Raising: " +
                          str(countPosArea / 1000000) + "\n")
            analyse.write(
                "Thresholded (0.1) Volume [m3] of Surface Lowering: " +
                str(countNeg) + "\n")
            analyse.write(
                "Thresholded (0.1) Volume [m3] of Surface Raising: " +
                str(countPos) + "\n")
            analyse.write("Thresholded (0.1) Volume [m3] of Difference: " +
                          str(countPos + countNeg) + "\n")
            analyse.write("Thresholded (0.1) Net Volume [m3] of Difference: " +
                          str(countPos - countNeg) + "\n")
            analyse.write("\n")
            analyse.write("\n")
            analyse.write(
                "Volume [m3] of Error within Threshold of -0.1 and 0.1: " +
                str(countAcc) + "\n")
            analyse.write("Count of Cells within -0.1 and 0.1: " +
                          str(countCell) + "\n")
            analyse.write("Volume [m3] of Cells between -0.1 and 0.1: " +
                          str(countCellVol) + "\n")
            analyse.write(
                "Percent [%] of Error of Cells between -0.1 and 0.1: " +
                str((countCellVol / (countPosGes + countNegGes)) * 100) + "\n")
            analyse.write("\n")
            analyse.write("\n")

            analyse_csv.write("0.1; " + str(countAOI) + "; " +
                              str(countPosArea + countNegArea) + "; " +
                              str(((countPosArea + countNegArea) / countAOI) *
                                  100) + "; " + str(countNegArea) + "; " +
                              str(countPosArea) + "; " + str(countNeg) + "; " +
                              str(countPos) + "; " + str(countPos + countNeg) +
                              "; " + str(countPos - countNeg) + "\n")
            net_v_1 = countPos - countNeg
            sr_1 = countPos
            sl_1 = countNeg

            del countPos
            del countNeg
            del countPosArea
            del countNegArea
            del countAcc
            del countCell
            del countCellVol

            ## BarChart
            plotdata = pd.DataFrame(
                {
                    'surface raising': [sr_0, sr_1],
                    'surface lowering': [-sl_0, -sl_1]
                },
                index=['raw', str(val) + ' m'])
            New_Colors = ['silver', 'dimgrey']
            rcParams['font.family'] = 'sans-serif'
            rcParams['font.sans-serif'] = ['Verdana']
            plotdata.plot(kind="bar",
                          stacked=True,
                          width=0.5,
                          color=New_Colors,
                          align='center',
                          widtH=0.5)
            #plt.xticks(np.arange(0, 4, step=1))
            plt.xticks(rotation=5, horizontalalignment="center")
            #plt.yticks(rotation=0, horizontalalignment="center")
            plt.title('volume changes [m3]', fontsize=10)
            plt.xlabel('threshold', fontsize=10)
            #plt.ylabel('volume changes [m3]', fontsize=10)
            #plt.ylabel('net volume [m3]', fontsize=10)
            plt.grid(True)

            plt.savefig(final_path + '/' + 'change_detection_plot.png')

            ## Grid UC
            out3 = temp_path + '/' + 'diff_thresholded_old.tif'
            out4 = final_path + '/' + 'diff_thresholded.tif'
            grid_diff_uc = np.flip(grid_diff_uc, 1)
            grid_diff_uc = np.rot90(grid_diff_uc)
            imsave = Image.fromarray(grid_diff_uc, mode='F')
            imsave.save(out3, "TIFF")

            ## Raster georeferenzieren
            src_ds = gdal.Open(out3)
            format = "GTiff"
            driver = gdal.GetDriverByName(format)

            dst_ds = driver.CreateCopy(out4, src_ds, 0)
            dst_ds.SetGeoTransform(gt)
            #srs = osr.SpatialReference()
            #srs.ImportFromEPSG(epsg)
            #dest_wkt = srs.ExportToWkt()
            dst_ds.SetProjection(dest_wkt)

            # Close files
            dst_ds = None
            src_ds = None

            feedback.pushInfo(str("OK"))

        ## ----------------------------------------------------------------------------------------------------------##
        ## Add Layer
        root = QgsProject.instance().layerTreeRoot()
        mygroup = root.insertGroup(1, "QCD_Tool")
        rlayer = QgsRasterLayer(out4, 'ChangeDetection')
        rprovider = rlayer.dataProvider()
        colDic = {
            'f': '#d7191c',
            'f1': '#eb6640',
            'f2': '#feb165',
            'f3': '#ffdc96',
            'f4': '#ffffff',
            'f5': '#ffffff',
            'f6': '#9cd3a7',
            'f7': '#5ea7b1',
            'f8': '#2b83ba',
            'f9': '#1e5c83'
        }
        valueList = [-3, -2, -1, -0.5, -0.05, 0.05, 0.5, 1, 2, 3]
        lst = [
            QgsColorRampShader.ColorRampItem(valueList[0],
                                             QColor(colDic['f'])),
            QgsColorRampShader.ColorRampItem(valueList[1],
                                             QColor(colDic['f1'])),
            QgsColorRampShader.ColorRampItem(valueList[2],
                                             QColor(colDic['f2'])),
            QgsColorRampShader.ColorRampItem(valueList[3],
                                             QColor(colDic['f3'])),
            QgsColorRampShader.ColorRampItem(valueList[4],
                                             QColor(colDic['f4'])),
            QgsColorRampShader.ColorRampItem(valueList[5],
                                             QColor(colDic['f5'])),
            QgsColorRampShader.ColorRampItem(valueList[6],
                                             QColor(colDic['f6'])),
            QgsColorRampShader.ColorRampItem(valueList[7],
                                             QColor(colDic['f7'])),
            QgsColorRampShader.ColorRampItem(valueList[8],
                                             QColor(colDic['f8'])),
            QgsColorRampShader.ColorRampItem(valueList[9],
                                             QColor(colDic['f9']))
        ]
        my_shader = QgsRasterShader()
        my_colorramp = QgsColorRampShader()
        #fcn = QgsColorRampShader()
        #fcn.setColorRampType(QgsColorRampShader.Interpolated)
        #lst = [ QgsColorRampShader.ColorRampItem(0, QColor(0,255,0)),QgsColorRampShader.ColorRampItem(255, QColor(255,255,0)) ]
        my_colorramp.setColorRampItemList(lst)
        my_colorramp.setColorRampType(QgsColorRampShader.Interpolated)
        my_shader.setRasterShaderFunction(my_colorramp)
        renderer = QgsSingleBandPseudoColorRenderer(rlayer.dataProvider(), 1,
                                                    my_shader)
        rasterTransparency = QgsRasterTransparency()
        myTransparentSingleValuePixelList = []
        myTransparentPixel1 = QgsRasterTransparency.TransparentSingleValuePixel(
        )
        myTransparentPixel1.min = -0.05
        myTransparentPixel1.max = 0.05
        myTransparentPixel1.percentTransparent = 100
        myTransparentSingleValuePixelList.append(myTransparentPixel1)
        rasterTransparency.setTransparentSingleValuePixelList(
            myTransparentSingleValuePixelList)
        renderer.setRasterTransparency(rasterTransparency)
        rlayer.setRenderer(renderer)
        rlayer.triggerRepaint()
        QgsProject.instance().addMapLayer(rlayer)
        mygroup.addLayer(rlayer)

        outputs['LastStep'] = out4
        results['Tool abgeschlossen'] = outputs['LastStep']
        return results
Beispiel #22
0
def _setNewRasterStyle(theQgsRasterLayer, theClasses):
    """Set QGIS raster style based on InaSAFE style dictionary for QGIS >= 2.0.

    This function will set both the colour map and the transparency
    for the passed in layer.

    Args:
        * theQgsRasterLayer: QgsRasterLayer
        * theClasses: List of the form as in the example below.

    Returns:
        * list: RangeList
        * list: TransparencyList

    Example:
        style_classes = [dict(colour='#38A800', quantity=2, transparency=0),
                         dict(colour='#38A800', quantity=5, transparency=50),
                         dict(colour='#79C900', quantity=10, transparency=50),
                         dict(colour='#CEED00', quantity=20, transparency=50),
                         dict(colour='#FFCC00', quantity=50, transparency=34),
                         dict(colour='#FF6600', quantity=100, transparency=77),
                         dict(colour='#FF0000', quantity=200, transparency=24),
                         dict(colour='#7A0000', quantity=300, transparency=22)]

    """
    # Note imports here to prevent importing on unsupported QGIS versions
    # pylint: disable=E0611
    # pylint: disable=W0621
    # pylint: disable=W0404
    from qgis.core import (QgsRasterShader, QgsColorRampShader,
                           QgsSingleBandPseudoColorRenderer,
                           QgsRasterTransparency)
    # pylint: enable=E0611
    # pylint: enable=W0621
    # pylint: enable=W0404

    myRampItemList = []
    myTransparencyList = []
    LOGGER.debug(theClasses)
    for myClass in theClasses:

        LOGGER.debug('Evaluating class:\n%s\n' % myClass)

        if 'quantity' not in myClass:
            LOGGER.exception('Class has no quantity attribute')
            continue

        myMax = myClass['max']
        if math.isnan(myMax):
            LOGGER.debug('Skipping class - max is nan.')
            continue

        myMin = myClass['min']
        if math.isnan(myMin):
            LOGGER.debug('Skipping class - min is nan.')
            continue

        myColour = QtGui.QColor(myClass['colour'])
        myLabel = QtCore.QString()
        if 'label' in myClass:
            myLabel = QtCore.QString(myClass['label'])
        myRampItem = QgsColorRampShader.ColorRampItem(myMax, myColour, myLabel)
        myRampItemList.append(myRampItem)

        # Create opacity entries for this range
        myTransparencyPercent = 0
        if 'transparency' in myClass:
            myTransparencyPercent = int(myClass['transparency'])
        if myTransparencyPercent > 0:
            # Check if range extrema are integers so we know if we can
            # use them to calculate a value range
            myPixel = QgsRasterTransparency.TransparentSingleValuePixel()
            myPixel.min = myMin
            # We want it just a leeetle bit smaller than max
            # so that ranges are discrete
            myPixel.max = myMax
            myPixel.percentTransparent = myTransparencyPercent
            myTransparencyList.append(myPixel)

    myBand = 1  # gdal counts bands from base 1
    LOGGER.debug('Setting colour ramp list')
    myRasterShader = QgsRasterShader()
    myColorRampShader = QgsColorRampShader()
    myColorRampShader.setColorRampType(QgsColorRampShader.INTERPOLATED)
    myColorRampShader.setColorRampItemList(myRampItemList)
    LOGGER.debug('Setting shader function')
    myRasterShader.setRasterShaderFunction(myColorRampShader)
    LOGGER.debug('Setting up renderer')
    myRenderer = QgsSingleBandPseudoColorRenderer(
        theQgsRasterLayer.dataProvider(), myBand, myRasterShader)
    LOGGER.debug('Assigning renderer to raster layer')
    theQgsRasterLayer.setRenderer(myRenderer)

    LOGGER.debug('Setting raster transparency list')

    myRenderer = theQgsRasterLayer.renderer()
    myTransparency = QgsRasterTransparency()
    myTransparency.setTransparentSingleValuePixelList(myTransparencyList)
    myRenderer.setRasterTransparency(myTransparency)
    # For interest you can also view the list like this:
    #pix = t.transparentSingleValuePixelList()
    #for px in pix:
    #    print 'Min: %s Max %s Percent %s' % (
    #       px.min, px.max, px.percentTransparent)

    LOGGER.debug('Saving style as default')
    theQgsRasterLayer.saveDefaultStyle()
    LOGGER.debug('Setting raster style done!')
    return myRampItemList, myTransparencyList
Beispiel #23
0
def _setNewRasterStyle(theQgsRasterLayer, theStyle):
    """Set QGIS raster style based on InaSAFE style dictionary for QGIS >= 2.0.

    This function will set both the colour map and the transparency
    for the passed in layer.

    Args:
        * theQgsRasterLayer: QgsRasterLayer
        * style: Dictionary of the form as in the example below.

    Returns:
        * list: RangeList
        * list: TransparencyList

    Example:
        style_classes = [dict(colour='#38A800', quantity=2, transparency=0),
                         dict(colour='#38A800', quantity=5, transparency=50),
                         dict(colour='#79C900', quantity=10, transparency=50),
                         dict(colour='#CEED00', quantity=20, transparency=50),
                         dict(colour='#FFCC00', quantity=50, transparency=34),
                         dict(colour='#FF6600', quantity=100, transparency=77),
                         dict(colour='#FF0000', quantity=200, transparency=24),
                         dict(colour='#7A0000', quantity=300, transparency=22)]

    """
    # Note imports here to prevent importing on unsupported QGIS versions
    # pylint: disable=E0611
    # pylint: disable=W0621
    # pylint: disable=W0404
    from qgis.core import (QgsRasterShader,
                           QgsColorRampShader,
                           QgsSingleBandPseudoColorRenderer,
                           QgsRasterTransparency)
    # pylint: enable=E0611
    # pylint: enable=W0621
    # pylint: enable=W0404

    myClasses = theStyle['style_classes']
    myRampItemList = []
    myTransparencyList = []
    myLastValue = 0
    for myClass in myClasses:
        LOGGER.debug('Evaluating class:\n%s\n' % myClass)
        myMax = myClass['quantity']

        if math.isnan(myMax):
            LOGGER.debug('Skipping class.')
            continue

        myColour = QtGui.QColor(myClass['colour'])
        myLabel = QtCore.QString()
        if 'label' in myClass:
            myLabel = QtCore.QString(myClass['label'])
        myRampItem = QgsColorRampShader.ColorRampItem(myMax, myColour, myLabel)
        myRampItemList.append(myRampItem)
        # Create opacity entries for this range
        myTransparencyPercent = 0
        if 'transparency' in myClass:
            myTransparencyPercent = int(myClass['transparency'])
        if myTransparencyPercent > 0:
            # Check if range extrema are integers so we know if we can
            # use them to calculate a value range
            myPixel = QgsRasterTransparency.TransparentSingleValuePixel()
            myPixel.min = myLastValue
            myPixel.max = myMax
            myPixel.percentTransparent = myTransparencyPercent
            myTransparencyList.append(myPixel)
            myLastValue = myMax

    myBand = 1  # gdal counts bands from base 1
    LOGGER.debug('Setting colour ramp list')
    myRasterShader = QgsRasterShader()
    myColorRampShader = QgsColorRampShader()
    myColorRampShader.setColorRampType(QgsColorRampShader.INTERPOLATED)
    myColorRampShader.setColorRampItemList(myRampItemList)
    LOGGER.debug('Setting shader function')
    myRasterShader.setRasterShaderFunction(myColorRampShader)
    LOGGER.debug('Setting up renderer')
    myRenderer = QgsSingleBandPseudoColorRenderer(
        theQgsRasterLayer.dataProvider(),
        myBand,
        myRasterShader)
    LOGGER.debug('Assigning renderer to raster layer')
    theQgsRasterLayer.setRenderer(myRenderer)
    LOGGER.debug('Setting raster transparency list')
    #if len(myTransparencyList) > 0:
    #    myRasterTransparency = QgsRasterTransparency()
    #    myRasterTransparency.setTransparentSingleValuePixelList(
    #        myTransparencyList)
    #    myRenderer.setRasterTransparency(myRasterTransparency)
    LOGGER.debug('Saving style as default')
    theQgsRasterLayer.saveDefaultStyle()
    LOGGER.debug('Setting raster style done!')
    return myRampItemList, myTransparencyList
def styleRaster(filename):
    # Create outfile name
    outfile = "".join(filename.strip().split('.raw'))

    # Open layer from filename
    rasterfile = filename.strip().split('/')[-1]
    rasterlayer = rasterfile.split('.')[0]
    rlayer = QgsRasterLayer(filename, rasterlayer, 'gdal')

    # Check if layer is valid
    if rlayer.isValid() is True:
        # Get layer data provider
        provider = rlayer.dataProvider()

        # Calculate histrogram
        provider.initHistogram(QgsRasterHistogram(), 1, 100)
        hist = provider.histogram(1)

        # Get histograms stats
        nbins = hist.binCount
        minv = hist.minimum
        maxv = hist.maximum

        # Create histogram array, bin array, and histogram index
        hista = np.array(hist.histogramVector)
        bins = np.arange(minv, maxv, (maxv - minv) / nbins)
        index = np.where(hista > 5)

        # Get bottom and top color values from bin values
        bottomcolor = bins[index[0][0]]
        topcolor = bins[index[0][-1]]

        # Calculate range value between the bottom and top color values
        if bottomcolor < 0:
            vrange = topcolor + bottomcolor
        else:
            vrange = topcolor - bottomcolor

        # Calculate values for bottom middle, and top middle color values
        if rasterlayer == 'maxele':
            bottommiddle = vrange * 0.3333
            topmiddle = vrange * 0.6667
        else:
            bottommiddle = vrange * 0.375
            topmiddle = vrange * 0.75

        # Create list of color values
        valueList = [bottomcolor, bottommiddle, topmiddle, topcolor]

        # Create color dictionary
        if rasterlayer == 'maxele':
            colDic = {
                'bottomcolor': '#0000ff',
                'bottommiddle': '#00ffff',
                'topmiddle': '#ffff00',
                'topcolor': '#ff0000'
            }
        else:
            colDic = {
                'bottomcolor': '#000000',
                'bottommiddle': '#ff0000',
                'topmiddle': '#ffff00',
                'topcolor': '#ffffff'
            }

        # Create color ramp function and add colors
        fnc = QgsColorRampShader()
        fnc.setColorRampType(QgsColorRampShader.Interpolated)
        lst = [QgsColorRampShader.ColorRampItem(valueList[0], QColor(colDic['bottomcolor'])),\
               QgsColorRampShader.ColorRampItem(valueList[1], QColor(colDic['bottommiddle'])), \
               QgsColorRampShader.ColorRampItem(valueList[2], QColor(colDic['topmiddle'])), \
               QgsColorRampShader.ColorRampItem(valueList[3], QColor(colDic['topcolor']))]
        fnc.setColorRampItemList(lst)

        # Create raster shader and add color ramp function
        shader = QgsRasterShader()
        shader.setRasterShaderFunction(fnc)

        # Create color render and set opacity
        renderer = QgsSingleBandPseudoColorRenderer(provider, 1, shader)
        renderer.setOpacity(0.75)

        # Get output format
        output_format = QgsRasterFileWriter.driverForExtension(
            os.path.splitext(outfile)[1])

        # Open output file for writing
        rfw = QgsRasterFileWriter(outfile)
        rfw.setOutputProviderKey('gdal')
        rfw.setOutputFormat(output_format)

        # Add EPSG 4326 to layer crs
        crs = QgsCoordinateReferenceSystem()
        crs.createFromSrid(4326)

        # Create Raster pipe and set provider and renderer
        pipe = QgsRasterPipe()
        pipe.set(provider.clone())
        pipe.set(renderer.clone())

        # Get transform context
        transform_context = QgsProject.instance().transformContext()

        # Write to file
        rfw.writeRaster(pipe, provider.xSize(), provider.ySize(),
                        provider.extent(), crs, transform_context)

        logger.info(
            'Conveted data in ' + rasterfile +
            ' from float64 to 8bit, added color palette and saved to tiff (' +
            outfile.split('/')[-1] + ') file')

    if not rlayer.isValid():
        raise Exception('Invalid raster')

    return (valueList)
Beispiel #25
0
    def Color(self, file_in, calcType=None):
        """
        Color the Inbound file (Essentially the File we JUST exported) and display it to screen)

        :param file_in: The file that was just exported
        :type file_in: FileImport

        :return: TO SCREEN Rendered Image
        :rtype: None
        """
        k = self.iface.addRasterLayer(file_in.filePath, file_in.baseName)
        stats = k.dataProvider().bandStatistics(1, QgsRasterBandStats.All,
                                                k.extent(), 0)
        minimum = stats.minimumValue
        maximum = stats.maximumValue

        self.com.log("Color func: [Min val: {0} | Max val: {1}".format(
            str(minimum), str(maximum)),
                     level=0)

        ramp_shader = QgsColorRampShader()
        ramp_shader.setColorRampType(QgsColorRampShader.INTERPOLATED)

        if calcType is None:
            color_list = [
                QgsColorRampShader.ColorRampItem(minimum, QColor(255, 0, 0)),
                QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)),
                QgsColorRampShader.ColorRampItem(maximum, QColor(0, 255, 0))
            ]

        elif calcType == "EVI":
            color_list = [
                QgsColorRampShader.ColorRampItem(-2, QColor(255, 0, 0)),
                QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)),
                QgsColorRampShader.ColorRampItem(2, QColor(0, 255, 0))
            ]

        else:
            color_list = [
                QgsColorRampShader.ColorRampItem(minimum, QColor(255, 0, 0)),
                QgsColorRampShader.ColorRampItem(0, QColor(255, 207, 74, 255)),
                QgsColorRampShader.ColorRampItem(maximum, QColor(0, 255, 0))
            ]

        ramp_shader.setColorRampItemList(color_list)

        shader = QgsRasterShader()
        shader.setRasterShaderFunction(ramp_shader)

        renderer = QgsSingleBandPseudoColorRenderer(k.dataProvider(), 1,
                                                    shader)
        k.setRenderer(renderer)
        """
        Export colored image to file
        """
        export_path = file_in.filePath + ".colored.tif"
        file_writer = QgsRasterFileWriter(export_path)
        pipe = QgsRasterPipe()
        provide = k.dataProvider()

        # Pipe Setter
        if not pipe.set(provide.clone()):
            self.com.error(Bold="PipeProviderError:",
                           String="Cannot set pipe provider",
                           level=1,
                           duration=3)
            self.com.log(
                "mainPlug - Color: Pipe provider error on line 473, Continuing...",
                level=1)

        self.com.log(str(pipe.renderer()), level=0)
        pipe.set(renderer.clone())
        file_writer.writeRaster(pipe, provide.xSize(), provide.ySize(),
                                provide.extent(), provide.crs())
Beispiel #26
0
def runThresholding(iface, dlg, conf, layersName, dir_raster_src, dir_dest,
                    ficRaster, seuilStr, fromActiveLayerRaster):

    # Recuperation du chemin compler du fichier raster source
    if fromActiveLayerRaster:
        if ficRaster == "":
            QMessageBox.information(
                None, "Attention !!!",
                "Le fichier raster est inexistant ou incorrect ou le foramt n'est pas supporté par le plugin !",
                QMessageBox.Ok, QMessageBox.NoButton)
            return None
    else:
        if os.path.isfile(ficRaster):
            try:
                dir_raster_src.decode('ascii')
                dir_dest.decode('ascii')
            except:
                QMessageBox.information(
                    None, "Attention !!!",
                    "Certaines fonctions comme gdal_polygonize n'acceptent pas les dossiers avec des caractères accentués. Le chemin d'accès au fichier raster n'est pas valable.",
                    QMessageBox.Ok, QMessageBox.NoButton)
                return None
            if platform.system() == "Linux" and conf.rbOTB.isChecked():
                try:
                    ficRaster.decode('ascii')
                except:
                    QMessageBox.information(
                        None, "Attention !!!",
                        "Certaines fonctions comme Band Math (OTB) n'acceptent pas les caractères accentués. Le nom du raster n'est pas valable.",
                        QMessageBox.Ok, QMessageBox.NoButton)
                    return None
        else:
            QMessageBox.information(
                None, "Attention !!!",
                "Le fichier raster est inexistant ou incorrect ou le foramt n'est pas supporté par le plugin !",
                QMessageBox.Ok, QMessageBox.NoButton)
            return None

    if dlg.rbSeuil.isChecked():
        if dlg.delta.text() in ('', '+', '-') or float(dlg.delta.text()) == 0:
            QMessageBox.information(None, "Attention !!!",
                                    "Valeur de delta incorrecte !",
                                    QMessageBox.Ok, QMessageBox.NoButton)
            dlg.delta.setFocus()
            return None

    # On lance le seuillage
    messInfo(dlg, "Seuillage en cours...")
    messInfo(dlg, "")

    canvas = iface.mapCanvas()
    li = layerList()

    # Nom du fichier raster
    if fromActiveLayerRaster:
        if ficRaster in li:
            layerRaster = li[ficRaster]
            rasterAssembly = layerRaster.dataProvider().dataSourceUri()
        else:
            QMessageBox.information(
                None, "Attention !!!", ficRaster +
                " n'existe plus dans la liste des couches disponible. Vérifiez réininitialisé la liste des couches d'entrée.",
                QMessageBox.Ok, QMessageBox.NoButton)
            messErreur(dlg, ficRaster + " n'existe plus dans la liste.")
            return None

    else:
        rasterAssembly = ficRaster
    extension_input_raster = os.path.splitext(
        os.path.basename(rasterAssembly))[1]
    messInfo(dlg, "Raster en entrée: " + layersName['raster'])

    li = layerList()
    canvas.refresh()

    # Variables
    global start_time
    raster = None

    # récupération du nom de base pour les fichiers temporaires et du répertoire de travail
    if fromActiveLayerRaster:
        if layersName['raster'] in li:
            raster = li[layersName['raster']]
    else:
        raster = loadRaster(dlg, ficRaster, layersName['raster'])

    if not raster:
        messErreur(dlg, "Le raster ne peut pas être chargé.")
        return None

    start_time = time.time()

    setLayerVisible(raster, True)

    # Création d'une couche vectorielle sur l'emprise du raster
    # Va permettre d'éliminer ultérieurement les bords du cadre lors de la recherche des contours
    LayerRasterExtendName = layersName['emprise']
    LayerRasterExtendPath = dir_dest + os.sep + LayerRasterExtendName + EXT_VECTOR

    if os.path.exists(LayerRasterExtendPath):
        try:
            os.remove(LayerRasterExtendPath)
        except:
            QMessageBox.information(
                None, "Attention !!!", LayerRasterExtendPath +
                " ne peut pas être effacé. Vérifiez que le fichier n'est pas verrouillé par un autre utilisateur ou que le fichier peut être effacé manuellement (droits d'écriture sur le répertoire).",
                QMessageBox.Ok, QMessageBox.NoButton)
            messErreur(dlg,
                       LayerRasterExtendPath + " ne peut pas être effacé.")
            return None

    messInfo(dlg, "Création de la couche: " + LayerRasterExtendName + ".")
    messInfo(dlg, "")

    crs = raster.crs()
    crsWkt = crs.toWkt()
    layerExtend = QgsVectorLayer("Polygon?crs=" + crsWkt,
                                 LayerRasterExtendName, "memory")

    if not layerExtend.isValid():
        messErreur(dlg, LayerRasterExtendPath + " ne peut pas être chargé.")
        return None

    QgsProject.instance().addMapLayer(layerExtend)

    li = layerList()
    symbol = li[LayerRasterExtendName].renderer().symbol()
    symbol.setColor(QColor.fromRgb(0, 0, 255))
    symbol.setOpacity(0.4)

    provider = li[LayerRasterExtendName].dataProvider()

    fields = QgsFields()
    fields.append(QgsField("HEIGHT", QVariant.Double))
    fields.append(QgsField("WIDTH", QVariant.Double))

    for f in fields:
        provider.addAttributes([f])

    writer = QgsVectorFileWriter(LayerRasterExtendPath, "CP1250", fields,
                                 QgsWkbTypes.Polygon, crs, FORMAT_VECT)
    if writer.hasError() != QgsVectorFileWriter.NoError:
        messErreur(dlg, LayerRasterExtendPath + " ne peut pas être créé.")
        return None

    li[LayerRasterExtendName].startEditing()

    extent = raster.extent()
    minx = extent.xMinimum()
    miny = extent.yMinimum()
    maxx = extent.xMaximum()
    maxy = extent.yMaximum()
    height = raster.height()
    width = raster.width()
    cntx = minx + (width / 2.0)
    cnty = miny + (height / 2.0)
    area = width * height
    perim = (2 * width) + (2 * height)
    rect = [
        QgsPointXY(minx, miny),
        QgsPointXY(minx, maxy),
        QgsPointXY(maxx, maxy),
        QgsPointXY(maxx, miny),
        QgsPointXY(minx, miny)
    ]
    geometry = QgsGeometry().fromPolygonXY([rect])
    feat = QgsFeature()
    feat.setGeometry(geometry)
    feat.setAttributes([height, width])
    writer.addFeature(feat)
    provider.addFeatures([feat])
    del writer

    li[LayerRasterExtendName].commitChanges()
    setLayerVisible(li[LayerRasterExtendName], False)

    node = QgsProject.instance().layerTreeRoot().findLayer(
        li[LayerRasterExtendName].id())
    iface.layerTreeView().layerTreeModel().refreshLayerLegend(node)
    li[LayerRasterExtendName].triggerRepaint()
    canvas.refresh()
    rasterTreatName = ""

    # Cas du traitement d'une image optique
    if conf.rbOptique.isChecked():

        # Calcul du NDVI
        if dlg.rbComputeNdvi.isChecked():
            rasterTreatName = layersName['ndvi']
            dir_raster_treat = dir_dest
            layer = computeNdvi(dlg, conf, dir_raster_src, dir_dest,
                                layersName["raster"], layersName["ndvi"],
                                extension_input_raster)
            if layer is None:
                return None

            QgsProject.instance().addMapLayer(layer)
            setLayerVisible(layer, False)
            extension_input_raster = EXT_RASTER

        # Calcul du NDWI2
        elif dlg.rbComputeNdwi2.isChecked():
            rasterTreatName = layersName['ndwi2']
            dir_raster_treat = dir_dest
            layer = computeNdwi2(dlg, conf, dir_raster_src, dir_dest,
                                 layersName["raster"], layersName["ndwi2"],
                                 extension_input_raster)
            if layer is None:
                return None

            QgsProject.instance().addMapLayer(layer)
            setLayerVisible(layer, False)
            extension_input_raster = EXT_RASTER

        else:
            rasterTreatName = layersName['raster']
            dir_raster_treat = dir_raster_src

    # Cas du traitement d'une image radar
    elif conf.rbRadar.isChecked():

        # Despeckele Lee
        if dlg.rbDespeckLee.isChecked():
            rasterTreatName = layersName['lee']
            dir_raster_treat = dir_dest
            layer = despeckeleLee(dlg, conf, dir_raster_src, dir_dest,
                                  layersName["raster"], layersName["lee"],
                                  extension_input_raster)
            if layer is None:
                return None

            QgsProject.instance().addMapLayer(layer)
            setLayerVisible(layer, False)
            extension_input_raster = EXT_RASTER

        # Despeckele Gamma
        elif dlg.rbDespeckGamma.isChecked():
            rasterTreatName = layersName['gamma']
            dir_raster_treat = dir_dest
            layer = despeckeleGamma(dlg, conf, dir_raster_src, dir_dest,
                                    layersName["raster"], layersName["gamma"],
                                    extension_input_raster)
            if layer is None:
                return None

            QgsProject.instance().addMapLayer(layer)
            setLayerVisible(layer, False)
            extension_input_raster = EXT_RASTER
        else:
            rasterTreatName = layersName['raster']
            dir_raster_treat = dir_raster_src

    li = layerList()

    # Calcul du masque d'eau à partir du seuil estimé
    deltaStr = dlg.delta.text()
    layers_list = computeMaskThreshold(dlg, conf, dir_raster_treat, dir_dest,
                                       rasterTreatName, layersName['seuil'],
                                       seuilStr, deltaStr,
                                       extension_input_raster)
    if layers_list is None:
        return None

    # Informations de style
    for layer in layers_list:
        QgsProject.instance().addMapLayer(layer)
        fcn = QgsColorRampShader()
        fcn.setColorRampType(QgsColorRampShader.Type.Exact)
        lst = [QgsColorRampShader.ColorRampItem(1, QColor(QColor(0, 0, 255)))]
        fcn.setColorRampItemList(lst)
        shader = QgsRasterShader()
        shader.setRasterShaderFunction(fcn)
        renderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 1,
                                                    shader)
        if renderer:
            layer.setRenderer(renderer)
            if layer.renderer():
                layer.renderer().setOpacity(0.5)
        layer.triggerRepaint()
        setLayerVisible(layer, False)

    li = layerList()
    messInfo(
        dlg, "Temps de calcul:  " + str(round(time.time() - start_time)) +
        " secondes.")
    messInfo(dlg, "")

    global start_timeVect
    start_timeVect = time.time()

    layerName = li[layersName['raster']]
    setLayerVisible(layerName, False)

    layerSeuilName = layersName['seuil'] + seuilStr
    layerSeuil = li[layerSeuilName]
    setLayerVisible(layerSeuil, True)

    li[layersName['raster']].triggerRepaint()
    canvas.refresh()
    extent = li[layersName['raster']].extent()
    canvas.setExtent(extent)

    # Retour avec le bon nom du fichier seuillé
    layersName['seuil'] = layerSeuilName

    return layersName
Beispiel #27
0
def _setNewRasterStyle(theQgsRasterLayer, theStyle):
    """Set QGIS raster style based on InaSAFE style dictionary for QGIS >= 2.0.

    This function will set both the colour map and the transparency
    for the passed in layer.

    Args:
        * theQgsRasterLayer: QgsRasterLayer
        * style: Dictionary of the form as in the example below.

    Returns:
        * list: RangeList
        * list: TransparencyList

    Example:
        style_classes = [dict(colour='#38A800', quantity=2, transparency=0),
                         dict(colour='#38A800', quantity=5, transparency=50),
                         dict(colour='#79C900', quantity=10, transparency=50),
                         dict(colour='#CEED00', quantity=20, transparency=50),
                         dict(colour='#FFCC00', quantity=50, transparency=34),
                         dict(colour='#FF6600', quantity=100, transparency=77),
                         dict(colour='#FF0000', quantity=200, transparency=24),
                         dict(colour='#7A0000', quantity=300, transparency=22)]

    """
    # Note imports here to prevent importing on unsupported QGIS versions
    # pylint: disable=E0611
    # pylint: disable=W0621
    # pylint: disable=W0404
    from qgis.core import (QgsRasterShader, QgsColorRampShader,
                           QgsSingleBandPseudoColorRenderer,
                           QgsRasterTransparency)
    # pylint: enable=E0611
    # pylint: enable=W0621
    # pylint: enable=W0404

    myClasses = theStyle['style_classes']
    myRampItemList = []
    myTransparencyList = []
    myLastValue = 0
    for myClass in myClasses:
        LOGGER.debug('Evaluating class:\n%s\n' % myClass)
        myMax = myClass['quantity']

        if math.isnan(myMax):
            LOGGER.debug('Skipping class.')
            continue

        myColour = QtGui.QColor(myClass['colour'])
        myLabel = QtCore.QString()
        if 'label' in myClass:
            myLabel = QtCore.QString(myClass['label'])
        myRampItem = QgsColorRampShader.ColorRampItem(myMax, myColour, myLabel)
        myRampItemList.append(myRampItem)
        # Create opacity entries for this range
        myTransparencyPercent = 0
        if 'transparency' in myClass:
            myTransparencyPercent = int(myClass['transparency'])
        if myTransparencyPercent > 0:
            # Check if range extrema are integers so we know if we can
            # use them to calculate a value range
            myPixel = QgsRasterTransparency.TransparentSingleValuePixel()
            myPixel.min = myLastValue
            myPixel.max = myMax
            myPixel.percentTransparent = myTransparencyPercent
            myTransparencyList.append(myPixel)
            myLastValue = myMax

    myBand = 1  # gdal counts bands from base 1
    LOGGER.debug('Setting colour ramp list')
    myRasterShader = QgsRasterShader()
    myColorRampShader = QgsColorRampShader()
    myColorRampShader.setColorRampType(QgsColorRampShader.INTERPOLATED)
    myColorRampShader.setColorRampItemList(myRampItemList)
    LOGGER.debug('Setting shader function')
    myRasterShader.setRasterShaderFunction(myColorRampShader)
    LOGGER.debug('Setting up renderer')
    myRenderer = QgsSingleBandPseudoColorRenderer(
        theQgsRasterLayer.dataProvider(), myBand, myRasterShader)
    LOGGER.debug('Assigning renderer to raster layer')
    theQgsRasterLayer.setRenderer(myRenderer)
    LOGGER.debug('Setting raster transparency list')
    #if len(myTransparencyList) > 0:
    #    myRasterTransparency = QgsRasterTransparency()
    #    myRasterTransparency.setTransparentSingleValuePixelList(
    #        myTransparencyList)
    #    myRenderer.setRasterTransparency(myRasterTransparency)
    LOGGER.debug('Saving style as default')
    theQgsRasterLayer.saveDefaultStyle()
    LOGGER.debug('Setting raster style done!')
    return myRampItemList, myTransparencyList
Beispiel #28
0
def idw_interpolation(layer, parent_dialog):
    """Run interpolation using inverse distance weight algorithm

    :param layer: Vector layer with drivetimes
    :type layer: QgsVectorLayer

    :param parent_dialog: A dialog that called this function.
    :type parent_dialog: QProgressDialog

    :returns raster_layer: Interpolated raster layer with drivetimes
    :rtype raster_layer: QgsRasterLayer

    """
    raster_layer = None
    try:
        Processing.initialize()
        Processing.updateAlgsList()

        output_raster = processing.runalg('gdalogr:gridinvdist', layer,
                                          'minutes', 2, 0, 0, 0, 0, 0, 0, 0, 5,
                                          "[temporary file]")

        output_file = output_raster['OUTPUT']
        file_info = QFileInfo(output_file)
        base_name = file_info.baseName()

        # retrieving the raster output , styling it and load it in Qgis

        raster_layer = QgsRasterLayer(output_file, base_name)

    except Exception as exception:  # pylint: disable=broad-except
        # noinspection PyCallByClass,PyTypeChecker,PyArgumentList
        if parent_dialog:
            display_warning_message_box(
                parent_dialog, parent_dialog.tr('Error'),
                parent_dialog.tr('Error loading isochrone map,'
                                 'please check if you have processing '
                                 'plugin installed '))
        else:
            display_warning_message_box(
                parent_dialog, 'Error', 'Error loading isochrone map,'
                'please check if you have processing '
                'plugin installed ')

    if raster_layer:
        if raster_layer.isValid():
            color_shader = QgsColorRampShader()
            color_shader.setColorRampType(QgsColorRampShader.INTERPOLATED)
            colors = {
                'deep_green': '#1a9641',
                'light_green': '#a6d96a',
                'pale_yellow': '#ffffc0',
                'light_red': '#fdae61',
                'red': '#d7191c'
            }
            provider = raster_layer.dataProvider()
            stats = provider.bandStatistics(1, QgsRasterBandStats.All,
                                            raster_layer.extent(), 0)

            values = {}

            if stats:
                min = stats.minimumValue
                max = stats.maximumValue
                stat_range = max - min
                add = stat_range / 4
                values[0] = min
                value = min
                for index in range(1, 4):
                    value += add
                    values[index] = value
                values[4] = max
            else:
                display_warning_message_box(
                    parent_dialog, parent_dialog.tr('Error'),
                    parent_dialog.tr('Error loading isochrone map'
                                     ' Problem indexing the isochrones map'))

            color_list = [
                QgsColorRampShader.ColorRampItem(values[0],
                                                 QColor(colors['deep_green'])),
                QgsColorRampShader.ColorRampItem(values[1],
                                                 QColor(
                                                     colors['light_green'])),
                QgsColorRampShader.ColorRampItem(values[2],
                                                 QColor(
                                                     colors['pale_yellow'])),
                QgsColorRampShader.ColorRampItem(values[3],
                                                 QColor(colors['light_red'])),
                QgsColorRampShader.ColorRampItem(values[4],
                                                 QColor(colors['red']))
            ]

            color_shader.setColorRampItemList(color_list)
            raster_shader = QgsRasterShader()
            raster_shader.setRasterShaderFunction(color_shader)

            renderer = QgsSingleBandPseudoColorRenderer(
                raster_layer.dataProvider(), 1, raster_shader)
            raster_layer.setRenderer(renderer)

        else:
            if parent_dialog:
                display_warning_message_box(
                    parent_dialog, parent_dialog.tr('Problem'),
                    parent_dialog.tr('Problem styling the isochrone map'))
            else:
                display_warning_message_box(
                    parent_dialog, 'Problem',
                    'Problem styling the isochrone map')

        QgsMapLayerRegistry.instance().addMapLayers([raster_layer])

    else:
        if parent_dialog:

            display_warning_message_box(
                parent_dialog, parent_dialog.tr('Error'),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load interpolated file!'))
        else:
            display_warning_message_box(
                parent_dialog, 'Error', 'Error loading isochrone map '
                'Could not load interpolated file!')

    return raster_layer
Beispiel #29
0
def create_raster_layer(matrix):
    driver = gdal.GetDriverByName("GTiff")

    filename = tempfile.mktemp(prefix="hmtk", suffix=".tif")

    # sort the data by lon, lat
    gridded_data = numpy.array(
        sorted(matrix, key=lambda row: (90 + row[1]) * 180 + (180 + row[0])))

    # extract it into separate vars
    lons, lats, vals = (
        gridded_data[:, 0], gridded_data[:, 1], gridded_data[:, 3])

    ncols = lons[lons == lons[0]].size
    nrows = lats[lats == lats[0]].size

    # put values in a grid
    gridded_vals = vals.reshape((ncols, nrows)).T

    dataset = driver.Create(filename, ncols, nrows, 1, gdal.GDT_Float32)

    dataset.SetGeoTransform((
        min(lons),
        (max(lons) - min(lons)) / ncols,
        0,
        max(lats),
        0,
        -(max(lats) - min(lats)) / nrows))

    out_srs = osr.SpatialReference()
    out_srs.ImportFromEPSG(4326)
    dataset.SetProjection(out_srs.ExportToWkt())

    out_band = dataset.GetRasterBand(1)
    out_band.WriteArray(gridded_vals)
    out_band.SetNoDataValue(0)
    out_band.FlushCache()
    out_band = None
    dataset = None

    fileInfo = QFileInfo(filename)
    baseName = fileInfo.baseName()
    layer = QgsRasterLayer(filename, baseName)

    stat = layer.dataProvider().bandStatistics(1)

    minVal = stat.minimumValue
    maxVal = stat.maximumValue
    entries_nr = 20

    colorRamp = QgsStyleV2().defaultStyle().colorRamp("Spectral")
    currentValue = float(minVal)
    intervalDiff = float(maxVal - minVal) / float(entries_nr - 1)

    colorRampItems = []
    for i in reversed(xrange(entries_nr)):
        item = QgsColorRampShader.ColorRampItem()
        item.value = currentValue
        item.label = unicode(currentValue)
        currentValue += intervalDiff
        item.color = colorRamp.color(float(i) / float(entries_nr))
        item.color.setAlphaF(0.75)
        colorRampItems.append(item)

    rasterShader = QgsRasterShader()
    colorRampShader = QgsColorRampShader()

    colorRampShader.setColorRampItemList(colorRampItems)
    colorRampShader.setColorRampType(QgsColorRampShader.INTERPOLATED)
    rasterShader.setRasterShaderFunction(colorRampShader)

    layer.setDrawingStyle('SingleBandPseudoColor')
    layer.renderer().setShader(rasterShader)

    QgsMapLayerRegistry.instance().addMapLayer(layer)

    return layer
class Threshold:
    """QGIS Plugin Implementation."""
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(self.plugin_dir, 'i18n',
                                   'Threshold3_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&Threshold3')

        self.color_picker = QColorDialog()
        self.color_picker.setOption(QColorDialog.ShowAlphaChannel, on=True)

        self.t_0_COLOR = QColor(0, 0, 255)
        self.t_1_COLOR = QColor(0, 255, 0)
        self.t_2_COLOR = QColor(255, 0, 0)
        self.CLEAR = QColor(255, 255, 255, 0)

        self.layer = None
        self.fcn = None
        self.shader = None
        self.renderer = None
        self.is_initial = True
        self.MIN = float("inf")
        self.MAX = float("-inf")
        self.precision = 2
        self.last_time = time() * 1000

        self.render_debounce_timer = QTimer()
        self.render_debounce_timer.timeout.connect(self.render)
        self.render_debounce_timer.setSingleShot(True)

        # TODO: We are going to let the user set this up in a future iteration
        self.toolbar = self.iface.addToolBar(u'Threshold3')
        self.toolbar.setObjectName(u'Threshold3')

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('Threshold3', message)

    def add_action(self,
                   icon_path,
                   text,
                   callback,
                   enabled_flag=True,
                   add_to_menu=True,
                   add_to_toolbar=True,
                   status_tip=None,
                   whats_this=None,
                   parent=None):
        """Add a toolbar icon to the toolbar.

        :param icon_path: Path to the icon for this action. Can be a resource
            path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
        :type icon_path: str

        :param text: Text that should be shown in menu items for this action.
        :type text: str

        :param callback: Function to be called when the action is triggered.
        :type callback: function

        :param enabled_flag: A flag indicating if the action should be enabled
            by default. Defaults to True.
        :type enabled_flag: bool

        :param add_to_menu: Flag indicating whether the action should also
            be added to the menu. Defaults to True.
        :type add_to_menu: bool

        :param add_to_toolbar: Flag indicating whether the action should also
            be added to the toolbar. Defaults to True.
        :type add_to_toolbar: bool

        :param status_tip: Optional text to show in a popup when mouse pointer
            hovers over the action.
        :type status_tip: str

        :param parent: Parent widget for the new action. Defaults None.
        :type parent: QWidget

        :param whats_this: Optional text to show in the status bar when the
            mouse pointer hovers over the action.

        :returns: The action that was created. Note that the action is also
            added to self.actions list.
        :rtype: QAction
        """

        # Create the dialog (after translation) and keep reference
        self.dlg = ThresholdDialog()

        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            self.toolbar.addAction(action)

        if add_to_menu:
            self.iface.addPluginToMenu(self.menu, action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""

        icon_path = ':/plugins/Threshold3/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(
                u'Add colored layers according to user-defined thresholds.'),
            callback=self.run,
            parent=self.iface.mainWindow())

    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginMenu(self.tr(u'&Threshold3'), action)
            self.iface.removeToolBarIcon(action)
        # remove the toolbar
        del self.toolbar

    def run(self):
        """Run method that performs all the real work"""
        # show the dialog
        self.dlg.show()
        self.toggle_widgets(False)

        self.layer = self.iface.activeLayer()
        if self.layer is None:
            self.dlg.header.setText("No layer selected.")
            self.dlg.header.setStyleSheet("color: #000000;")
        else:
            if isinstance(self.layer, QgsRasterLayer) is False:
                raise TypeError("Expected QgsRasterLayer, got {}".format(
                    type(self.layer)))
            self.dlg.header.setText("")  # Active layer
            if not hasattr(self.layer, "hasFilter"):
                self.fcn = QgsColorRampShader()
                self.fcn.setColorRampType(QgsColorRampShader.Interpolated)
                self.layer.hasFilter = True
            else:
                self.toggle_widgets(True)
        if self.MAX == float("-inf"):
            self.startWorker(self.iface, self.layer)
        # Run the dialog event loop

        # self.set_values(True)

        result = self.dlg.exec_()

        self.dlg.threshold_0_button.clicked.disconnect()
        self.dlg.threshold_1_button.clicked.disconnect()
        self.dlg.threshold_2_button.clicked.disconnect()

        # See if OK was pressed
        if result:
            pass
            # print("OK was pressed.")
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
        else:
            pass
            # print("CANCEL was pressed.")

    def set_values(self, connect=False):

        self.dlg.precision_spinbox.setMinimum(1)
        self.dlg.precision_spinbox.setMaximum(5)
        if connect:
            self.dlg.precision_spinbox.setValue(2)
            self.dlg.precision_spinbox.valueChanged.connect(
                lambda: self.on_changed(None, "precision"))

        increment = 1.0 / (10**self.precision)

        self.dlg.doubleSpinBox_b.setSingleStep(increment)
        self.dlg.doubleSpinBox_1.setSingleStep(increment)
        self.dlg.doubleSpinBox_2.setSingleStep(increment)
        self.dlg.doubleSpinBox_3.setSingleStep(increment)

        self.dlg.doubleSpinBox_b.setDecimals(5)
        self.dlg.doubleSpinBox_1.setDecimals(5)
        self.dlg.doubleSpinBox_2.setDecimals(5)
        self.dlg.doubleSpinBox_3.setDecimals(5)

        self.dlg.doubleSpinBox_b.setMinimum(0)
        self.dlg.doubleSpinBox_1.setMinimum(self.MIN)
        self.dlg.doubleSpinBox_2.setMinimum(self.MIN)
        self.dlg.doubleSpinBox_3.setMinimum(self.MIN)

        self.dlg.doubleSpinBox_b.setMaximum(abs(self.MAX - self.MIN))
        self.dlg.doubleSpinBox_1.setMaximum(self.MAX)
        self.dlg.doubleSpinBox_2.setMaximum(self.MAX)
        self.dlg.doubleSpinBox_3.setMaximum(self.MAX)

        if connect:
            self.dlg.doubleSpinBox_b.valueChanged.connect(
                lambda: self.on_changed(None, "box"))
            self.dlg.doubleSpinBox_1.valueChanged.connect(
                lambda: self.on_changed(0, "box"))
            self.dlg.doubleSpinBox_2.valueChanged.connect(
                lambda: self.on_changed(1, "box"))
            self.dlg.doubleSpinBox_3.valueChanged.connect(
                lambda: self.on_changed(2, "box"))

        self.dlg.alpha_0_slider.setMinimum(0)
        self.dlg.alpha_0_slider.setMaximum(255)
        self.dlg.alpha_1_slider.setMinimum(0)
        self.dlg.alpha_1_slider.setMaximum(255)
        self.dlg.alpha_2_slider.setMinimum(0)
        self.dlg.alpha_2_slider.setMaximum(255)

        self.dlg.alpha_0_slider.setValue(255)
        self.dlg.alpha_1_slider.setValue(255)
        self.dlg.alpha_2_slider.setValue(255)

        if connect:
            self.dlg.alpha_0_slider.valueChanged.connect(
                lambda: self.on_changed(None))
            self.dlg.alpha_1_slider.valueChanged.connect(
                lambda: self.on_changed(None))
            self.dlg.alpha_2_slider.valueChanged.connect(
                lambda: self.on_changed(None))

        self.dlg.base_slider.setMinimum(0)

        # setMaximum throws Error here, and sockets don't get connected
        # This is why some sliders won't work.
        # Find out why OverflowError occurs or add

        self.dlg.base_slider.setMaximum(
            abs(self.MAX - self.MIN) * (10**self.precision))
        self.dlg.base_slider.setValue(0)

        self.dlg.threshold_0_slider.setMinimum(self.MIN * (10**self.precision))
        self.dlg.threshold_0_slider.setMaximum(self.MAX * (10**self.precision))
        self.dlg.threshold_1_slider.setMinimum(self.MIN * (10**self.precision))
        self.dlg.threshold_1_slider.setMaximum(self.MAX * (10**self.precision))
        self.dlg.threshold_2_slider.setMinimum(self.MIN * (10**self.precision))
        self.dlg.threshold_2_slider.setMaximum(self.MAX * (10**self.precision))

        if connect:
            self.dlg.base_slider.valueChanged.connect(
                lambda: self.on_changed("base"))
            self.dlg.threshold_0_slider.valueChanged.connect(
                lambda: self.on_changed(0))
            self.dlg.threshold_1_slider.valueChanged.connect(
                lambda: self.on_changed(1))
            self.dlg.threshold_2_slider.valueChanged.connect(
                lambda: self.on_changed(2))

            # Turn it on and off again... I don't know why but
            # connecting and disconnecting these listeners fixes
            # the double popup problem.

            self.dlg.threshold_0_button.clicked.connect(
                lambda: self.on_color_button_clicked(0))
            self.dlg.threshold_1_button.clicked.connect(
                lambda: self.on_color_button_clicked(1))
            self.dlg.threshold_2_button.clicked.connect(
                lambda: self.on_color_button_clicked(2))
            self.dlg.threshold_0_button.clicked.disconnect()
            self.dlg.threshold_1_button.clicked.disconnect()
            self.dlg.threshold_2_button.clicked.disconnect()
            self.dlg.threshold_0_button.clicked.connect(
                lambda: self.on_color_button_clicked(0))
            self.dlg.threshold_1_button.clicked.connect(
                lambda: self.on_color_button_clicked(1))
            self.dlg.threshold_2_button.clicked.connect(
                lambda: self.on_color_button_clicked(2))

        self.dlg.threshold_0_color_box.setStyleSheet(
            "background-color: {}".format(self.t_0_COLOR.name()))
        self.dlg.threshold_1_color_box.setStyleSheet(
            "background-color: {}".format(self.t_1_COLOR.name()))
        self.dlg.threshold_2_color_box.setStyleSheet(
            "background-color: {}".format(self.t_2_COLOR.name()))
        pass

    def render(self):
        t_0 = self.dlg.threshold_0_slider.value() / (10.0**self.precision)
        t_1 = self.dlg.threshold_1_slider.value() / (10.0**self.precision)
        t_2 = self.dlg.threshold_2_slider.value() / (10.0**self.precision)
        base = self.dlg.base_slider.value() / (10.0**self.precision)
        lst = [
            QgsColorRampShader.ColorRampItem(t_0 - base, self.CLEAR),
            QgsColorRampShader.ColorRampItem(t_0, self.t_0_COLOR),
            QgsColorRampShader.ColorRampItem(t_1, self.t_1_COLOR),
            QgsColorRampShader.ColorRampItem(t_2, self.t_2_COLOR),
        ]
        self.fcn = QgsColorRampShader()
        self.fcn.setColorRampType(QgsColorRampShader.Interpolated)
        self.fcn.setColorRampItemList(lst)
        self.shader = QgsRasterShader()

        self.shader.setRasterShaderFunction(self.fcn)

        self.renderer = QgsSingleBandPseudoColorRenderer(
            self.layer.dataProvider(), 1, self.shader)

        self.layer.setRenderer(self.renderer)
        self.layer.triggerRepaint()

    @QtCore.pyqtSlot(bool)
    def on_color_button_clicked(self, which):
        print(which)
        setattr(
            self, "t_{}_COLOR".format(which),
            self.color_picker.getColor(
                getattr(self, "t_{}_COLOR".format(which))))
        getattr(self.dlg,
                "threshold_{}_color_box".format(which)).setStyleSheet(
                    "background-color: {}".format(
                        getattr(self, "t_{}_COLOR".format(which)).name()))
        self.render()

    def on_changed(self, which, source=""):
        if time() * 1000 - self.last_time < 25:
            return
        else:
            self.last_time = time() * 1000

        base = self.dlg.doubleSpinBox_b.value()
        t_0 = self.dlg.doubleSpinBox_1.value()
        t_1 = self.dlg.doubleSpinBox_2.value()
        t_2 = self.dlg.doubleSpinBox_3.value()
        coef = 10**self.precision
        if source == "box":
            base = self.dlg.doubleSpinBox_b.value()
            t_0 = self.dlg.doubleSpinBox_1.value()
            t_1 = self.dlg.doubleSpinBox_2.value()
            t_2 = self.dlg.doubleSpinBox_3.value()
        elif source == "precision":
            prec = self.dlg.precision_spinbox.value()
            self.precision = prec
            # self.dlg.doubleSpinBox_b.setSingleStep(figs)
            # self.dlg.doubleSpinBox_1.setSingleStep(figs)
            # self.dlg.doubleSpinBox_2.setSingleStep(figs)
            # self.dlg.doubleSpinBox_3.setSingleStep(figs)
            self.set_values()
        else:
            base = self.dlg.base_slider.value() / float(coef)
            t_0 = self.dlg.threshold_0_slider.value() / float(coef)
            t_1 = self.dlg.threshold_1_slider.value() / float(coef)
            t_2 = self.dlg.threshold_2_slider.value() / float(coef)

        alpha_0 = self.dlg.alpha_0_slider.value()
        alpha_1 = self.dlg.alpha_1_slider.value()
        alpha_2 = self.dlg.alpha_2_slider.value()

        self.t_0_COLOR.setAlpha(alpha_0)
        self.t_1_COLOR.setAlpha(alpha_1)
        self.t_2_COLOR.setAlpha(alpha_2)

        #print("Which: {}".format(which))
        if which == 0:
            if t_0 > t_1:
                t_1 = t_0
                self.dlg.threshold_1_slider.setValue(t_1)
                self.dlg.doubleSpinBox_2.setValue(t_1)

            if t_1 > t_2:
                t_2 = t_1
                self.dlg.threshold_2_slider.setValue(t_2)
                self.dlg.doubleSpinBox_3.setValue(t_2)
        elif which == 1:
            if t_0 > t_1:
                t_0 = t_1
                self.dlg.threshold_0_slider.setValue(t_0)
                self.dlg.doubleSpinBox_1.setValue(t_0)

            if t_1 > t_2:
                t_2 = t_1
                self.dlg.threshold_2_slider.setValue(t_2)
                self.dlg.doubleSpinBox_3.setValue(t_2)

        elif which == 2:
            if t_0 > t_1:
                t_1 = t_0
                self.dlg.threshold_1_slider.setValue(t_1)
                self.dlg.doubleSpinBox_2.setValue(t_1)

            if t_1 > t_2:
                t_1 = t_2
                self.dlg.threshold_1_slider.setValue(t_1)
                self.dlg.doubleSpinBox_2.setValue(t_1)

            if t_0 > t_2:
                t_0 = t_2
                self.dlg.threshold_1_slider.setValue(t_0)
                self.dlg.doubleSpinBox_2.setValue(t_0)

        # if base > t_0:
        #     base = t_0
        #     self.dlg.base_slider.setValue(base)
        #     self.dlg.doubleSpinBox_b.setValue(base)
        self.dlg.base_slider.setValue(base * coef)
        # self.dlg.base_value.setText(str(base))
        # self.dlg.threshold_0_value.setText(str(t_0))
        # self.dlg.threshold_1_value.setText(str(t_1))
        # self.dlg.threshold_2_value.setText(str(t_2))
        self.dlg.threshold_0_slider.setValue(t_0 * coef)
        self.dlg.threshold_1_slider.setValue(t_1 * coef)
        self.dlg.threshold_2_slider.setValue(t_2 * coef)
        self.dlg.doubleSpinBox_1.setValue(t_0)
        self.dlg.doubleSpinBox_2.setValue(t_1)
        self.dlg.doubleSpinBox_3.setValue(t_2)
        self.dlg.doubleSpinBox_b.setValue(base)

        self.dlg.alpha_0_value.setText(str(alpha_0))
        self.dlg.alpha_1_value.setText(str(alpha_1))
        self.dlg.alpha_2_value.setText(str(alpha_2))

        if source == "box":
            self.render_debounce_timer.start(25)
        else:
            self.render_debounce_timer.start(75)

    def toggle_widgets(self, value):
        self.dlg.doubleSpinBox_1.setEnabled(value)
        self.dlg.doubleSpinBox_2.setEnabled(value)
        self.dlg.doubleSpinBox_3.setEnabled(value)
        self.dlg.doubleSpinBox_b.setEnabled(value)
        self.dlg.threshold_0_slider.setEnabled(value)
        self.dlg.threshold_1_slider.setEnabled(value)
        self.dlg.threshold_2_slider.setEnabled(value)
        self.dlg.threshold_0_button.setEnabled(value)
        self.dlg.threshold_1_button.setEnabled(value)
        self.dlg.threshold_2_button.setEnabled(value)
        self.dlg.alpha_0_slider.setEnabled(value)
        self.dlg.alpha_1_slider.setEnabled(value)
        self.dlg.alpha_2_slider.setEnabled(value)
        self.dlg.precision_spinbox.setEnabled(value)

    def startWorker(self, iface, layer):
        self.dlg.header.setText("Calculating...")
        worker = Worker(iface, layer)
        messageBar = self.iface.messageBar().createMessage(
            'Calculating range...', )
        progressBar = QProgressBar()
        progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        cancelButton = QPushButton()
        cancelButton.setText('Cancel')
        cancelButton.clicked.connect(worker.kill)
        messageBar.layout().addWidget(progressBar)
        messageBar.layout().addWidget(cancelButton)
        self.iface.messageBar().pushWidget(messageBar)
        self.messageBar = messageBar

        #start the worker in a new thread
        thread = QThread()
        worker.moveToThread(thread)
        worker.finished.connect(self.workerFinished)
        worker.error.connect(self.workerError)
        worker.progress.connect(progressBar.setValue)
        thread.started.connect(worker.run)
        thread.start()
        self.thread = thread
        self.worker = worker
        pass

    def workerFinished(self, ret):
        self.dlg.header.setText("")
        # clean up the worker and thread
        self.worker.deleteLater()
        self.thread.quit()
        self.thread.wait()
        self.thread.deleteLater()
        # remove widget from message bar
        self.iface.messageBar().popWidget(self.messageBar)
        if ret is not None:
            # report the result
            _min, _max = ret
            self.MIN = _min
            self.MAX = _max
            self.set_values(self.is_initial)
            self.toggle_widgets(True)
            self.iface.messageBar().pushMessage(
                "Worker finished: MAX {}, MIN {}".format(_max, _min))
            # self.iface.messageBar().pushMessage('min: {}, max: {}'.format(_min, _max))
        else:
            # notify the user that something went wrong
            self.iface.messageBar().pushMessage(
                'Something went wrong! See the message log for more information.',
                level=QgsMessageBar.CRITICAL,
                duration=3)
        if self.is_initial:
            self.is_initial = False

    def workerError(self, e, exception_string):
        raise Exception("workerError {}".format(exception_string))
Beispiel #31
0
 def aggregate_layers(self, layers, d):
     aggregation = self.frequency.itemData(self.frequency.currentIndex())
     month = str(d.month)
     month = month if len(month) == 2 else '0' + month
     day = str(d.day)
     day = day if len(day) == 2 else '0' + day
     filtered_layers = filter(lambda x: '.tif' in x, layers)
     datasets = []
     file_name = None
     for l in filtered_layers:
         datasets.append(Dataset(l))
     sum = datasets[0]
     for i in range(1, len(datasets) - 1):
         sum += datasets[i]
     if aggregation == 'SUM':
         Env.overwrite = True
         avg = sum
         file_name = self.download_folder.text() + '/' + str(
             d.year) + '_' + month + '_' + day + '_SUM.tif'
         avg.save(file_name)
     elif aggregation == 'AVG':
         Env.overwrite = True
         avg = sum
         avg /= len(datasets)
         file_name = self.download_folder.text() + '/' + str(
             d.year) + '_' + month + '_' + day + '_AVG.tif'
         avg.save(file_name)
     if self.add_to_canvas.isChecked() is True:
         self.bar.pushMessage(None,
                              str(file_name),
                              level=QgsMessageBar.INFO)
         title = None
         if aggregation == 'SUM':
             title = self.tr('TRMM Aggregate (Sum): ') + str(
                 d.year) + '-' + str(month) + '-' + str(day)
         elif aggregation == 'AVG':
             title = self.tr('TRMM Aggregate (Average): ') + str(
                 d.year) + '-' + str(month) + '-' + str(day)
         rl = self.iface.addRasterLayer(file_name, title)
         fcn = QgsColorRampShader()
         fcn.setColorRampType(QgsColorRampShader.INTERPOLATED)
         lst = [
             QgsColorRampShader.ColorRampItem(0, QColor(247, 251, 255, 0),
                                              '< 2.6 [mm]'),
             QgsColorRampShader.ColorRampItem(2.6, QColor(222, 235, 247),
                                              '< 5.2 [mm]'),
             QgsColorRampShader.ColorRampItem(5.2, QColor(199, 220, 239),
                                              '< 7.8 [mm]'),
             QgsColorRampShader.ColorRampItem(7.8, QColor(162, 203, 226),
                                              '< 10.4 [mm]'),
             QgsColorRampShader.ColorRampItem(10.4, QColor(114, 178, 215),
                                              '< 13 [mm]'),
             QgsColorRampShader.ColorRampItem(13, QColor(73, 151, 201),
                                              '< 15.6 [mm]'),
             QgsColorRampShader.ColorRampItem(15.6, QColor(40, 120, 184),
                                              '< 18 [mm]'),
             QgsColorRampShader.ColorRampItem(18, QColor(13, 87, 161),
                                              '< 20 [mm]'),
             QgsColorRampShader.ColorRampItem(20, QColor(8, 48, 107),
                                              '>= 20 [mm]')
         ]
         fcn.setColorRampItemList(lst)
         shader = QgsRasterShader()
         shader.setRasterShaderFunction(fcn)
         renderer = QgsSingleBandPseudoColorRenderer(
             rl.dataProvider(), 1, shader)
         rl.setRenderer(renderer)
         rl.triggerRepaint()
def idw_interpolation(layer, parent_dialog):
    """Run interpolation using inverse distance weight algorithm

    :param layer: Vector layer with drivetimes
    :type layer: QgsVectorLayer

    :param parent_dialog: A dialog that called this function.
    :type parent_dialog: QProgressDialog

    :returns raster_layer: Interpolated raster layer with drivetimes
    :rtype raster_layer: QgsRasterLayer

    """
    raster_layer = None
    try:
        Processing.initialize()
        Processing.updateAlgsList()

        output_raster = processing.runalg(
        'gdalogr:gridinvdist',
        layer,
        'minutes',
        2, 0, 0, 0, 0, 0, 0, 0, 5,
        "[temporary file]")

        output_file = output_raster['OUTPUT']
        file_info = QFileInfo(output_file)
        base_name = file_info.baseName()

        # retrieving the raster output , styling it and load it in Qgis

        raster_layer = QgsRasterLayer(output_file, base_name)

    except Exception as exception:  # pylint: disable=broad-except
            # noinspection PyCallByClass,PyTypeChecker,PyArgumentList
        if parent_dialog:
                display_warning_message_box(
                    parent_dialog,
                    parent_dialog.tr(
                        'Error'),
                    parent_dialog.tr('Error loading isochrone map,'
                                     'please check if you have processing '
                                     'plugin installed '))
        else:
            display_warning_message_box(
                parent_dialog,
                'Error',
                'Error loading isochrone map,'
                'please check if you have processing '
                'plugin installed ')

    if raster_layer:
        if raster_layer.isValid():
            color_shader = QgsColorRampShader()
            color_shader.setColorRampType(QgsColorRampShader.INTERPOLATED)
            colors = {
                'deep_green': '#1a9641',
                'light_green': '#a6d96a',
                'pale_yellow': '#ffffc0',
                'light_red': '#fdae61',
                'red': '#d7191c'
            }
            provider = raster_layer.dataProvider()
            stats = provider.bandStatistics(
                1,
                QgsRasterBandStats.All,
                raster_layer.extent(),
                0)

            values = {}

            if stats:
                min = stats.minimumValue
                max = stats.maximumValue
                stat_range = max - min
                add = stat_range / 4
                values[0] = min
                value = min
                for index in range(1, 4):
                    value += add
                    values[index] = value
                values[4] = max
            else:
                display_warning_message_box(
                    parent_dialog,
                    parent_dialog.tr(
                        'Error'),
                    parent_dialog.tr('Error loading isochrone map'
                                     ' Problem indexing the isochrones map'))

            color_list = [
                QgsColorRampShader.ColorRampItem(
                    values[0],
                    QColor(colors['deep_green'])),
                QgsColorRampShader.ColorRampItem(
                    values[1],
                    QColor(colors['light_green'])),
                QgsColorRampShader.ColorRampItem(
                    values[2],
                    QColor(colors['pale_yellow'])),
                QgsColorRampShader.ColorRampItem(
                    values[3],
                    QColor(colors['light_red'])),
                QgsColorRampShader.ColorRampItem(
                    values[4],
                    QColor(colors['red']))
            ]

            color_shader.setColorRampItemList(color_list)
            raster_shader = QgsRasterShader()
            raster_shader.setRasterShaderFunction(color_shader)

            renderer = QgsSingleBandPseudoColorRenderer(
                raster_layer.dataProvider(),
                1,
                raster_shader)
            raster_layer.setRenderer(renderer)

        else:
            if parent_dialog:
                display_warning_message_box(
                    parent_dialog,
                    parent_dialog.tr(
                        'Problem'),
                    parent_dialog.tr('Problem styling the isochrone map'))
            else:
                display_warning_message_box(
                    parent_dialog,
                    'Problem',
                    'Problem styling the isochrone map')

        QgsMapLayerRegistry.instance().addMapLayers([raster_layer])

    else:
        if parent_dialog:

            display_warning_message_box(
                parent_dialog,
                parent_dialog.tr(
                    'Error'),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load interpolated file!'))
        else:
            display_warning_message_box(
                parent_dialog,
                'Error',
                'Error loading isochrone map '
                'Could not load interpolated file!')

    return raster_layer
Beispiel #33
0
def _setNewRasterStyle(theQgsRasterLayer, theClasses):
    """Set QGIS raster style based on InaSAFE style dictionary for QGIS >= 2.0.

    This function will set both the colour map and the transparency
    for the passed in layer.

    Args:
        * theQgsRasterLayer: QgsRasterLayer
        * theClasses: List of the form as in the example below.

    Returns:
        * list: RangeList
        * list: TransparencyList

    Example:
        style_classes = [dict(colour='#38A800', quantity=2, transparency=0),
                         dict(colour='#38A800', quantity=5, transparency=50),
                         dict(colour='#79C900', quantity=10, transparency=50),
                         dict(colour='#CEED00', quantity=20, transparency=50),
                         dict(colour='#FFCC00', quantity=50, transparency=34),
                         dict(colour='#FF6600', quantity=100, transparency=77),
                         dict(colour='#FF0000', quantity=200, transparency=24),
                         dict(colour='#7A0000', quantity=300, transparency=22)]

    """
    # Note imports here to prevent importing on unsupported QGIS versions
    # pylint: disable=E0611
    # pylint: disable=W0621
    # pylint: disable=W0404
    from qgis.core import (QgsRasterShader,
                           QgsColorRampShader,
                           QgsSingleBandPseudoColorRenderer,
                           QgsRasterTransparency)
    # pylint: enable=E0611
    # pylint: enable=W0621
    # pylint: enable=W0404

    myRampItemList = []
    myTransparencyList = []
    LOGGER.debug(theClasses)
    for myClass in theClasses:

        LOGGER.debug('Evaluating class:\n%s\n' % myClass)

        if 'quantity' not in myClass:
            LOGGER.exception('Class has no quantity attribute')
            continue

        myMax = myClass['max']
        if math.isnan(myMax):
            LOGGER.debug('Skipping class - max is nan.')
            continue

        myMin = myClass['min']
        if math.isnan(myMin):
            LOGGER.debug('Skipping class - min is nan.')
            continue

        myColour = QtGui.QColor(myClass['colour'])
        myLabel = QtCore.QString()
        if 'label' in myClass:
            myLabel = QtCore.QString(myClass['label'])
        myRampItem = QgsColorRampShader.ColorRampItem(myMax, myColour, myLabel)
        myRampItemList.append(myRampItem)

        # Create opacity entries for this range
        myTransparencyPercent = 0
        if 'transparency' in myClass:
            myTransparencyPercent = int(myClass['transparency'])
        if myTransparencyPercent > 0:
            # Check if range extrema are integers so we know if we can
            # use them to calculate a value range
            myPixel = QgsRasterTransparency.TransparentSingleValuePixel()
            myPixel.min = myMin
            # We want it just a leeetle bit smaller than max
            # so that ranges are discrete
            myPixel.max = myMax
            myPixel.percentTransparent = myTransparencyPercent
            myTransparencyList.append(myPixel)

    myBand = 1  # gdal counts bands from base 1
    LOGGER.debug('Setting colour ramp list')
    myRasterShader = QgsRasterShader()
    myColorRampShader = QgsColorRampShader()
    myColorRampShader.setColorRampType(QgsColorRampShader.INTERPOLATED)
    myColorRampShader.setColorRampItemList(myRampItemList)
    LOGGER.debug('Setting shader function')
    myRasterShader.setRasterShaderFunction(myColorRampShader)
    LOGGER.debug('Setting up renderer')
    myRenderer = QgsSingleBandPseudoColorRenderer(
        theQgsRasterLayer.dataProvider(),
        myBand,
        myRasterShader)
    LOGGER.debug('Assigning renderer to raster layer')
    theQgsRasterLayer.setRenderer(myRenderer)

    LOGGER.debug('Setting raster transparency list')

    myRenderer = theQgsRasterLayer.renderer()
    myTransparency = QgsRasterTransparency()
    myTransparency.setTransparentSingleValuePixelList(myTransparencyList)
    myRenderer.setRasterTransparency(myTransparency)
    # For interest you can also view the list like this:
    #pix = t.transparentSingleValuePixelList()
    #for px in pix:
    #    print 'Min: %s Max %s Percent %s' % (
    #       px.min, px.max, px.percentTransparent)

    LOGGER.debug('Saving style as default')
    theQgsRasterLayer.saveDefaultStyle()
    LOGGER.debug('Setting raster style done!')
    return myRampItemList, myTransparencyList
def style_raster_layer(raster_layer, parent_dialog):
    """Style interpolated raster layer

        :param raster_layer: Interpolated raster layer
        :type raster_layer: QgsRasterLayer

        :param parent_dialog: A dialog for showing progress.
        :type parent_dialog: QProgressDialog

        :returns raster_layer: Styled interpolated raster layer
        :rtype raster_layer: QgsRasterLayer

    """
    if raster_layer:
        if raster_layer.isValid():
            color_shader = QgsColorRampShader()
            color_shader.setColorRampType(QgsColorRampShader.Interpolated)
            colors = {
                'deep_green': '#1a9641',
                'light_green': '#a6d96a',
                'pale_yellow': '#ffffc0',
                'light_red': '#fdae61',
                'red': '#d7191c'
            }
            provider = raster_layer.dataProvider()
            stats = provider.bandStatistics(
                1,
                QgsRasterBandStats.All,
                raster_layer.extent(),
                0)

            values = {}

            if stats:
                min = stats.minimumValue
                max = stats.maximumValue
                stat_range = max - min
                add = stat_range / 4
                values[0] = min
                value = min
                for index in range(1, 4):
                    value += add
                    values[index] = value
                values[4] = max
            else:
                display_warning_message_box(
                    parent_dialog,
                    parent_dialog.tr(
                        'Error'),
                    parent_dialog.tr('Error loading isochrone map'
                                     ' Problem indexing the isochrones map'))

            color_list = [
                QgsColorRampShader.ColorRampItem(
                    values[0],
                    QColor(colors['deep_green'])),
                QgsColorRampShader.ColorRampItem(
                    values[1],
                    QColor(colors['light_green'])),
                QgsColorRampShader.ColorRampItem(
                    values[2],
                    QColor(colors['pale_yellow'])),
                QgsColorRampShader.ColorRampItem(
                    values[3],
                    QColor(colors['light_red'])),
                QgsColorRampShader.ColorRampItem(
                    values[4],
                    QColor(colors['red']))
            ]

            color_shader.setColorRampItemList(color_list)
            raster_shader = QgsRasterShader()
            raster_shader.setRasterShaderFunction(color_shader)

            renderer = QgsSingleBandPseudoColorRenderer(
                raster_layer.dataProvider(),
                1,
                raster_shader)

            raster_layer.setRenderer(renderer)
            raster_layer.triggerRepaint()

        else:
            if parent_dialog:
                display_warning_message_box(
                    parent_dialog,
                    parent_dialog.tr(
                        'Problem'),
                    parent_dialog.tr('Problem styling the isochrone map'))
            else:
                display_warning_message_box(
                    parent_dialog,
                    'Problem',
                    'Problem styling the isochrone map')

    else:
        if parent_dialog:

            display_warning_message_box(
                parent_dialog,
                parent_dialog.tr(
                    'Error'),
                parent_dialog.tr('Error loading isochrone map '
                                 'Could not load interpolated file!'))
        else:
            display_warning_message_box(
                parent_dialog,
                'Error',
                'Error loading isochrone map '
                'Could not load interpolated file!')

    return raster_layer
Beispiel #35
0
    def process(self, data):

        # data = {upd/npd: {dating = [calendar years BP, ...], uncert = [calendar years, ...], coords = [[x, y], ...], accur = [accuracy, ...]}}

        UPD_t_ds = np.round(data["upd"]["dating"]).astype(
            int
        )  # mean datings of archaeological components (calendar years BP)
        UPD_uncert_ds = np.round(data["upd"]["uncert"]).astype(
            int)  # uncertainties of the datings (calendar years)
        UPD_As = np.round(data["upd"]["coords"]).astype(
            int)  # spatial coordinates of archaeological components (metres)
        UPD_accurs = np.round(data["upd"]["accur"]).astype(
            int
        )  # accuracies of spatial coordinates of archaeological components (+-metres)

        NPD_t_ds = np.round(data["npd"]["dating"]).astype(
            int
        )  # measured radiocarbon ages of archaeological components (radiocarbon years)
        NPD_uncert_ds = np.round(data["npd"]["uncert"]).astype(
            int
        )  # 1-sigma uncertainties of the measured radiocarbon ages (radiocarbon years)
        NPD_As = np.round(data["npd"]["coords"]).astype(
            int)  # spatial coordinates of archaeological components (metres)
        NPD_accurs = np.round(data["npd"]["accur"]).astype(
            int
        )  # accuracies of spatial coordinates of archaeological components (+-metres)

        if (not UPD_t_ds.size) and (not NPD_t_ds.size):
            return

        s_halflife = self.s_duration / 2  # expected half-life of a settlement in years
        s_radius = self.s_diameter / 2  # expected radius of a settlement in metres

        # temporal extent
        t_min = np.inf
        t_max = -np.inf
        if UPD_t_ds.size:
            t_min = min(t_min,
                        (UPD_t_ds - UPD_uncert_ds).min() - self.s_duration)
            t_max = max(t_max,
                        (UPD_t_ds + UPD_uncert_ds).max() + self.s_duration)
        if NPD_t_ds.size:
            t_min = min(t_min,
                        (NPD_t_ds - 2 * NPD_uncert_ds).min() - self.s_duration)
            t_max = max(t_max,
                        (NPD_t_ds + 2 * NPD_uncert_ds).max() + self.s_duration)
        t_min, t_max = [
            int(round(value / 10) * 10) for value in [t_min, t_max]
        ]

        if self.time_from is not None:
            t_max = min(t_max, self.time_from)
        if self.time_to is not None:
            t_min = max(t_min, self.time_to)

        ts_slices = np.arange(t_max, t_min - 2 * self.time_step,
                              -self.time_step).tolist()  # times of time slices

        # prepare lookup for probability distributions of 14C datings
        self.setLabelText("Calibrating radiocarbon dates")
        cal_curve = load_curve(
            os.path.join(os.path.dirname(__file__), "intcal13.14c")
        )  # [[CalBP, ConvBP, CalSigma], ...], sorted by CalBP

        # filter calibration curve to include only time-step dates
        cal_curve = cal_curve[(cal_curve[:, 0] >= t_min)
                              & (cal_curve[:, 0] <= t_max)][::-1]
        ts = cal_curve[:, 0]
        curve_conv_age = cal_curve[:, 1]
        curve_uncert = cal_curve[:, 2]
        if ts[-1] < ts_slices[-1]:
            ts_slices.append(ts[-1])

        # calculate probability distributions for all combinations of 14c age and uncertainty
        unique_dates = set()  # ((age, uncert), ...)
        for idx in range(NPD_t_ds.shape[0]):
            unique_dates.add((NPD_t_ds[idx], NPD_uncert_ds[idx]))
        lookup_14c = defaultdict(
            dict
        )  # {age: {uncert: D, ...}, ...}; D[ti] = p; where ti = index in ts, p = probability
        cmax = len(unique_dates)
        cnt = 0
        for age, uncert in unique_dates:
            QtWidgets.QApplication.processEvents()
            if not self.running:
                return
            self.setValue((cnt / cmax) * 100)
            cnt += 1
            lookup_14c[age][uncert] = calibrate(age, uncert, curve_conv_age,
                                                curve_uncert)

        # prepare lookup of spatial probability distribution around evidence points
        self.setLabelText("Calculating spatial probability distribution")
        self.setValue(0)
        accurs = set()
        accurs.update(UPD_accurs.tolist())
        accurs.update(NPD_accurs.tolist())
        lookup_f_s = {
        }  # {accur: M, ...}; M[n, n] = f_s(d, accur, s_radius); where center is point A and n is 2 * [maximum distance from A in raster units] + 1; where f_s > 0
        cnt = 0
        cmax = len(accurs)
        for accur in accurs:
            QtWidgets.QApplication.processEvents()
            if not self.running:
                return
            self.setValue((cnt / cmax) * 100)
            cnt += 1
            r = int(round((accur + 2 * s_radius) / self.cell_size))
            n = 2 * r + 1
            lookup_f_s[accur] = np.zeros((n, n), dtype=float)
            rcs = np.argwhere(np.ones((n, n), dtype=bool))
            mask = (rcs > r).all(axis=1)
            for row, col in rcs[mask]:
                d = (((row - r)**2 + (col - r)**2)**0.5) * self.cell_size
                if self.approximate:
                    p = f_s_approx(d, accur, s_radius)
                else:
                    p = f_S_lens(d, accur, s_radius) / f_S(accur, s_radius)
                if (p == np.inf) or np.isnan(p):
                    p = 0
                lookup_f_s[accur][row, col] = p
                lookup_f_s[accur][n - row, col] = p
                lookup_f_s[accur][row, n - col] = p
                lookup_f_s[accur][n - row, n - col] = p
            lookup_f_s[accur][0, 0] = lookup_f_s[accur][0, 1]

        # spatial extent
        row_min, col_min = np.inf, np.inf
        row_max, col_max = -np.inf, -np.inf
        for As, accurs in [[UPD_As, UPD_accurs], [NPD_As, NPD_accurs]]:
            for idx in range(As.shape[0]):
                A = As[idx]
                accur = accurs[idx]
                r = int(lookup_f_s[accur].shape[0] / 2)
                col, row = np.round(A / self.cell_size).astype(int)
                row_min = min(row_min, row - r - 1)
                col_min = min(col_min, col - r - 1)
                row_max = max(row_max, row + r)
                col_max = max(col_max, col + r)
        width, height = (col_max - col_min), (row_max - row_min)
        x0, y0 = col_min * self.cell_size, row_min * self.cell_size

        # calculate time-slices
        self.setLabelText("Generating time-slices")
        paths = []
        summed = []
        val_max = -np.inf
        grid_summed = np.zeros((height, width), dtype=float)
        t_slice_prev = ts_slices.pop(0)
        t_slice = ts_slices.pop(0)
        n_slice = 1
        for ti in range(ts.shape[0]):
            QtWidgets.QApplication.processEvents()
            if not self.running:
                return
            self.setValue((ti / ts.shape[0]) * 100)

            grid = np.ones((height, width), dtype=float)

            for idx in range(UPD_t_ds.shape[0]):
                t_d = UPD_t_ds[idx]
                uncert_d = UPD_uncert_ds[idx]
                A = UPD_As[idx]
                accur = UPD_accurs[idx]
                M = 1 - lookup_f_s[accur] * f_t_UPD(ts[ti], t_d, uncert_d,
                                                    s_halflife)
                r = int((M.shape[0] - 1) / 2)
                col0, row0 = np.round((A - [x0, y0]) / self.cell_size - r -
                                      1).astype(int)
                grid[row0:row0 + M.shape[0], col0:col0 + M.shape[0]] *= M

            for idx in range(NPD_t_ds.shape[0]):
                t_d = NPD_t_ds[idx]
                uncert_d = NPD_uncert_ds[idx]
                A = NPD_As[idx]
                accur = NPD_accurs[idx]
                M = 1 - lookup_f_s[accur] * f_t_NPD(
                    ts[ti], s_halflife, lookup_14c[t_d][uncert_d], ts)
                r = int((M.shape[0] - 1) / 2)
                col0, row0 = np.round((A - [x0, y0]) / self.cell_size - r -
                                      1).astype(int)
                grid[row0:row0 + M.shape[0], col0:col0 + M.shape[0]] *= M

            grid = 1 - grid
            grid[np.isnan(grid)] = 0
            grid[grid == np.inf] = 0

            summed.append(grid.sum())

            if ts[ti] <= t_slice:
                val_max = max(val_max, grid_summed.max())
                t_ce, cebce = bp_to_ce(t_slice_prev)
                t_ce2, cebce2 = bp_to_ce(t_slice)
                datestr = "%03d_%d_%s_-_%d_%s" % (n_slice, t_ce, cebce, t_ce2,
                                                  cebce2)
                paths.append([
                    datestr,
                    os.path.join(self.path_layers, "ede_%s.tif" % (datestr))
                ])
                self.save_raster(grid_summed, x0, y0, paths[-1][1])
                t_slice_prev = t_slice
                t_slice = ts_slices.pop(0)
                n_slice += 1
                grid_summed[:] = grid
            else:
                grid_summed += grid

        if self.path_summed:
            self.save_summed(ts, summed)

        project = QgsProject.instance()
        val_max = val_max * 0.9
        self.setLabelText("Rendering time-slices")
        cnt = 0
        cmax = len(paths)
        for datestr, path in paths:
            QtWidgets.QApplication.processEvents()
            if not self.running:
                return
            self.setValue((cnt / cmax) * 100)
            cnt += 1
            layer = QgsRasterLayer(path, "EDE_%s" % (datestr))
            layer.setCrs(self.crs)
            s = QgsRasterShader()
            c = QgsColorRampShader()
            c.setColorRampType(QgsColorRampShader.Interpolated)
            i = []
            i.append(QgsColorRampShader.ColorRampItem(0, self.colors[0]))
            i.append(
                QgsColorRampShader.ColorRampItem(val_max / 2, self.colors[1]))
            i.append(QgsColorRampShader.ColorRampItem(val_max, self.colors[2]))
            c.setColorRampItemList(i)
            s.setRasterShaderFunction(c)
            ps = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 1, s)
            ps.setClassificationMin(0)
            ps.setClassificationMax(val_max)
            layer.setRenderer(ps)

            self.save_rendered(
                layer, os.path.join(self.path_rendered, "%s.tif" % (datestr)))

            project.addMapLayer(layer)
Beispiel #36
0
def add_layer(f, band_number, band_info):
    try:
        style = styles[band_info['name']]
    except KeyError:
        QtWidgets.QMessageBox.information(None,
                                      tr("Information"),
                                      tr(u"Trends.Earth does not have a style assigned for {}. To use this layer, manually add it to your map.".format(f)))
        log(u'No style found for {}'.format(band_info['name'] ))
        return False

    title = get_band_title(band_info)

    l = iface.addRasterLayer(f, title)
    if not l.isValid():
        log('Failed to add layer')
        return False

    if style['ramp']['type'] == 'categorical':
        r = []
        for item in style['ramp']['items']:
            r.append(QgsColorRampShader.ColorRampItem(item['value'],
                                                      QtWidgets.QColor(item['color']),
                                                      tr_style_text(item['label'])))
    elif style['ramp']['type'] == 'categorical with dynamic ramp':
        r = []
        for item in style['ramp']['items']:
            r.append(QgsColorRampShader.ColorRampItem(item['value'],
                                                      QtWidgets.QColor(item['color']),
                                                      tr_style_text(item['label'])))
        # Now add in the continuous ramp with min/max values and labels 
        # determined from the band info min/max
        r.append(QgsColorRampShader.ColorRampItem(band_info['metadata']['ramp_min'],
                                                  QtWidgets.QColor(style['ramp']['ramp min']['color']),
                                                  tr_style_text(style['ramp']['ramp min']['label'], band_info)))
        r.append(QgsColorRampShader.ColorRampItem(band_info['metadata']['ramp_max'],
                                                  QtWidgets.QColor(style['ramp']['ramp max']['color']),
                                                  tr_style_text(style['ramp']['ramp max']['label'], band_info)))

    elif style['ramp']['type'] == 'zero-centered stretch':
        # Set a colormap centred on zero, going to the max of the min and max 
        # extreme value significant to three figures.
        cutoff = get_cutoff(f, band_number, band_info, [style['ramp']['percent stretch'], 100 - style['ramp']['percent stretch']])
        log('Cutoff for {} percent stretch: {}'.format(style['ramp']['percent stretch'], cutoff))
        r = []
        r.append(QgsColorRampShader.ColorRampItem(-cutoff,
                                                  QtWidgets.QColor(style['ramp']['min']['color']),
                                                  '{}'.format(-cutoff)))
        r.append(QgsColorRampShader.ColorRampItem(0,
                                                  QtWidgets.QColor(style['ramp']['zero']['color']),
                                                  '0'))
        r.append(QgsColorRampShader.ColorRampItem(cutoff,
                                                  QtWidgets.QColor(style['ramp']['max']['color']),
                                                  '{}'.format(cutoff)))
        r.append(QgsColorRampShader.ColorRampItem(style['ramp']['no data']['value'],
                                                  QtWidgets.QColor(style['ramp']['no data']['color']),
                                                  tr_style_text(style['ramp']['no data']['label'])))

    elif style['ramp']['type'] == 'min zero stretch':
        # Set a colormap from zero to percent stretch significant to
        # three figures.
        cutoff = get_cutoff(f, band_number, band_info, [100 - style['ramp']['percent stretch']])
        log('Cutoff for min zero max {} percent stretch: {}'.format(100 - style['ramp']['percent stretch'], cutoff))
        r = []
        r.append(QgsColorRampShader.ColorRampItem(0,
                                                  QtWidgets.QColor(style['ramp']['zero']['color']),
                                                  '0'))
        if 'mid' in style['ramp']:
            r.append(QgsColorRampShader.ColorRampItem(cutoff/2,
                                                      QtWidgets.QColor(style['ramp']['mid']['color']),
                                                      str(cutoff/2)))
        r.append(QgsColorRampShader.ColorRampItem(cutoff,
                                                  QtWidgets.QColor(style['ramp']['max']['color']),
                                                  '{}'.format(cutoff)))
        r.append(QgsColorRampShader.ColorRampItem(style['ramp']['no data']['value'],
                                                  QtWidgets.QColor(style['ramp']['no data']['color']),
                                                  tr_style_text(style['ramp']['no data']['label'])))

    else:
        log('Failed to load Trends.Earth style. Adding layer using QGIS defaults.')
        QtWidgets.QMessageBox.critical(None,
                                   tr("Error"),
                                   tr("Failed to load Trends.Earth style. Adding layer using QGIS defaults."))
        return False

    fcn = QgsColorRampShader()
    if style['ramp']['shader'] == 'exact':
        fcn.setColorRampType("EXACT")
    elif style['ramp']['shader'] == 'discrete':
        fcn.setColorRampType("DISCRETE")
    elif style['ramp']['shader'] == 'interpolated':
        fcn.setColorRampType("INTERPOLATED")
    else:
        raise TypeError("Unrecognized color ramp type: {}".format(style['ramp']['shader']))
    # Make sure the items in the color ramp are sorted by value (weird display 
    # errors will otherwise result)
    r = sorted(r, key=attrgetter('value'))
    fcn.setColorRampItemList(r)
    shader = QgsRasterShader()
    shader.setRasterShaderFunction(fcn)
    pseudoRenderer = QgsSingleBandPseudoColorRenderer(l.dataProvider(),
                                                      band_number,
                                                      shader)
    l.setRenderer(pseudoRenderer)
    l.triggerRepaint()
    iface.legendInterface().refreshLayerSymbology(l)

    return True
Beispiel #37
0
def rat_classify(raster_layer, band, rat, criteria, ramp=None, feedback=QgsRasterBlockFeedback()) -> list:
    """Classify a raster.

    Note: cannot use a custom shader function QgsColorRampShader subclass because it's lost in
          the clone stage of the renderer.

    :param raster_layer: the raster layer to classify
    :type raster_layer: QgsRasterLayer
    :param band: band number (1-based)
    :type band: int
    :param rat: the RAT data
    :type rat: dict
    :param criteria: key of the RAT to be used for labels
    :type criteria: str
    :param ramp: optional color ramp, defaults to QgsRandomColorRamp()
    :type ramp: QgsColorRamp, optional
    :param feedback: QGIS feedback object, defaults to QgsRasterBlockFeedback()
    :type feedback: QgsRasterBlockFeedback, optional
    :return: unique row indexes for legend items (1-based)
    :rtype: list
    """

    has_color = rat.has_color
    labels = rat.data[criteria]
    label_colors = {}
    unique_indexes = []

    # QGIS >= 3.18 for first element label
    if Qgis.QGIS_VERSION_INT >= 31800:
        base_legend_row_index = 1
    else:
        base_legend_row_index = 0

    if rat.thematic_type == gdal.GRTT_THEMATIC:

        # Use paletted
        rat_log('Using paletted renderer')

        value_column_name = rat.field_name(gdal.GFU_MinMax)
        values = rat.data[value_column_name]
        is_integer = isinstance(values[0], int)

        if ramp is None:
            ramp = QgsRandomColorRamp()
        classes = QgsPalettedRasterRenderer.classDataFromRaster(
            raster_layer.dataProvider(), band, ramp, feedback)

        row_index = base_legend_row_index
        for klass in classes:
            value = int(klass.value) if is_integer else klass.value
            try:
                index = values.index(value)
            except ValueError:   # NODATA
                rat_log(
                    f'Value {value} not found in RAT, assuming NODATA', Qgis.Warning)
                data_provider = raster_layer.dataProvider()
                if not data_provider.userNoDataValuesContains(band, value):
                    nodata = data_provider.userNoDataValues(band)
                    nodata_value = QgsRasterRange(value, value)
                    nodata.append(nodata_value)
                    data_provider.setUserNoDataValue(band, nodata)
                continue
            klass.label = str(labels[index])
            if klass.label not in label_colors:
                unique_indexes.append(row_index)
                if has_color:
                    label_colors[klass.label] = rat.data[RAT_COLOR_HEADER_NAME][index]
                else:
                    label_colors[klass.label] = klass.color
            klass.color = label_colors[klass.label]
            row_index += 1

        renderer = QgsPalettedRasterRenderer(
            raster_layer.dataProvider(), band, classes)

    else:  # ranges

        rat_log('Using singleband pseudocolor renderer')

        min_value_column = rat.field_name(gdal.GFU_Min)
        max_value_column = rat.field_name(gdal.GFU_Max)

        # Collect unique values and colors from criteria
        row_index = base_legend_row_index
        unique_labels = []
        for index in range(len(labels)):
            label = labels[index]
            if label not in unique_labels:
                unique_labels.append(label)
                unique_indexes.append(row_index)
                # Collect color
                if has_color:
                    label_colors[label] = rat.data[RAT_COLOR_HEADER_NAME][index]
            row_index += 1

        # Assign colors from random ramp
        if not has_color:
            ramp = QgsRandomColorRamp()
            ramp.setTotalColorCount(len(unique_labels))
            i = 0
            for index in unique_indexes:
                label_colors[labels[index]] = ramp.color(ramp.value(i))
                i += 1

        # Create values for the ramp
        # Collect colors for all classes
        colors = []
        for label in labels:
            colors.append(label_colors[label])

        ramp = QgsPresetSchemeColorRamp(colors)
        minValue = min(rat.data[min_value_column])
        maxValue = max(rat.data[max_value_column])

        assert minValue < maxValue, "Min Value must be lower than Max Value"

        shader = QgsRasterShader(minValue, maxValue)

        colorRampShaderFcn = QgsColorRampShader(
            minValue, maxValue, ramp)
        colorRampShaderFcn.setClip(True)
        colorRampShaderFcn.setColorRampType(QgsColorRampShader.Discrete)

        items = []
        row = 0
        for label in labels:
            items.append(QgsColorRampShader.ColorRampItem(
                rat.data[max_value_column][row], label_colors[label], label))
            row += 1

        colorRampShaderFcn.setColorRampItemList(items)
        try:  # for older QGIS
            colorRampShaderFcn.legendSettings().setUseContinuousLegend(False)
        except AttributeError:
            rat_log(
                'QgsColorRampShader.legendSettings().setUseContinuousLegend() is not supported on ths QGIS version.', Qgis.Warning)
        shader.setRasterShaderFunction(colorRampShaderFcn)
        renderer = QgsSingleBandPseudoColorRenderer(
            raster_layer.dataProvider(), band, shader)

    raster_layer.setRenderer(renderer)
    raster_layer.triggerRepaint()

    return unique_indexes
Beispiel #38
0
def set_raster_style(raster_layer, style):
    """Set QGIS raster style based on InaSAFE style dictionary for QGIS >= 2.0.

    This function will set both the colour map and the transparency
    for the passed in layer.

    :param raster_layer: A QGIS raster layer that will be styled.
    :type raster_layer: QgsVectorLayer

    :param style: List of the form as in the example below.
    :type style: list

    Example::

        style_classes = [dict(colour='#38A800', quantity=2, transparency=0),
                         dict(colour='#38A800', quantity=5, transparency=50),
                         dict(colour='#79C900', quantity=10, transparency=50),
                         dict(colour='#CEED00', quantity=20, transparency=50),
                         dict(colour='#FFCC00', quantity=50, transparency=34),
                         dict(colour='#FF6600', quantity=100, transparency=77),
                         dict(colour='#FF0000', quantity=200, transparency=24),
                         dict(colour='#7A0000', quantity=300, transparency=22)]

    :returns: A two tuple containing a range list and a transparency list.
    :rtype: (list, list)

    """
    # Note imports here to prevent importing on unsupported QGIS versions
    # pylint: disable=E0611
    # pylint: disable=W0621
    # pylint: disable=W0404
    # noinspection PyUnresolvedReferences
    from qgis.core import (QgsRasterShader, QgsColorRampShader,
                           QgsSingleBandPseudoColorRenderer,
                           QgsRasterTransparency)
    # pylint: enable=E0611
    # pylint: enable=W0621
    # pylint: enable=W0404

    ramp_item_list = []
    transparency_list = []
    LOGGER.debug(style)
    for style_class in style:

        LOGGER.debug('Evaluating class:\n%s\n' % style_class)

        if 'quantity' not in style_class:
            LOGGER.exception('Class has no quantity attribute')
            continue

        class_max = style_class['max']
        if math.isnan(class_max):
            LOGGER.debug('Skipping class - max is nan.')
            continue

        class_min = style_class['min']
        if math.isnan(class_min):
            LOGGER.debug('Skipping class - min is nan.')
            continue

        colour = QtGui.QColor(style_class['colour'])
        label = ''
        if 'label' in style_class:
            label = style_class['label']
        # noinspection PyCallingNonCallable
        ramp_item = QgsColorRampShader.ColorRampItem(class_max, colour, label)
        ramp_item_list.append(ramp_item)

        # Create opacity entries for this range
        transparency_percent = 0
        if 'transparency' in style_class:
            transparency_percent = int(style_class['transparency'])
        if transparency_percent > 0:
            # Check if range extrema are integers so we know if we can
            # use them to calculate a value range
            # noinspection PyCallingNonCallable
            pixel = QgsRasterTransparency.TransparentSingleValuePixel()
            pixel.min = class_min
            # We want it just a little bit smaller than max
            # so that ranges are discrete
            pixel.max = class_max
            # noinspection PyPep8Naming
            pixel.percentTransparent = transparency_percent
            transparency_list.append(pixel)

    band = 1  # gdal counts bands from base 1
    LOGGER.debug('Setting colour ramp list')
    raster_shader = QgsRasterShader()
    color_ramp_shader = QgsColorRampShader()
    color_ramp_shader.setColorRampType(QgsColorRampShader.INTERPOLATED)
    color_ramp_shader.setColorRampItemList(ramp_item_list)
    LOGGER.debug('Setting shader function')
    raster_shader.setRasterShaderFunction(color_ramp_shader)
    LOGGER.debug('Setting up renderer')
    renderer = QgsSingleBandPseudoColorRenderer(raster_layer.dataProvider(),
                                                band, raster_shader)
    LOGGER.debug('Assigning renderer to raster layer')
    raster_layer.setRenderer(renderer)

    LOGGER.debug('Setting raster transparency list')

    renderer = raster_layer.renderer()
    transparency = QgsRasterTransparency()
    transparency.setTransparentSingleValuePixelList(transparency_list)
    renderer.setRasterTransparency(transparency)
    # For interest you can also view the list like this:
    # pix = t.transparentSingleValuePixelList()
    # for px in pix:
    #    print 'Min: %s Max %s Percent %s' % (
    #       px.min, px.max, px.percentTransparent)

    LOGGER.debug('Saving style as default')
    raster_layer.saveDefaultStyle()
    LOGGER.debug('Setting raster style done!')
    return ramp_item_list, transparency_list
    def processAlgorithm(self, parameters, context, feedback):
        ''' Here is where the processing itself takes place. '''
        #
        if not is_dependencies_satisfied:
            return {}

        # Get get input raster and check its one-band
        the_layer = self.parameterAsRasterLayer(parameters, self.THE_LAYER, context)
        #
        if not self._check_oneband(the_layer):
            self._error = self._the_strings["ERR_ONEB"]
            return {}

        # Get .clr file and check it
        clr = self.parameterAsFile(parameters, self.THE_CLR, context)
        if not self._check_clr(clr):
            self._error = self._the_strings["ERR_NOCLR"]
            return {}

        # Get raster min/max values
        provider = the_layer.dataProvider()
        ext1     = the_layer.extent()
        stats    = provider.bandStatistics(1, QgsRasterBandStats.All, ext1, 0)
        minv     = stats.minimumValue
        maxv     = stats.maximumValue
        d = (maxv - minv) / 100.

        # Scale percentages to raster values
        with codecs.open(clr, 'r', 'utf-8') as fi:
            buff = fi.readlines()
        # 0.00000000000000000  200  215  133  255
        ar = []
        for e in buff[2:]:
            br = e[:-1].split()
            v = float(br[0]) * d + minv
            ar.append([v, int(br[1]), int(br[2]), int(br[3]), int(br[4])])
            if br[0][:3] == '100':
                # end of colour ramp
                break

        # Style raster
        fcn = qRS()
        fcn.setColorRampType(qRS.Interpolated)
        lst = []
        for e in ar:
            lst.append(qRS.ColorRampItem(e[0],QColor(int(e[1]), int(e[2]), int(e[3]),
                                                     int(e[4])),str(e[0])))
        fcn.setColorRampItemList(lst)
        try:
            shader = QgsRasterShader()
            shader.setRasterShaderFunction(fcn)
            renderer = QgsSingleBandPseudoColorRenderer(the_layer.dataProvider(), 
                                                        the_layer.type(), shader)
            the_layer.setRenderer(renderer)
            the_layer.triggerRepaint()
        except:
            pass

        # Get output file name
        output_file = self.parameterAsFileOutput(parameters, self.OUTPUT, context)
        if output_file == '':
            output_file = os.path.join(QgsProcessingUtils.tempFolder(), the_layer.name())

        # Save QGIS colour ramp file
        with codecs.open(output_file, 'w', 'utf-8') as fo:
            fo.write('# bcclr2tbl Generated Color Map Export File\n')
            fo.write('INTERPOLATION:INTERPOLATED\n')
            # 614,46,124,228,255,614
            for e in ar:
                fo.write('%.3f,%d,%d,%d,%d,%.1f\n' % (e[0], int(e[1]), int(e[2]),
                                                      int(e[3]), int(e[4]), e[0]))

        return {self.OUTPUT:output_file}
Beispiel #40
0
def cvt_vtr(self):
    QSWATMOD_path_dict = self.dirs_and_paths()
    selectedVector = self.dlg.comboBox_vector_lyrs.currentText()
    layer = QgsProject.instance().mapLayersByName(str(selectedVector))[0]

    # Find .dis file and read number of rows, cols, x spacing, and y spacing (not allowed to change)
    for filename in glob.glob(str(QSWATMOD_path_dict['SMfolder']) + "/*.dis"):
        with open(filename, "r") as f:
            data = []
            for line in f.readlines():
                if not line.startswith("#"):
                    data.append(line.replace('\n', '').split())
        nrow = int(data[0][1])
        ncol = int(data[0][2])
        delr = float(data[2][1])  # is the cell width along rows (y spacing)
        delc = float(
            data[3][1])  # is the cell width along columns (x spacing).

    # get extent
    ext = layer.extent()
    xmin = ext.xMinimum()
    xmax = ext.xMaximum()
    ymin = ext.yMinimum()
    ymax = ext.yMaximum()
    extent = "{a},{b},{c},{d}".format(a=xmin, b=xmax, c=ymin, d=ymax)

    fdnames = [
        field.name() for field in layer.dataProvider().fields()
        if not (field.name() == 'fid' or field.name() == 'id'
                or field.name() == 'xmin' or field.name() == 'xmax'
                or field.name() == 'ymin' or field.name() == 'ymax'
                or field.name() == 'grid_id' or field.name() == 'row'
                or field.name() == 'col' or field.name() == 'elev_mf')
    ]

    # Create swatmf_results tree inside
    root = QgsProject.instance().layerTreeRoot()
    if root.findGroup("swatmf_results"):
        swatmf_results = root.findGroup("swatmf_results")
    else:
        swatmf_results = root.insertGroup(0, "swatmf_results")

    if root.findGroup(selectedVector):
        rastergroup = root.findGroup(selectedVector)
    else:
        rastergroup = swatmf_results.insertGroup(0, selectedVector)
    per = 0
    self.dlg.progressBar_cvt_vtr.setValue(0)
    for fdnam in fdnames:
        QCoreApplication.processEvents()
        nodata = float(self.dlg.lineEdit_nodata.text())
        mincolor = self.dlg.mColorButton_min_rmap.color().name()
        maxcolor = self.dlg.mColorButton_max_rmap.color().name()
        name = fdnam
        name_ext = "{}.tif".format(name)
        output_dir = QSWATMOD_path_dict['SMshps']
        # create folder for each layer output
        rasterpath = os.path.join(output_dir, selectedVector)
        if not os.path.exists(rasterpath):
            os.makedirs(rasterpath)
        output_raster = os.path.join(rasterpath, name_ext)
        params = {
            'INPUT': layer,
            'FIELD': fdnam,
            'UNITS': 1,
            'WIDTH': delc,
            'HEIGHT': delr,
            'EXTENT': extent,
            'NODATA': nodata,
            'DATA_TYPE': 5,  #Float32
            'OUTPUT': output_raster
        }
        processing.run("gdal:rasterize", params)
        rasterlayer = QgsRasterLayer(output_raster,
                                     '{0} ({1})'.format(fdnam, selectedVector))
        QgsProject.instance().addMapLayer(rasterlayer, False)
        rastergroup.insertChildNode(0, QgsLayerTreeLayer(rasterlayer))
        stats = rasterlayer.dataProvider().bandStatistics(
            1, QgsRasterBandStats.All)
        rmin = stats.minimumValue
        rmax = stats.maximumValue
        fnc = QgsColorRampShader()
        lst = [
            QgsColorRampShader.ColorRampItem(rmin, QColor(mincolor)),
            QgsColorRampShader.ColorRampItem(rmax, QColor(maxcolor))
        ]
        fnc.setColorRampItemList(lst)
        fnc.setColorRampType(QgsColorRampShader.Interpolated)
        shader = QgsRasterShader()
        shader.setRasterShaderFunction(fnc)
        renderer = QgsSingleBandPseudoColorRenderer(rasterlayer.dataProvider(),
                                                    1, shader)
        rasterlayer.setRenderer(renderer)
        rasterlayer.triggerRepaint()

        # create image
        img = QImage(QSize(800, 800), QImage.Format_ARGB32_Premultiplied)
        # set background color
        # bcolor = QColor(255, 255, 255, 255)
        bcolor = QColor(255, 255, 255, 0)
        img.fill(bcolor.rgba())
        # create painter
        p = QPainter()
        p.begin(img)
        p.setRenderHint(QPainter.Antialiasing)
        # create map settings
        ms = QgsMapSettings()
        ms.setBackgroundColor(bcolor)

        # set layers to render
        flayer = QgsProject.instance().mapLayersByName(rasterlayer.name())
        ms.setLayers([flayer[0]])

        # set extent
        rect = QgsRectangle(ms.fullExtent())
        rect.scale(1.1)
        ms.setExtent(rect)

        # set ouptut size
        ms.setOutputSize(img.size())

        # setup qgis map renderer
        render = QgsMapRendererCustomPainterJob(ms, p)
        render.start()
        render.waitForFinished()
        # get timestamp
        p.drawImage(QPoint(), img)
        pen = QPen(Qt.red)
        pen.setWidth(2)
        p.setPen(pen)

        font = QFont()
        font.setFamily('Times')
        # font.setBold(True)
        font.setPointSize(18)
        p.setFont(font)
        # p.setBackground(QColor('sea green')) doesn't work
        p.drawText(QRect(0, 0, 800, 800), Qt.AlignRight | Qt.AlignBottom,
                   fdnam)
        p.end()

        # save the image
        img.save(os.path.join(rasterpath, '{:03d}_{}.jpg'.format(per, fdnam)))

        # Update progress bar
        per += 1
        progress = round((per / len(fdnames)) * 100)
        self.dlg.progressBar_cvt_vtr.setValue(progress)
        QCoreApplication.processEvents()
        self.dlg.raise_()

    duration = self.dlg.doubleSpinBox_ani_r_time.value()

    # filepaths
    fp_in = os.path.join(rasterpath, '*.jpg')
    fp_out = os.path.join(rasterpath, '{}.gif'.format(selectedVector))

    # https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#gif
    fimg, *fimgs = [Image.open(f) for f in sorted(glob.glob(fp_in))]
    fimg.save(fp=fp_out,
              format='GIF',
              append_images=fimgs,
              save_all=True,
              duration=duration * 1000,
              loop=0,
              transparency=0)

    msgBox = QMessageBox()
    msgBox.setWindowIcon(QtGui.QIcon(':/QSWATMOD2/pics/sm_icon.png'))
    msgBox.setWindowTitle("Coverted!")
    msgBox.setText(
        "Fields from {} were converted successfully!".format(selectedVector))
    msgBox.exec_()

    questionBox = QMessageBox()
    questionBox.setWindowIcon(QtGui.QIcon(':/QSWATMOD2/pics/sm_icon.png'))
    reply = QMessageBox.question(questionBox, 'Open?',
                                 'Do you want to open the animated gif file?',
                                 QMessageBox.Yes, QMessageBox.No)
    if reply == QMessageBox.Yes:
        os.startfile(os.path.join(rasterpath, '{}.gif'.format(selectedVector)))
Beispiel #41
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        log = feedback.setProgressText
        input_lulc_source_index = self.parameterAsEnum(parameters,
                                                       self.INPUT_LULC_SOURCE,
                                                       context)
        input_lulc_source = self.LULC_SOURCES[input_lulc_source_index]
        input_raster = self.parameterAsRasterLayer(parameters,
                                                   self.INPUT_RASTER, context)
        input_esv_field_index = self.parameterAsEnum(parameters,
                                                     self.INPUT_ESV_FIELD,
                                                     context)
        input_esv_field = self.INPUT_ESV_FIELD_OPTIONS[input_esv_field_index]
        input_esv_stat_index = self.parameterAsEnum(parameters,
                                                    self.INPUT_ESV_STAT,
                                                    context)
        input_esv_stat_full_name = self.STATS[input_esv_stat_index]
        input_esv_stat = self.STATS_MAP[input_esv_stat_full_name]
        output_raster_destination = self.parameterAsOutputLayer(
            parameters, self.OUTPUT_RASTER, context)
        result = {self.OUTPUT_RASTER: output_raster_destination}

        #  // STEP 1. Check output file format to make sure it is a geotiff //
        output_format = QgsRasterFileWriter.driverForExtension(
            splitext(output_raster_destination)[1])

        if not output_format or output_format.lower() != "gtiff":
            error_message = "CRITICAL: Currently only GeoTIFF output format allowed, exiting!"
            feedback.reportError(error_message)
            return ({'error': error_message})
        else:
            message = "Output file is GeoTIFF. Check"
            log(message)

        #  // STEP 2. Make instance of LULC dataset from clipped layer here //
        LULC_raster = LULC_dataset(input_lulc_source, input_raster)

        # Check to make sure all land use codes are valid
        valid = LULC_raster.is_valid()
        if isinstance(valid, str):
            #If is instance returns a string it is not valid. The string contains the error message
            error_message = valid
            feedback.reportError(error_message)
            return {'error': error_message}

        #  // STEP 3. Reclassification //
        # Get reclassify table for selected parameters
        ESV_data = ESV_dataset()
        reclass_table = ESV_data.make_reclassify_table(LULC_raster.cell_size(),
                                                       input_lulc_source,
                                                       input_esv_stat,
                                                       input_esv_field)

        # Perform reclassification
        reclassify_params = {
            'INPUT_RASTER': input_raster,
            'RASTER_BAND': 1,
            'TABLE': reclass_table,
            'NO_DATA': -9999,
            'RANGE_BOUNDARIES': 0,
            'NODATA_FOR_MISSING': True,
            'DATA_TYPE': 6,
            'OUTPUT': output_raster_destination
        }

        processing.run("native:reclassifybytable", reclassify_params)

        #must add raster to iface so that is becomes active layer, then symbolize it in next step
        output_raster = QgsRasterLayer(output_raster_destination)
        iface.addRasterLayer(output_raster_destination)

        #grabs active layer and data from that layer
        layer = iface.activeLayer()
        provider = layer.dataProvider()
        extent = layer.extent()

        raster_stats = provider.bandStatistics(1, QgsRasterBandStats.All)

        #   // STEP 4. Symbolize output layer //
        log("Symbolizing Output Layer")

        #creates raster shader and creates discrete color ramp
        raster_shader = QgsColorRampShader()
        raster_shader.setColorRampType(QgsColorRampShader.Discrete)

        #creates layer symbology from raster_stats data
        raster_stats = provider.bandStatistics(1, QgsRasterBandStats.All)
        symbology = Symbology(raster_stats, input_esv_field)
        colors_list = symbology.symbolize_input_raster()

        raster_shader.setColorRampItemList(
            colors_list)  #applies symbology to raster_shader
        shader = QgsRasterShader()
        shader.setRasterShaderFunction(raster_shader)

        renderer = QgsSingleBandPseudoColorRenderer(
            layer.dataProvider(), 1, shader)  #renders selected raster layer
        layer.setRenderer(renderer)
        layer.triggerRepaint()

        log(self.tr(f"Adding final raster to map."))
        #need to add result from gdal:rastercalculator to map (doesn't happen automatically)

        log(self.tr("Done!\n"))

        # Return the results of the algorithm. In this case our only result is
        # the feature sink which contains the processed features, but some
        # algorithms may return multiple feature sinks, calculated numeric
        # statistics, etc. These should all be included in the returned
        # dictionary, with keys matching the feature corresponding parameter
        # or output names.
        return result
Beispiel #42
0
def set_raster_style(raster_layer, style):
    """Set QGIS raster style based on InaSAFE style dictionary for QGIS >= 2.0.

    This function will set both the colour map and the transparency
    for the passed in layer.

    :param raster_layer: A QGIS raster layer that will be styled.
    :type raster_layer: QgsVectorLayer

    :param style: List of the form as in the example below.
    :type style: list

    Example::

        style_classes = [dict(colour='#38A800', quantity=2, transparency=0),
                         dict(colour='#38A800', quantity=5, transparency=50),
                         dict(colour='#79C900', quantity=10, transparency=50),
                         dict(colour='#CEED00', quantity=20, transparency=50),
                         dict(colour='#FFCC00', quantity=50, transparency=34),
                         dict(colour='#FF6600', quantity=100, transparency=77),
                         dict(colour='#FF0000', quantity=200, transparency=24),
                         dict(colour='#7A0000', quantity=300, transparency=22)]

    :returns: A two tuple containing a range list and a transparency list.
    :rtype: (list, list)

    """
    # Note imports here to prevent importing on unsupported QGIS versions
    # pylint: disable=E0611
    # pylint: disable=W0621
    # pylint: disable=W0404
    # noinspection PyUnresolvedReferences
    from qgis.core import (QgsRasterShader,
                           QgsColorRampShader,
                           QgsSingleBandPseudoColorRenderer,
                           QgsRasterTransparency)
    # pylint: enable=E0611
    # pylint: enable=W0621
    # pylint: enable=W0404

    ramp_item_list = []
    transparency_list = []
    LOGGER.debug(style)
    for style_class in style:

        LOGGER.debug('Evaluating class:\n%s\n' % style_class)

        if 'quantity' not in style_class:
            LOGGER.exception('Class has no quantity attribute')
            continue

        class_max = style_class['max']
        if math.isnan(class_max):
            LOGGER.debug('Skipping class - max is nan.')
            continue

        class_min = style_class['min']
        if math.isnan(class_min):
            LOGGER.debug('Skipping class - min is nan.')
            continue

        colour = QtGui.QColor(style_class['colour'])
        label = ''
        if 'label' in style_class:
            label = style_class['label']
        # noinspection PyCallingNonCallable
        ramp_item = QgsColorRampShader.ColorRampItem(class_max, colour, label)
        ramp_item_list.append(ramp_item)

        # Create opacity entries for this range
        transparency_percent = 0
        if 'transparency' in style_class:
            transparency_percent = int(style_class['transparency'])
        if transparency_percent > 0:
            # Check if range extrema are integers so we know if we can
            # use them to calculate a value range
            # noinspection PyCallingNonCallable
            pixel = QgsRasterTransparency.TransparentSingleValuePixel()
            pixel.min = class_min
            # We want it just a little bit smaller than max
            # so that ranges are discrete
            pixel.max = class_max
            # noinspection PyPep8Naming
            pixel.percentTransparent = transparency_percent
            transparency_list.append(pixel)

    band = 1  # gdal counts bands from base 1
    LOGGER.debug('Setting colour ramp list')
    raster_shader = QgsRasterShader()
    color_ramp_shader = QgsColorRampShader()
    color_ramp_shader.setColorRampType(QgsColorRampShader.INTERPOLATED)
    color_ramp_shader.setColorRampItemList(ramp_item_list)
    LOGGER.debug('Setting shader function')
    raster_shader.setRasterShaderFunction(color_ramp_shader)
    LOGGER.debug('Setting up renderer')
    renderer = QgsSingleBandPseudoColorRenderer(
        raster_layer.dataProvider(),
        band,
        raster_shader)
    LOGGER.debug('Assigning renderer to raster layer')
    raster_layer.setRenderer(renderer)

    LOGGER.debug('Setting raster transparency list')

    renderer = raster_layer.renderer()
    transparency = QgsRasterTransparency()
    transparency.setTransparentSingleValuePixelList(transparency_list)
    renderer.setRasterTransparency(transparency)
    # For interest you can also view the list like this:
    # pix = t.transparentSingleValuePixelList()
    # for px in pix:
    #    print 'Min: %s Max %s Percent %s' % (
    #       px.min, px.max, px.percentTransparent)

    LOGGER.debug('Saving style as default')
    raster_layer.saveDefaultStyle()
    LOGGER.debug('Setting raster style done!')
    return ramp_item_list, transparency_list
Beispiel #43
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        log = feedback.setProgressText
        input_raster = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
        input_nodata_value = self.INPUT_NODATA_VALUE
        input_esv_field_index = self.parameterAsEnum(parameters, self.INPUT_ESV_FIELD, context)
        input_esv_field = self.INPUT_ESV_FIELD_OPTIONS[input_esv_field_index]
        input_esv_stat_index = self.parameterAsEnum(parameters, self.INPUT_ESV_STAT, context)
        input_esv_stat = self.STATS[input_esv_stat_index]

        log(f"ESV chosen: {input_esv_field}")

        #Labeling output layer in legend        
        if isinstance(parameters['OUTPUT_RASTER'], QgsProcessingOutputLayerDefinition):
            if input_esv_field != 'protection from extreme events':         #'protection from exteme events' is too long for legend in step 3 so it is shortened here
                if input_esv_stat == 'min':
                    setattr(parameters['OUTPUT_RASTER'], 'destinationName', f'Minimum Value - {input_esv_field}')
                elif input_esv_stat == 'max':
                    setattr(parameters['OUTPUT_RASTER'], 'destinationName', f'Maximum Value - {input_esv_field}')
                elif input_esv_stat == 'mean':
                    setattr(parameters['OUTPUT_RASTER'], 'destinationName', f'Mean Value - {input_esv_field}')
            else:
                if input_esv_stat == 'min':
                    setattr(parameters['OUTPUT_RASTER'], 'destinationName', f'Minimum Value - extreme event protection')
                elif input_esv_stat == 'max':
                    setattr(parameters['OUTPUT_RASTER'], 'destinationName', f'Maximum Value - extreme event protection')
                elif input_esv_stat == 'mean':
                    setattr(parameters['OUTPUT_RASTER'], 'destinationName', f'Mean Value - extreme event protection')


        output_raster_destination = self.parameterAsOutputLayer(parameters, self.OUTPUT_RASTER, context)
        result = {self.OUTPUT_RASTER: output_raster_destination}

        # Check that the input raster is in the right CRS
        input_raster_crs = input_raster.crs().authid()
        if input_raster_crs == "EPSG:102003":
            log("The input raster is in the right CRS: EPSG:102003. Check")
        else:
            error_message = "The input raster isn't in the right CRS. It must be in EPSG:102003. The one you input was in " + str(input_raster_crs) + "."
            feedback.reportError(error_message)
            log("")
            return {'error': error_message}

        # Check that the input raster has the right pixel size
        units_per_pixel_x = input_raster.rasterUnitsPerPixelX()
        units_per_pixel_y = input_raster.rasterUnitsPerPixelY()
        if units_per_pixel_x != 30 or units_per_pixel_y != 30:
            if round(units_per_pixel_x) == 30 and round(units_per_pixel_y) == 30:
                feedback.pushDebugInfo("Your input raster pixels weren't exactly 30x30 meters, but were close enough that the program will continue to run. Your input raster pixels were " + str(units_per_pixel_x) + "x" + str(units_per_pixel_y) + ".")
            else:
                error_message = "The input raster should have 30x30 meter pixels. The one you input has " + str(units_per_pixel_x) + "x" + str(units_per_pixel_y) + "."
                feedback.reportError(error_message)
                log("")
                return {'error': error_message}
        else:
            log("The input raster's pixel size is correct: 30x30. Check")

        input_esv_table = self.parameterAsSource(parameters, self.INPUT_ESV_TABLE, context)

        # Check to make sure the input ESV table has at least 4 columns
        input_esv_table_col_names = input_esv_table.fields().names()
        if len(input_esv_table_col_names) <= 4:
            feedback.reportError("The Input ESV table should have at least 5 columns, the one you input only has " + str(len(input_esv_table_col_names)))
            log("")
            return result
        else:
            log("Input ESV table has at least 5 columns. Check")

        # Check to make sure the input ESV table appears to have columns with ESV stats
        stats = ['min', 'mean', 'max']
        input_esv_table_esv_stat_col_names = input_esv_table_col_names[4:]
        input_esv_table_name_stats = []
        for name in input_esv_table_esv_stat_col_names:
            if len(name.split('_', 1)) > 1:
                input_esv_table_name_stats.append(name.split('_', 1)[1])
            else:
                feedback.reportError("One or more of the columns in your Input ESV table doesn't appear to be an ESV stat. Columns 5 through the last column should all have an underscore between the ecosystem service and the statistic, e.g. aesthetic_min.")
                log("")
                return result
        if all(str(i) in stats for i in input_esv_table_name_stats):
            log("The table appears to include ESV stats columns. Check")
        else:
            feedback.reportError("One or more of the columns in your Input ESV table doesn't appear to be an ESV stat. Columns 5 through the last column should all end with \"_min\", \"_mean\", or \"_max\".")
            log("")
            return result

        # Check output format
        output_format = QgsRasterFileWriter.driverForExtension(splitext(output_raster_destination)[1])
        if not output_format or output_format.lower() != "gtiff":
            log("CRITICAL: Currently only GeoTIFF output format allowed, exiting!")
            return result

        raster_value_mapping_dict = {}

        input_esv_table_features = input_esv_table.getFeatures()

        nlcd_codes = ['11', '21', '22', '23', '24', '31', '41', '42', '43', '52', '71', '81', '82', '90', '95']

        for input_esv_table_feature in input_esv_table_features:
            nlcd_code = input_esv_table_feature.attributes()[0]
            # Check to make sure this is a legit nlcd code. If it's not throw and error and abort the alg
            if nlcd_code not in nlcd_codes:
                error_message = "Found a value in the first column of the input ESV table that isn't a legitimate NLCD code: " + str(nlcd_code) + ". All the values in the first column of the input ESV table must be one of these: " + str(nlcd_codes)
                feedback.reportError(error_message)
                log("")
                return {'error': error_message}
            try:
                selected_esv = input_esv_table_feature.attribute(input_esv_field.lower().replace(" ", "-").replace(",", "") + "_" + input_esv_stat)
            except KeyError:
                feedback.reportError("The Input ESV field you specified (" + input_esv_field + "_" + input_esv_stat + ") doesn't exist in this dataset. Please enter one of the fields that does exist: ")
                feedback.pushDebugInfo(str(input_esv_table.fields().names()[4:]))
                log("")
                return result
            # If there is no ESV for tis particular NLCD-ES combo Then
            # the cell will be Null (i.e. None) and so we're dealing with
            # that below by setting the value to 255, which is the value
            # of the other cells that don't have values (at least for this
            # data)
            if selected_esv is None:
                selected_esv = input_nodata_value
            # If it's not null then we need to convert the total ESV for
            # the whole area covered by that land cover (which is in USD/hectare)
            # to the per pixel ESV (USD/pixel)
            else:
                num_pixels = input_esv_table_feature.attributes()[2]
                selected_esv = int(selected_esv[1:].replace(',', '')) / int(num_pixels)
            raster_value_mapping_dict.update({int(nlcd_code): selected_esv})

        # Create a new raster whose pixel values are, instead of being NLCD code values, the per-pixel ecosystem service values corresponding to the NLCD codes
        log(self.tr("Reading input raster into numpy array ..."))
        grid = Raster.to_numpy(input_raster, band=1, dtype='int64')
        # Check to make sure the input raster is an NLCD raster, i.e. has the right kinds of pixel values
        unique_pixel_values_of_input_raster = np.unique(grid)
        nlcd_codes.append(str(input_nodata_value))
        if all(str(i) in nlcd_codes for i in unique_pixel_values_of_input_raster):
            log("The input raster has the correct NLCD codes for pixel values. Check")
        else:
            error_message = "The input raster's pixels aren't all legitimate NLCD codes. They must all be one of these values: " + str(nlcd_codes) + ". The raster you input had these values: " + str(unique_pixel_values_of_input_raster)
            feedback.reportError(error_message)
            log("")
            return {'error': error_message}
        log(self.tr("Array read"))
        log(self.tr("Mapping values"))
        output_array = copy(grid)
        for key, value in raster_value_mapping_dict.items():
            if feedback.isCanceled():
                return result
            output_array[grid == key] = value
        log(self.tr("Values mapped"))
        
        Raster.numpy_to_file(output_array, output_raster_destination, src=str(input_raster.source()))
        
        log(self.tr("Reclassifying 255 (no data value) to 0 with GDAL: Raster Calculator."))
        
        parameters = {'INPUT_A' : output_raster_destination,
                      'BAND_A' : 1,
                      'FORMULA' : '(A != 255) * A',
                      'OUTPUT' : output_raster_destination}
        
        processing.run('gdal:rastercalculator', parameters)
        
        #must add raster to iface so that is becomes active layer, then symbolize it in next step
        iface.addRasterLayer(output_raster_destination)
        log("Symbolizing Output")
        
        #this symbolizes the raster layer in the map
        layer = iface.activeLayer()
        provider = layer.dataProvider()
        extent = layer.extent()
        #Using RasterBandStats to find range of values in raster layer
        raster_stats = provider.bandStatistics(1, QgsRasterBandStats.All) 
        min_val = raster_stats.minimumValue            #minimum pixel value in layer
        max_val = raster_stats.maximumValue            #maximum pixel value in layer

        value_range = list(range(int(min_val), int(max_val+1)))           #Range of values in raster layer. Without +1 doesn't capture highest value
        value_range.sort()
        for value in value_range:                   #deletes 0 value from value range so as not to skew shading in results
            if value < raster_stats.minimumValue:
                del value

        #we will categorize pixel values into 5 quintiles, based on value_range of raster layer
        #defining min and max values for each quintile. 
        #Also, values are rounded to 2 decimal places
        first_quintile_max = round(np.percentile(value_range, 20), 2)
        first_quintile_min = round(min_val, 2)
        second_quintile_max = round(np.percentile(value_range, 40), 2)
        second_quintile_min = round((first_quintile_max + .01), 2)
        third_quintile_max = round(np.percentile(value_range, 60), 2)
        third_quintile_min = round((second_quintile_max + .01), 2)
        fourth_quintile_max = round(np.percentile(value_range, 80), 2)
        fourth_quintile_min = round((third_quintile_max + .01), 2)
        fifth_quintile_max = round(np.percentile(value_range, 100), 2)
        fifth_quintile_min = round((fourth_quintile_max + .01), 2)


        #builds raster shader with colors_list. Most ESVs have unique colors. 
        
        #green color ramp
        if input_esv_field == 'aesthetic':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(204, 255, 204), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(153, 255, 153), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(51, 255, 51), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(0, 204, 0), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(0, 102, 0), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]

        #light blue color ramp
        elif input_esv_field == 'air quality':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(204, 255, 255), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(153, 255, 255), f"${second_quintile_min} - {second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(51, 255, 255), f"${third_quintile_min} - {third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(0, 204, 204), f"${fourth_quintile_min} - {fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(0,102,102), f"${fifth_quintile_min} - {fifth_quintile_max}0")]
            
        #green color ramp
        elif input_esv_field == 'biodiversity':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(204, 255, 229), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(153, 255, 204), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(51, 255, 153), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(0, 204, 102), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(0, 102, 51), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]
        
        #orange color ramp
        elif input_esv_field == 'climate regulation':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(255, 229, 204), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(255, 204, 153), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(255, 153, 51), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(204, 102, 0), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(102, 51, 0), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]
        
        #orange color ramp
        elif input_esv_field == 'cultural, Other':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(255, 229, 204), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(255, 204, 153), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(255, 153, 51), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(204, 102, 0), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(102, 51, 0), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]
        
        #brown color ramp
        elif input_esv_field == 'erosion control':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(220,187,148), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(198,168,134), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(169,144,115), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(138,117,93), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(100,85,67), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]
        
        #pink color ramp
        elif input_esv_field == 'food/nutrition':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(255,204,229), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(255,153,204), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(255,51,153), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(204,0,102), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(102,0,51), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]        

        #pink color ramp
        elif input_esv_field == 'medicinal':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(255,204,229), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(255,153,204), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(255,51,153), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(204,0,102), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(102,0,51), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]


        #yellow color ramp
        elif input_esv_field == 'pollination':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(255,255,204), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(255,255,153), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(255,255,51), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(204,204,0), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(102,102,0), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]        

        #gray/black color ramp
        elif input_esv_field == 'protection from extreme events':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(224,224,224), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(192,192,192), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(128,128,128), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(64,64,64), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(0,0,0), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]       
        
        #purple color ramp
        elif input_esv_field == 'raw materials':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(229,204,255), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(204,153,255), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(153,51,255), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(102,0,204), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(51,0,102), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]
        
        #red color ramp
        elif input_esv_field == 'recreation':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(255,102,102), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(255,51,51), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(255,0,0), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(204,0,0), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(153,0,0), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]

        #red color ramp
        elif input_esv_field == 'renewable energy':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(255,102,102), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(255,51,51), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(255,0,0), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(204,0,0), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(153,0,0), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]

        
        #brown color ramp
        elif input_esv_field == 'soil formation':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(220,187,148), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(198,168,134), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(169,144,115), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(138,117,93), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(100,85,67), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]       
        
        #blue/purple color ramp
        elif input_esv_field == 'waste assimilation':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(204,204,255), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(153,153,255), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(51,51,255), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(0,0,204), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(0,0,102), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]
        
        #medium blue color ramp
        elif input_esv_field == 'water supply':
            raster_shader = QgsColorRampShader()
            raster_shader.setColorRampType(QgsColorRampShader.Discrete)           #Shading raster layer with QgsColorRampShader.Discrete
            colors_list = [ QgsColorRampShader.ColorRampItem(0, QColor(255, 255, 255, .5), 'No Value'), \
                       QgsColorRampShader.ColorRampItem(first_quintile_max, QColor(204,229,255), f"${first_quintile_min}0 - ${first_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(second_quintile_max, QColor(153,204,255), f"${second_quintile_min} - ${second_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(third_quintile_max, QColor(51,153,205), f"${third_quintile_min} - ${third_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fourth_quintile_max, QColor(0,102,204), f"${fourth_quintile_min} - ${fourth_quintile_max}0"), \
                       QgsColorRampShader.ColorRampItem(fifth_quintile_max, QColor(0,51,102), f"${fifth_quintile_min} - ${fifth_quintile_max}0")]       
        
        raster_shader.setColorRampItemList(colors_list)         #applies colors_list to raster_shader
        shader = QgsRasterShader()
        shader.setRasterShaderFunction(raster_shader)       

        renderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 1, shader)    #renders selected raster layer
        layer.setRenderer(renderer)
        layer.triggerRepaint()
        
        
        log(self.tr(f"Adding final raster to map."))
        #need to add result from gdal:rastercalculator to map (doesn't happen automatically)
        
        
        log(self.tr("Done!\n"))

        # Return the results of the algorithm. In this case our only result is
        # the feature sink which contains the processed features, but some
        # algorithms may return multiple feature sinks, calculated numeric
        # statistics, etc. These should all be included in the returned
        # dictionary, with keys matching the feature corresponding parameter
        # or output names.
        return result
Beispiel #44
0
    def processAlgorithm(self, parameters, context, feedback):
        # get input variables
        raster = self.parameterAsFile(parameters, self.INPUT, context)
        color_ramp = self.parameterAsEnum(parameters, self.COLORRAMP, context)
        colors = self.color_ramps[self.colors_list[color_ramp]]
        min = self.parameterAsInt(parameters, self.MIN, context)
        max = self.parameterAsInt(parameters, self.MAX, context)
        z_pos_down = self.parameterAsBoolean(parameters, self.Z_POS_DOWN,
                                             context)

        # set new default values in config
        feedback.pushConsoleInfo(
            self.tr(f'Storing new default settings in config...'))
        self.config.set(self.module, 'min', min)
        self.config.set(self.module, 'max', max)
        self.config.set(self.module, 'color_ramp', color_ramp)

        # get file info
        base_path, base_name, ext = utils.get_info_from_path(raster)

        # BATHY:
        # load grid
        feedback.pushConsoleInfo(
            self.tr(f'Creating new raster layer [ {base_name} ]...'))
        dem_layer = QgsRasterLayer(raster, base_name)

        # test if the files loads properly
        if not dem_layer.isValid():
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        # create color scale values
        feedback.pushConsoleInfo(self.tr(f'Creating color ramp...'))
        n_values = len(colors)
        width = max - min
        step = width / (n_values - 1)
        values = []
        value = min
        for i in range(n_values):
            values.append(value)
            value = value + step

        # create color_ramp
        ramp = []
        for i, item in enumerate(colors):
            ramp.append(
                QgsColorRampShader.ColorRampItem(values[i], QColor(str(item)),
                                                 str(values[i])))
        color_ramp = QgsColorRampShader()
        color_ramp.setColorRampItemList(ramp)
        color_ramp.setColorRampType(QgsColorRampShader.Interpolated)

        # create shader and set color_ramp
        feedback.pushConsoleInfo(self.tr(f'Creating raster shader...'))
        shader = QgsRasterShader()
        shader.setRasterShaderFunction(color_ramp)

        # create renderer
        feedback.pushConsoleInfo(self.tr(f'Creating raster renderer...'))
        renderer = QgsSingleBandPseudoColorRenderer(dem_layer.dataProvider(),
                                                    dem_layer.type(), shader)

        # set min max values
        renderer.setClassificationMin(min)
        renderer.setClassificationMax(max)

        # apply renderer to layer
        dem_layer.setRenderer(renderer)

        # apply brightness & contrast of layer
        feedback.pushConsoleInfo(self.tr(f'Adjusting display filters...'))
        brightness_filter = QgsBrightnessContrastFilter()
        brightness_filter.setBrightness(-20)
        brightness_filter.setContrast(10)
        dem_layer.pipe().set(brightness_filter)

        # apply resample filter (Bilinear)
        feedback.pushConsoleInfo(self.tr(f'Setting up resampling...'))
        resample_filter = dem_layer.resampleFilter()
        resample_filter.setZoomedInResampler(QgsBilinearRasterResampler())
        resample_filter.setZoomedOutResampler(QgsBilinearRasterResampler())

        # create group with layer base_name
        feedback.pushConsoleInfo(self.tr(f'Creating layer group...'))
        root = context.project().layerTreeRoot()
        bathy_group = root.addGroup(base_name)

        # add bathy layer to group
        bathy_group.insertChildNode(1, QgsLayerTreeLayer(dem_layer))

        # add bathy layer to project
        dem_layer.triggerRepaint()
        context.project().addMapLayer(dem_layer, False)

        # 50% done
        feedback.setProgress(50)

        # HILLSHADE:
        # load grid again with layer style file style_hillshade.qml
        feedback.pushConsoleInfo(
            self.tr(
                f'Creating new hillshade layer [ {base_name}_hillshade ]...'))
        hillshade_layer = QgsRasterLayer(raster, base_name + '_hillshade')

        # if raster is geographic, load hillshade_geo style (different exaggeration)
        # if raster is Z positive down, load *_pos_down_* style
        feedback.pushConsoleInfo(self.tr(f'Setting hillshade style...\n'))
        if dem_layer.crs().isGeographic() and not z_pos_down:
            hillshade_layer.loadNamedStyle(self.style_hillshade_geo)
        elif dem_layer.crs().isGeographic() and z_pos_down:
            hillshade_layer.loadNamedStyle(self.style_hillshade_pos_down_geo)
        # else load hillste_prj style
        elif z_pos_down:
            hillshade_layer.loadNamedStyle(self.style_hillshade_pos_down_prj)
        else:
            hillshade_layer.loadNamedStyle(self.style_hillshade_prj)

        # add hillshade layer to group
        bathy_group.insertChildNode(0, QgsLayerTreeLayer(hillshade_layer))

        # add hillshade layer to project
        hillshade_layer.triggerRepaint()
        context.project().addMapLayer(hillshade_layer, False)

        # 100% done
        feedback.setProgress(100)
        feedback.pushInfo(
            self.tr(f'{utils.return_success()}! Grid loaded successfully!\n'))

        result = {
            self.GROUP: bathy_group,
            self.DEM_LAYER: dem_layer,
            self.HILLSHADE_LAYER: hillshade_layer
        }

        return result
Beispiel #45
0
class RasterSymbolizer(QgsRasterLayer):

    def __init__(self, layer):
        self.colDic = {'tan':'#ffebb0', 'green':'#267300', 'brown':'#734d00', 'white':'#ffffff',
                                'red':'#e60000', 'light gray':'#f0f0f0', 'blue':'#004cab'}
        self.shader = QgsRasterShader()
        self.ramp = QgsColorRampShader()
        self.colLst = []
        self.valLst = []
        self.labLst = []
        self.opacity = 1.0

        self.layer = layer
        self.provider = layer.dataProvider()
        extent = layer.extent()
        self.ver = self.provider.hasStatistics(1, QgsRasterBandStats.All)
        self.stats = self.provider.bandStatistics(1, QgsRasterBandStats.All, extent, 0)

    def render_GCD(self, type):

        self.setRendererOptions(type)

        self.shader.setRasterShaderFunction(self.ramp)
        renderer = QgsSingleBandPseudoColorRenderer(self.layer.dataProvider(), 1, self.shader)

        self.layer.setRenderer(renderer)
        self.layer.renderer().setOpacity(self.opacity)
        self.layer.triggerRepaint()

    def setRendererOptions(self, type):

        if type == "DEM":
            self.setValueBreaks_DEM()
            self.setColorRamp_DEM()

        elif type == "DoD":
            self.setValueBreaks_DoD()
            self.setColorRamp_DoD()

        elif type == "Slope_deg":
            self.setValueBreaks_SlopeDeg()
            self.setColorRamp_Slope()

        elif type == "Slope_per":
            self.setValueBreaks_SlopePer()
            self.setColorRamp_Slope()

        elif type == "Roughness":
            self.setValueBreaks_Roughness()
            self.setColorRamp_Roughness()

    def setValueBreaks_DEM(self):
        lo = self.stats.minimumValue
        hi = self.stats.maximumValue
        rng = hi - lo
        interval = rng/3.0
        self.valLst = [lo, lo+interval, hi-interval, hi]

    def setValueBreaks_DoD(self):
        nClasses = 20
        lo = self.stats.minimumValue
        hi = self.stats.maximumValue
        mid = 0.0

        if abs(lo) > abs(hi):
            hi = abs(lo)

        else:
            lo = hi*-1.0

        rng = hi*2.0
        interval = rng/(nClasses*1.0)

        nRound = self.magnitude(rng)

        if nRound < 0:
            nRound = abs(nRound) + 2

        else:
            nRound = 2

        self.valLst.append(lo)

        for i in range(1,nClasses+1,1):
            self.valLst.append(lo + i*interval)
            self.labLst.append(str(round(self.valLst[i-1], nRound))+" to "+str(round(self.valLst[i], nRound)))

    def setValueBreaks_SlopeDeg(self):

        self.valLst.append(self.stats.minimumValue)
        self.valLst.append(2.0)
        self.valLst.append(5.0)
        self.valLst.append(10.0)
        self.valLst.append(15.0)
        self.valLst.append(25.0)
        self.valLst.append(35.0)
        self.valLst.append(45.0)
        self.valLst.append(60.0)
        self.valLst.append(80.0)

        self.labLst.append("0 to 2")
        self.labLst.append("2 to 5")
        self.labLst.append("5 to 10")
        self.labLst.append("10 to 15")
        self.labLst.append("15 to 25")
        self.labLst.append("25 to 35")
        self.labLst.append("35 to 45")
        self.labLst.append("45 to 60")
        self.labLst.append("60 to 80")
        self.labLst.append("80 to 90")

    def setValueBreaks_SlopePer(self):
        self.valLst.append(0.0)
        self.valLst.append(3.5)
        self.valLst.append(8.75)
        self.valLst.append(15.0)
        self.valLst.append(25.0)
        self.valLst.append(45.0)
        self.valLst.append(70.0)
        self.valLst.append(100.0)
        self.valLst.append(175.0)
        self.valLst.append(565.0)

        self.labLst.append("0 to 3.5%")
        self.labLst.append("3.5% to 8.75%")
        self.labLst.append("8.75% to 15%")
        self.labLst.append("15% to 25%")
        self.labLst.append("25% to 45%")
        self.labLst.append("45% to 70%")
        self.labLst.append("70% to 100%")
        self.labLst.append("100% to 175%")
        self.labLst.append("175% to 565%")
        self.labLst.append("> 565%")

    def setValueBreaks_Roughness(self):
        self.valLst.append(0)
        self.valLst.append(2)
        self.valLst.append(16)
        self.valLst.append(64)
        self.valLst.append(256)

        self.labLst.append("Fines, Sand (0 to 2 mm)")
        self.labLst.append("Fine Gravel (2 mm to 16 mm)")
        self.labLst.append("Coarse Gravel (16 mm to 64 mm)")
        self.labLst.append("Cobbles (64 mm to 256 mm)")
        self.labLst.append("Boulders (> 256 mm)")

    def setColorRamp_DEM(self):

        self.colLst = [QgsColorRampShader.ColorRampItem(self.valLst[0], QColor(self.colDic['tan']), str(self.valLst[0])),
                           QgsColorRampShader.ColorRampItem(self.valLst[1], QColor(self.colDic['green']), str(self.valLst[1])),
                           QgsColorRampShader.ColorRampItem(self.valLst[2], QColor(self.colDic['brown']), str(self.valLst[2])),
                           QgsColorRampShader.ColorRampItem(self.valLst[3], QColor(self.colDic['white']), str(self.valLst[3]))]

        self.ramp.setColorRampItemList(self.colLst)
        self.ramp.setColorRampType(QgsColorRampShader.INTERPOLATED)
        self.opacity = 0.6

    def setColorRamp_DoD(self):

        self.colLst = [QgsColorRampShader.ColorRampItem(self.valLst[0], QColor(230,0,0), self.labLst[0]),
                       QgsColorRampShader.ColorRampItem(self.valLst[1], QColor(235,45,23), self.labLst[1]),
                       QgsColorRampShader.ColorRampItem(self.valLst[2], QColor(240,67,41), self.labLst[2]),
                       QgsColorRampShader.ColorRampItem(self.valLst[3], QColor(242,88,61), self.labLst[3]),
                       QgsColorRampShader.ColorRampItem(self.valLst[4], QColor(245,108,81), self.labLst[4]),
                       QgsColorRampShader.ColorRampItem(self.valLst[5], QColor(245,131,105), self.labLst[5]),
                       QgsColorRampShader.ColorRampItem(self.valLst[6], QColor(245,151,130), self.labLst[6]),
                       QgsColorRampShader.ColorRampItem(self.valLst[7], QColor(242,171,155), self.labLst[7]),
                       QgsColorRampShader.ColorRampItem(self.valLst[8], QColor(237,190,180), self.labLst[8]),
                       QgsColorRampShader.ColorRampItem(self.valLst[9], QColor(230,208,207), self.labLst[9]),
                       QgsColorRampShader.ColorRampItem(self.valLst[10], QColor(218,218,224), self.labLst[10]),
                       QgsColorRampShader.ColorRampItem(self.valLst[11], QColor(197,201,219), self.labLst[11]),
                       QgsColorRampShader.ColorRampItem(self.valLst[12], QColor(176,183,214), self.labLst[12]),
                       QgsColorRampShader.ColorRampItem(self.valLst[13], QColor(155,166,207), self.labLst[13]),
                       QgsColorRampShader.ColorRampItem(self.valLst[14], QColor(135,150,201), self.labLst[14]),
                       QgsColorRampShader.ColorRampItem(self.valLst[15], QColor(110,131,194), self.labLst[15]),
                       QgsColorRampShader.ColorRampItem(self.valLst[16], QColor(92,118,189), self.labLst[16]),
                       QgsColorRampShader.ColorRampItem(self.valLst[17], QColor(72,105,184), self.labLst[17]),
                       QgsColorRampShader.ColorRampItem(self.valLst[18], QColor(49,91,176), self.labLst[18]),
                       QgsColorRampShader.ColorRampItem(self.valLst[19], QColor(2,7,168), self.labLst[19])]

        self.ramp.setColorRampItemList(self.colLst)
        self.ramp.setColorRampType(QgsColorRampShader.DISCRETE)

    def setColorRamp_Slope(self):
        self.colLst = [QgsColorRampShader.ColorRampItem(self.valLst[0], QColor(255,235,176), self.labLst[0]),
                       QgsColorRampShader.ColorRampItem(self.valLst[1], QColor(255,219,135), self.labLst[1]),
                       QgsColorRampShader.ColorRampItem(self.valLst[2], QColor(255,202,97), self.labLst[2]),
                       QgsColorRampShader.ColorRampItem(self.valLst[3], QColor(255,186,59), self.labLst[3]),
                       QgsColorRampShader.ColorRampItem(self.valLst[4], QColor(255,170,0), self.labLst[4]),
                       QgsColorRampShader.ColorRampItem(self.valLst[5], QColor(255,128,0), self.labLst[5]),
                       QgsColorRampShader.ColorRampItem(self.valLst[6], QColor(255,85,0), self.labLst[6]),
                       QgsColorRampShader.ColorRampItem(self.valLst[7], QColor(255,42,0), self.labLst[7]),
                       QgsColorRampShader.ColorRampItem(self.valLst[8], QColor(161,120,120), self.labLst[8]),
                       QgsColorRampShader.ColorRampItem(self.valLst[9], QColor(130,10,130), self.labLst[9])]

        self.ramp.setColorRampItemList(self.colLst)
        self.ramp.setColorRampType(QgsColorRampShader.DISCRETE)

    def setColorRamp_Roughness(self):
        self.colLst = [QgsColorRampShader.ColorRampItem(self.valLst[0], QColor(194,82,60), self.labLst[0]),
                       QgsColorRampShader.ColorRampItem(self.valLst[1], QColor(240,180,17), self.labLst[1]),
                       QgsColorRampShader.ColorRampItem(self.valLst[2], QColor(123,237,0), self.labLst[2]),
                       QgsColorRampShader.ColorRampItem(self.valLst[3], QColor(27,168,124), self.labLst[3]),
                       QgsColorRampShader.ColorRampItem(self.valLst[4], QColor(11,44,122), self.labLst[4])]

    def magnitude(self, x):
        return int(math.floor(math.log10(x)))