Skip to content

Instantly share code, notes, and snippets.

@mdouchin
Created September 11, 2015 09:43
Show Gist options
  • Save mdouchin/3cbf178dcaca4daa57a9 to your computer and use it in GitHub Desktop.
Save mdouchin/3cbf178dcaca4daa57a9 to your computer and use it in GitHub Desktop.
Pour bien comprendre les soucis de performance, il faut voir comment fonctionne Lizmap pour l'instant. Je vais essayer de présenter les concepts utilisés, et de proposer des solutions concrètes (et des idées d'amélioration de Lizmap)
Par défaut, pour chaque couche QGIS ajoutée dans Lizmap, la légende de Lizmap propose une case à cocher, qui est activée (cochée) si la couche était visible dans QGIS. Cela veut donc dire que si vous avez 30 couches, Lizmap doit demander à QGIS Server les images pour chacune des 30 couches, dès le démarrage de l'application.
Dans la version stable actuelle du plugin Lizmap, l'option Image unique n'est pas cochée. Cela signifie que pour chacune des couches à afficher dans le navigateur, au lieu de demander une seule image à QGIS server (toute la largeur de l'écran), Lizmap, via OpenLayers, demande à la place autant de "tuiles" carrées d'environ 250 pixels de côté. Chaque tuile est une image. Le système de tuile a un avantage : les tuiles sont créées en fonction de l'emprise maximale du projet QGIS et d'autres paramètres, et donc en gros si 2 personnes différentes affichent la même zone, les mêmes tuiles sont demandées et envoyées. Cela permet donc de mettre en cache ces petites images:
* côté "serveur" (là où sont installés Lizmap et QGIS Server) Si la tuile a déjà été demandée, est dans le cache, et n'est pas "expirée", alors Lizmap ne redemande pas à QGIS Server de la régénérer, mais l'envoie directement au navigateur de l'utilisateur.
* côté "client" (le navigateur web): les tuiles qui sont dans le cache du navigateur, et non expirées, ne sont pas demandées au serveur. Il n'y a donc même pas de requête (de question posée) faite au serveur dans ce cas.
Le" souci" du cache serveur, c'est qu'il faut le générer. Dans la version actuelle de Lizmap, le seul moyen est d'aller "visiter" les différentes zones et échelles du projet, et d'attendre patiemment que chaque tuile arrive. En gros le cache est généré à la demande, lorsque les utilisateurs se baladent sur la carte. Ce n'est pas optimum pour les projets importants (grande zone et nombreux niveaux de zoom). Dans la prochaine version de Lizmap, nous avons ajouté un prégénérateur de cache (en ligne de commande) qui permet de lancer la création de toutes les tuiles ( choix des couches, des échelles, etc.)
Je vais essayer de présenter maintenant comment la carte Lizmap récupère les images des couches à afficher sur la carte.
Admettons que votre l'écran de l'utilisateur visualisant la carte Lizmap fasse environ 1280 X 768 pixels. Si les couches sont affichées en tuiles, pour chaque couche, on doit donc afficher environ 5 X 3 tuiles de 256 pixels, soit 15 tuiles pour chaque couche.. Cela peut bien sûr être encore plus si l'écran est plus grand. Et c'est souvent un peu plus car on récupère aussi les images en bordure de la zone. Disons pour la démonstration, qu'on doit récupérer en moyenne 20 tuiles
Avec 30 couches, c'est donc 30 x 20 = 600 tuiles à afficher en même temps par Lizmap, et ce au démarrage, puis à chaque fois que l'utilisateur va sur une zone et une échelle nouvelles (par exemple lorsqu'il se déplace ou qu'il zoome). Cela veut donc dire que pour chaque utilisateur, il faut environ 600 requêtes au serveur Lizmap par zone affichée. Si il y a 10 utilisateurs en parallèle, cela commence à être problématique si le cache n'a pas été généré et que Qgis Server doit faire le travail (en fonction bien sûr des performances du serveur, et de la complexité du projet QGIS)
En fonction de la donnée (vecteur, raster, ensemble de couches) et du format d'image demandé via la configuration de Lizmap(PNG, JPG) , les tuiles sont plus ou moins grosses en taille. Disons pour la démonstration que chaque tuile fait environ 30ko.
Dans le cas de notre écran, avec 20 tuiles par couche, il faut donc télécharger 20 x 30ko = 600ko pour chaque couche.
Si on a 30 couches "cochées" dans la légende, le navigateur doit donc télécharger 30 x 600 = 18000 ko, soit environ 18Mo pour les 30 couches ! Cela devient donc un assez lourd pour le serveur (bande passante consommée), et pour chaque utilisateur (temps de téléchargement, même avec une bonne connexion)
Ces petits calculs montrent bien qu'il faut faire des compromis lorsqu'on fait du web mapping. Si on regarde notre ami Google Map ou d'autres outils, en plus d'avoir des serveurs bien dimensionnés , ils ont fait un choix de simplicité : une seule couche de fond affichée à la fois, et très peu de couches affichées par dessus (et pas toutes en même temps). Sans aller vers cet extrême, il est important de savoir quelle donnée doit être affichée lors de l'affichage de la carte, et quels compromis ont peut faire pour améliorer les performances. Il faut penser "publication web pour plusieurs utilisateurs" et non "affichage d'une carte dans QGIS par une seule personne".
Si vous présentez une carte avec 50 couches à cocher, la plupart des utilisateurs ne les cocheront ou décocheront jamais. Bien sûr, je comprends qu'il faut permettre parfois aux utilisateurs d'afficher certaines données et pas d'autres, et que parfois ce n'est pas possible de restreindre le nombre de couches proposées. Cela dépends du projet, de sa finalité, etc.
Je vais essayer de présenter les possibilités actuelles de Lizmap pour optimiser les choses.
* Faire plusieurs projets QGIS = plusieurs cartes Lizmap, pour regrouper les données par thématique. Les utilisateurs préfèrent souvent une carte "urbanisme" avec 10 couches, une carte "Environnement" avec 5 couches, etc., plutôt qu'une seule grosse carte qui montre toutes les données. En ajoutant une petite imagette pour chaque projet QGIS, Lizmap peut présenter les choses de manière claire dans la page projet. Vous pouvez aussi partager certaines couches entre projets via l'intégration de couches dans QGIS.
* Utiliser l'option Seulement des cartes dans la partie Services de l'interface d'aministration. Cette option permet à l'utilisateur de basculer automatiquement d'une carte Lizmap à l'autre, via le bouton "Maison", tout en conservant au maximum l'emprise et l'échelle actuelle. La page d'accueil de Lizmap classique, avec les imagettes des projets, n'est plus visible, et l'utilisateur arrive directement sur une carte (configurée via l'administration). Il utilise le bouton "Maison" pour changer rapidement de thématique. C'est une possibilité intéressante pour faire des projets par thèmes (voir ci-dessus)
* Ne pas activer l'affichage de toutes les couches au démarrage (case "Activée" dans le plugin Lizmap). Ainsi, seules les données importantes seront visibles au début, et chaque utilisateur pourra, s'il le souhaite, cocher les couches qu'il veut voir. On évite ainsi beaucoup de requêtes.
* Regrouper les couches dans des groupes, et utiliser l'option "Grouper comme une couche" de Lizmap. Très souvent, on peut afficher simultanément plusieurs couches d'une même thématique, si la symbologie est adaptée. Lizmap ne montrera alors qu'une case à cocher pour le groupe. Et surtout il ne demandera pas une tuile par couche, mais une seule tuile pour toutes les couches du groupe. Cela peut vraiment beaucoup diminuer le nombre de tuiles à afficher, donc de requêtes au serveur (et de volume de données à télécharger par l'utilisateur). La légende présentée est alors la légende du groupe.
* Utiliser l'option "Image non tuilée" pour certaines couches. Au lieu de demander des tuiles à Lizmap (donc à QGIS Server), une seule tuile d'environ la taille de l'écran est alors demandée pour chaque couche (ou groupe de couche regroupé comme une couche). Cette option peut donc aussi beaucoup réduire le nombre de requêtes demandées au serveur. Par exemple dans notre cas initial, sans les optimisations ci-dessus, et si toutes les couches ont cette option cochée, alors chaque utilisateur de Lizmap demande 30 images (une par couche) à chaque changement de position ou d'échelle, au lieu des 480 tuiles. C'est moins de requêtes au serveur (mais la taille à télécharger est relativement identique). Par contre, comme bien sûr les tailles d'écran diffèrent entre utilisateur, et que les zones vues par chacun sont rarement les mêmes, on ne peut alors plus mettre en cache ces images. C'est pourquoi cette option et l'option "Cache serveur" sont exclusives. En fonction du type de couche, il peut être plus intéressant de conserver le format tuilé pour mettre en cache, ou au contraire d'avoir un système d'image unique. Par exemple, un fond cadastrale créé à partir de 15 couches, dédié à l'affichage, pourra être "Regroupé comme une couche" et mis en cache, alors qu'une couche de lignes de bus, plus légère, pourrait être affichée en mode "Image non tuilée"
* Cocher la case "Cacher les cases à cocher des groupes". Cela permet ainsi d'éviter que les utilisateurs cochent un groupe de 20 couches "sans faire exprès", et donc lancent autant de requêtes au serveur. Au passage, éviter les groupes avec plus de 5 ou 10 couches est une bonne pratique.
* Optimiser les données et votre projet QGIS. Bien sûr, porter une carte sur internet change le paradigme de votre projet QGIS. Vous n'êtes plus seul à zoomer, vous déplacez sur la carte comme dans QGIS. Il y a plusieurs utilisateurs qui peuvent le faire en parallèle. C'est donc plus de travail pour QGIS Server. Autant lui faciliter la tâche !
- Créer des indexes spatiaux pour toutes vos couches vectorielles
- Créer des pyramides pour tous vos rasters (sauf les très légers)
- N'afficher les couches qu'aux échelles pertinentes. Pas besoin par exemple d'afficher un bâti au 1/ 500 000, ou les chemins de la BDTopo au 1/250 000
- Utiliser des versions simplifiées des données pour l'affichage aux petites échelles entre 1/2 000 000 et 1/250 000 (au moins). Vous pouvez regrouper les versions des couches dans des groupes, adapter les seuils de visibilité, et "regrouper comme une couche" pour offrir une seule couche dans Lizmap.
- Attention aux reprojections à la volée Si vous affichez des données en Lambert 93 (EPSG:2154) sur un fond IGN, OpenStreetmap ou Google (en Pseudo Mercator, EPSG:3857), QGIS Server va devoir reprojeter vecteurs et raster avant de faire le rendu. En fonction du volume et de la complexité des données, cela peut avoir un impact important. Nous allons prochainement ajouter la possibilité d'utiliser les fonds IGN Géoportail en 2154 (récemment ajouté par l'IGN) pour éviter ces reprojections.
- Attention aux options de rendu dans QGIS, qui peuvent impacter beaucoup les performances (en fonction des données) : étiquettes, utilisation d'expressions, etc.
- Optimiser les requêtes PostGIS (si vous utilisez ce format) : ajout des indexes spatiaux, des indexes pour les champs filtrés, pour les clés étrangères, paramétrer la configuration de PostGreSQL pour l'adapter à votre serveur, etc.
- Utiliser le bon format d'image Pour les fonds de carte, utilisez le format d'image JPG : les tuiles seront plus petites, et donc plus rapide à télécharger. Et vous n'avez pas besoin de transparence. Pour les autres couches, essayez le PNG 16bit ou 8 bit. En fonction de la symbologie, le rendu peut être identique, pour des tuiles moins lourdes. Il faut tester pour voir comment l'image initiale est dégradée.
* Augmenter les capacités du serveur C'est toujours une possibilité , mais c'est inutile si toutes les optimisations ci-dessus n'ont pas été faites. En tout cas, évitez d'utiliser un serveur de 2Go de RAM avec 2 processeurs à 2.2 Ghz. Un minimum pourrait être un processeur quadri-core assez véloce, et 8Go de RAM. Éviter aussi d'installer QGIS Server et Lizmap sous Windows, c'est plus complexe et moins performant.
Nous travaillons actuellement sur la version 3 de Lizmap, qui apportera quelques améliorations
* outil de pré-génération du cache serveur, via l'utilisation du protocole WMTS. Il sera au passage aussi possible d'utiliser les couches en cache Lizmap comme des couches WMTS dans QGIS
* non téléchargement des légendes au démarrage de la carte (et à chaque changement d'échelle), mais seulement à la demande, si la légende est ouverte (30 requêtes en moins au démarrage, et à chaque zoom, dans notre exemple),
* options "Image non tuilée" et "Cacher les cases à cocher des groupes" cochées par défaut
* Optimisations du code.
Pour le futur:
Nous pensons aussi à avoir un système équivalent à certaines autres outils, mais en option. Beaucoup d'outils de WebMapping ne demandent qu'une seule image au serveur, quelque soit le nombre de couches cochées dans la légende. Le fonctionnement est alors très proche de celui utilisé dans QGIS. Pour le navigateur de l'utilisateur, c'est une seule image demandée à la fois. Elle peut donc être longue à arriver si beaucoup de couches sont cochées (beaucoup de travail de rendu pour QGIS Server), mais on diminue alors beaucoup le nombre de requêtes.
Par contre, le système n'est pas tuilé, et aucun cache ne peut être utilisé, ce qui peut poser des problèmes d'accès concurrentiels si le nombre d'utilisateurs simultanés est important, car alors c'est QGIS Server qui doit faire tout le travail à chaque requête.
Nous allons essayer de voir comment proposer une solution qui permette de bénéficier des avantages des 2 "techniques".
J'espère que cela pourra aider toutes les personnes qui se posent des questions équivalentes sur l'optimisation des projets QGIS pour Lizmap. J'ai sûrement oublié des choses, mais on pourra toujours les ajouter au fur et à mesure.
Michaël
http://docs.3liz.com/fr/index.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment