Créer un raster discret à l'aide de QGIS?

11

J'ai des rasters avec des valeurs discrètes (catégories Landuse, valeurs booléennes ...). J'aimerais pouvoir les styliser de manière discrète:

0 -> Red
1 -> Blue
2 -> Green
...

Je souhaite quelque chose comme les "catégories uniques" dans ArcGIS: http://resources.arcgis.com/en/help/main/10.1/index.html#/representing_unique_categories_such_as_land_use/009t00000074000000/

Cependant, toutes les options que je vois impliquent des rampes de couleurs ... Ai-je oublié quelque chose?


J'ai ouvert une demande de fonctionnalité, car il ne semble y avoir que des solutions de contournement disponibles, pas des solutions: http://hub.qgis.org/issues/14845

Stéphane Henriod
la source

Réponses:

8

Vous pouvez créer un schéma de style personnalisé, quelque chose comme des catégories uniques, mais vous devrez ajouter toutes les catégories manuellement (au moins je dois le faire, mais j'utilise une ancienne version de QGIS).

Cliquez avec le bouton droit sur le raster -> propriétés -> style. Là, choisissez singleband pseudocolorcomme Render typeet cliquez sur le petit plus rouge pour ajouter vos propres valeurs et les couleurs correspondantes. Quelque chose dans le sens de: entrez la description de l'image ici

Notez que vous pouvez également utiliser classify pour obtenir les valeurs automatiquement, mais si vous avez des valeurs discrètes, il est préférable de simplement les ajouter manuellement, selon la façon dont vos données sont distribuées.

Si vos données suivent un modèle, si elle est 0,1,2 .... 10, vous pouvez définir l' Modeintervalle égal, définir la plage Min:0, Max:10puis Classes:11cliquer Classifyet vous obtiendrez automatiquement toutes les valeurs. Ensuite, vous pouvez les modifier comme bon vous semble. entrez la description de l'image ici Je sais que ce n'est pas parfait, mais c'est le meilleur que j'ai trouvé jusqu'à présent. Il peut y avoir un plugin qui traite ce problème.

Hasan Mustafa
la source
J'espérais la possibilité de récupérer automatiquement toutes les valeurs possibles de mon raster discret mais apparemment cela n'existe pas (encore?). Merci!
Stéphane Henriod
Pour autant que je sache, ce n'est pas encore possible, mais il peut y avoir un plugin qui le fait.
Hasan Mustafa
@ Stéph, pour obtenir automatiquement toute la plage de valeurs: sous 'Charger les valeurs min / max', vous pouvez sélectionner 'min / max' puis cliquer sur 'charger', puis définir le nombre de classes pour couvrir cette plage (selon les notes de Hasan ) et cliquez sur "classer". Si vous avez des valeurs manquantes dans la plage, vous devrez les supprimer manuellement.
Simbamangu
2
Merci, c'est en effet la solution de contournement que j'utilise. Mais je ne le trouve pas très intuitif, surtout lorsque j'enseigne Qgis aux nouveaux utilisateurs. De plus, si j'ai une valeur "6" que je ne veux pas afficher sur mon raster, j'ai un problème: tous les pixels avec "6" miseront une couleur interpolée entre "5" et "7". Je peux bien sûr dire que "6" doit être considéré comme NoData ou je peux utiliser la calculatrice raster pour créer un nouveau raster sans "6" mais, encore une fois, ce sont toutes des solutions. Idéalement, je souhaiterais un bouton "Récupérer toutes les valeurs individuelles". Je vais vérifier si c'est prévu pour les futures versions ...
Stéphane Henriod
1
J'ai créé un ticket sur un problème connexe: hub.qgis.org/issues/14449
Kurt Menke
5

Voici un script de traitement rapide et sale qui fait exactement ce que vous demandez (excuses pour les choix de couleurs!). Placez-le dans votre répertoire de scripts de traitement (par exemple, C: \ Users \ .qgis2 \ processing \ scripts) et il apparaîtra dans la boîte à outils de traitement sous Scripts> Raster.

Nous remercions Yury Ryabov pour le script Unique_values_count.py sur lequel il est basé.

EDIT: Je suis en train de soumettre une demande de tirage pour l'obtenir dans le référentiel de scripts de traitement.

##Raster=group
##Generate unique values style=name
##Raster_to_extract_unique_values=raster
##round_values_to_ndigits=number 0

from osgeo import gdal
from random import randint
import math
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.utils import iface

# Rename verbose input vars
input = Raster_to_extract_unique_values
rdig = round_values_to_ndigits

# Initialize unique values list
sort_values = []
# create set for unique values list
cell_values = set()

# load raster
gdalData =  gdal.Open(str(input))

# get width and heights of the raster
xsize = gdalData.RasterXSize
ysize = gdalData.RasterYSize

# get number of bands
bands = gdalData.RasterCount

# process the raster
for i in xrange(1, bands + 1):
    progress.setText("processing band " + str(i) + " of " + str(bands))
    band_i = gdalData.GetRasterBand(i)
    raster = band_i.ReadAsArray() # This loads the entire raster into memory!
    # count unique values for the given band
    for col in range( xsize ):
        if col % 10 == 0: progress.setPercentage(int(100*col/xsize))
        for row in range( ysize ):
            cell_value = raster[row, col]
            # check if cell_value is NaN - don't add if it is
            if not math.isnan(cell_value):
                # round floats if needed
                if rdig:
                    try:
                        cell_value = round(cell_value, int(rdig))
                    except:
                        cell_value = round(cell_value)
                # Add to the unique values set
                cell_values.add(cell_value)

del(gdalData)

# decide whether to sort by the count-column or the value-column
sort_values = sorted(cell_values)

# Now load the layer and apply styling
layer = processing.getObjectFromUri(input)

qCRS = QgsColorRampShader()

# Build the colour ramp using random colours
colList = ['#ff0000','#ffff00','#0000ff','#00ffff','#00ff00','#ff00ff']

lst = []
for i,val in enumerate(sort_values):
    lst.append(QgsColorRampShader.ColorRampItem(val,QColor(colList[i % 6]),str(val)))

qCRS.setColorRampItemList(lst)
qCRS.setColorRampType(QgsColorRampShader.EXACT)

shader = QgsRasterShader()
shader.setRasterShaderFunction(qCRS)

renderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), layer.type(), shader)
layer.setRenderer(renderer)
layer.triggerRepaint()
Andy Harfoot
la source
Cela fonctionne parfaitement, des trucs géniaux! Demande effrontée, mais une chance de mettre à jour l'étiquette afin qu'elle affiche les valeurs dans la table des matières? Pour une raison quelconque, il ne les montre pas.
Ed Rollason
Fait - vient de
modifier
Merci beaucoup! Btw Je suis en train de rassembler une description des fonctionnalités pour avoir un tel moteur de rendu inclus dans 3.0: docs.google.com/document/d/… N'importe qui, n'hésitez pas à vérifier / commenter / modifier. Ce serait formidable de pouvoir facilement styliser des rasters discrets en utilisant n'importe quelle solution de contournement / script, ...
Stéphane Henriod
4

Vous pouvez essayer ceci:

1) Créez un style simple dans les propriétés du calque, puis enregistrez-le dans un fichier d'exportation à l'aide du bouton Enregistrer. Ce sont sous la forme:

valeur, R, G, B, Alpha, étiquette

2) Utilisez r.category dans la boîte à outils Grass (6 ou 7) du module de traitement. Cela devrait fournir une liste de valeurs raster. Copiez ces valeurs. Vous pouvez utiliser r.quantile pour des données continues.

3) Ouvrez le fichier d'exportation que vous avez enregistré précédemment dans un éditeur de texte (par exemple, bloc-notes ++ sur Windows, charges de choix sur Linux). Collez les valeurs et reformatez en fonction.

@Stephane

3a) Pour les valeurs discrètes, vous pouvez définir l'alpha sur 0, ou supprimer ou commenter (en utilisant # au début de la ligne) toutes les données que vous ne souhaitez pas afficher dans le fichier de catégorie.

3b) Pour les valeurs continues, créez une ligne pour la valeur de début et une autre pour la valeur de fin. Réglez l'alpha pour les deux à 0.

4) Par exemple, supposons que vous ayez créé trois fichiers:

categories.txt - sortie de r.category, copier-coller, ajoutez deux lignes vides en haut. Longueur totale 1 colonne. Vérifiez le nombre de valeurs uniques et créez un style avec le même nombre d'entrées dans QGIS.

colours.txt - un fichier d'exportation de carte de couleurs généré par QGIS avec les couleurs que vous aimez. Longueur totale 6 colonnes.

labels.txt - fichier avec les étiquettes que vous voulez, ajoutez deux lignes vides en haut. Longueur totale 1 colonne.

Utilisez une feuille de calcul pour fusionner les fichiers et les enregistrer au format csv. Ouvrez-le dans QGIS.

Alternativement, sur la ligne de commande (bash ou msys):

paste -d, categories.txt colours.txt labels.txt |cut -d, -f 1,3-6,8 > new_style.txt

Voir également:

https://pvanb.wordpress.com/2014/02/05/creating-a-qgis-color-map-from-text-file/

Palette de couleurs avancée pour les données raster

vinh
la source
Très belle méthode! Mais quand même, s'il y a des catégories dans mon raster que je ne veux pas afficher, je suis bloqué ...
Stéphane Henriod