Journal Servir ses propres tuiles OSM

Posté par  . Licence CC By‑SA.
Étiquettes :
45
21
nov.
2020

Sommaire

Salut les moule·e·s

Contexte

Pour le boulot, j’avais besoin de représenter sur une carte les points d’implantation de nos produits. C’est un serveur interne avec très peu d’utilisateurs, quasiment pas d’accès concurrent (si on est 3 à s’en servir en même temps ce sera bien le bout du monde).

Jusqu’à présent on faisait avec les cartes GoogleMaps. La représentation en elle-même est pas trop mal : on importe un CSV avec les coordonnées géographiques, on ajoute au CSV les colones qu’on veut, et ensuite on peut faire des règles de couleur des points en fonction des valeurs des colonnes.

Là ou le bât blesse, c’est que je n’ai pas réussi à trouver d’API (payante ou pas) permettant de gérer ces cartes (ajouter des points, modifier les valeurs, etc.). Il en résulte pas mal d’opérations manuelles à chaque modification.

J’ai donc décidé de regarder du côté de OpenStreetMap (OSM) pour le fond de carte.

Comment ça marche

Applet

En gros pour afficher quelques coordonnées GPS sur une carte OSM, il faut :
– une page web à laquelle se connecter (dans mon cas c’est mon application qui propose quelques pages contenant une carte en encart)
– sur la page utiliser un composant Javascript dédié (Leaflet ou OpenLayer sont les deux stars)
– donner à ce composant l’URL d’un serveur de tuiles pour qu’il télécharge les tuiles

En effet le calcul du rendu n’est pas fait par le client à partir de données géographiques, mais par un serveur qui a pré-calculé (ou pas, nous y reviendront) des morceaux de la carte : les tuiles.

Tuiles

Ces tuiles sont donc une image au format PNG généralement de 256x256 pixels et sont désignées par une coordonée à 3 valeurs : Z, X et Y.

L’URL finale d’une tuile est sous la forme : https://url_de_votre_serveur/tiles/{z}/{x}/{y}.png

Z est un niveau de zoom, X et Y sont des coordonnées (absices et ordonnées) dans ce niveau de zoom.

Zoom

Au niveau zéro de zoom, toute la carte du monde est représentée par une seule tuile, aux coordonnées X=0 et Y=0.

La tuile {Z=0,X=0,Y=0} :
Zoom 0

Au niveau de zoom 1, la carte du monde est coupée en 4 tuiles, les coordonnées étant {Z=1,X=0,Y=0}, {Z=1,X=0,Y=1}, {Z=1,X=1,Y=0}, {Z=1,X=1,Y=1}

   
image image
image image

Au niveau de zoom 2, la carte est coupée en 16 tuiles, X et Y variant de 0 à 3, et ainsi de suite.

Au niveau de zoom 18 (qui est par défaut le plus gros niveau de zoom calculé, mais monter à 20 reste assez courant), il faut 418 soit environ 68 milliards de tuiles pour représenter le monde.

Au passage, le calcul qui, à partir d’une coordonnée GPS et un niveau de zoom donne les coordonnées X et Y de la tuile est assez chiadé : la représentation utilisée étant une projection de Mercator, un pixel ne représentera pas la même distance au niveau de l’équateur ou aux pôles. Je vous laisse vérifier tout ça ici.

Trouver un fond de carte

Assez rapidement je me rends compte de la chose suivante : autant sur OpenStreetMap les données géographiques sont librement téléchargeables (par exemple vous pouvez télécharger ici les données récentes de votre région française préférée, ou même l’intégralité des données OSM), autant pour les tuiles, c’est un peu plus compliqué.

En effet, les ressources demandées étant assez importantes, très peu d’organismes permettent à n’importe qui d’utiliser leurs cartes. On trouve des fournisseurs (par exemple OpenStreetMapFr) mais rapidement une lecture des conditions d’utilisation des différents fournisseurs montre que si pour une utilisation personnelle il n’y a pas de problème, par contre, si le trafic doit être important, ou si on est dans un cadre pro, il faut soit payer une licence, soit aller voir ailleurs.

Le mieux est donc de se monter un serveur de rendu, d’autant que mon outil étant destiné à un Intranet, éventuellement coupé de connexion Internet, ce peut être une excellente option.

Calculer son fond de carte

Je commence à chercher et c’est un peu compliqué. Il faut une base de donnée dans laquelle on injecte les données géographiques téléchargées, Mapnik qui est une application de rendu, mettre tout ça sur un serveur Apache avec le module mod_tile. De plus Mapnik a besoin d'une feuille de style décrivant les couleurs, les types de traits, les informations à afficher (en fonction des zooms) etc. Une idée de la variété de rendus possibles est disponible sur cette jolie page.

Une fois une tuile calculée, elle est stockée sur le disque du serveur, et elle sera ainsi resservie directement au prochain appel. On ne sollicite donc Mapnik qu’une fois par tuile (mais pour rappel, les tuiles étant différentes à chaque niveau de zoom, pour un même quartier on peut finir à calculer plusieur dizaines de tuiles).

Switch2OSM

En ayant à peu près compris l’enchaînement et en commençant à me documenter je trouve rapidement le site qu’il me fallait : Switch2OSM.org.

Ce site destiné à promouvoir l’utilisation de OSM explique pas à pas comment monter son serveur de tuiles.

Plusieurs bases sont proposées :
– ubuntu 20.04 LTS (celle qui j’ai choisi)
– ubuntu 18.04 LTS
– ubuntu 16.04 LTS
– une image Docker

Les explications sont à jour, il faut suivre exactement la recette, et en quelques (dizaines de) minutes j’ai mon serveur de tuiles sur pied.

Ressources

Au niveau des ressources, on ne peut pas dire que j’ai utilisé un foudre de guerre : j’ai sorti d’un placard un PC à base de i7-6700 avec 16Go de RAM et un SSD de 120Go sur lequel j’ai mis Proxmox pour maquetter tout ça.

Ce serveur servira à tout mon projet :
– Une VM (base Debian10, 4Go de RAM) sur laquelle va tourner mon application de gestion de nos produits. Une BdD locale et une application que je développe en Python
– Une VM destinée à servir les tuiles OSM (base Ubuntu 20.04 LTS donc), avec 8Go de RAM

C’est reparti pour un nouveau suivi (à la lettre, j’insiste, j’ai essayé de moufter, j’aurais pas dû) des instructions de Switch2OSM sur cette nouvelle VM.

CPU/RAM

Les premiers essais sont concluants : côté RAM et CPU, ça ira. On est loin de l’instantané (le calcul d’une tuile met quelque chose comme 5 à 10 secondes), mais une fois les tuiles les plus utilisées calculées, c’est très fluide côté client. Comme précisé en préambule, il y a très peu de traffic de prévu, usage interne uniquement… ça ira quoi.

Par contre niveau espace disque, il va falloir voir plus grand.

Disque

Oui là c’est un peu compliqué, et mes 120Go ne suffiront pas.

Lors du déroulé de la recette Switch2OSM, on utilise des régions du monde avec peu de données, comme la carte de l’Azerbaïdjan par exemple. Cela permet d’aller assez vite et de voir rapidement un résultat (et que tout fonctionne) :
– taille du fichier télécharge : 24Mo
– temps d’importation : 2 minutes (de mémoire)
– taille de la base de donnée : je n’ai pas regardé (naïf, je ne me posais même pas la question)

Une fois ceci fait, je suis parti pour ajouter la carte de Midi-Pyrénées (nos principales implantations actuelles):
– taille du fichier téléchargé : 258Mo
– temps d’importation : 20 minutes (de mémoire)
– taille de la base de donnée : 8.8Go

Ah quand même… non parce que je veux tout simplement faire la France (métropolitaine) entière.

Pour la France :
– taille du fichier téléchargé : 3.7Go
– temps d’importation : ça a planté (plus d’espace disque) (si on fait une interpolation sur la taille du fichier téléchargé, on partirait sur 4-5h)
– taille de la base de donnée : la même interpolation donnerait 120Go

Pour info, le monde entier :
– taille du fichier : 54Go
– temps d’importation : compter 3 jours
– taille de la base de données : 1.8To ?

Et les tuiles ?

Eh bien l’espace pris sera donc dépendant des zones visitées par les utilisateurs puisque ce n’est que le cache de ce qui a été demandé. Là, en ayant largement couvert la région Toulousaine, je ne suis qu’à 150Mo de tuiles pré-calculées. Donc ce n’est pas vraiment ça qui compte dans l’usage de l’espace disque, en tous cas dans mon cas.

D’ailleurs OSM a une page sur ce sujet sur son Wiki (attention, les chiffres datent de 2015), et il est amusant que constater que jusqu’aux niveaux de zoom 12 (voire 13), toutes les tuiles ont été calculées, par contre au niveau de zoom 18, c’est seulement 0,2% de tuiles possibles qui ont été téléchargées. Oui, on comprend facilement que personne n’est encore allé zoomer au maximum sur l’océan Pacifique ni sur les steppes d’Asie centrale.

Conclusion

Va falloir demander une rallonge :), mais simplement sous la forme d’un espace de stockage. Avec 1To je devrais être tranquille pour servir la carte de France, et même un peu plus. Même si les débits demandés ne sont pas gigantesques, un SSD serait tout de même recommandé pour la multitude de petits accès qui y seront faits. Et à 100€ HT environ le cours actuel on ne va pas se gêner.

Servir ses propres cartes OSM ce n’est finalement pas compliqué quand on est bien guidé, et c’est le cas avec Switch2OSM. Cela permet notamment de s’affranchir de la dépendance de fournisseurs tiers (GoogleMaps, mais aussi les différents fournisseurs de fond de carte OSM), mais aussi éventuellement de ne pas être dépendant de la disponibilité d’une connexion Internet.

Une autre utilité sera de gérer exactement ce qui est affiché ou pas, ce qui sera le cas : je suis parti sur la feuille de style officielle OSM et on voit donc apparaître les commerces par exemple, qui n’ont rien à faire dans mon cas d’usage.

  • # Re:

    Posté par  . Évalué à 7 (+6/-0).

    – taille de la base de données : 1.8To ?

    C'est quand-même hallucinant de se dire que de nos jours, potentiellement tout le monde pourrait avoir "dans sa poche" une carte complète du monde avec un niveau de détail de l'ordre de potentiellement quelques dizaines de centimètres :)

    • [^] # Re:

      Posté par  . Évalué à 6 (+4/-0).

      Oui c'est vrai qu'on n'est pas dans des tailles gigantesques. Après attention, ce chiffre est également modeste parce que peu de pays ont autant de données que la France par exemple. Si on arrivait à ce niveau de détail partout, on aurait sûrement un ou deux ordres de grandeur supplémentaire.

      En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

  • # format d'image

    Posté par  (site Web personnel) . Évalué à 7 (+6/-1).

    Journal très intéressant!

    Est ce qu'il est possible de changer le format d'image utilisé pour les tuiles? J'ai fait un test rapide en capturant une ville avec un zoom de 12, en PNG l'image fait 200ko et en JPG de qualité 90% elle fait 60ko, et impossible de distinguer la différence à l’œil nu. J'imagine que cette différence peut varier en fonction de la quantité de détails et d'aplats de couleur, mais je me demande si quelqu'un a vraiment réfléchi à la question, d'autant plus que de nouveaux formats d'image plus performants encore existent aujourd'hui.

    Un LUG en Lorraine : https://enunclic-cappel.fr

    • [^] # Re: format d'image

      Posté par  . Évalué à 2 (+1/-0).

      Le JPEG est le format d’image qui est le plus souvent retenu pour le partage de photographies numériques. Sa qualité lui permet de restituer toute la complexité des clichés : les ombres, les nuances, les dégradés. Il puise dans un référentiel de 16,7 millions de couleurs pour y parvenir.

      Le PNG a été créé pour offrir une alternative libre au GIF. Il dispose de deux niveaux de compression :
      l’un (PNG-8), très léger mais qui ne peut afficher que 256 couleurs (à comparer au GIF qui n'a pas la transparence) ;
      l’autre (PNG-24), plus lourd que le JPEG, mais avec le même rendu au niveau des teintes.

      À première vue, le JPEG permet une meilleure compression d’image, mais le PNG offre la possibilité de gérer des fonds transparents, utiles pour les montages par exemple. D'un autre côté, la compression du JPEG étant destructive, on peut se retrouver avec un mauvais rendu d'une part, et ça se prête moins au zoom avant d'autre part. https://www.digitaltrends.com/computing/jpeg-vs-png/ Par défaut (sans présupposer sur les zoom final), pour le web, PNG reste la meilleure option (sinon il y a aussi le SVG à considérer quand on peut vectoriser) https://modomodoagency.com/2019/01/22/jpg-vs-png-vs-gif-vs-svg-image-format-guide/

      • [^] # Re: format d'image

        Posté par  (site Web personnel) . Évalué à 2 (+0/-0).

        A priori on ne zoome pas sur les tuiles: si on zoome sur la carte c'est une nouvelle tuile plus détaillée qui est affichée. Donc utiliser un format de compression destructeur n'est pas forcément un problème.

        Le format SVG parait bien adapté pour ce genre d'images, ça permet de réduire la taille des données envoyées tout en conservant la qualité. Mais par contre ça peut demander plus de puissance au client pour l'affichage.

        Un LUG en Lorraine : https://enunclic-cappel.fr

        • [^] # Re: format d'image

          Posté par  . Évalué à 5 (+3/-0). Dernière modification le 22/11/20 à 08:02.

          A priori on ne zoome pas sur les tuiles

          En général c'est bien ça, mais les clients (Leaflet en tous cas) permettent tout de même de zoomer dans la tuile : si le serveur ne propose qu'un zoom 18 au maximum, on peut tout de même afficher un zoom 20 par exemple. À ce moment, les 2 derniers niveaux de zoom sont bien réalisés par un grossissement des pixels.

          Mais ça reste un peu marginal.

          En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

        • [^] # Re: format d'image

          Posté par  . Évalué à 1 (+0/-0).

          Bon à savoir (je ne savais pas que les tuiles étaient régénérées lorsqu'on zoome, d'où l'importance du cache donc…)

          Oui, le vectoriel est une bonne alternative si le contenu s'y prête bien. J'ai vu un autre commentaire donner des pistes dans ce sens.

  • # Tuiles vectorielles

    Posté par  . Évalué à 10 (+14/-0).

    Je ne sais pas si tu as vu qu'il existait aussi des tuiles vectorielles à la place des tuiles images. C'est juste des géométries, pas des images. Du coup les tuiles sont plus légères. Il faut ajouter un fichier de style sur le client, ça permet de changer des choses à la volée, comme le style ou la langue…

    Je dis ça parce que justement je travaille sur une pile vectorielle comme alternative à celle proposé par Switch2OSM.org. Comme ma solution elle lave plus blanc que celle que tu as déjà, je te promets la France pour 50 Go !

    https://github.com/makina-maps/makina-maps

    • [^] # Re: Tuiles vectorielles

      Posté par  . Évalué à 6 (+4/-0).

      Je ne connaissais pas du tout cette approche (je découvre un peu l'univers OSM) mais c'est très intéressant. N'hésite pas à proposer une publication le jour où c'est prêt !

      En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

  • # en dépêche !

    Posté par  (site Web personnel) . Évalué à 9 (+7/-0).

    Une dépêche, une dépêche !

  • # Nécessité de télécharger les données OSM ?

    Posté par  . Évalué à -1 (+3/-0).

    D’abord merci pour cette mise en avant d’OSM, un des plus beaux projets libres pour moi.

    Utilisant régulièrement différentes applications pour cartographier mon environnement (ajout de pistes cyclables et sentiers de randonnées principalement), je ne comprends pas la nécessité de charger par avance les données OSM.
    Selon mon expérience, l’affichage à bas de niveau de zoom demande peu de détail dont on se fiche d’ailleurs un peu, puisqu’on cherche autre chose.

    N’est-il pas possible de charger à la volée les données correspondant à la tuile à afficher (qui sera ensuite stockée) ?

    Question subsidiaire : qu’en est-il du rafraichissement des tuiles (les données d’une tuile vont forcément bouger avec le temps) ?

    • [^] # Re: Nécessité de télécharger les données OSM ?

      Posté par  . Évalué à 5 (+3/-0).

      N’est-il pas possible de charger à la volée les données correspondant à la tuile à afficher (qui sera ensuite stockée) ?

      C'est sûrement possible mais apparemment ce n'est pas l'idée actuelle.

      Question subsidiaire : qu’en est-il du rafraichissement des tuiles (les données d’une tuile vont forcément bouger avec le temps) ?

      J'avoue que j'ai un peu délaissé cette partie dans mon journal car je ne m'y suis pas encore trop penché. Apparemment lors de l'importation de nouvelles données, il y a moyen de générer la liste des tuiles obsolètes et de le donner à manger à mod_tile qui en déduira de regénérer les tuiles impactées. Mais je n'en sais pas plus (pas encore en tous cas, mais ça viendra bien).

      En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

  • # Projection

    Posté par  . Évalué à 3 (+0/-0).

    J'ai deux questions :

    1. Est-il possible d'utiliser une autre projection que la projection Mercator ? La projection Mercator a des défauts et j'aimerais utiliser d'autres projections qui n'ont pas ses défauts, mais qui en ont d'autres desquels je peux m'accomoder.
    2. Et si on veut rendre uniquement une région par exemple, une seule fois, et récupérer le fichier, y a-t-il un moyen simple ? J'avais essayé à un moment donné, mais la taille des données m'avait refroidi un peu, et puis je ne savais pas bien quoi en faire après.
  • # Autre solution ?

    Posté par  . Évalué à 3 (+2/-0).

    Merci pour ces infos précieuses.
    Je me demandais si Umap (https://umap.openstreetmap.fr/fr/) n'aurait pas pu répondre aux besoins ?
    On peut créer des cartes en important des données mais on peut aussi aller plus loin avec des données distantes et mises à jour automatiquement :
    http://www.mappa-mercia.org/2014/09/creating-an-always-up-to-date-map.html

    Normalement Umap fr est une instance de production à priori sans limite.

Envoyer un commentaire

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.