Académique Documents
Professionnel Documents
Culture Documents
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.
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.
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
/**
* 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;
}
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.
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.
Contenus corrélés
Infrastructure webmapping minimaliste (partie 1)