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 :
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
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 :
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).