Imprimer des cartes web avec geoserver : évitez le plugin!

Nous verrons ici comment mettre en place une solution pour générer des pdf pour impression à partir d’une page de cartographie interactive, la page codée en OpenLayers 4 et le serveur avec Geoserver 2.14.

En principe, à lire la doc de Geoserver, tout devait être très simple: installation du plugin Print de Geoserver, test de l’install, configuration et c’est tout.

Si l’installation est simple et rapide, les problèmes commencent quand on veut utiliser la page de test proposée pour vérifier que tout marche. Impossible de la faire marcher et à chaque fois où l’on trouve l’origine du problème et qu’on le résout, c’est pour avoir un nouveau message d’erreur et un autre problème à essayer de résoudre.

Les chemins des scripts ne sont plus valables, le contenu des bibliothèques ont changé, bref, si vous voulez perdre votre temps, vous pouvez toujours essayer.

Vous pouvez aussi chercher les solutions sur le net et comme moi, trouver des posts dans des forums avec les mêmes questions posées… et sans aucune réponse.

Reprenons depuis le début…

Le module d’impression doit générer un fichier pdf contenant une carte et des informations. Cette carte est produite par Geoserver et la demande est générée par une page html écrite avec OpenLayers. Même si l’on peut tout faire sans autre bibliothèque, on fait souvent appel à la bibliothèque GeoExt qui simplifie le travail de codage de l’application.

Pour ce qui est de la génération du pdf, elle s’appuie sur la bibliothèque java Mapfish Print.

Si côté Geoserver la version utilisée n’influe pas dans le résultat, il n’en est pas de même pour les autres composants.

L’installation décrite dans la documentation Geoserver fait référence à la version 2 de Mapfish. Celle-ci a été remplacée par MapFish3 en 2015. Il faut comprendre surtout que les deux versions sont complètement différentes tant au niveau des syntaxes qu’au niveau du workflow de travail.

MapFish V2 est utilisée avec la bibliothèque GeoExt V2 qui s’appuie sur OpenLayers 2. C’est à dire des vieilles versions.

Si vous travaillez avec OpenLayers 4 ou 5, la version de GeoExt à utiliser est la version 3, et la version de Mapfish à utiliser est la version 3.

Et donc, il ne faut surtout pas installer le plugin d’impression de Geoserver (MapFish V2).

Ceci n’est pas un problème, MapFish3 s’installe facilement. Le ou les problèmes viennent quand vous cherchez de la documentation, des exemples, des infos sur des messages d’erreur, sur le net. Vous aurez pêle-mêle des références à toutes les versions mais sans savoir à quelle version elle se réfèrent…

Installation de Mapfish 3

Le fichier WAR de Mapfish Print est une archive Java qui peut être exécutée sur tout serveur d’applications Web Java tel que Tomcat ou Jetty. Pour utiliser Mapfish Print en tant qu’application Web autonome, vous devez:

  • Installer Java 7 ou une version ultérieure
  • Télécharger le serveur d’applications Web: fichier war à partir de l’adresse http://mapfish.github.io/mapfish-print-doc/download.html
  • Placer le fichier WAR print Mapfish dans le répertoire webapps du serveur d’applications Web.
  • Renommer le fichier WAR de Mapfish Print en un nom plus pratique, tel que print.war (le nom fera partie de l’URL).
  • Démarrer le serveur d’applications Web (Tomcat ou Jetty)
  • Vérifiez que l’application est exécutée correctement en visitant http: // localhost: 8080 / print / index.html. (Cela suppose que le serveur s’exécute sur le port 8080 de l’hôte local et que vous ayez renommé war. Print.war)

Pour l’instant, ne faites rien avec cette page. Le fait qu’elle s’affiche suffit pour confirmer que l’installation de MapFish s’est passée correctement.

Fonctionnement de Mapfish 3

Le peu de documentation en ligne est difficile à appréhender, car il n’y a pas d’introduction claire sur l’architecture générale

Pour que l’utilisateur obtienne un document de ce type en cliquant sur un bouton « Imprimer » situé sur une page avec une carte interactive (page html avec du code OpenLayers) il y a trois éléments à travailler:

  • Un modèle de formulaire créé avec Jasper Studio
  • un fichier config.yaml configuré sur le serveur d’impression
  • un élément « specs » à ajouter à l’ordre POST ou GET de la page html

Voyons ça un peu plus en détail.

Modèle de formulaire

Pour créer le formulaire on utilise Jaspersoft Studio. Vous pouvez le télécharger à partir de cette page.

Jasper Studio permet de créer un modèle de formulaire où vous pourrez placer les blocs de textes, d’images, de cartes et de légende mais également d’autres blocs comme les graphiques

Le but de ce travail est de créer un fichier .jrxml avec le modèle de page à créer. Le contenu même de la page va être défini ailleurs: les couches à représenter, l’échelle, la projection,…

Fichier de configuration .yaml

Par rapport à la version 2 de Mapfish Print, il y a toujours un fichier de configuration au format yaml mais celui-ci est maintenant beaucoup plus simple et se focalise sur la définition des modèles:  les fichiers Jasper à utiliser (le .jrxml précédent), et les paramètres à envoyer au moteur Jasper pour remplir les blocs du modèle.

Voici un exemple de fichier de configuration très simple:

Ce qu’il faut comprendre dans ce fichier:

  • la ligne A4 portrait: !template défini le nom du modèle. Quand on voudra utiliser cette configuration on le fera en se référant au layout A4 portrait
  • le reportTemplate permet d’indiquer le nom de notre fichier .jrxml créé avec Jaspersoft Studio.
  • les attributes title et map contiennent les informations à transmettre au moteur Jasper. Ceci veut dire que nous avons créé dans le modèle de formulaire un bloc title et un bloc map. Ici on renseigne le contenu de ces deux blocs.

Bien sûr, il y a d’autres options disponibles pour les fichiers de configuration. Mais pour l’instant restons simples.

Nous avons un modèle de formulaire .jrxml et un fichier de configuration .yaml. Il ne nous reste qu’a envoyer la demande de création du pdf.

Demande d’impression

A partir de la page html nous allons faire un POST vers le serveur avec un paramètre spec qui va contenir, au format json, les paramètres de notre demande d’impression.

Voici un exemple de spec :

{
    "layout": "A4 portrait",
    "attributes": {"map": {
        "center": [
            5,
            45
        ],
        "rotation": 0,
        "longitudeFirst": true,
        "layers": [{
            "geoJson": "file://countries.geojson",
            "style": {
                "*": {"symbolizers": [{
                    "fillColor": "#5E7F99",
                    "strokeWidth": 1,
                    "fillOpacity": 1,
                    "type": "polygon",
                    "strokeColor": "#CC1D18",
                    "strokeOpacity": 1
                }]},
                "version": "2"
            },
            "type": "geojson"
        }],
        "scale": 100000000,
        "projection": "EPSG:4326",
        "dpi": 72
    }}
}

La ligne « layout »: « A4 portrait » sert à indiquer le lien avec le fichier config.yaml avec sa ligne A4 portrait: !template

Dans la liste des attributs envoyés, sur cet exemple simple, nous avons seulement la carte à afficher (« map« ) avec ses paramètres de mise en forme (centrage, rotation,échelle,projection, définition) et, surtout, la définition des couches à cartographier avec la définition de leur sources des données (ici un fichier geoJson local).

En réponse à ce post la page reçoit l’url de téléchargement du document pdf produit.

Pour vérifier ceci, vous pouvez maintenant copier-coller le code json correspondant aux spec, dans la fenêtre de Test Print:

Cliquez sur Create and Get Print ou Post and Poll Print , vous aurez en retour votre fichier pdf:

Le même fichier de configuration yaml et le même modèle jrxml peuvent être appelés avec des données différentes. Voici une autre version du code json spec qui demande les données des pays servies en WMS par Geoserver:

{
  "layout": "A4 portrait",
  "outputFormat": "pdf",
  "attributes": {
    "map": {
      "projection": "EPSG:3857",
      "dpi": 72,
      "rotation": 0,
      "center": [-8233518.5005945, 4980320.4059228],
      "scale": 130000000,
      "layers": [
        {
          "baseURL": "http://carto-dei-brest.fr/geoserver/postgres/wms",
          "opacity": 1,
          "type": "WMS",
          "layers": ["postgres:pays"],
          "imageFormat": "image/png",
          "styles": ["polygon"],
          "customParams": {
            "TRANSPARENT": "true"
          }
        }
               ]
    }
  }
}

Dans la page de test print nous remplaçons le texte json et le résultat obtenu est le suivant:

Pour aller plus loin, vous avez une présentation de CampToCamp et la documentation de Mapfish,

Et si vous utilisez le plugin print de Geoserver…

Si vous décidez quand même d’utiliser le plugin mis à disposition par Geoserver, il faut savoir que:

  • il n’y a pas de possibilité d’utiliser Jaspersoft pour créer un modèle. Tout ce que vous faites avec Jaspersoft et MapFish 3 vous devrez le faire à la main dans le fichier config.yaml. Et vous n’aurez pas les mêmes possibilités comme, par exemple, inclure des graphiques dans votre sortie pdf.
  • la syntaxe du fichier yaml est totalement différente. Vous trouverez sa description sur cette page.
  • Si vous voulez utiliser les exemples de la bibliothèque GeoExt comme base de vos développements, il faudra installer et utiliser la version GeoExt2. GeoExt 3 n’est pas compatible avec le module Print de Geoserver.

Si cet article vous a intéressé et que vous pensez qu'il pourrait bénéficier à d'autres personnes, n'hésitez pas à le partager sur vos réseaux sociaux en utilisant les boutons ci-dessous. Votre partage est apprécié !

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *