samedi 23 février 2013

Densité de population

À la fin du mois dernier, j'ai vu passer un tweet dans ma timeline Twitter, parlant de carroyage. Il pointait vers le site de l'INSEE, sur les données carroyées à 200 mètres de la population française. En clair, ça signifie que l'INSEE avait découpé le territoire français en petits carrés de 200 m de côté et recensé dans chacun d'entre eux le nombre d'habitants. Plutôt cool, non ?

Là, je me dis : « mon bonhomme, y'a moyen de faire une carte trop top avec ces données ». Je commence par télécharger les archives pour chacune des 22 régions de France métropolitaine[1] (quelques centaines de Mo, une broutille). Chacune comprend un fichier .dbf stockant les données, un format que, par chance, Excel lit[2]. Première action de ma part, sélectionner trois colonnes : les coordonnées géographique de chaque carreau et la population correspondante. Je copie-colle cette sélection dans un fichier texte. 22 ouvertures de fichier .dbf plus tard, j'obtiens un beau fichier texte de 2 272 481 lignes. Sur chacune, la coordonnée x d'un carré de 200 m de côté, sa coordonnée y et sa population. Bon début.

Il est temps de passer ces données à la moulinette. Je ponds rapidement un petit programme en C++[3] qui parcourt ce fichier texte et recherche les extremums de coordonnées ; comme je sais que chaque carré est espacé de ses voisins par 200 unités de coordonnées (un système simple), je constate que l'ensemble tient dans une carte de 5 371 pixels de large sur 5 524 de haut, où chaque pixel correspond à un carré de 200 m de côté. Je farfouille un peu parmi les cartes de densité de population sur Commons, tombe sur celle du Maine et décide d'en utiliser les couleurs. Je modifie mon programme pour qu'il me génère l'image suivante :


Projection ETRS89

Première constatation : c'est über-cool, mais la projection rend la carte un peu inhabituelle. C'est parce que les coordonnées utilisent le système ETRS89, une projection azimutale équivalente de Lambert. Elle a le bon goût de conserver localement les surfaces (ce qui est indispensable pour les données de l'INSEE), mais pas les angles (normal, il est impossible de conserver les deux dans une projection cartographique).

Je décide que ça serait sympa d'avoir la projection de Mercator correspondante. OK, c'est une projection naze, mais elle parle un peu à tout le monde.

Première étape : convertir les coordonnées ETRS89 en latitude et longitude. La géométrie elliptique est notoirement complexe, mais par chance, ce pdf a déjà fait les calculs sordides et donne le mode d'emploi pour passer des unes aux autres (page 72, pour les intéressés). Les formules font un peu peur au premier abord, mais il suffit de les suivre avec rigueur, l'une après l'autre, pour obtenir le résultat. Modification du programme, donc. En projetant naïvement la latitude et la longitude de façon linéaire, convertissant à chaque pixel en ETRS89 et regardant la population correspondante, j'arrive à la carte suivante :


Projection naïve

Ah, oui, c'est un peu aplati. C'est parce que la projection de Mercator nécessite une correction supplémentaire en fonction de la latitude. Remodification du programme : pour chaque pixel, je convertis tout d'abord les coordonnées en longitude/latitude, puis en coordonnées ETRS89. Voici le résultat :


Projection de Mercator

Là, c'est bon. Je suis content de moi, je charge le résultat sur Commons.

Quelques temps plus tard, je me rends compte que j'ai trop réduit la définition du fichier final (4 000 pixels de large) et qu'on perd des détails importants. Je regénère la carte en plus grand (5 371 pixels de large). Malheureusement, le fichier final compte plus de 25 millions de pixels et Commons est incapable d'afficher un aperçu d'une telle image PNG. Tant pis.

Pour finir, je change les couleurs pour la palette Solarized. Le résultat final ressemble à ces vues de la France la nuit (ce qui est normal, après tout, quand on y réfléchit) :


Projection de Mercator (fond sombre)

Le résultat est assez fascinant, la résolution est suffisante pour discerner la forme des cours d'eau, des vallées, des forêts. Dans certains cas, on distingue les routes. La dichotomie ouest/est est évidente. La diagonale du vide fait des zigzags. Les Landes sont presque complètement inhabitées. La limite entre le Nord et le Pas-de-Calais apparait. La Sologne également. Et puisque les données initiales ne comprennent que les carrés de 0.04 km² qui sont habités et qu'on en a le nombre exact, on en déduit que 83% du territoire français métropolitain est inhabité. Impressionnant, non ?

Pour finir, je tiens à mettre l'accent sur un point : je n'ai fait qu'écrire un petit programme qui lit un fichier texte, place les données en mémoire puis assigne à chaque pixel d'une image une couleur en convertissant ses coordonnées. Je n'irai pas jusqu'à dire que c'est du niveau d'« Hello World », mais ce n'est pas d'une algorithmique bien complexe. La seule difficulté est initiale : se convaincre qu'avec ces données, on a la capacité de produire quelque chose. Vous aussi, vous pouvez.


[1] J'ai laissé tomber les deux départements d'outre-mer disponibles ; c'est mal, je sais.
[2] On ne répètera jamais assez à quel point Excel permet d'effectuer tout un tas de manipulations de données. Et si votre religion (ou les circonstances) vous interdit d'utiliser du Microsoft, vous pouvez toujours utiliser les équivalents libres et gratuits (je les apprécie moins, mais c'est juste moi).
[3] J'utilise le C++ parce que c'est le langage dans lequel je programme le plus facilement, même pour réaliser un p'tite moulinette à données. Je suis vieux, que voulez-vous.