Produire un effet de “couleur dégradée” avec Mapserver

Nous avons  travaillé sur un projet de Web mapping dernièrement dans lequel on voulait produire un effet de "couleur dégradée" (fade to white) entre la terre ferme et l'océan. J'ai trouvé dernièrement une superbe carte dans l'"Atlas of Design" (que je recommande fortement pour les maniaques comme moi) de la NACIS (North American Cartographic Information Society).

À la page 64 on trouvera le genre d'effet de "couleur dégradée" en question:

On a l'habitude de voir ce genre d'effet dans un atlas et il s'agit la plupart du temps d'une retouche "photoshop". Il est par contre possible de reproduire l'effet avec une suite de buffers "concentrique" ou "excentrique" autour des entités d'une classe de provinces ou de continents par exemple pour "dégrader" la couleur de l'eau. Je me suis inspiré de d'une recette sur le forum SIG pour le faire dans PostGIS.

La méthode pourrait certe être plus optimale et performante si elle était gérée nativement dans Mapserver (nous acceptons volontier le financement pour le faire), par contre le résultat est superbe.

Donc première étape: chargement... shp2pgsql -s 3163 -c -g the_geom -I -W "latin1" QUARTIER_POLYGON.shp nc_noumea | psql -d nc -h 192.168.6.20 -p 5432 -U nc

Pour créer les anneaux "excentriques" j'ai utilisé ces suites de requêtes SQL. On devra jouer avec la largeur du buffer si on doit afficher le "fade effect" à plusieurs échelles et créer plus d'anneaux. Dans l'exemple suivant (de 0 a 35 mètres) on comprendra que l'effet ne sera visible qu'à très petite échelle. Si on veut appliquer la recette à plus grande échelle, il suffira simplement d'ajouter des anneaux supplémentaires ET à des intervalles plus larges.

NOTE: Merci à Vincent Picavet de la firme Oslandia pour le conseil de l'incroyable commande generate_series(), que je connaissais pas! Vraiment bien cette commande. Cette instruction SQL très compacte, va même créer la table pour moi! drop table nc_noumea_step; create table nc_noumea_step as select 0 as gid,0 as step,the_geom from nc_noumea; insert into nc_noumea_step (gid,step,the_geom) select 1 as gid,5 as step,ST_Difference(ST_Buffer(st_multi,5),ST_Buffer(the_geom,0)) from nc_noumea; insert into nc_noumea_step (gid,step,the_geom) select 2 as gid,10 as step,ST_Difference(ST_Buffer(st_multi,10),ST_Buffer(the_geom,5)) from nc_noumea; insert into nc_noumea_step (gid,step,the_geom) select 3 as gid,15 as step,ST_Difference(ST_Buffer(st_multi,15),ST_Buffer(the_geom,10)) from nc_noumea; insert into nc_noumea_step (gid,step,the_geom) select 4 as gid,20 as step,ST_Difference(ST_Buffer(st_multi,20),ST_Buffer(the_geom,15)) from nc_noumea; insert into nc_noumea_step (gid,step,the_geom) select 5 as gid,25 as step,ST_Difference(ST_Buffer(st_multi,25),ST_Buffer(the_geom,20)) from nc_noumea; insert into nc_noumea_step (gid,step,the_geom) select 6 as gid,30 as step,ST_Difference(ST_Buffer(st_multi,30),ST_Buffer(the_geom,25)) from nc_noumea; insert into nc_noumea_step (gid,step,the_geom) select 7 as gid,35 as step,ST_Difference(ST_Buffer(st_multi,35),ST_Buffer(the_geom,30)) from nc_noumea;
SELECT i as step, ST_Difference(ST_Buffer(st_multi,i),ST_Buffer(st_multi,i-5))
INTO nc_noumea_step
FROM nc_noumea n, generate_series(5,35,5) AS i;

On pourra utiliser un buffer négatif pour produire le même effet mais en dégradant la couleur vers l'intérieur (anneaux concentriques):

...
insert into communes_50_step (gid,cod_commun,step,the_geom) select gid,cod_commun,200 as step,ST_Difference(ST_Buffer(the_geom,-100),ST_Buffer(the_geom,-200)) as the_geom from communes_50;
insert into communes_50_step (gid,cod_commun,step,the_geom) select gid,cod_commun,300 as step,ST_Difference(ST_Buffer(the_geom,-200),ST_Buffer(the_geom,-300)) as the_geom from communes_50;
...

J’ai fait plusieurs essais dont des buffers successifs qui embarquent les uns sur les autres, mais l'effet est moins propre et le résultat moins prévisible. Le meilleur résultat et le plus flexible est vraiment une suite d'anneaux (buffers polygone) successifs qui n'empiètent pas les uns sur les autres. De cette façon on peut gérer la transparence avec couleur de fond pour chaque classe ET/OU des couleurs uniques ET/OU une orthophoto en fond de carte, tout est possible.

Enfin, dans le mapfile j'ai cartographié dans plusieurs CLASS chacun des anneaux désirés avec une transparence spécifique en dégradé :

LAYER
    TYPE POLYGON
    STATUS ON
    GROUP "zone"
    NAME "nc_contour_2_16"
    PROJECTION
        "init=epsg:3163"
    END
    MINSCALEDENOM 4096
    MAXSCALEDENOM 8192
    DATA "DATA_VDN/nc_noumea_step.shp"
    CLASSITEM "step"
    CLASS
        EXPRESSION "0"
        STYLE
            COLOR 255 255 255
        END
    END
    CLASS
        EXPRESSION "5"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 80
        END
    END
    CLASS
        EXPRESSION "10"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 60
        END
    END
    CLASS
        EXPRESSION "15"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 50
        END
    END
    CLASS
        EXPRESSION "20"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 40
        END
    END
    CLASS
        EXPRESSION "25"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 30
        END
    END
    CLASS
        EXPRESSION "30"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 20
        END
    END
    CLASS
        EXPRESSION "35"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 10
        END
    END
END
LAYER
    TYPE POLYGON
    STATUS ON
    GROUP "zone"
    NAME "nc_contour_1_17"
    PROJECTION
        "init=epsg:3163"
    END
    MINSCALEDENOM 2048
    MAXSCALEDENOM 4096
    DATA "DATA_VDN/nc_noumea_step.shp"
    CLASSITEM "step"
    CLASS
        EXPRESSION "0"
        STYLE
            COLOR 255 255 255
            OUTLINECOLOR "#3fc1b7"
            WIDTH 0.4
        END
    END
    CLASS
        EXPRESSION "5"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 50
        END
    END
    CLASS
        EXPRESSION "10"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 30
        END
    END
    CLASS
        EXPRESSION "15"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 10
        END
    END
END
LAYER
    TYPE POLYGON
    STATUS ON
    GROUP "zone"
    NAME "nc_contour_1_18"
    PROJECTION
        "init=epsg:3163"
    END
    MINSCALEDENOM 1500
    MAXSCALEDENOM 2048
    DATA "DATA_VDN/nc_noumea_step.shp"
    CLASSITEM "step"
    CLASS
        EXPRESSION "0"
        STYLE
            COLOR 255 255 255
            OUTLINECOLOR "#3fc1b7"
            WIDTH 0.4
        END
    END
    CLASS
        EXPRESSION "5"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 50
        END
    END
    CLASS
        EXPRESSION "10"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 20
        END
    END
END
LAYER
    TYPE POLYGON
    STATUS ON
    GROUP "zone"
    NAME "nc_contour_1_18"
    PROJECTION
        "init=epsg:3163"
    END
    MINSCALEDENOM 0
    MAXSCALEDENOM 1500
    DATA "DATA_VDN/nc_noumea_step.shp"
    CLASSITEM "step"
    CLASS
        EXPRESSION "0"
        STYLE
            COLOR 255 255 255
            OUTLINECOLOR "#3fc1b7"
            WIDTH 0.4
        END
    END
    CLASS
        EXPRESSION "5"
        STYLE
            COLOR "#3fc1b7"
            OPACITY 50
        END
    END
END