logo
Published on PostGIS.fr (http://old.postgis.fr)

MapServer 5.4.0 affichage de symboles aux extrémintés d'une ligne

By djay
Créé 28 Avr 2009 - 14:41

Avec MapServer 5.4.0, l'affichage des extrémités des couches linéaires est maintenant facilité et possible à l'aide d'une seule couche.

Plus besoin donc de pré-traitement pour récupérer le début et la fin de la ligne requêtes suivantes, qui se faisait néanmoins très facilement avec des couches PostGIS. En utilisant, par exemple, les définitions de couches (1 et 2) ci-dessous ( la définition de la couche ligne de base est omise), respectivement pour le point de départ et le point final (on suppose que la table est <table>):

Définition de couche 1 :

LAYER
    CONNECTION ""
    CONNECTIONTYPE POSTGIS

    DATA "wkb_geometry1 from (SELECT startPoint( <table>.wkb_geometry) as wkb_geometry1,<table>.ogc_fid, CASE WHEN plus(pow((y(e)-y(s)),2),pow((x(e)-x(s)),2)) = 0 THEN 1 ELSE (180*(acos((x(e)-x(s))/sqrt(plus(pow((y(e)-y(s)),2),pow((x(e)-x(s)),2))))/pi()))-90 END as angle FROM (select ogc_fid, pointN(wkb_geometry,2) as e, startPoint(wkb_geometry) as s from <table>) as foo,  <table> WHERE foo.ogc_fid=<table>.ogc_fid)  as foo1 using unique ogc_fid using SRID=27572"

    NAME "espt_start"
    PROCESSING "CLOSE_CONNECTION=DEFER"
    STATUS OFF
    TOLERANCE 0
    TYPE POINT
    UNITS METERS
    CLASS
        NAME "espt_start1"
        STYLE
            ANGLE [angle]
            COLOR 250 8 255
            SIZE 10
            SYMBOL "triangle_isocele"
            WIDTH 1
        END
    END
END

Définition de couche 2 :

LAYER
    CONNECTION ""
    CONNECTIONTYPE POSTGIS

    DATA "wkb_geometry1 from (SELECT endPoint( 	<table>.wkb_geometry) as wkb_geometry1,<table>.ogc_fid, CASE WHEN plus(pow((y(e)-y(s)),2),pow((x(e)-x(s)),2)) = 0 THEN 1 ELSE (180*(acos((x(e)-x(s))/sqrt(plus(pow((y(e)-y(s)),2),pow((x(e)-x(s)),2))))/pi()))-270 END as angle FROM (select ogc_fid, pointN(wkb_geometry,numPoints(wkb_geometry)-1) as s, endPoint(wkb_geometry) as e from <table>) as foo,  poisson.total_especes2 WHERE foo.ogc_fid=<table>.ogc_fid)  as foo1 using unique ogc_fid using SRID=27572"

    NAME "espt_end"
    PROCESSING "CLOSE_CONNECTION=DEFER"
    STATUS OFF
    TOLERANCE 0
    TYPE POINT
    UNITS METERS
    CLASS
        NAME "espt_end1"
        STYLE
            ANGLE [angle]
            COLOR 250 8 255
            SIZE 10
            SYMBOL "triangle_isocele"
            WIDTH 1
    END
        END
    END


L'astuce consistait donc simplement à ajouter deux couches supplémentaires, l'une pour le point de départ et l'autre pour le point final (si votre symbol est orienté) en plus de la couche de la ligne elle-même. Avec la nouvelle version de MapServer 5.4.0, on peut utiliser l'option GEOMTRANSFORM d'une balise STYLE qui, comme son nom l'indique, permet de réaliser une opération sur une géométrie (end, start, buffer ...). Par exemple, si vous souhaitez afficher une barre perpendiculaire aux extrémités d'une ligne, voilà la définition d'une couche MapServer qui utilise ce nouveau paramètre :

LAYER
     CONNECTION ""
    CONNECTIONTYPE POSTGIS
    DATA "wkb_geometry FROM <table>"
    NAME "espt"
    PROCESSING "CLOSE_CONNECTION=DEFER"
    STATUS OFF
    TOLERANCE 0
    TYPE LINE
    UNITS METERS
    CLASS
        NAME "1"
        STYLE
        ANGLE 360
        COLOR 250 8 255
        SYMBOL 0
        WIDTH 2
    END
    STYLE
        ANGLE 360
        ANTIALIAS TRUE
        COLOR 0 0 255
        SIZE 5
        SYMBOL "l_oant_01_line"
        WIDTH 2
    END
    STYLE
        ANGLE AUTO
        ANTIALIAS TRUE
        COLOR 250 8 255
        MAXSIZE 100
        SIZE 10
        SYMBOL "openoffice_137"
        WIDTH 1
        GEOMTRANSFORM "end([wkb_geometry])"
    END
    STYLE
        ANGLE AUTO
        ANTIALIAS TRUE
        COLOR 250 8 255
        MAXSIZE 100
        SIZE 10
        SYMBOL "openoffice_137"
        WIDTH 1
        GEOMTRANSFORM "start([wkb_geometry])"
    END
    END
END

Il est donc maintenant possible de facilement afficher un symbole quelconque au début, à la fin ou pour les plus gourmands les deux Eye-wink

Attention, lors d'une interrogation de données, vous constaterez sans doute le même résultat que l'image ci-dessous, le trait horizontal est répété tout au long de la ligne :

Mapserver 5.4.0 pb


Lors de la sauvegarde des mapfiles à l'aide de l'API mapscript avec cette nouvelle version, j'ai rencontré un problème pour les couches ayant un STYLE utilisant ANGLE AUTO. Cette partie de la définition de la couche était remplacée par ANGLE 360. Du coup, j'ai créé le "patch" qui suit (applicable à l'aide de la commande patch -P0 mapserver.patch depuis le répertoire des sources de MapServer) pour corriger ce problème :

 
diff -ru ./mapfile.c ./mapfile.c
--- ./mapfile.c 2009-04-07 22:30:23.000000000 +0200
+++ ./mapfile.c 2009-04-28 23:52:43.000000000 +0200
@@ -1911,7 +1911,7 @@
style->minscaledenom=style->maxscaledenom = -1.0;
style->offsetx = style->offsety = 0; /* no offset */
style->antialias = MS_FALSE;
- style->angle = 360;
+ style->angle = 0;
style->autoangle= MS_FALSE;

style->opacity = 100; /* fully opaque */
style->_geomtransformexpression = NULL;
@@ -2127,7 +2127,9 @@
fprintf(stream, " STYLE\n");
if(style->numbindings > 0 && style->bindings[MS_STYLE_BINDING_ANGLE].item)
fprintf(stream, " ANGLE [%s]\n", style->bindings[MS_STYLE_BINDING_ANGLE].item);
- else if(style->angle != 0) fprintf(stream, " ANGLE %g\n", style->angle);
+ else if(style->angle != 0 && style->autoangle!=MS_TRUE)
+ fprintf(stream, " ANGLE %g\n", style->angle);
+ else if(style->autoangle==MS_TRUE) fprintf(stream, " ANGLE AUTO \n");

if(style->antialias) fprintf(stream, " ANTIALIAS TRUE\n");
writeColor(&(style->backgroundcolor), stream, "BACKGROUNDCOLOR", " ");

On utilise donc la propriété autoangle de style pour vérifier si l'angle doit être ajouté ou non. Au passage, vous noterez que l'on n'ajoute plus un angle de 360 par défaut si aucun angle n'est spécifié pour la couche en question (ref. #2991 [1]).

Un autre détail, en passant, concernant cette nouvelle version 5.4.0 de MapServer : la nécessité d'avoir le mot clef SYMBOLSET au début du fichier symbols.sym (la balise END n'est pas requise).