miércoles, 29 de marzo de 2017

Interpolación de colores con PyQGIS

La interpolación de colores es un aspecto importante en la simbolización de capas vectoriales y raster porque permite visualizar rasgos (features) o píxeles según un color asignado a la clase a la que pertenecen. El método de interpolación más sencillo que existe es el lineal, sin embargo, para rampas con sólo dos colores, tiene la dificultad (sobre todo para ráster) de establecer buenas gradaciones entre ambos. No obstante, esto se puede mitigar con la incorporación de un color intermedio y así mejorar la gradación.


La interpolación lineal es empleada en QGIS y se implementa fácilmente; tal como se observa en este link. En el código siguiente se incluye la generación de 5 clases diferentes de colores, entre el verde y el blanco (pasando por el marrón como color intermedio), para colorizar un ráster DEM con pseudocolor.


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
from qgis.PyQt.QtGui import QColor
import re
from colour import Color

def linear_color_interpolation(c1, c2, t):

    r = int(c1.red() + (c2.red() - c1.red()) * t)
    g = int(c1.green() + (c2.green() - c1.green()) * t)
    b = int(c1.blue() + (c2.blue() - c1.blue()) * t)
    
    return QColor(r, g, b)

layer = iface.activeLayer()
renderer = layer.renderer()
provider = layer.dataProvider()

band = renderer.usesBands()

min = provider.bandStatistics(band[0], QgsRasterBandStats.All).minimumValue
max = provider.bandStatistics(band[0], QgsRasterBandStats.All).maximumValue

#To set an interpolated own color ramp shader with five classes
number_classes = 5

interval = (max - min)/(number_classes -1 )

#classes
sum = min
classes = []

for i in range(number_classes):
    tmp = int(round(sum, 0))
    classes.append(tmp)
    sum += interval

t_list = []

init = 0

for i in range(number_classes/2):
    t_list.append(init)
    init += 1./((number_classes/2)-1)

c1 = QColor('green')
c_int = QColor('#5E1919')
c2 = QColor('#F2E3E3')

colors1 = [ linear_color_interpolation(c1, c_int, t_list[i]) for i in range(number_classes/2) ]

t_list = []

init = 0

for i in range(int(round(number_classes/2.,0))+1):
    t_list.append(init)
    init += 1./int(round(number_classes/2.,0))

colors2 = [ linear_color_interpolation(c_int, c2, t_list[i]) for i in range(int(round(number_classes/2.,0))+1)]

del colors2[0]

z = colors1 + colors2

color_list = [ QgsColorRampShader.ColorRampItem(classes[i], z[i])  for i in range(number_classes) ]

myRasterShader = QgsRasterShader()
myColorRamp = QgsColorRampShader()
 
myColorRamp.setColorRampItemList(color_list)
myColorRamp.setColorRampType(QgsColorRampShader.INTERPOLATED)
myRasterShader.setRasterShaderFunction(myColorRamp)
 
myPseudoRenderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), 1, myRasterShader)
 
layer.setRenderer(myPseudoRenderer)
 
layer.triggerRepaint()

Después de ejecutado en la Python Console de QGIS se puede observar que el resultado es bastante aceptable; a pesar de la sencillez del procedimiento de interpolación lineal y del limitado número de clases.



No hay comentarios: