Vous êtes sur la page 1sur 7

Webmapping avec Drupal et Leaflet

Par Simon Georges Google — publié 11/05/2015


L'intégration de @LeafletJS avec #drupal est vraiment très rapide à
mettre en œuvre.

Introduction
Pour le site Drupal d'un client, nous avons du développer une page
listant des partenaires (type de contenu pré-existant) de 2 façons :
d'abord une carte dynamique, ensuite un listing plus classique. La
majorité du travail est réalisable directement dans l'interface, et nous
n'avons utilisé le développement que pour améliorer l'import des
données.

Voici à quoi ressemble le résultat final (partie cartographique


uniquement) :

Modules utilisés
Pour la partie webmapping, notre bibliothèque de prédilection chez
Makina Corpus est Leaflet, dont nous avons déjà parlé dans plusieurs
articles.

Le stockage de données géographiques dans Drupal se fait avec


Geofield, et le géocodage des données souvent avec Geocoder (dont
nous sommes d'ailleurs co-mainteneurs). Le champ de référence du
geocodage est une des questions à se poser : Adressfield ? Un simple
champ texte ? Tout dépend du format des données que nous avons
(qui sont alors plus ou moins facile à importer selon le champ choisi),
mais aussi de comment nous allons les exploiter : si nous avons
besoin de la visualisation par ville, par exemple, alors une séparation
des champs (et donc, éventuellement, un AdressField) sera
nécessaire.

Voici pour référence la partie d'un fichier pour drush make utilisé pour
le cas présent :
projects[] = geophp
projects[] = geofield
libraries[leaflet][download][type] = "get"
libraries[leaflet][download][url] = "http://leaflet-
cdn.s3.amazonaws.com/build/leaflet-0.7.3.zip"
projects[] = leaflet
projects[] = addressfield
projects[] = geocoder

Récupération des données


Les données sources provenant d'un fichier .xls, ma première idée fut
d'utiliser le module Feeds, dédié à l'import de données, qui comporte
une interface graphique permettant au client d'éventuellement
modifier le mapping si le fichier venait à changer. C'est l'approche la
plus "site builder" possible, sans aucun développement associé.
Malheureusement, le fichier de données nécessitait trop de
transformations (même en utilisant des modules additionnels comme
Feeds Tamper, qui permet d'effectuer quelques transformations durant
l'import).

Heureusement, comme souvent dans Drupal, il existe une approche


"développeur" au besoin : l'utilisation du module Migrate. Il m'a suffit
d'ajouter au module pré-existant un fichier mymodule.migrate.inc
contenant la déclaration de ma migration pour réaliser les traitements
que je voulais (notamment, tout est réalisée dans la fonction
prepareRow() :
/**
* Implements hook_migrate_api().
*/
function mymodule_migrate_api() {
return array(
'api' => 2,
'groups' => array(
'client_name' => array(
'title' => 'Migration for the new version of the client website',
),
),
'migrations' => array(
'ClientPartners' => array('class_name' => 'ClientPartnersMigration',
'group_name' => 'client_name'),
),
);
}

/**
* Main migration class.
*/
class ClientPartnerMigration extends Migration {
public function __construct() {
parent::__construct();
// "Real" CSV columns.
$columns = array(
0 => array('id', 'ID'),
2 => array('country', 'Country'),
3 => array('city', 'City'),
...
12 => array('address', 'Address'),
13 => array('website', 'Website'),
);
// "Pseudo-colums".
$fields = array(
'field1' => 'composite field populated by prepareRow()',
'field2' => 'composite field populated by prepareRow()',
'field3' => 'composite field populated by prepareRow()',
);
$this->source = new MigrateSourceCSV(
DRUPAL_ROOT . '/' . drupal_get_path('module', 'mymodule') .
'/partners.csv',
$columns,
array('header_rows' => 1),
$fields
);
$this->destination = new MigrateDestinationNode('partners');
$this->map = new MigrateSQLMap(
$this->machineName,
array('id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' =>
TRUE,)),
MigrateDestinationNode::getKeySchema()
);
$this->addFieldMappings();
}

function prepareRow($row) {
// Aggregate & transform data so we can use it during field mapping.
$row->field1 = ... ;
    $row->field2 = ... ;
 }

function addFieldMappings() {
// Contents are published and created by admin.
$this->addFieldMapping('uid')->defaultValue('1');
$this->addFieldMapping('status')->defaultValue('1');
// "Real" field mappings.
$this->addFieldMapping('title', 'name');
$this->addFieldMapping('field_country', 'country');
...
 $this->addFieldMapping('field_custom', 'field1');
}
}

Amélioration du géocodage
L'avantage d'utiliser une migration, c'est qu'on peut revenir en arrière
et la relancer tant que les données importées ne sont pas correctes,
cela m'a permis d'ajuster la précision du géocodage en ajoutant par
exemple la ville et / ou le pays au champ adresse dans le cas où celui-
ci ne les contenait pas déjà, passant de 80 points correctement
localisés à 145 (sur 150 données entrantes).

Réalisation de la carte
Views
La carte elle-même est réalisée rapidement en utilisant le module
Drupal d'intégration de Leaflet, et en créant simplement une Views
listant les contenus concernés sous forme de Leaflet Map (attention, il
faut ajouter impérativement à la vue le champ contenant les
informations géographiques, le Geofield mentionné au début de
l'article).

Fond de carte
Le module Leaflet ne contient qu'un fond de carte standard, et notre
client souhaitait un fond un peu plus travaillé. De nombreux fonds sont
disponibles sur internet, celui présenté sur la capture d'écran au début
de l'article a été intégré en ajoutant simplement le hook suivant à
notre code (c'est vraiment tout ce qu'il y a à faire, à part vider les
caches, comme toujours avec Drupal) :
/**
* Implementation of hook_leaflet_map_info().
*/
function mymodule_leaflet_map_info() {
$default_settings = array(
'attributionControl' => TRUE,
'closePopupOnClick' => TRUE,
'doubleClickZoom' => TRUE,
'dragging' => TRUE,
'fadeAnimation' => TRUE,
'layerControl' => FALSE,
'maxZoom' => 18,
'minZoom' => 1,
'scrollWheelZoom' => TRUE,
'touchZoom' => TRUE,
'trackResize' => TRUE,
// Don't specify, if you want to use Auto-box.
// 'zoom' => 2,
'zoomAnimation' => TRUE,
'zoomControl' => TRUE,
);
$map_info = array();
$map_info['Stamen Toner Lite'] = array(
'label' => 'Stamen Toner Lite',
'description' => 'Stamen Toner Lite',
'settings' => $default_settings,
'layers' => array(
'layer' => array(
'urlTemplate' => '//{s}.tile.stamen.com/toner-lite/{z}/{x}/{y}.png',
'options' => array(
'attribution' => 'Map tiles by Stamen Design, under CC BY 3.0. Data
by OpenStreetMap, under ODbL.',
'detectRetina' => TRUE,
),
),
),
);
return $map_info;
}

Si vous cherchez d'autres exemples de fonds utilisables, vous pouvez


regarder dans le module Leaflet More Maps qui en contient de très
nombreux. Ici, nous avons fait le choix de la performance en n'ajoutant
pas un module supplémentaire au site.

Marqueurs
Les marqueurs standard de Leaflet n'étant pas du tout en accord avec
la charte graphique du site, nous avons simplement dans Views
changé les options pour utiliser des marqueurs "divIcon" (permettant
de les thémer par CSS) en utilisant en plus l'option "Ajouter une classe
CSS" et en utilisant le champ taxonomie de notre contenu (qui nous
permet de changer la couleur du marqueur selon le type de
partenaire).

Ajout de la légende
La légende est alors une simple liste HTML reprenant les classes
utilisées dans la carte, positionnée en "pied de page" de la vue.

Réalisation du listing attenant à la carte


Avec ce listing, nous sommes dans notre élement : une simple Vue
listant les éléments, groupés par pays. L'unique subtilité est de
réaliser ce listing dans la même vue, en utilisant un affichage de type
attachment (incorrectement traduit par "fichier attaché" en français),
qui permet aux deux affichages de partager les filtres exposés, et
donc d'obtenir un rendu dynamique agréable.

Conclusion
La plus longue partie est venue cette fois encore (comme souvent
dans la manipulation de données) de l'import et de la transformation
de données. En effet, la mise en place de l'affichage se réalise en
quelques minutes grâce à la combinaison des modules Views et
Leaflet de Drupal. Vous pouvez d'ailleurs consulter le résultat final en
ligne sur le site de TBS Education.

Si vous rencontrez des difficultés dans la mise en place de ce type de


page, venez bénéficiez de nos formations à la construction de site
Drupal ou à la mise en place de portail géographiques avec Leaflet.

Contenus corrélés
 Infrastructure webmapping minimaliste (partie 1)

Vous aimerez peut-être aussi