I need to visualize two elevation models (DEM) on the same color scale, that means the same color refers to the same elevation, even if “updated canvas” is set. It`s important if I want to check terrain (DTM) compared to surface model (DSM).
Color scale is the same if I set the same min/max value for the whole rasters, but in this case in details the canvas is just grey, so I need a solution for updated canvas. I tried the following code, which get the min/max value of DSM for the actual canvas, and apply it to the DTM. It is processed after each canvas change
from qgis.core import QgsProject, QgsSingleBandPseudoColorRenderer, QgsRasterShader, QgsColorRampShader, QgsRasterBandStats
from qgis.gui import QgsMapCanvas
`# Function to synchronize color ramp and min/max values between two layers
def sync_dem_colors(layer1, layer2):
# Get the renderer from the first layer
renderer1 = layer1.renderer()`
# Ensure the renderer is of type singleband pseudocolor
if not isinstance(renderer1, QgsSingleBandPseudoColorRenderer):
print("The first layer is not using singleband pseudocolor renderer.")
return
# Get the shader from the first layer's renderer
shader1 = renderer1.shader()
if not isinstance(shader1, QgsRasterShader):
print("The first layer's shader is not a QgsRasterShader.")
return
color_ramp_shader1 = shader1.rasterShaderFunction()
if not isinstance(color_ramp_shader1, QgsColorRampShader):
print("The first layer's shader function is not a QgsColorRampShader.")
return
# Get the color ramp from the first layer's shader function
color_ramp1 = color_ramp_shader1.colorRampItemList()
# Get the current canvas extent
canvas = iface.mapCanvas()
extent = canvas.extent()
#print (extent)
# Get the min/max values from the first layer
provider1 = layer1.dataProvider()
stats = provider1.bandStatistics(1, QgsRasterBandStats.All, extent)
min_value = stats.minimumValue
max_value = stats.maximumValue
print("stat1:", min_value,max_value)
# Create a new color ramp shader for the second layer
color_ramp_shader2 = QgsColorRampShader()
color_ramp_shader2.setColorRampType(QgsColorRampShader.Interpolated)
color_ramp_shader2.setColorRampItemList(color_ramp1)
color_ramp_shader2.setMinimumValue(min_value)
color_ramp_shader2.setMaximumValue(max_value)
#pure QC
provider2 = layer2.dataProvider()
stats2=provider2.bandStatistics(1, QgsRasterBandStats.All, extent)
min_value2 = stats2.minimumValue
max_value2 = stats2.maximumValue
print("stat2:",min_value2,max_value2)
# Create a new raster shader for the second layer
shader2 = QgsRasterShader()
shader2.setRasterShaderFunction(color_ramp_shader2)
# Create a new renderer for the second layer
renderer2 = QgsSingleBandPseudoColorRenderer(layer2.dataProvider(), 1, shader2)
# Set the renderer to the second layer
layer2.setRenderer(renderer2)
# Refresh the symbology of the second layer
layer2.triggerRepaint()
# Replace 'dem_layer_1' and 'dem_layer_2' with the actual layer names or IDs
layer2 = QgsProject.instance().mapLayersByName('DTM-dcm')[0]
layer1 = QgsProject.instance().mapLayersByName('DSM')[0]
## Function to be called when the canvas extent changes
def on_canvas_extent_changed():
sync_dem_colors(layer1, layer2)
# Get the active map canvas
canvas = iface.mapCanvas()
# Connect the extentChanged signal to the on_canvas_extent_changed slot
canvas.extentsChanged.connect(on_canvas_extent_changed)
# Initial synchronization
#sync_dem_colors(layer1, layer2)
# Refresh the map canvas
canvas.refresh()`
problem is that stats are still not the same, and I don`t understand why
Gergely Kóródy is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.