Le webmapping occupe une place prépondérante sur le web depuis quelques années avec la démocratisation de cartes tel que google maps, openstreetmap et d’autres. La généralisation des smartphones et tablettes ont aussi explosé ces dernières années. De facto cela a entrainé l’émergence de la cartographie mobile et qui dit mobilité dit connectivité. A l’heure du cloud, du tout connecté, on en arrive a oublier les réalités du terrain : en pleine nature pas de réseau wifi à l’horizon, ni 4G, ni même 3G…

Nous voilà arrivé à notre problématique : comment réaliser une application SIG mobile déconnectée avec des données cartographiques raster et vecteur ?

Pour cela nous avons utilisé un certain nombre de librairies à savoir :

Apache Cordova (anciennement PhoneGap)

Cordova est un SDK OpenSource qui permet un développement d’applications cross-platform (iOS, Android, WP8, Blackberry…) en HTML, CSS et JavaScript. Le SDK permet d’accéder aux fonctions natives du terminal (système de fichier, caméra, accéléromètre…) et dispose d’un grand nombre de plugins. Dans un souci de mutualisation des sources et d’un développement multiplateforme cette solution est apparue comme adéquate. De part la quantité de données nécessaires en mode déconnecté, une solution en HTML5 n’était pas envisageable.

Sencha Touch

Sencha Touch est un framework JavaScript permettant à une application web d’avoir un aspect et comportement natif pour Android, iOS, Windows Phone 8 et Blackberry.

Leaflet

Leaflet est une librairie JavaScript OpenSource qui permet d’afficher des cartes interactives optimisées pour les appareils mobiles. La génération de la carte en HTML5 et CSS3 permet un rendu optimal sur smartphone et tablette. La librairie n’est pas aussi complète que OpenLayers mais celle-ci est plus performante sur mobile (en attendant la sortie de OpenLayers 3).

Sqlite

Sqlite est un moteur de base de données très léger et puissant, cela en fait un outil incontournable pour la gestion des données sur smartphone et tablette.

MBTiles

MBTiles est une spécification pour stocker des données cartographiques tuilées dans une base de données SQLite. Les tuiles sont stockées en base64 dans une table avec une récupération de ces tuiles via le principe du protocole TMS avec les valeurs z, x et y. Il existe différentes implémentations pour lire/écrire ces fichiers MBTiles notamment MapProxy et TileMill. La spécification définit un schéma suivant :

CREATE TABLE tiles (
  zoom_level INTEGER,
  tile_column INTEGER,
  tile_row INTEGER,
  tile_data BLOB
);
 
CREATE TABLE metadata (
  name text,
  VALUE text
);

Les fonctionnalités de l’application

Le but de l’application est la saisie d’observations (stade de culture, maladies…) sur les parcelles agricoles accessibles au conseiller ou technicien de la Chambre d’agriculture. Une géolocalisation de l’utilisateur permet de le situer sur la carte et d’afficher les représentations géographiques des parcelles afin qu’il puisse sélectionner la ou les parcelles qui seront incluses dans son observation.

Une fois les parcelles sélectionnées celui-ci accède à différents formulaires générés dynamiquement suivant le contenu en base pour saisir les caractéristiques du type d’observation qu’il aura choisi.

Toutes les fonctionnalités de saisie, consultation, recherche et visualisation cartographique sont disponibles en mode connecté ou déconnecté en ayant auparavant effectué une importation des données sur lesquels nous souhaitons travailler (emprise géographique choisie par l’utilisateur).

Les fondements de l’application

Au delà de l’encapsulation de l’HTML, CSS et JavaScript dans une application native, Apache Cordova permet dans l’application :

  • d’accéder à la caméra pour la lecture d’un QR code afin de renseigner la configuration propre à chaque Chambre d’agriculture régionale
  • de gérer le système de fichier pour télécharger les fichiers MBTiles
  • d’interagir avec les bases de données SQLite et MBTiles

La lecture et décodage du QR code se base sur un plugin Cordova qui utilise la librairie zxing. Une fois les différentes librairies intégrées dans les projets Xcode et eclipse, l’utilisation en devient très facile :

window.plugins.barcodeScanner.scan(
  function(result) {
    if (!result.cancelled) {
      //contenu texte du décodage du QR Code
      alert(result.text);
    }
  },
  function(error) {
    console.warn("scanning failed: " + error)
  }
);

De la même façon, Le téléchargement et l’interaction avec les bases MBTiles se fait via une api JavaScript de manière assez facile et efficace. Cela permet de mettre efficacement en place un nouveau type de couche dans Leaflet afin d’aller lire le contenu des fichiers MBTiles téléchargés :

L.TileLayer.MBTiles = L.TileLayer.extend({
  mbTilesDB : null,
 
  initialize : function(url, options, db) {
    this.mbTilesDB = db;
    L.Util.setOptions(this, options);
  },
 
  getTileUrl : function(tilePoint, tile) {
    this._adjustTilePoint(tilePoint);
    var z = this._getZoomForUrl();
    var x = tilePoint.x;
    var y = tilePoint.y;
    var base64Prefix = 'data:image/png;base64,';
    this.mbTilesDB.transaction(function(tx) {
      var query = 'SELECT tile_data FROM tiles WHERE zoom_level = ? AND tile_column = ? AND tile_row = ? ;';
      tx.executeSql(query, [z, x, y], function(tx, result) {
        if (result.rows.length > 0) {
          tile.src = base64Prefix + result.rows.item(0).tile_data;
        } else {
          //on pourrait retourner une image en base64 pour les tuiles non trouvées (image en 256px x 256px)
          console.log('tile not found z:' + z + ' x:' + x + ' y:' + y);
        }
      }, function(tx, er) {
        console.log('error with executeSql', er);
      });
    });
  },
  _loadTile : function(tile, tilePoint) {
    tile._layer = this;
    tile.onload = this._tileOnLoad;
    tile.onerror = this._tileOnError;
    this.getTileUrl(tilePoint, tile);
  }
});

Sencha Touch permet de s’abstraire des problèmes de résolution, de taille d’écran et de système d’exploitation entre les différents modèles de smartphone et tablette. La gestion des formulaires, liste de données est aussi facilitée, cela permet d’avoir des formulaires et des listes avec un style et un comportement proche des composants natifs :

La partie cartographique est assurée par Leaflet, qui en mode connecté, affiche des fonds de plan issus d’un service WMS (OpenStreetMap, IGN…. etc) ainsi que des couches vectorielles provenant de WebServices en GeoJSON. En mode déconnecté (ou même en connecté par choix de l’utilisateur), cette même carte affiche le contenu des fichiers MBTiles en fond de plan ainsi que les géométries en GeoJSON issues d’une base SQLite en tant que couche vectorielle.

Bilan

Le bilan que l’on peut dresser à la fin de ce projet est plus que positif. La rapidité et la fluidité de l’application sont là et même avec plusieurs caches MBTiles supérieurs à 1Go chacun. Nous étions partis avec quelques appréhensions sur Sencha Touch qui ne s’était pas montré très véloce et performant dans sa version 1.1. Force est de constater que les défauts de cette première monture ont largement été corrigés dans la version 2.2.0 qui s’avère très performante (même à partir de la première version alpha).

Sur la partie cartographique, l’utilisation de la librairie Leaflet a montré parfois quelques défauts de jeunesse comparé à OpenLayers comme par exemple sur le manque d’un outil de sélection vectorielle. Les quelques défauts et lacunes dans Leaflet sont compensés par une rapidité et fluidité d’utilisation sur smartphone et tablette. Ce choix pourrait être remis en question avec la sortie prochaine de OpenLayers 3 qui d’après les premiers tests, semble rattraper son retard sur les terminaux mobiles.

Fort de nombreux développements Web/WebMobile et cartographiques, nous partions en terrain connu sur les librairies JavaScript. Cordova quant à lui était la nouvelle inconnue de cette équation, mais une fois passé l’initialisation des différents workspace et intégration des plugins nécessaires, il n’y a pas eu de difficultés majeures. Le principal défaut que l’on pourrait reprocher à Cordova est aussi une de ses qualités : à savoir la fréquence des mises à jour de version qui s’effectue au rythme d’une par mois. Cela nécessite des migrations de version dans les workspace pas toujours évidentes du fait de l’intégration de divers plugins qui ne suivent pas forcément le même rythme de publication. Mais l’avantage de cela est de voir des bugs rapidement corrigés dans la version suivante notamment grâce à une communauté assez importante sur gitHub.

Nous finirons cet article par une petite vidéo de démonstration de l’application :