David Madore's WebLog: Réalisation de posters de Paris et de sa région, suite

[Index of all entries / Index de toutes les entréesLatest entries / Dernières entréesXML (RSS 1.0) • Recent comments / Commentaires récents]

↓Entry #2629 [older| permalink|newer] / ↓Entrée #2629 [précédente| permalien|suivante] ↓

(mardi)

Réalisation de posters de Paris et de sa région, suite

À 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 :

[Plan de Paris][Plan des environs de Paris]

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 comme OpenStreetMap). 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 pris france-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 web www.openstreetmap.org (pour le plan par défaut), il s'appelle openstreetmap-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 style openstreetmap-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 style openstreetmap-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.

↑Entry #2629 [older| permalink|newer] / ↑Entrée #2629 [précédente| permalien|suivante] ↑

[Index of all entries / Index de toutes les entréesLatest entries / Dernières entréesXML (RSS 1.0) • Recent comments / Commentaires récents]