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 testTransparency(self): 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 renderer = QgsSingleBandGrayRenderer(myRasterLayer.dataProvider(), 1) myRasterLayer.setRenderer(renderer) myRasterLayer.setContrastEnhancement( QgsContrastEnhancement.StretchToMinimumMaximum, QgsRasterMinMaxOrigin.MinMax) myContrastEnhancement = myRasterLayer.renderer().contrastEnhancement() # print ("myContrastEnhancement.minimumValue = %.17g" % # myContrastEnhancement.minimumValue()) # print ("myContrastEnhancement.maximumValue = %.17g" % # myContrastEnhancement.maximumValue()) # Unfortunately the minimum/maximum values calculated in C++ and Python # are slightly different (e.g. 3.3999999521443642e+38 x # 3.3999999521444001e+38) # It is not clear where the precision is lost. # We set the same values as C++. myContrastEnhancement.setMinimumValue(-3.3319999287625854e+38) myContrastEnhancement.setMaximumValue(3.3999999521443642e+38) #myType = myRasterLayer.dataProvider().dataType(1); #myEnhancement = QgsContrastEnhancement(myType); myTransparentSingleValuePixelList = [] rasterTransparency = QgsRasterTransparency() myTransparentPixel1 = \ QgsRasterTransparency.TransparentSingleValuePixel() myTransparentPixel1.min = -2.5840000772112106e+38 myTransparentPixel1.max = -1.0879999684602689e+38 myTransparentPixel1.percentTransparent = 50 myTransparentSingleValuePixelList.append(myTransparentPixel1) myTransparentPixel2 = \ QgsRasterTransparency.TransparentSingleValuePixel() myTransparentPixel2.min = 1.359999960575336e+37 myTransparentPixel2.max = 9.520000231087593e+37 myTransparentPixel2.percentTransparent = 70 myTransparentSingleValuePixelList.append(myTransparentPixel2) rasterTransparency.setTransparentSingleValuePixelList( myTransparentSingleValuePixelList) rasterRenderer = myRasterLayer.renderer() assert rasterRenderer rasterRenderer.setRasterTransparency(rasterTransparency) QgsProject.instance().addMapLayers([myRasterLayer, ]) myMapSettings = QgsMapSettings() myMapSettings.setLayers([myRasterLayer]) myMapSettings.setExtent(myRasterLayer.extent()) myChecker = QgsRenderChecker() myChecker.setControlName("expected_raster_transparency") myChecker.setMapSettings(myMapSettings) myResultFlag = myChecker.runTest("raster_transparency_python") assert myResultFlag, "Raster transparency rendering test failed"
def testTransparency(self): 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 renderer = QgsSingleBandGrayRenderer(myRasterLayer.dataProvider(), 1) myRasterLayer.setRenderer(renderer) myRasterLayer.setContrastEnhancementAlgorithm( QgsContrastEnhancement.StretchToMinimumMaximum, QgsRasterLayer.ContrastEnhancementMinMax) myContrastEnhancement = myRasterLayer.renderer().contrastEnhancement() #print ("myContrastEnhancement.minimumValue = %.17g" % # myContrastEnhancement.minimumValue()) #print ("myContrastEnhancement.maximumValue = %.17g" % # myContrastEnhancement.maximumValue()) # Unfortunately the minimum/maximum values calculated in C++ and Python # are slightly different (e.g. 3.3999999521443642e+38 x # 3.3999999521444001e+38) # It is not clear where the precision is lost. # We set the same values as C++. myContrastEnhancement.setMinimumValue(-3.3319999287625854e+38) myContrastEnhancement.setMaximumValue(3.3999999521443642e+38) #myType = myRasterLayer.dataProvider().dataType(1); #myEnhancement = QgsContrastEnhancement(myType); myTransparentSingleValuePixelList = [] rasterTransparency = QgsRasterTransparency() myTransparentPixel1 = \ QgsRasterTransparency.TransparentSingleValuePixel() myTransparentPixel1.min = -2.5840000772112106e+38 myTransparentPixel1.max = -1.0879999684602689e+38 myTransparentPixel1.percentTransparent = 50 myTransparentSingleValuePixelList.append(myTransparentPixel1) myTransparentPixel2 = \ QgsRasterTransparency.TransparentSingleValuePixel() myTransparentPixel2.min = 1.359999960575336e+37 myTransparentPixel2.max = 9.520000231087593e+37 myTransparentPixel2.percentTransparent = 70 myTransparentSingleValuePixelList.append(myTransparentPixel2) rasterTransparency.setTransparentSingleValuePixelList( myTransparentSingleValuePixelList) rasterRenderer = myRasterLayer.renderer() assert rasterRenderer rasterRenderer.setRasterTransparency(rasterTransparency) QgsMapLayerRegistry.instance().addMapLayers([ myRasterLayer, ]) myMapRenderer = QgsMapRenderer() myLayers = QStringList() myLayers.append(myRasterLayer.id()) myMapRenderer.setLayerSet(myLayers) myMapRenderer.setExtent(myRasterLayer.extent()) myChecker = QgsRenderChecker() myChecker.setControlName("expected_raster_transparency") myChecker.setMapRenderer(myMapRenderer) myResultFlag = myChecker.runTest("raster_transparency_python"); assert myResultFlag, "Raster transparency rendering test failed"
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 _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 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