Amélioration du rendu OSM-FR à petite échelle

Le rendu par défaut d'OpenStreetMap sur les premiers niveaux de zoom (les petites échelles) n'est pas très lisible, ni représentatif des données existantes. En fait, ces premiers niveaux de zoom n'utilisent quasiment pas de données OSM, mais des données provenant généralement de Natural Earth.

Le résultat est plutôt pauvre :

Rendu OSM par défaut au zoom 3

De plus, les libellés provenant de Natural Earth et ne sont disponibles que dans une seule langue alors que des données beaucoup plus riches sont disponibles dans les bases OSM (noms traduits, nom international, etc).

Le fond de carte est presque vide... et ceci est dû à un autre problème beaucoup plus technique.

En effet, la densité d'information présente dans OSM pour rendre une tuile à ce niveau est énorme. Le temps de traitement est donc extrèmement long. Les tuiles qui composent la carte visible font 256 pixels de côté, mais sont produites par dalles (metatile) de 8x8 tuiles soit 2048x2048 pixels et couvrent ici des étendues très importantes contenant des dizaines voire centaines giga-octets de données. Au zoom 3, il n'y a qu'une seule dalle et donc il faut interroger la base de données OSM dans sont intégralité pour la produire.

Il n'est donc pas possible par exemple d'utiliser les polygones qui décrivent l'occupation du sol pour la représenter à ce niveau, cela prendrait sûrement plusieurs jours à calculer à ces échelles.

Par contre, ce calcul est fait à des échelles plus grandes d'où l'idée de précalculer une occupation du sol à un zoom intermédiaire (vers 8 ou 9) pour ensuite réduire cette image pour les zooms de plus petite échelle (3 à 7).

L'idée ne m'est pas venue toute seule, mais via un message posté par Frederik Ramm sur la mailing list OSM internationale et un exemple de mise en œuvre.

Exemple "lowzoom" de Frederik Ramm

Je suis donc parti de cette idée qui m'a semblée intéressante et pour en profiter pour améliorer globalement le rendu "FR" sur ces premiers niveaux de zoom.

Cela a tout d'abord consisté à prendre la feuille de style du rendu OSM-FR et à supprimer libellés et frontières afin de générer de gros fichiers PNG couvrant la planète entière au zoom 8.

J'ai commencé par vouloir générer un seul fichier d'un coup, mais c'était un peu trop gros, donc 4 fichiers sont générés NO/NE/SO/SE. Il font chacun 715 milliosn de pixels et pèsent entre 13 et 95Mo compressés en PNG. L'image produite a un fond transparent et ne contient donc que l'occupation du sol et les principaux tracés de routes et voies maritimes.

Voici la ligne de commande qui génère un de ces fichiers:

nik2img.py osmfr-cartocss-z8.xml layers/z8-0.png -f png -e -20037508 -19929239 0 0 -d 32768 21845 -w pgw

nik2img est un script python qui permet de générer une image à l'aide de Mapnik. On lui indique le fichier XML de configuration de Mapnik, puis où enregistrer l'image, le formet (png), l'étendue (en coordonnées projetées "Google Mercator"), les dimensions de l'image souhaitée et la génération d'un fichier "worldfile" donnant le géoréférencement de l'image produite.

Ensuite ces 4 images sont traitées pour produire un image unique correspondant au zoom 7 et "dallée" c'est à dire compresser par dalles et non dans sa globalité, ce qui permet d'extraire ensuite plus facilement une portion de l'image sans avoir à tout décompresser.

Pour recoller les morceaux ensemble et produire cette unique image de zoom 7, j'ai utilisé gdal et les commandes gdalbuildvrt qui permet de créer une image virtuelle composée des 4 images PNG et gdalwarp pour réduire à 32768 pixels de côté l'image (ça correspond à la largeur de la planète en zoom 7).

gdalbuildvrt -overwrite z8png.vrt z8-*.png
gdalwarp -ts 32768 0 -r lanczos -overwrite z8png.vrt z7.tif -co TILED=YES -co COMPRESS=DEFLATE 

Pour gdalwarp, on indique les dimensions de l'image finale (32768 de largeur, la hauteur sera calculée en proportion), l'algorithme de réduction (ici c'est laczos pour obtenir le meilleur résultat graphique), et les options pour "daller" le résultat et utiliser une compression DEFLATE qui permet de conserver la transparence (ce que ne permet pas JPEG).

Voici un aperçu (largement réduit) sur fond gris de l'image générée qui fait 72Mo pour 32768x26157, soit 857 millions de pixels:


Il ne reste plus qu'à insérer cette image raster dans la feuille de style OSM-FR... tout en supprimant désormais tout le rendu autre que les frontières et toponymes.

Voici le premier résultat obtenu (en zoom 7) :


Premier rendu "OSM-FR" avec raster précalculé en fond.

A comparer à la version précédente :

 

Le gain est aussi très intéressant sur le plan du temps de génération des tuiles, car celui-ci a été divisé par 3, vu que les couches "routes" ne sont plus rendues. On passe du coup de 25 minutes à environ 8 minutes pour générer le zoom 7 mondial.

La technique du raster précalculé donne donc un résultat visuellement agréable et permet maintenant de se concentrer sur le remplissage par d'autres éléments par dessus ce fond.

... à suivre !