PostGIS › Traitements raster

← Précédent ↑ Retour Suivant →

A Modification des raster

AA Modifier la résolution

La fonction ST_Resize prend un raster en argument et retourne le même raster ré-échantilloné. La géographie totale du raster ne change pas mais le nombre de points change – donc leur résolution – pour correspondre aux dimensions données en argument.

Si pour X ou Y le nombre de pixels en sortie n’est pas un multiple de celui en entrée, un algorithme est utilisé pour interpoler la valeur des pixels « qui tombent entre deux ». Les algorithmes disponibles sont par ordre de rapidité (inverse de la qualité) : NearestNeighbor, Bilinear, Cubic, CubicSpline, Lanczos.

Exemple avec notre modèle numérique de terrain (MNT) importé dans le dernier module :

SELECT rid, 
                                
                                    ST_Resize
                                
                            
(rast, 0.05, 0.05) rast FROM mnt_25m

Dans cet exemple, on ré-échantillonne le raster en ne gardant sur chaque dimension que 5 % des points (soit 0,0025 % des points au total).

Afin de visualiser le résultat avec QGIS, on crée une table à partir de cette requête :

CREATE TABLE mnt_resize AS
SELECT rid, 

                                
                                    ST_Resize
                                
                            
(rast, 0.05, 0.05) rast FROM mnt_25m;

Sans oublier d’ajouter les contraintes (sinon QGIS n’affichera pas la couche) :

SELECT AddRasterConstraints(’mnt_resize’, ’rast’);
Résultat de ST_Resize
MNT d’origine (401 x 401 pixels)

Au lieu de donner des pourcentages à ST_Resize (en nombre réels), on peut lieu donner des dimensions absolues. Étant donné que les tuiles font ici 100 pixels de côté, on aurait pu écrire en nombre entiers (attention : 5 est un nombre entier, 5.0 est un nombre réel) :

SELECT rid, 
                                
                                    ST_Resize
                                
                            
(rast, 5, 5) rast FROM mnt_25m

Cependant, parce que notre raster de taille 401x401 compte 5 tuiles sur chaque dimension (4 tuiles de 100 pixels et une de 1 pixel), la dernière tuile plus petite se « densifie » et monte en résolution pour avoir le même nombre de pixels que les autres (5x5), au lieu de rester en 5x1 ou 1x5. La converture raster devient alors hétérogène en résolution, ce qui n’est pas un problème en soi tant qu’on le prend en compte dans les opérations qu’on souhaite mener ensuite.

AB Reprojection

Comme pour les géométries, la fonction ST_Transform reprojette le raster en entrée dans le référentiel spatial (SRID) donné. À cet effet, PostGIS ré-échantillonne les pixels par application de la fonction de transformation du référentiel source vers celui de destination.

CREATE TABLE mnt_4326 AS
SELECT rid, 

                                
                                    ST_Transform
                                
                            
(rast, 4326) rast FROM mnt_25m;
SELECT AddRasterConstraints(’mnt_4326’, ’rast’);

Rendu QGIS du raster reprojeté en EPSG:4326 : attention, le projet QGIS doit être dans la même projection (indiqué en bas à droite) pour éviter une double-reprojection par QGIS.

On observe des perturbations en noir, à cause de la division en tuiles : chaque tuile a été reprojetée indépendemment. La solution consiste à donner en argument à ST_Transform un raster de référence au lieu du SRID. Pour notre exemple, on utilisera simplement ST_Union pour agréger les tuiles en un seul raster avant de reprojeter. En conséquence la table mnt_4326_2 aura un raster monolithique non-tuilé :

CREATE TABLE mnt_4326_2 AS
SELECT 1 as rid, 

                                
                                    ST_Transform
                                
                            
(
                                
                                    ST_Union
                                
                            
(rast), 4326) rast FROM mnt_25m;
SELECT AddRasterConstraints(’mnt_4326_2’, ’rast’);

Reprojection sans erreur avec l’aggrégation par ST_Union

AC Extraction de région ou polygone

La fonction ST_Clip permet de couper un raster sur un polygone donné.

CREATE TABLE mnt_clip1 AS
SELECT 1 as rid,
  

                                
                                    ST_Clip
                                
                            
(
                                
                                    ST_Union
                                
                            
(rast, 1), 1,
  

                                
                                    ST_Buffer
                                
                            
(
                                
                                    ST_Centroid
                                
                            
(
                                
                                    ST_Envelope
                                
                            
(
                                
                                    ST_Union
                                
                            
(rast))), 3000),
  false) as rast
FROM mnt_25m;

SELECT AddRasterConstraints(’mnt_clip1’, ’rast’);

On travaille sur la couverture raster dans sa globalité donc on aggrège avec ST_Union . L’argument suivant 1 est le numéro de canal à utiliser : notre MNT n’en a qu’un de toute façon.

À partir de l’enveloppe ( ST_Envelope ), on calcule le centroïde qui est donc le centre de notre MNT. ST_Buffer transforme le point en un disque (qui est physiquement un polygone), lequel est passé à ST_Clip comme forme pour le découpage.

Le dernier argument, false , indique à ST_Clip de ne pas couper à la plus petite enveloppe possible contenant toutes les valeurs qui ne sont pas « no data ».

Résultat de ST_Clip sur QGIS

On observe cependant que du noir entoure le disque : c’est à cause d’une mauvaise gestion des « no data ». À l’aide de la fonction d’interrogation de QGIS, on s’aperçoit que ST_Clip a mis des valeur zéro pour toute la zone coupée, qui n’est pas considérée comme un « no data ».

Quelques ajustements sont à faire :

CREATE TABLE mnt_clip1 AS
SELECT 1 AS rid,
  

                                
                                    ST_SetBandNoDataValue
                                
                            
(
    

                                
                                    ST_Clip
                                
                            
(
                                
                                    ST_Union
                                
                            
(rast), 1,
    

                                
                                    ST_Buffer
                                
                            
(
                                
                                    ST_Centroid
                                
                            
(
                                
                                    ST_Envelope
                                
                            
(
                                
                                    ST_Union
                                
                            
(rast))), 3000),
    0, false),
  0) AS rast
FROM mnt_25m;

SELECT AddRasterConstraints(’mnt_clip1’, ’rast’);
Rendu QGIS avec le « no data » correct

B Opérations sur les raster

BA Analyse de pente

La fonction ST_Aspect produit à partir d’un canal un autre canal (sous forme de nouveau raster) dont la valeur représente l’azimut de la pente au pixel.

CREATE TABLE mnt_aspect AS
SELECT 1 rid, 

                                
                                    ST_Aspect
                                
                            
(
                                
                                    ST_Union
                                
                            
(rast)) rast FROM mnt_25m;
SELECT AddRasterConstraints(’mnt_aspect’, ’rast’);

ST_Aspect rendu par QGIS (style par défaut : le constraste de gris ne représente aucunement la pente, mais l’azimut de la pente)

La fonction ST_Slope calcule l’angle vertical de la pente et s’utilise comme ST_Aspect .

CREATE TABLE mnt_slope AS
SELECT 1 rid, 

                                
                                    ST_Slope
                                
                            
(
                                
                                    ST_Union
                                
                            
(rast)) rast FROM mnt_25m;
SELECT AddRasterConstraints(’mnt_slope’, ’rast’);

ST_Slope rendu par QGIS : la luminosité est proportionnelle à l’angle (min → max) (exprimé en degrés)

Recombinaison en multiples canaux d’un même raster

Nous avons produit a raster spécifique comme résultat de ST_Slope et un autre pour ST_Aspect . Il serait intéressant de les combiner au sein d’un même raster, pour simplifier la manipulation. Il appartient au SIG comment coloriser le raster en fonction de ces canaux.

Pour combiner des canaux, on utilise la fonction ST_AddBand qui retourne le raster donné en argument auquel on a ajouté les canaux provenant des raster donnés en argument ARRAY.

Exemple tuile par tuile (un léger défaut appraît sur les frontières des tuiles) :

CREATE TABLE mnt_slope_aspect AS
SELECT 1 rid,
  

                                
                                    ST_AddBand
                                
                            
(rast, ARRAY[
                                
                                    ST_Slope
                                
                            
(rast), 
                                
                                    ST_Aspect
                                
                            
(rast)]) rast
FROM mnt_25m;

SELECT AddRasterConstraints(’mnt_slope_aspect’, ’rast’);

QGIS appliquera par défaut un style RVB (canal 1 = rouge, 2 = vert, 3 = bleu), en utilisant l’intervalle valeur minimale → maximale pour la proportionnalité de luminosité. L’outil d’interrogation (icône i ) permet d’inspecter ces 3 canaux et de constater qu’en tout point leur valeur est bien égale au raster indépendant équivalent (le canal 2 de mnt_slope_aspect et bien égale au canal 1 unique de raster à canal unique mnt_slope .

Avec ce style, le quantité de rouge représente l’altitude, la quantité de vert l’importance de la pente et de bleu l’orientation de la pente (de 0° à 360°).

Exemple du mnt_slope_aspect avec le style par défaut : canal 1 = rouge, 2 = vert, 3 = bleu

BB Reclassifier les valeurs

La fonction ST_Reclass permet de reclasser les valeurs du canal donné d’un raster, c’està-dire modifier la valeur par proportionnalité sur intervalles discrets.

Dans ce premier exemple, les valeurs entre 24 et 40 sont « dilatés » sur l’intervale [0–90] et les valeurs entre 40 et 104 « comprimées » sur l’intervalle [91–100], ce qui a pour effet de bien montrer les nuances de faible altitude au détriment des différences entre hautes altitudes. En d’autres termes :

  • une valeur égale à 24 devient la valeur 0
  • une valeur X entre 24 et 40 (compris) devient la valeur (X – 24) / (40 – 24), proportionelle
  • une valeur X entre 40 et 104 devient la valeur (X – 91) / (100 – 91) + 91
CREATE TABLE mnt_reclass AS
SELECT 1 rid, 

                                
                                    ST_Reclass
                                
                            
(rast, 1,
  ’24-40]:0-90,(40-104:91-100’, ’16BUI’
) rast FROM mnt_25m;

SELECT AddRasterConstraints(’mnt_reclass’, ’rast’);
Rendu QGIS

Classification en 3 canaux et représentation RVB

On peut effectuer plusieurs classifications et les réunir en canaux respectifs au sein d’un raster unique, qui sera rendu par défaut dans QGIS en couleur RVB (rouge, vert, bleu) :

CREATE TABLE mnt_reclass2 AS
SELECT 1 rid, 

                                
                                    ST_AddBand
                                
                            
(
                                
                                    ST_MakeEmptyRaster
                                
                            
(rast), ARRAY[
  

                                
                                    ST_Reclass
                                
                            
(rast, 1, ’24-40]:255-0,(40-80]:0,(80-104:0-255’, ’8BUI’),
  

                                
                                    ST_Reclass
                                
                            
(rast, 1, ’24-104:0-255’, ’8BUI’),
  

                                
                                    ST_Reclass
                                
                            
(rast, 1, ’24-104:255-0’, ’8BUI’)
]) rast FROM mnt_25m;

SELECT AddRasterConstraints(’mnt_reclass2’, ’rast’);

L’argument 8BUI (ou plus haut 16BUI est le type de la valeur pixel : 4 bits, 8 bits, signé ou non-signé, etc. On utilise 8BUI pour des entiers non-signés (positifs) codés sur 8 bits, soit les valeurs entières de l’intervalle [0–255]. Pour plus d’information, on se référera à la documentation officielle [http://postgis.net/docs/RT_ST_BandPixelType.html]

Dans cet exemple, on affecte du rouge aux altitudes les plus basses (inférieures à 40) et les plus hautes (supérieures à 80), ce qui se traduit par du violet dans le premier cas et du jaune dans le second (les altitudes entre 40 et 80 ont une valeur « rouge » de zéro). Le vert quant à lui est proportionnel à l’altitude sur l’intervalle [24–104] ; en revanche, le bleu est proportionnellement inverse à l’altitude sur ce même intervalle, d’où le violet à basse altitude (beaucoup de bleu) et le jaune à haute altitude (peu de bleu).

Rendu par défaut de QGIS pour l’interpolation RVB avec ST_Reclass

BC Calcul sur voisinage

La fonction ST_MapAlgebra est très puissante : elle permet de produire un nouveau canal calculé d’après une expression arbitraire fournie en argument. Exemple :

CREATE TABLE mnt_algebra AS
SELECT 1 rid, 

                                
                                    ST_MapAlgebra
                                
                            
(
                                
                                    ST_Union
                                
                            
(rast), 1, ’16BUI’,
  ’[rast.val] * (300 - sqrt( ([rast.x]-200)^2 + ([rast.y]-200)^2))’
) rast FROM mnt_25m;

SELECT AddRasterConstraints(’mnt_algebra’, ’rast’);

Dans cet exemple, on calcule avec l’expression sqrt() la distance du pixel par rapport au centre du raster (le pixel (100 ; 100) ) par le théorême de Pythagore, puis son complément à 300 que l’on multiplie par la valeur du pixel (qui représente l’altitude). Par conséquent on obtient un raster dont le pixel central est l’altitude multipliée par 300 et les autres multipliés par un facteur qui décroît quand on s’aloigne du centre jusqu’à atteindre 0 à la distance 300.

Rendu QGIS de MapAlgebra selon la formule prenant en compte la distance au centre

BD Vectoriser un raster

La fonction ST_DumpAsPolygons transforme le canal donné d’un raster (par défaut le canal n°1) en polygones représentant les surfaces des pixels adjacents de même valeur.

CREATE TABLE mnt_polygon AS
SELECT (

                                
                                    ST_DumpAsPolygons
                                
                            
(
                                
                                    ST_Union
                                
                            
(rast))).* FROM mnt_25m;

Rendu des polygones avec QGIS : style gradué, palette bleu → jaune → rouge en 5 classes en intervalles égaux. L’outil d’identification montre la valeur 30 pour la couche vectorielle (le polygone de valeur 30 est sélectionné en rouge) et la couche raster (tous les pixels qui recouvrent ce polygone ont la valeur 30).

Zoom sur une région pour observer la forme des polygones, résultat de l’union des surfaces des pixels adjacents de même valeur

On peut combiner ST_DumpAsPolygons avec ST_MapAlgebra pour discrétiser les altitudes dans PostGIS. Dans l’exemple suivant, on réduit la précision à ± 10 mètres afin d’établir des courbes de nivellement tous les 10 mètres

CREATE TABLE mnt_polygon_10m AS
SELECT (

                                
                                    ST_DumpAsPolygons
                                
                            
(
                                
                                    ST_MapAlgebra
                                
                            
(
                                
                                    ST_Union
                                
                            
(rast), 1, ’16BUI’, ’round([rast.val] / 10) * 10’))).* FROM mnt_25m;

Rendu en style catégorisé selon la même palette "Spectrale" (inverse) : chaque valeur a sa couleur propre, pour montrer la discrétisation opérée.

Pour obtenir des courbes de nivellement, il suffit de paramétrer la bordure de ces polygones en désactivant le remplissage. Superposé au MNT d’origine, on obtient un rendu représentant l’altitude précise par nuance de gris :

Rendu des lignes de niveaux par dessus le MNT d’origine. En rouge est sélectionné un polygone qui englobe les pixels de valeur 40 ± 5 mètres.

Zoom : les iso-lignes ne sont pas si courbes que cela : elles suivent les contours des pixels. Dans cet exemple, on a cliqué sur un pixel de valeur 58 mais le polygone a la valeur 60 suite à la discrétisation ± 5 mètres par ST_MapAlgebra .

Suivant → ← Précédent Retour