À la fin de l'entrée précédente,
j'évoquais le projet de faire imprimer des posters au format 2A0 (on
me signale qu'on ne dit pas A−1
) de Paris et de l'Île-de-France
à partir de leur rendu OpenStreetMap. J'ai un peu progressé et je
voudrais dire où j'en suis actuellement, quitte à éditer plus tard
cette entrée-ci (plutôt que la précédente) pour raconter s'il y a du
nouveau.
D'abord, je pense que je vais plutôt viser le format
A0 (119cm×84cm, de surface 1m²) que 2A0 (168cm×119cm, de surface 2m²),
parce que ce dernier est vraiment ambitieux : l'impression coûte
encore plus cher (logique), les fichiers sont encore plus pénibles à
générer et à manipuler, et je me sentirai encore plus agacé si je me
rends compte (ce qui est sans doute inévitable) qu'il y a un problème
sur la carte. En échelle, je pense que je vais utiliser le 1:15 000
pour le plan de Paris en A0, et 1:75 000 pour le plan des environs de
Paris aussi en A0[#].
J'écris environs de Paris
parce que je ne vais finalement pas
englober toute l'Île-de-France, ça fait une échelle trop petite et on
n'y voit plus assez de choses intéressantes. Pour ce qui est du
centrage, je pense que je vais centrer les deux sur la tour
Saint-Jacques à Paris : ainsi, à 1:15 000 en A0, on a une carte qui
inclut tout le bois de Vincennes et quasiment tout le bois de
Boulogne, et en 1:75 000 on a Rambouillet, Corbeil-Essonnes, Meaux,
l'Isle-Adam, Thoiry, Montfort-l'Amaury — mais pas Fontainebleau, par
exemple.
[#] Bon, il y a un
problème possible à régler (ou à décider d'ignorer), là, c'est que, de
ce que je comprends, Nik4 (comme le site d'OpenStreetMap et plein
d'autres) utilise une
projection Web
Mercator, c'est-à-dire, utilise les formules de la projection de
Mercator d'une sphère en les appliquant à un ellipsoïde, et plus
exactement, en les appliquant à la
latitude géodétique φ (celle qu'on utilise par
défaut quand on parle de latitude
, et qu'on donne dans les
coordonnées GPS/WGS84/IERS).
Or si on veut que la projection de Mercator soit conforme sur un
ellipsoïde, il faut utiliser une autre latitude,
la latitude conforme χ
(c'est essentiellement la définition de la latitude conforme que c'est
celle qui permet de faire comme si l'ellipsoïde était une sphère dans
toute projection cartographique conforme). Du coup, la projection Web
Mercator n'est pas conforme (elle applique les formules de
Mercator à φ alors qu'elle eût dû les appliquer
à χ pour obtenir une projection conforme), ce qui signifie,
concrètement, que les deux directions (horizontale et verticale) n'ont
pas la même échelle :
si mes
calculs sont corrects, ce qui est loin d'être certain, il y a une
différence d'échelle de 0.86% entre les deux axes à la latitude de
Paris (φ=48.86°). Je peux corriger ce problème en
transformant un peu l'image (ou, mieux, en essayant de modifier Nik4
pour qu'il accepte une résolution différente dans les deux axes,
histoire que le texte ne soit pas déformé par la transformation) ;
mais il reste à savoir si le remède ne serait pas pire que le mal — et
si, d'ailleurs, j'arrive à trouver quelle est la bonne échelle,
c'est-à-dire comment Nik4 (ou Mapnik, ou je ne sais quoi) interprète
le paramètre échelle qu'on lui fournit.
Bref, les images ressembleraient sans doute à ceci :
Cliquez sur les images pour les agrandir juste un peu, mais ce ne
seront pas encore les images à taille bonne à tirer : je mets des
versions A0 en 75dpi (soit
3511×2483) ici
pour Paris
et là
pour les environs, mais je ne promets pas de garder pérennes
ces URL (et si je fais des changements, je garderai les
mêmes noms alors que les images au-dessus resteront attachées à cette
entrée) ; et je mets des versions à 150dpi (soit 7022×4967) aux mêmes
adresses en remplaçant 75dpi
par 150dpi
,
mais comme ce sont des fichiers déjà assez gros (44Mo pour Paris) je
ne fais pas de lien direct pour ne pas que des gens cliquent dessus
par accident ; la version à imprimer sera sans doute en 300dpi (cela
donne un fichier d'environ 115Mo pour Paris).
(Comme expliqué ci-dessous, ces images sont © OpenStreetMap 2019 et redistribuables sous les termes de la licence ODbL.)
Ajout () : On me signale
(en commentaire de cette entrée-ci, ainsi
que sur
Twitter) que l'IGN vend
des cartes
à la carte
, à différentes formats dont 110cm×96cm, qu'on peut
choisir en papier indéchirable et non plié, et à différentes échelles
(randonnée et découverte
: 1:15 000, 1:20 000, 1:25 000 ou
1:30 000 avec le niveau de détails et la présentation des cartes TOP25
au 1:25 000 ; ou bien tourisme et découverte
: 1:60 000,
1:80 000, 1:100 000 ou 1:120 000 avec le niveau de détails et la
présentation des cartes TOP100 au 1:100 000), c'est donc très proche
de ce que je voulais faire. Je trouve le rendu OpenStreetMap plus
joli et plus fin (même si évidemment il faut s'attendre à toutes
sortes de petits bugs dans l'affichage et le contenu de la carte
finale), et ces cartes seraient plutôt complémentaires, mais je me
dois en tout cas de les signaler ici.
Comment génère-t-on les images ci-dessus ? D'abord, il faut avoir une petite idée de la manière dont OpenStreetMap fonctionne et dont les composantes s'emboîtent. (Généralement c'est la partie la plus compliquée à comprendre quand on a affaire à un projet informatique : les docs vous expliquent ce que font les différents bouts, mais personne ne prend la peine de présenter une vue d'ensemble qui décrive comment agencer ces différents bouts.) Voici ce que je peux dire (ou en tout cas, ce que je pense avoir compris) :
- Commençons par le
début : OpenStreetMap
(ou OSM) est un projet collaboratif, un peu analogue à
Wikipédia (au sens où tout le monde peut
éditer[#2], et librement
redistribuable sous la
licence ODbL),
mais dont le but est
de cartographier la Terre entière, à tous les niveaux de détail
possibles. C'est-à-dire, quand je dis
cartographier
, qu'il ne s'agit pas juste de produire des cartes mais des données cartographiques à partir desquelles des cartes pourront être générées, mais les données cherchent à être les plus précises possibles et à couvrir toutes les types d'informations qu'on arrive à rassembler (découpages administratifs, méta-informations comme la nature ou la vitesse limite des route, ce genre de choses). - Ces données représentant des quantités assez énormes d'information, on a besoin de programmes pour rendre commode leur accès : pour ça, OpenStreetMap utilise la base de données PostgreSQL (moteur de base de données relationnelle libre) et son extension PostGIS spécialisée dans le traitement des données géographiques (il permet, par exemple, de stocker un nombre énorme de points et de récupérer rapidement les points contenus dans un rectangle donné).
- On a parfois besoin d'échanger, de stocker, d'archiver ou de
publier les données géographiques en question indépendamment d'une
base de données : pour ça, OpenStreetMap utilise un format spécifique,
une instance de XML appelée Osmium (
osm
commeOpenStreetMap
). Il existe différents outils pour lire des données OpenStreetMap au format Osmium et l'insérer dans une base de données PostGIS (j'ai utiliséosm2pgsql
) ou, inversement, pour stocker le contenu d'une telle base de données à ce format. Certains outils savent manipuler les données OpenStreetMap à la fois au format Osmium ou déjà insérés dans une base de données PostGIS (et certains ne savent faire que l'un des deux et, bien sûr, ne vous disent pas clairement ce qu'ils attendent). Pour récupérer les données OpenStreetMap complètes d'un pays, voire de la planète entière, on va les récupérer sur le site Web Geofabric au format Osmium (comprimé selon différents mécanismes : PBF ou Bzip2 — quand j'ai regardé, la version PBF était cassée donc j'ai prisfrance-latest.osm.bz2
comme source, qui fait quand même 5.5Go comprimé). - On a aussi besoin d'un outil pour transformer les données (abstraites) en cartes (des images, comme celles ci-dessus) : pour ça, on utilise généralement (c'est ce que j'ai fait, et c'est ce que fait OpenStreetMap sur son site, mais ce n'est pas la seule possibilité) la bibliothèque Mapnik (j'avais déjà joué avec il y a bien longtemps, mais pas avec les données OSM). Mapnik n'est qu'une bibliothèque, c'est-à-dire un ensemble de fonctions capables de faire différentes tâches de rendu : on peut utiliser différents programmes de plus haut niveau pour appeler ces fonctions, pour ma part j'ai utilisé celui qui s'appelle Nik4.
- Il ne suffit pas de mettre ensemble les données OSM
(fussent-elles stockées en PostGIS) et Mapnik
(fût-elle appelée depuis Nik4) pour obtenir une carte : il faut encore
définir le style de la carte, c'est-à-dire, en gros, sa
légende : ce qu'on va représenter et comment. Mapnik est juste le
moteur : il transforme les données et le style en une image. Mais le
style est vraiment ce qui va lui donner ses instructions (du
genre
les autoroutes, tu les traceras en rouge, avec telle largeur, et tu mettras leur nom en encadré en le positionnant comme ceci
). Il existe un style « par défaut » pour OpenStreetMap, c'est celui qui est affiché sur le site webwww.openstreetmap.org
(pour le plan par défaut), il s'appelleopenstreetmap-carto
(et c'est celui que j'ai utilisé pour les cartes ci-dessus, en me disant que je n'avais pas les compétences pour refaire un style moi-même, même si j'aurai peut-être envie de le modifier un peu et d'ailleurs je l'ai fait, très minimalement). Pour donner un exemple illustrant l'importance du style, comparer cette vue de Paris avec le styleopenstreetmap-carto
et celle-ci sur Géoportail à la même échelle et utilisant aussi les données OpenStreetMap mais affichées dans un style différent (je ne sais pas s'ils passent par Mapnik, à vrai dire, mais je suppose que c'est plausible). - Mapnik fonctionne avec un style défini par un
fichier XML. Ce dernier étant très complexe à écrire, on
a introduit (je ne sais pas si c'est pour OpenStreetMap ou simplement
que c'est utilisé par OpenStreetMap)
un autre format
appelé CartoCSS, plus facile à éditer, et les outils
nécessaires pour le transformer en le XML pris en entrée
par Mapnik. Le style
openstreetmap-carto
que j'évoque ci-dessus est écrit en CartoCSS (plus toutes sortes de petites images ad hoc pour les symboles représentant les points d'intérêt). - Bref, les ingrédients pour générer une carte sont, en gros : les
données OpenStreetMap téléchargées au format Osmium +
PostgreSQL + PostGIS
+
osm2pgsql
(pour convertir depuis Osmium) + Mapnik + Nik4 + le styleopenstreetmap-carto
+ CartoCSS. - Il faut que je fasse une digression sur le niveau de zoom. Les
cartes papier sont définies par une échelle comme 1:60 000. Pour une
carte informatique, c'est-à-dire une image, si celle-ci sera affichée
sur un écran, comme on ne connaît pas la taille de l'écran sur lequel
on va faire le rendu, l'échelle devrait s'exprimer en pixels par
kilomètre ou quelque chose comme ça. Mais comme par ailleurs les
cartes interactives (rendues dans un navigateur ou une application
smartphone) fonctionnent en mettrant côte à côte des images carrées
(tiles, comme un carreau de carrelage,
typiquement de taille 256×256 parce que c'est bien pratique),
une convention,
initiée par Google Maps et réutilisée par OpenStreetMap,
Géoportail et d'autres, consiste à parler de
niveau de zoom
, numéroté de 0 à 22 (ou autant qu'on voudra) avec un facteur 2 à chaque niveau de zoom. Plus exactement, au niveau 0, le carreau représentant en projection de Mercator toutes les latitudes de −180° à +180° (et les latitudes de −85°03′04″ à +85°03′04″, donc essentiellement le monde entier) tient dans un seul carreau de 256×256 ; et chaque carreau de niveau k est divisé en 2×2=4 carreaux de niveau k+1 : au niveau 1, le carreau de taille 256×256 contient 180° de longitude et la Terre utilise 4 carreaux, au niveau 2 le carreau contient 90° de longitude et la Terre utilise 16 carreaux, et ainsi de suite. Ainsi, voici les vues OpenStreetMap centrées sur Paris au niveau de zoom 8, 9, 10, 11, 12 et 13. (Notons que Google Maps, maintenant, est plus raffiné et utilise des fractions arbitraires de niveau, notamment des quarts quand on zoome à la molette de la souris, ce qui rend son zoom beaucoup plus agréable et plus fluide alors qu'avec OpenStreetMap on ne peut zoomer que par des facteurs 2 et rien d'intermédiaire.) - Le style qu'on voudra utiliser pour une carte dépend évidemment de
son échelle (ou, ce qui revient au même, dans le cas d'une image
informatique, du niveau de zoom évoqué au point précédent). C'est
normal : on n'affiche pas les mêmes informations, ou on ne les affiche
pas de la même manière, et pas même juste en changeant la taille, sur
une carte au 1:120 000 que sur une carte au 1:15 000 : une carte au
1:120 000 n'est pas une carte au 1:15 000 dont on aurait réduit toutes
les dimensions par 8 (cela rendrait les symboles, le texte, et ainsi
de suite, complètement illisibles). Comparer les images
de ce
tweet pour un exemple de ce que sont les différences si je ramène
les cartes à la même taille en pixels. Un style tel
que
openstreetmap-carto
contient donc comme paramètre un niveau de détails d'affichage, ce paramètre étant identifié au niveau de zoom évoqué ci-dessus. C'est là que les choses deviennent un peu confuses : en principe, on peut régler indépendamment le niveau de détails du style et l'échelle du rendu (pour produire, par exemple, les cartes du tweet que je viens de lier, j'ai fait une carte à l'échelle 1:60 000 à imprimer à 300dpi, une carte à l'échelle 1:30 000 à imprimer à 150dpi et une carte à l'échelle 1:15 000 à imprimer à 75dpi, toutes les trois ayant donc une échelle rendu de 197 pixels par kilomètre de terrain) ; mais dans la pratique, ce n'est pas vraiment prévu, et si on veut jouer avec ça on doit essentiellement mentir sur d'autres paramètres.[#3]
Une fois qu'on a compris tout ça, il reste à enchaîner correctement
les commandes en espérant ne pas tomber sur des incompatibilités
subtiles entre versions. Je suis arrivé
à la
suite de manœuvres que j'ai notée ici (en espérant ne pas m'être
tompé en notant) sur ma machine de bureau qui est une
Ubuntu 18.04.3 LTS Bionic
Beaver avec 32Go de mémoire (mon PC personnel en a
le double, ce qui aurait été utile, mais sa connexion réseau est bien
trop mauvaise pour pouvoir en faire quoi que ce soit d'utile) : il y a
peu de chances que ces commandes puissent resservir telles quelles à
quelqu'un d'autre, mais ça donnera au moins une idée de l'ordre et de
la manière dont on peut enchaîner les bouts. (Je note n'ai pas tout
compris à ce que je faisais : par exemple, je ne comprends pas
pourquoi osm2pgsql
a besoin de faire intervenir des bouts
de openstreetmap-carto
alors que, dans ce que j'ai
compris, la feuille de style intervient uniquement pour le rendu par
Mapnik et pas pour l'interconversion entre Osmium et la base de
données PostGIS. Passons.)
[#2] Je me demande d'ailleurs comment OpenStreetMap gère le vandalisme (grossier ou insidieux), qui doit être beaucoup plus subtil à détecter et complexe à corriger que sur Wikipédia, et qui peut présenter un enjeu économique plus important (par exemple, en marquant un certain endroit comme infranchissable sur OpenStreetMap, on peut espérer rerouter ailleurs toutes sortes de véhicules qui utiliseraient les données OpenStreetMap pour leur navigation) ; et notamment, je me demande comment vérifier que le poster que je vais imprimer ne contient pas (trop) de vandalisme.
[#3] Un autre point que je dois d'ailleurs signaler est que le niveau de détails affiché par le style est choisi (de ce que je comprends) d'après le niveau de zoom, mais même pour une résolution fixe (en points par pouce), le niveau de zoom correspond à une échelle différente à l'équateur et près des pôles (à l'équateur, le niveau de zoom 12 correspond à 26.2 pixels par kilomètre, tandis qu'à la latitude de Tromsø il correspond à 75.1 pixels par kilomètre). C'est-à-dire que si on a fait des choix raisonnables à une latitude moyenne (de quoi afficher à un niveau de zoom donné), ils risquent de donner des cartes trop riches en détails à l'équateur et trop avares de détails aux latitudes polaires. Mais je n'ai peut-être pas bien compris comment fonctionne le choix du niveau de détails dans la feuille de style.
J'ai effectué de petites modifications dans le
style openstreetmap-carto
, essentiellement pour retirer
des éléments qui étaient affichés de façon à mon avis bien trop
visible et distrayantes : les hôpitaux, notamment, sont affichés dès
le niveau
de zoom 15, or il y en a plein à Paris (pour une certaine
définition de hôpital
), ce qui donnait une image remplie de
symboles d'hôpitaux qui, à mon avis, aurait été moche comme poster ;
de façon peut-être plus discutable, j'ai retiré l'affichage des
châteaux (pour une certaine définition de château
qui inclut le
Palais-Bourbon) et des parkings.
Il faudrait encore passer ces images en revue. Je suis sûr qu'il y a plein de problèmes avec qui ne sautent pas forcément immédiatement aux yeux mais qui, si on les imprime en poster, finiront par être remarquées et ensuite on ne verra que ça. Ce ne sera malheureusement pas forcément possible de corriger les problèmes en question, vu que je ne connais rien à CartoCSS ni aux autres couches utilisées. La manière dont Mapnik décide quels textes afficher, par exemple, est probablement bien trop complexe à régler pour que je puisse y faire quoi que ce soit. Même la taille des caractères des différents textes, je pense que c'est tout un sac de vipères de commencer à jouer avec.
Je ne pense pas faire apparaître d'échelle sur la carte elle-même,
ni quoi que ce soit comme insert : j'aime bien l'idée d'un poster qui
représente directement le terrain, sans petit encart qui donne un
titre, une date, une échelle ou une légende. (Et je doute fortement
qu'on vienne me chercher des noises parce que je n'aurais pas dénaturé
le plan en écrivant © OpenStreetMap et contributeurs 2019
: je
prévoirai éventuellement un post-it à coller dessus avec cette
indication. )
✾
Après tout ça, il faut (enfin, il faudra) donner l'image à imprimer. Cela ouvre un autre jeu de problèmes, parce que les imprimeurs ont leur propre langage, que je ne comprends pas forcément (et donc, après avoir fait le boulot de décoder le langage des cartographes, il faut faire le boulot d'en décoder un nouveau, soupir).
De ce que je comprends, pour faire imprimer une image d'une
certaine taille, on fournit une image plus grande, qui sera coupée à
la taille demandée ou zone de rogne
(ou trim
box
en anglais) : au-delà de cette zone de rogne, on ajoute
prolonge l'image un peu plus (typiquement 5mm dans chaque direction)
en ce qu'on appelle un fond perdu
(bleed
box
en anglais), et on fait apparaître des traits de coupe
qui empiètent sur le fond perdu et se prolognent encore au-delà (i.e.,
plus à l'extérieur), alignés avec les côtés de la zone de rogne, pour
indiquer où on va couper celle-ci. Il faut donc fournir une image
(zone de support
ou media box
) encore plus
grande que la zone de fond perdu (elle-même plus grande que la zone de
rogne qu'on veut vraiment), mais la taille qu'elle est censée faire
m'échappe un peu, ainsi que les spécifications précises des traits de
coupe (ce n'est probablement pas très important). Il va donc falloir
que je joue avec ImageMagick ou autre chose, pour ajouter ces traits
de coupe (les fonds perdus eux-mêmes ne posent pas de problème, ça
consiste simplement à générer une image plus grande). Ça ne devrait
pas être compliqué, mais si je dois convertir en PDF en
en remplissant correctement les métadonnées
(TrimBox
, BleedBox
, MediaBox
),
je risque d'avoir plus de mal.
L'autre problème possible que je vois venir concerne la conversion de RGB (couleurs en système additif rouge-vert-bleu) en CMYK (système soustractif cyan-magenta-jaune-noir) : je m'y connais un peu en colorimétrie « abstraite », mais je ne sais pas comment fonctionne ce genre d'espace de couleur ni comment faire la conversion dans la pratique. (Le rendu exact des couleurs n'est pas important puisqu'il s'agit juste d'un diagramme, donc en ce qui concerne l'intention de rendu je veux probablement celui qui maximise la saturation.)
Heureusement, plusieurs personnes se sont dévouées pour faire l'interface entre l'imprimeur et moi et, au moins, me fournir des consignes claires sur ce que je dois donner.
Quand j'aurai compris tout ça, je mettrai évidemment les PDF finaux à un endroit publiquement accessible pour que le travail puisse resservir à d'autres.
Encore après ça, il faudra que je recense les gens qui peuvent être intéressés par une copie du poster. J'ai intérêt à faire de la pub, parce que l'imprimeur que j'ai trouvé (et qu'on m'a conseillé) demande 90€ pour un exemplaire unique au format A0 (papier 190g/m² satiné), mais ça descend à 38.40€ l'exemplaire s'il y en a cinq. (Il y aura, cependant, le problème de faire parvenir les exemplaires aux personnes qui les auront demandés.) Pour l'instant, tout ça est largement en flottement.