Aller au contenu

Afficher le nombre d'éléments dans un Cluster Strategy#

📆 Date de publication initiale : 07 février 2009

Introduction#

logo OpenLayers

Une des grandes améliorations de la version 2.7 d'OpenLayers était la possibilité de pouvoir "jouer" avec les données vecteurs avant même leur affichage. Cette fonctionnalité nommée Strategy propose 4 types d'actions : BBOX, Cluster, Fixed, pagging. Pour un aperçu rapide vous pouvez consulter ce précédent tutoriel dont les bases sont d'ailleurs reprises dans celui-ci.

Nous allons nous attarder sur la méthode Strategy.Cluster, qui permet avant même leur chargement de regrouper les données en fonction de l'échelle en cours. Dans le tutoriel cité précédemment nous avons joué sur la taille des cercles afin de définir le nombre d'entité regroupé. Nous allons maintenant ajouter grâce à la librairie PHP GD le nombre d'entité regroupé à l'intérieur de ces cercles.

Afficher le nombre d'entités agglomérées#

La logique de fonctionnement est simple, en effet la classe Layer.Vector propose un attribut style dans lequel il est possible de définir l'URL de l'image à utiliser. Dans notre cas, cela ne sera pas une image simple mais un script PHP qui renvoie une image.

Concrètement en javaScript cela se passe de la manière suivante, la propriété externalGraphic a pour valeur une fonction pointant vers un fichier PHP nommé custom_cluster.php Dans ce dernier nous passons deux paramètres : numCluster et size :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
var GMLstyle = new OpenLayers.Style({
 pointRadius: "${radius}",
 fillColor: "#ffcc66",
 fillOpacity: 0.8,
 strokeColor: "#ff0000",
 strokeWidth: 2,
 strokeOpacity: 0.3,
 externalGraphic: "${getChartURL}"  
      }, {
 context: {
   radius: function(feature) {  
     var minV = 1;
     var maxV = 10;
     var minR =  5;
     var maxR = 50;
     surf = Math.round(
               minR+((maxR-minR)*((feature.attributes.count-minV)/(maxV-minV)))
            );  
            return surf;
 },
          //Fonction qui interroge le script PHP
   getChartURL: function(feature) {
     var charturl = 'http://ks356007.kimsufi.com/arno/geotribu/applications/tutoriaux/openlayers/
                       cluster_count/custom_cluster.php?numCluster='+feature.attributes.count+'&size='+surf;
     return charturl;
 } // End of function getChartURL
      }
});

GML = new OpenLayers.Layer.Vector(
 "GML", {
 strategies:[
  new OpenLayers.Strategy.Fixed(),
  new OpenLayers.Strategy.Cluster()
 ],
 protocol: new OpenLayers.Protocol.HTTP({
  url: "../random_poi/poi_random/gml/random_poi.gml",
  format: new OpenLayers.Format.GML()
 }),
 styleMap:new OpenLayers.StyleMap({
  "default": GMLstyle,
  "select": {
     fillColor: "red",
     strokeColor: "red"
  }
        })
});

Le code PHP utilise la librairie GD pour générer une image en fonction des paramètres que nous avons passé dans l'URL :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//Get Paramz
 $getNumCluster = $_GET["numCluster"];
 $getSize  = $_GET["size"]*3;
 // create Obj image
 $image = imagecreatetruecolor($getSize,$getSize);
 // allocate some solors
 $white  = imagecolorallocate($image, 255, 255, 255);
 $red    = imagecolorallocate($image, 0, 0, 0);
 $orange = imagecolorallocate($image, 241, 90, 36);
 $orangeDark = imagecolorallocate($image, 178, 56, 18);
 $black  = imagecolorallocate($image, 0, 0, 0);
 //Border of the Circle
 imagefilledarc($image, $getSize/2, $getSize/2, $getSize-3, $getSize-3, 0, 360 , $orangeDark, IMG_ARC_PIE);
 //Fill Circle
 imagefilledarc($image, $getSize/2, $getSize/2, $getSize-8, $getSize-8, 0, 360 , $orange, IMG_ARC_PIE);
 //Text in the circle
 if($getNumCluster>1){
  //We must Calculate the BBOX of the text to align it with the img
  $bbox = imagettfbbox($getSize/2, 0, './arialbi.ttf', $getNumCluster);
  $x = $bbox[2]+$bbox[0];
  $y = $bbox[7]-$bbox[1];
  //Final Center position
  $xPos = imagesx($image)/2-$x/2;
  $yPos = imagesy($image)/2-$y/2;
  //Obj Text
  imagettftext($image,$getSize/2,0,$xPos,$yPos,$white,'./arialbi.ttf',$getNumCluster);
 }
 imagecolortransparent($image, $black);
 // flush image
 header('Content-type: image/png');
 imagepng($image);
 imagedestroy($image);

Et voilà, rien de plus compliqué. Le résultat de ces deux scripts est visible ci-dessous.

Exemple#

Info

Le serveur hébergeant la démonstration n'étant plus disponible depuis de nombreuses années, la démonstration, autre fois intégrée en iFrame est désactivée.
<iframe src="http://ks356007.kimsufi.com/arno/geotribu/applications/tutoriaux/openlayers/cluster_count/clusterCount.html" height="600px" width="600px"></iframe>


Auteur#

Arnaud Vandecasteele#

portrait

Bien qu'issu à l'origine d'un parcours universitaire (doctorat et post-doc), j'ai finalement tenté l'aventure entrepreunariale au travers de Geolab.
Mes principaux centres d'intêrets dans le domaine de la géomatique portent sur les logiciels Open Source et plus particulièrement QGIS.
J'aime également le développement informatique avec une forte préférence à tout ce qui se passe côté serveur (base de données, traitements, etc.). Côté techno, mes choix se portent habituellement sur du (Geo)Django et PostgreSQL/PostGIS.

Pendant mon temps libre, vous me trouverez un GPS à la main afin de contribuer à OpenStreetMap ou sur un tatami en train de pratiquer le Jiu-Jitsu Brésilien.

Si vous êtes intéressé par l'un ou tous ces sujets, n'hésitez pas à me contacter !

Contributions à cette page : Julien Moura (73.48%), Florian Boret (25.76%), Geotribot (0.76%)

Ce contenu est sous licence Creative Commons BY-NC-SA 4.0 International Pictogramme Creative Commons Pictogramme Creative Commons BY Pictogramme Creative Commons NC Pictogramme Creative Commons SA


Commentaires

Une version minimale de la syntaxe markdown est acceptée pour la mise en forme des commentaires.
Propulsé par Isso.