mercredi 21 novembre 2018

La colère des gilets jaunes témoigne de la fragilité du tout-automobile



Les manifestations qui ont commencé le 17 novembre sont le fait de gens intégrés à la société par le travail, qui vivent à la périphérie des villes moyennes ou des métropoles. C’est ce que rapportent les observateurs et les témoignages recueillis sur place.

Ils ont aussi de plus en plus de mal à payer tout ce qui va avec la vie dans un territoire périurbain. Il y a la maison bien sûr, avec son chauffage et son assurance. Et surtout, il y a les déplacements en voiture, incessants et nécessaires pour effectuer presque toutes les démarches quotidiennes, et pas seulement pour aller au travail : faire les courses au supermarché, amener les enfants à l’école, lorsque celle-ci n’est pas dans le village, et même aller chercher le pain ou passer à la pharmacie.

Leur situation géographique les rend vulnérables vis à vis des variations des prix du carburant. Et ce qui peut les inquiéter, au-delà des taxes qui focalisent leur colère, ce sont les nouvelles sur la fin du pétrole, à laquelle ils assisteront sans doute, rendue inéluctable du fait de la raréfaction progressive de cette matière première. Et aucun discours audible n’esquisse un chemin pour sortir de cette configuration. Va-t-on développer le télétravail et l’emploi local (dans l’agriculture?), ramener des services publics à proximité, développer des transports publics à la demande, des voitures partagées et légères ? Ou s’occuper enfin de la question du logement en ville, qui permettrait à des salariés d’habiter à peu de distance de leur travail et de tous les services offerts par la ville ?

Là-dessus, on peut écouter l’émission Dimanche et Après du 18 novembre 2018, sur France-Culture, avec les commentaires éclairants d’Hervé le Bras.



Mais l’objet de cette note est d’illustrer en une image comment la périphérie des villes a évolué depuis environ 50 ans.


À partir des données de recensement de l’Insee, j’ai calculé l’écart à la moyenne de la croissance de la population. Sur la carte, tout ce qui est en bleu est une population qui croît moins vite que la moyenne (qui est d’environ +50 % sur la période 1968-2013). Tout ce qui est dans des tons jaunes, orangés, croît plus vite.

Le constat est frappant. Les centres villes ont vu croître leur population dans la moyenne nationale ou, le plus souvent, beaucoup moins que ça. La population des couronnes périurbaines a augmenté rapidement, avec des multiplications par dix ou vingt par endroit. C'est valable pour les villes moyennes comme pour les métropoles.



Ces ronds autour des villes racontent cette fuite des classes moyennes des centres-villes, dans un contexte où l’État a favorisé les aides au logement à la personne au détriment des aides à la construction (réforme Barre en 1977), se désengageant ainsi progressivement du logement social. Dans le même temps, on a construit beaucoup d’autoroutes et de routes autour des villes et pour contourner les villages. Les distances domicile-travail ont explosé, mais ce sera l’objet d’un autre post et d’une autre image.

mercredi 22 août 2018

Où sont les ponts routiers dangereux ?

En cette fin août 2018, à la suite de l’effondrement du pont Morandi à Gênes, on débat dans les médias sur l’état des infrastructures routières en France. Si vous avez raté, je recommande vivement le Téléphone Sonne (France Inter) du lundi 20 août, dont l’invité, Philippe Duron, sénateur et rapporteur de Mobilités 21, donne une vision d’ensemble des problèmes. Ce rapport de 2013 faisait un tri dans tous les projets accumulés dans le SNIT (Schéma national d’infrastructures de transport). Il mettait la priorité sur la modernisation d’infrastructures existantes (nœuds ferroviaires en particulier Lyon, desserte des ports maritimes du Havre et de Marseille, quelques aménagements routiers) et préconisait de repousser à plus tard de nouveaux équipements chers et à l’utilité discutée, comme les voies fluviales de liaison à grand gabarit Saône-Moselle / Saône-Rhin, l’A51 Gap-Grenoble ou la LGV Rhin-Rhône branches sud et ouest. Le souci d’entretien du patrimoine grandissait depuis quelques années. En 2006, un rapport réalisé par l’EPFL, l’école Polytechnique de Lausanne, avait alerté sur l’état du réseau ferré français. Il émettait l’idée de concentrer les ressources vers les lignes secondaires fréquentées, au prix de l’abandon des moins utilisées.

Bon, mais les ponts alors ?


Un moment, j’y arrive. La commission Mobilité 21 s’inquiétait aussi de l’état du réseau routier, avec mention spéciale pour les ponts. Page 14, on peut lire « En 2012, 15 % des chaussées et 12 % des ouvrages d’art du réseau routier national non concédé avaient un indice de qualité mauvais. » Les données récentes de 2016 recensent 6,4 % de ponts dans les catégories 3 (structure altérée) et 3U (travaux urgents) et 29,2 % si on y adjoint la catégorie 2E (risques à court terme pour la structure). Mais ces données agrégées par région ne précisent pas quels ponts sont concernés.


Avec un petit traitement graphique, on voit bien les ponts en question. Comment ça racoleur ?

Cependant, les données fournies par le ministère, une fois traitées, permettent de préciser le périmètre de recherche pour un localier qui ferait une enquête dans son périmètre. Je suis parti des données géographiques de l’état du réseau national non concédé et celles portant sur les trafics moyens journaliers annualisés (TMJA). Là-dessus, j’ai superposé dans QGIS les ponts routiers extraits de la couche IGN des points de franchissements, à l’aide de l’éditeur de requêtes (onglet source de la couche). Pour faire apparaître les ponts routiers sur les tronçons les plus dégradés, on procède à une série d’opérations, dans l’ordre :




- Sélectionner dans la couche IQOA (indice de qualité des ouvrages d’art) les tronçons en catégorie 3, avec l’outil de sélection par expression.
- Former autour de ces tronçons routiers un tampon de 100 mètres de large, soit à peu près l’emprise en largeur d’une autoroute. La commande Tampon se trouve dans la boîte à outil, accédée depuis le menu Traitements.
- Créer la sélection des ponts qui intersectent ces tampons avec l’outil de sélection par localisation, toujours dans la boîte à outil.
- On enregistre cette sélection dans un fichier ou une base géospatiale.
- Pour faciliter les recherche, on peut ajouter les coordonnées GPS de chaque point. Dans la calculatrice de champ, on créé un champ latitude = x(transform($geometry,  layer_property( 'couche_des_ponts', 'crs'), 'EPSG:4326')) et
et longitude = x(transform($geometry,layer_property( 'couche_des_ponts', 'crs'), 'EPSG:4326')).



La région Méditerranée est très concernée par le problème

 

La part cachée des collectivités


On part de l’hypothèse raisonnable que les ponts situés sur les routes dégradées sont dans un état similaire. Mais pour être fixé, il faut aller voir sur place ou trouver d’autres sources plus précises. La création de tampons est nécessaire pour faire une jointure spatiale car les routes sont représentées dans l’ordinateur par des lignes sans épaisseur. Trouver une intersection avec un point (un pont) relèverait presque du miracle.

La limite de cet exercice est qu'il ne concerne que le réseau routier national non concédé, un petite partie de l'ensemble des routes et des ponts du pays. Le nombre se trouve sur le réseau à la charge des collectivités locales, pour lequel on ne dispose pas toujours de données sur la fréquentation ou l'état.

lundi 13 août 2018

Croiser les données spatiales pour gagner en précision

Une représentation précise de la population dans un système d'information géographique (SIG) revêt une importance particulière lorsqu'on s'intéresse à l'aménagement urbain, aux infrastructures de transport, aux équipements publics, à la gestion des risques ou celle des espaces naturels. Lorsqu'on est capable de situer la population dans l'espace, on peut aussi répondre à un tas de questions comme "combien de personnes âgées de plus de 75 ans habitent à plus de 300 m d'un transport public", "combien d'enfants de moins de 15 ans n'ont pas d'établissements scolaires à moins de 5 km", "combien de gens seront affectés par le bruit de la future rocade nord", "voit-on une corrélation entre la distance aux entreprises et les ménages à bas revenus", pour peu qu'on dispose dans le SIG de données sur la population et les entreprises.



De nombreux bâtiments (en jaune) de la ville de Nîmes sont soumis au risque d'inondation (zones bleues).


Carroyage de population + bâti cadastral = précision accrue


Les données carroyées de la population de l'Insee rendent la chose possible, je l'ai montré sur quelques exemples dans ce blog. La précision est de l'ordre de 200 mètres, la maille du carroyage. C'est assez fin pour faire des agrégats au niveau des quartiers (la subdivision IRIS). Je me suis demandé si on pouvait obtenir une meilleur précision pour évaluer l'exposition au risque d'inondation ou la distance d'une population à des services publics (transports, écoles, hôpitaux). J'avais observé des maisons, généralement anciennes, construites juste un peu en retrait de lits majeurs de rivières sujettes à des crues dans le Gard et dans l'Hérault. Ces maisons ne devraient pas être affectées par des crues ordinaires. Dans un SIG, la représentation de la population à l'échelle du carreau est trop grossière pour tenir compte de ces stratégies locales. La part des habitants affectés est calculée en appliquant la proportion de la superficie du carreau couverte par la zone inondable. Cette règle de trois marche bien dans beaucoup de cas mais sans doute assez mal si la population n'est pas répartie de façon homogène dans les carreaux.

Mon idée était donc de peupler le bâti du cadastre, une donnée géographique disponible librement depuis peu. Parmi les éléments du bâti, certains seulement sont des immeubles et tous ces immeubles ne sont pas des logements, c'est bien là où se situe la difficulté. On pourrait en première approximation répartir uniformément la population de chaque carreau dans le bâti qu'il contient mais on se retrouverait alors à peupler d'habitants des garages, des armoires électriques sur la voie publique, des entrepôts, des stades de foot, ce qui réduirait le gain de précision espéré. Il y a aussi la question de la surface habitable qui est fonction de la surface et du nombre d'étages, une donnée absente du cadastre.


 
Quels carrés jaunes sont des logements ?

Little Big Data


Pour estimer si un élément du bâti du cadastre est un logement, j'ai d'abord employé une série d'heuristiques basées sur des mesures géométriques pour exclure certains bâtiments publics, entrepôts, grandes surfaces. En croisant d'autres données spatiales, comme la vocation des IRIS, les IRIS A étant consacrés aux activités commerciales ou industrielles, on peut considérer que les grands bâtiments sont a priori des hangars. Pour estimer le nombre d'étages, j'ai fait une statistique au doigt mouillé sur la surface et les dimensions d'immeubles de logements. C'est un modèle assez rudimentaire, basé sur des observations, de nombreux tâtonnement et avec 0% d'IA.

L'algorithme a été réalisé en PL/PgSQL, il procède à une série de créations de tables à partir de jointures et de calculs sur les données d'origine pour ajouter à la couche du bâti un nombre d'habitants. La raison de ce découpage tient d'abord à la simplification du code, qui autrement aurait été extrêmement complexe à concevoir, à optimiser et à lire. Ensuite, entre chaque création de table, on peut créer des index GIST qui accélèrent considérablement le calcul.

Heuristique du logement


Les premières tentatives de validation sont encourageantes, j'obtiens des valeurs vraisemblables pour les villas, les grands ensembles et les immeubles en ville. En regardant de près la ville de Nîmes que je connais, j'ai trouvé des bizarreries, comme certaines tours d'habitations qui se retrouvent désertes, ou la Maison Carrée qui compte quelques habitants, ce que est une erreur manifeste. Mais le Carré d'Art, les Arènes et le Lycée Feuchère n'en ont pas, ils ont bien été pris en compte par mon algorithme. Agrégée au niveau de l'IRIS, la population localisée au cadastre présente des écarts avec les données de population des IRIS 2010 de l'Insee, mais moins que les calculs réalisés directement sur le carroyage.

Pour les autres données démographiques et économiques de l’Insee livrées avec le carroyage, on reste prudent. Ces chiffres sur la tranche d'âge, la taille du ménage, le statut de propriétaire ou le revenu fiscal déclaré par unité de consommation sont lissés à l'échelle de rectangles qui englobent plusieurs carreaux de population. Pour les affecter dans tels ou tels bâtiments avec plus de précision que cette échelle, il faudrait les croiser, encore, avec d'autres données.

Qu'est-ce qu'une jointure spatiale ?

Lorsqu'on fait la jointure de deux tableaux de données, on enrichit l'information initiale. Mais il faut pour cela trouver une clé de jointure, un identifiant commun et non ambigu, comme un numéro Insee de commune, le numéro SIREN des entreprises ou le symbole d'un élément chimique. Pour les données géolocalisées, la clé est une relation spatiale (inclusion, contact, distance) entre deux éléments. Concevoir cette clé nécessite un questionnement et un raisonnement géographique. Cette démarche, très simplifiée dans le cas illustré ici, peut faire intervenir des statistiques ou des modèles plus ou moins compliqués. 



mardi 25 juillet 2017

Une expérience de la data dans une rédaction

Comment une rédaction peut-elle utiliser des données numériques pour mener des enquêtes, apporter une valeur supplémentaire à des articles, raconter des histoires avec davantage de contraintes factuelles et en s'appuyant sur des méthodes quantitatives, bref faire son métier avec des outils d'aujourd'hui. Je pose ici la question à propos des moyens nécessaires, de l'organisation du travail et du partage des tâches. Mon passage de quelques mois dans la rédaction de The Conversation France (j'écrirai ici La Conversation) m'en a donné une expérience et je vous la livre ici. C'est mon point de vue et il n'engage en rien la rédaction.

Le site privé

Quelques lignes pour présenter La Conversation, un média original à bien des égards. Les auteurs sont des chercheurs affiliés à une université ou une institution de recherche (pas de think tank). Ils écrivent sous leur nom des articles, des textes d'analyse sur un débat, un thème en rapport avec leur domaine d'étude. Les journalistes de la rédaction sont des éditeurs, des secrétaires de rédaction si l'on veut, au service du travail des auteurs, pour le rendre accessible aux lecteurs sans le trahir. Les auteurs en approuvent la version finale. Les articles sont publiés en licence CC et un mécanisme de republication simple est proposé aux autres médias en ligne qui disposent ainsi d'une agence de presse en prise avec la recherche scientifique. L'audience de chaque article est mesurée sur le site https://www.theconversation.fr ainsi que sur les sites qui l'ont repris. Ces statistiques sont fournies à l'auteur et à son université.

Un modèle économique à n bandes


Les revenus ne proviennent pas de la revente de contenus ou de l'exploitation des données personnelles des lecteurs mais du soutien financier des institutions qui emploient les chercheurs-auteurs. Il faut avoir à l'esprit que les établissements d'enseignement supérieur sont en compétition pour attirer à eux des étudiants, des enseignants et des fonds. La présence de leurs chercheurs dans les débats qui intéressent la société, par médias interposés, leur apporte une visibilité utile à cet égard. Le modèle économique de La Conversation est donc une forme de médiation d'influence et de réputation.

Le projet Data, dans lequel j'ai été impliqué entre octobre 2016 et juin 2017, vise à offrir aux auteurs de La Conversation un autre moyen de faire connaître leurs recherches, au moyen de la présentation de certaines de leurs données, des data qu'ils utilisent ou produisent au cours de leurs travaux.

Il ne s'agissait pas a priori de produire des des infographies de données que l'on aurait collées dans des articles comme on le fait pour une illustration, bien qu'on ait pu procéder ainsi à l'occasion. On souhaitait prendre la donnée – si possible inédite – comme point de départ et travailler avec l'auteur sur sa représentation et son commentaire.

Le site public

Une équipe ad hoc


Si toute l'équipe a contribué au projet à des degrés divers, c'est à une équipe de trois personnes que la réalisation a été confiée, sans que le flux de production normal soit modifié. La réalisation comprenait la mise en place d'un hébergement pour les infographies, lesquelles ne pouvaient être accueillies dans le système de publication actuel (pas très data friendly, donc), la recherche des auteurs susceptibles d'apporter des données et la création des infographies elles-mêmes. Le plus dur a été de trouver les auteurs.

Dans l'organisation habituelle de la rédaction, les éditeurs ont un rôle clé pour trouver le bon auteur sur un sujet donné. Dans le projet, ils ont été mis à contribution pour trouver les auteurs susceptibles de fournir des jeux de données et les clés d'explication. Aurait-on pu leur demander de produire directement les infographies ? Cette voie directe, qui aurait fait de chaque journaliste de la rédaction un journaliste data, semblait difficile à prendre tant il restait de questions en suspens. Les chercheurs voudraient-ils partager leurs données, sachant que le fonctionnement de La Conversation implique une republication ? Sous quelle forme et dans quels formats ces données nous arriveraient ? Parviendrait-on à en faire quelque chose de lisible et de rigoureux à la fois ? Les plate-formes de création d'infographies pour le web sont-elles assez riches pour visualiser des jeux de données variés que produit la recherche ?

Probablement, seule une équipe dédiée pouvait explorer le terrain, valider les outils et montrer des choses dans le temps imparti par le financement limité dans le temps dont La Conversation disposait. Il avait été obtenu auprès du fonds Digital News Initiative (https://www.theguardian.com/technology/2015/apr/27/google-mistakes-news-outlets-announces-digital-partnership), abondé par Google et il fallait présenter des résultats au bout de quelques mois. On a donc déchargé les éditeurs de la quête des données (même s'ils ont contribué) et de la réalisation des infographies.

Dans mon idée, une étape de transmission devait suivre la phase d'exploration. Elle consisterait à former les éditeurs à la conception de sujets data et à intégrer dans le système de publication des outils de visualisation de données qui ne demandent pas de programmer, possiblement à partir du code de Datawrapper, qui est un logiciel libre et que l'on peut adapter à ses besoins.

Les éditeurs étaient intéressés – et même demandeurs – pour réaliser des sujets à partir de données ou de cartes. De part leurs domaines d'expertises (économie, santé, environnement, science, géopolitique), ils voyaient très bien l'intérêt de la chose. Pour une rédaction, le fait que plusieurs personnes sachent chercher des données et y trouver du sens me semble être l'objectif ultime d'une démarche de transformation avec le numérique. Ça n'exclut pas d'avoir en plus des personnes spécialement formées à la statistique et à l'infographie web et qui viendraient en appui. Pour atteindre ce niveau d'autonomie, il faudrait du temps, un budget relativement important pour former les équipes et développer des outils adaptés à des non-programmeurs, ce point est important.

Les voies de la data


Nous avons sollicité les chercheurs de trois manières. La première a consisté à produire des infographies à partir de données ouvertes et à trouver ensuite des spécialistes de la question qui accepteraient d'en prendre à leurs comptes. Commencer par la création d'infographies était aussi justifié par la nécessité de tester le nouveau site destiné à leur hébergement. Il a été plus difficile de trouver des auteurs pour les commenter, soit parce qu'on ne trouvait pas d'auteur sur le thème traité – il fallait que le contenu couvre exactement le domaine d'étude du chercheur et on a eu des refus pour ça – soit que l'auteur ne pouvait pas écrire pour La Conversation de part son statut (think tank, dans un cas). Dans ce type de démarche, le travail avec le chercheur a consisté à adapter l'infographie proposée.

La deuxième façon de faire supposait que l'auteur amène ses données et que nous réalisions les infographies. C'est ce qui s'est passé à plusieurs reprises. Les données étaient parfois accompagnées de graphiques simples produits dans un tableur ou de suggestions pour leur représentation. À charge pour nous de traiter les données et de produire du code ou des cartes. Les données étaient déjà élaborées suivant les hypothèses et les modèles de l'auteur. C'était donc des résultats de recherche et non des données brutes. Cependant, il a parfois fallu en laisser une partie ou faire des simplifications pour en faciliter la lecture.

La troisième voie a consisté à « mettre en page » des images réalisées par le chercheur. Ces images étaient issues d'un traitement numérique ou d'un travail cartographique destiné à l'imprimé. Notre rôle s'est borné à les rendre plus lisibles sur le web, avec des effets de transition commandés par des boutons, ou de zoom, programmés en JavaScript. C'est ainsi qu'on a procédé pour la série de cartes de Hervé Le Bras sur « La France inégale ».

Un outillage hétéroclite


Concernant les outils, nous avons employé Datawrapper pour les infographies simples et lorsque le jeu de données était peu important. Dans d'autres cas, c'est QGIS en frontal d'un serveur PostgreSQL / PostGIS qui a servi à générer des cartes au format PNG. Pour animer ces cartes, j'ai eu recours à un peu de JavaScript et la bibliothèque D3js pour faire des transitions. L'avantage par rapport à la génération de SVG à la volée dans le navigateur à partir de données, c'est que ça s'affiche vite sur une machine qui n'a pas loin de 10 ans. Enfin, pour les cas qui réclamaient un traitement spécial, on a adapté des bouts de code donnés en exemple par Mike Bostock, le créateur de D3js. C'est là où on se rend compte à quel point D3js est de « bas niveau », c'est à dire qu'elle propose uniquement des fonctions élémentaires et qu'il faut écrire beaucoup de code pour obtenir le moindre résultat ou adapter du code libre existant. Certes, elle donne toute liberté de création au codeur mais elle réclame aussi beaucoup d'effort.

Voyant la nécessité de ce bricolage, et même en faisant abstraction des contraintes spéciales de La Conversation, on pourrait douter que la data puisse devenir un truc réellement low cost dans un avenir prévisible. C'est en tous cas ce que je pensais au début. Pourtant, en voyant un peu plus loin, je me suis convaincu qu'il est possible d'autonomiser les journalistes intéressés à travailler sur des chiffres avec des outils du type Datawrapper. Ces derniers n'offrent à ce jour pas beaucoup de possibilités – pour notre projet Data, ils n'ont couvert qu'une partie des besoins. Mais au moins ils ne sont pas trop complexes et surtout je crois qu'ils vont progresser. L'aspect sur lequel j'attends le plus d'améliorations est la variété des types d'infographies. Datawrapper et les logiciels similaires pourraient bénéficier de bibliothèques de visualisations de données plus abordables que D3js

 
Utilisées directement, ces bibliothèques de haut niveau ouvriront la visualisation de données à des programmeurs dont le niveau sera inversement proportionnel et pourquoi pas à des journalistes un peu codeurs.

Si on peut attendre quelque chose de l'outillage technique, ça ne dispensera pas de travailler le côté humain de la chose, ce travail proprement journalistique de recueil, d'interrogation et de présentation des faits qu'il faudra pratiquer désormais avec des données. Dans le nécessaire conceptuel des journalistes, on cherchera des notions de statistiques, de mathématiques, de cartographie et de programmation. Mais ça, c'est une autre histoire.

lundi 7 mars 2016

Fessenheim, Cattenom, combien de voisins ?

En ce début mars 2016, le débat se focalise en France sur la fermeture de la centrale de Fessenheim et les voisins européens s'inquiètent des conséquences d'un accident sur un site nucléaire proche de leur frontière. Au risque de passer pour un obsessionnel, je vais continuer à documenter cette question, avec des requêtes sur une base SQL spatiale assemblée à partir de données publiques (voir les articles précédents). Les sources primaires sont Eurostat (pour le fond de carte, la population carroyée) et Wikipedia (pour les centrales).


Nombre d'habitants à moins de 30 km des centrales frontalières, suivant le pays

Le cadre de travail est l'hypothèse d'un accident majeur, avec des rejets importants de matières radioactives. La question que l'on se pose d'abord est l'étendue de la zone touchée pour des conséquences données. Le problème lorsqu'on considère des distances importantes, disons 100 km, c'est la difficulté de prévoir ce qui se passerait réellement. Les conséquences ne seraient certainement pas uniformes. Suivant la direction des vents, les précipitations, le relief on pourrait avoir des pollutions graves ou aucune conséquences. Ensuite, où devrait-on s'arrêter ? Au printemps 1986, le sud-est de la France a été sérieusement affecté par le nuage venu de Tchernobyl, à 3000 km de là. J'ai eu connaissance de plusieurs personnes ayant eu un cancer de la thyroïde. Des mesures de rayonnement ont montré, en Provence, de très fortes concentrations de radionucléides par endroit, dans des dépressions du terrain qui collectent l'eau de pluie.

Mais ce que nous apprennent les cas de la centrale ukrainienne et celle de Fukushima, c'est qu'à moins de 30 km, il est difficile de maintenir des établissements humains permanents.

On a donc créé une table contenant les zones de chaque pays situées à moins de 30 km autour des centrales.

CREATE TABLE eustat.zone_nuc_30km AS
SELECT a.name,st_buffer(st_centroid(a.geom),30000,'quad_segs=50')
FROM eustat.centrales_nuc_fr_tampon20km AS a
;

Explication : depuis le barycentre de la zone 20 km créé précédemment, on a créé un nouveau tampon de 30 km de rayon. À partir de cette table, on en créé une autre, dont les champs sont les suivants: nom de la centrale, code du pays, géométrie de la zone de ce pays concernée par cette centrale.

CREATE TABLE eustat.zone_population_30km AS SELECT a.name,b.cntr_code,
st_intersection(b.geom,a.geom)
AS geom
FROM eustat.eeu AS b
JOIN eustat.zone_nuc_30km AS a
ON st_intersects(a.geom,b.geom)
WHERE a.name IN('CATTENOM','Fessenheim','GRAVELINES')
AND b.cntr_code IN('FR','DE','BE','CH')
;

Le Luxembourg et la Belgique sont concernés


L'affichage dans QGIS de cette table montre deux problèmes. Une partie du Luxembourg est concernée par Cattenom et la centrale de Chooz est presque enclavée en Belgique. On rajoute donc les données manquantes. La requête est sur le modèle ci-dessus, mais avec INSERT INTO et les noms de centrales et codes pays corrects.

Après avoir ajouté le nombre d'habitants de chaque zone, on  formatte le résultat dans QGIS.




lundi 15 février 2016

Distribution d'iode stable, des questions et des données

En ce début d'année 2016, les riverains des centrales nucléaires françaises doivent renouveler les pastilles d'iodure de potassium dans leur pharmacie domestique. Ce petit exercice de data-journalisme illustre comment, au croisement des données géospatiales, on peut faire naître de nouvelles questions.

Lors d'un accident nucléaire grave, un réacteur endommagé peut relâcher dans l'atmosphère des éléments radioactifs, dont l'iode 131, un produit de la fission de l'uranium. L'iode stable, celui qu'on mange dans les produits de la mer, est l'isotope 127. La demi-vie de l'iode 131 est de huit jours. Il est donc très radioactif mais décroît vite et disparaît au bout de trois mois. S'il est absorbé ou inhalé peu de temps après l'accident, il est dangereux. En se se concentrant dans la thyroïde, il provoque des mutations et des cancers. La prise de cachets d'iodure de potassium stable, en saturant la glande, empêche de l'iode supplémentaire de s'y fixer et procure une certaine protection pour cet élément.

10 km, pourquoi 10 km ?


Les ménages concernés habitent à moins de 10 km. Cette limite est, semble-t-il, liée à une contrainte logistique (http://www.courrier-picard.fr/region/nucleaire-pres-de-penly-il-est-temps-d-aller-chercher-ia176b0n718481). Si on comprend bien les raisons avancées dans l'article par le chef de la division normande de l’Autorité de sécurité nucléaire, dans ce rayon, on n'aurait pas le temps d'approvisionner dans l'urgence ou d'évacuer, parce qu'on ne dispose que de six heures.

La volonté d'informer le public des pouvoirs publics en charge de la sûreté nucléaire doit être remarquée. « L'accident nucléaire n'est pas probable mais il est possible, en France », c'est le discours aujourd'hui et on mesure les progrès réalisés en trente ans.

Ceci dit, on peut poser d'autres questions. Combien de gens sont concernés et où ? La limite de dix kilomètres est-elle sûre ? En cas de vent puissant, serait-elle valide ? Si on avait étendu la zone à 20 km ou plus, combien de boîtes aurait-il fallu distribuer, à quel coût ? Etc. Des cartes et des données vont nous aider à cerner un peu mieux ces questions.

Si on veut compter la population à une certaine distance des centrales, il faut de toute évidence une carte de chaque.

Openstreetmap est une base de données


Dans un précédent article, on avait montré comment géolocaliser la population européenne, avec des données de Eurostat (http://www.mentrek.org/2015/10/on-enfin-geolocalise-le-peuple.html). Pour ajouter à cette carte les centrales nucléaires française, on va demander à Openstreetmap, ou plus exactement à http://overpass-turbo.eu. Le site aide à formuler des requêtes pour extraire des objets de la base OSM. Dans le cas qui nous intéresse, on recherche les centrales électro-nucléaires : generator:source :nuclear ou generator:method : fission. Le wiki de OSM apporte des précisions utiles pour comprendre l'emploi des attributs: (http://wiki.openstreetmap.org/wiki/FR:Tag:generator:source=nuclear?uselang=fr).




On récupère un fichier au format geojson, que l'on ajoute au projet QGIS, comme on le ferait avec un shapefile. Le projet doit transformer à la volée les données cartographiques car la projection du fond de carte est EPSG 3035 et le fichier récupéré est en WGS 84 (voir les préférences du projet).

L'étape suivante consiste à créer un tampon de 10 km autour des sites de centrales en service. L'idée est de faire la somme des points de la couche de population qui sont dans l'intersection avec la zone tampon pour obtenir la réponse. Là encore, PostgreSQL sera très intéressant.

L'outil Vecteur > Géotraitement > Tampons est appliqué à la couche des centrales. On obtient une nouvelle couche contenant des disques, centrés sur chaque réacteur. À cette étape, l'opération de comptage décrite plus haut produirait des doublons, puisque les centrales comptent plusieurs réacteurs. La solution la plus simple est de sélectionner un disque par site et d'effacer les autres manuellement. Il y a dix-neuf sites électro-nucléaires, c'est pas la mort.

On en profite pour vérifier à l'aide d'une source indépendante les emplacements, les noms, les doublons et erreurs qui ne manquent pas de survenir (dans notre cas, Chinon avait un triple tampon confondu avec Saint-Laurent-des-Eaux et Cattenom). La couche résultante est importée dans Postgres, à l'aide du gestionnaire de base de données de QGIS.



On interroge alors la base, avec la requête SQL suivante, tapée dans le gestionnaire de DB ou un terminal pgsql. Elle donne, par site nucléaire, la population qui habite à moins de 10 km.

SQL, mon amour

Et c'est parti pour quelques requêtes avec jointures, imbrications, groupements, fonctions spatiales et statistiques.

SELECT a.name,sum(b.population)
FROM eustat.euview AS b
JOIN eustat.centrales_nuc_fr_tampon10km AS a
ON st_intersects(b.geom,a.geom)
GROUP BY a.name
ORDER BY sum(b.population) DESC;


 

Pour écrire le résultat dans la couche des tampons, ce qui permettra de l'afficher dans les étiquettes de QGIS, on fait les requêtes suivantes (création d'un champ population, puis mise à jour à partir de la requête) :


ALTER TABLE eustat.centrales_nuc_fr_tampon10km ADD COLUMN population INTEGER;

UPDATE eustat.centrales_nuc_fr_tampon10km
SET population =
(SELECT d.population FROM (
SELECT a.name,sum(b.population) AS population
FROM eustat.euview AS b
JOIN eustat.centrales_nuc_fr_tampon10km AS a
ON st_intersects(b.geom,a.geom)
GROUP BY a.name
) AS d
WHERE d.name = eustat.centrales_nuc_fr_tampon10km.name);


Si on reproduit ces opérations avec un tampon de 20 km, et que l'on compare avec la zone des 10 km, on commence à comprendre le problème posé :



Le nombre de personnes concernées peut être multiplié par six, lorsqu'on étend la zone à 20 km. On le comprend aisément, les centrales sont en dehors des agglomérations mais pas très éloignées d'elles.


On se demande si la zone de 10 km est une limite établie par la raison et la prudence ou alors un choix résigné, contraint par les moyens. Pour tenter d'y répondre, on cherchera à quelle vitesse se déplacent les nuages de poussières, en fonction de la vitesse du vent, du relief ou du couvert forestier, par exemple. Dans cette recherche, on utilisera des données ouvertes (CLC pour le couvert végétal, les MNT de Eurostat, les données climatiques de infoclimat.fr…), on interrogera aussi des climatologues, l'IRSN, la CRIIRAD…

Il me semble que les données sont plus une aide pour l'enquête et le questionnement qu'une source de certitude, une fin en soi. Elle demandent des vérifications, sa dose de sens critique et une analyse à plusieurs entrées.

La carte obtenue a un fond OpenStreetMap, comme indiqué ici: http://www.3liz.com/blog/rldhont/index.php?post/2012/07/17/Les-Tuiles-OpenStreetMap-dans-QGIS. La projection 900913 (pour google) est corrigée avec son appellation officielle, EPSG :3857.

Elle n'est pas très lisible sur le web. J'essaierai d'en faire une interactive, avec D3.js, quand j'aurai un peu de temps de me remettre au Javascript.

mercredi 7 octobre 2015

On a enfin géolocalisé le peuple ! [Postgresql]

Dans Postgres, avec le SQL spatial et des statistiques simples, on pose des faits et des questions politiques

 

Les inondations, les submersions de portions du littoral, l'exposition à des risques industriels sont des questions qui préoccupent, à juste titre, les citoyens. Elles traitent au fond du voisinage, de l'environnement proche. Là où les gens vivent dit beaucoup sur leurs vies : les réseaux de relations, les emplois, les services auxquels ils peuvent prétendre, les équipements publics accessibles, les déplacements contraints, les sources d'agrément ou de nuisance, les risques encourus...

Du côté des aménageurs, des géographes on peut voir ces phénomènes divers à travers la question de la répartition de la population. Parce que, dans les decennies passées, les effets de l'étalement urbain et l'artificialisation rapide des sols ont joué à plein, cette question profondément politique a pris une acuité particulière - et c'est là où la population rejoint le peuple. Qui, traitant des affaires de la cité, peut ignorer où il se trouve ?

Open data pour le débat public

Eurostat publie sur son site un jeu de données carroyées sur la population à l'échelle de l'Europe. C'est une grille de polygones (carrés) de 1 km de côté et un tableau de chiffres dont chaque ligne est identifiée par par une coordonnée de grille et un code de pays. Comme il existe des coordonnées identiques entre pays et que les éléments de la grille ne sont pas liés à un pays, il n'est pas possible de relier les deux de façon rigoureuse de prime abord. Mais on va faire ça avec PostgreSQL et des fonctions spatiales de SQL.

Après avoir créé dans Postgres une base et ajouté les extensions spatiales (voir le manuel de Postgis), on y importe le tableau de population et la grille d'éléments. Pour ce dernier, on emploie shp2pgsql avec une projection EPSG 3035, faite pour représenter l'ouest du continent.

Les jointures spatiales pour relier l'information

On importe ensuite le tableau des entités administratives des pays européens NUTS. L'idée est de faire une jointure spatiale entre la table des éléments de la grille et la table des entités NUTS et de récupérer le code nuts en guise de code pays. À ceci près que les deux ne sont pas toujours identiques. Dans le cas du Royaume-Uni, il existe un code pays pour l'Angleterre, l'Écosse, le Pays de Galles et l'Irlande du nord. Au préalable, on créé, dans la table NUTS, un attribut pays (cntr_code) reprenant le code nuts, sauf pour ces cas particuliers.

D'ordinaire, pour enrichir des données dans une table, on joint une autre table sur un ou plusieurs champs communs. Ici, il n'y a pas de champ commun mais c'est une relation spatiale, qui peut être d'inclusion, d'intersection, de distance (moyenne, minimale...),  qui permet de relier entre elles les informations et d'ajouter du sens.

L'autre idée est de simplifier la géométrie de la grille avec la fonction st_centroid(). Un ensemble de points, centres de chaque carré, est équivalent en information. Il sera notamment plus simple de déterminer à quel pays rattacher un point qu'un carré qui pourrait être à cheval sur une frontière.

On créé donc la nouvelle table, qui comprend une géométrie de type point et dont chaque élément est identifié par une coordonnée de grille et un code de pays.

create table eupop_q as
select c.geom, c.code as grid_id, c.cntr_code, c.nuts_id
  from
    (select a.code,b.cntr_code,b.nuts_id,a.geom
      from
        (select * from eustat.eeu
          where (niveau = 0 and nuts_id != 'UK') or (niveau = 1 and nuts_id like 'UK%') ) as b
      join eustat.eupop_grid as a
      on st_within(st_centroid(a.geom),b.geom)
    ) as c
with data
;


Une jointure spatiale sur une table de près de deux millions d'enregistrements prend un certain temps, surtout sur une machine plus jeune du tout. Pour l'exploitation, il existe quelques moyens pour accélérer les traitements. Mais, il faut l'avoir à l'esprit, une requête mal réfléchie (je suis sûr que c'est le cas ici) prendra un temps considérable sur un matériel ultra rapide, dès lors que les tables ont beaucoup de lignes.

La table obtenue par la requête ci-dessus n'est pas parfaite, loin s'en faut. On se rend compte qu'elle omet tous les points situés un peu en dehors des limites administratives, sur les côtes, côté mer. Le carroyage d'Eurostat n'est précis qu'à 700 m près, et parfois l'imprécision est à dessein, par souci de préserver les personnes (certains carrés contiennent un seul individu). On a trouvé plus de 20 000 points dans ce cas. Comment rattacher ces points au pays le plus proche et leur attribuer un code ?


 

Logique des ensembles

La méthode consiste à chercher, pour tout point situé en dehors des limites administratives, la distance à chaque pays et d'autre part de rechercher, pour chacun de ces point, la distance au plus proche pays. Les deux sous-requêtes ne diffèrent que par le jeu des groupements (group  by). La jointure entre les deux tables résultantes donne le pays le plus proche, avec ses attributs. On réintègre le résultat dans le tableau de points (avec insert into).

select x.geom,x.code as grid_id,x.cntr_code,x.nuts_id
from (
  select min(st_distance(st_closestpoint(a.geom,b.geom),b.geom)) as mini,b.id,b.geom,b.code,a.cntr_code,a.nuts_id
  from (select * from eustat.eeu where (niveau = 0 and nuts_id != 'UK') or (niveau = 1 and nuts_id LIKE 'UK%')) as a,
    (select id,st_centroid(geom) as geom,code from eustat.eupop_r) as b
  group by b.id,b.geom,b.code,a.cntr_code,a.nuts_id
  ) as x
join (
  select min(st_distance(st_closestpoint(c.geom,d.geom),d.geom)) as mini,d.id,d.code
  from (select * from eustat.eeu where (niveau = 0 and nuts_id != 'UK') or (niveau = 1 and nuts_id LIKE 'UK%')) as c,
    (select id,st_centroid(geom) as geom,code from eustat.eupop_r) as d
  group by d.id,d.code
  ) as y
on x.id = y.id
where x.mini = y.mini
;


Ya peut-être une meilleure façon mais je l'ai pas trouvée. La table est complète. Manquent quelques paradis fiscaux et le Vatican, ce qui est négligeable.

Une jointure plus loin, avec le tableau de population, sur les attributs de grille et de pays, et on obtient la table qui sera exploitée dans l'outil de cartographie QGIS.



Après un petit travail sur la visualisation dans QGIS (cercles proportionnels à la population) le résultat est spectaculaire et éloquent. La présence ou l'absence de population révèle bien sûr les agglomérations mais aussi les fleuves, les routes, les lacs, les montagnes, les vallées de montagne.



Mais la contemplation a ses limites. Et le SQL spatial donne des résultats chiffrés, par exemple pour évaluer le voisinage d'une centrale nucléaire. Par exemple, combien de gens vivent à proximité de nos centrales, disons 20 km ?

Nous avons préparé un fichier de points avec quelques établissements industriels. La requête combine les fonctions spatiales et les statistiques, ici une simple somme.

select c.nom_centrale,sum(p.population) as pop_evacues
from eustat.centralesnuc as c join eustat.eupop_q as p
on st(intersects(st_buffer(c.geom,20000),p.geom)
;



Pour Gravelines, c'est 252 925 habitants.

SQL spatial et statistiques, constituent ensemble un outil précis pour l'exploration du réel.

lundi 8 juin 2015

Les majuscules aux bons endroits avec JavaScript

L’étiquetage des toponymes - les noms de lieux - est un problème récurrent en cartographie, en tous cas pour la France où les noms composés abondent. Souvent, on dispose de bases de noms en bas de casse ou capitales. QGIS propose une fonction, Title(), pour passer l'initiale en majuscule. Mais rien pour Saint-Paul-Trois-Châteaux ou Sotteville-les-Rouen. Dans ce dernier cas, l'article doit rester en bas de casse. Je m'étais arraché les cheveux sur un un script dans QGIS, sans succès. La dernière version du logiciel propose de définir ses propres fonctions, ce qui donne de l'espoir. Parce que, c'est assez facile à comprendre, la fonction dont on a besoin ici est récursive. En effet, on ne sait pas a priori combien de mots séparés par des tirets le toponyme comportera.

L'idée de l'algorithme est de capitaliser le premier mot situé avant un tiret (sauf si c'est un mot de liaison) et d'appeler la fonction en lui passant en argument le reste du nom de lieu. Une fonction qui s'appelle elle-même en un point de son exécution, c'est l'illustration de ce style dit fonctionnel qu'affectionnent tant les matheux. Et c'est vrai que c'est assez joli. Peu de code, peu de bug (pour voir le code Ctrl-u).

J'ai découvert récemment le JavaScript. Le langage se prête bien au style fonctionnel. Et le programme marche. Il restera à reprendre l'idée pour QGIS.

Dernière itération du code : 22 août 2016.






EnMajUScuLeS

--

mercredi 27 mai 2015

QGIS et PostgreSQL : des données sur des cartes

Avec le couple QGIS/PostgreSQL (et son extension PostGIS), nous avons agrégé des données démographiques pour les projeter ensuite sur une carte de l'Europe.

QGIS est un très bel outil pour la cartographie l'analyse des données géospatiales. Ces dernières années, les nouvelles versions se sont succédé à un rythme rapide du fait d'une communauté très active de développeurs et d'utilisateurs.
La difficulté de travailler avec un tel outil tient plutôt à la forme la plus fréquemment disponible des données, un ensemble de fichiers (d'extensions .shp, .shx, .dbf, .proj). Ces fichiers (shapefile pour faire court) sont faits pour l'échange mais pas du tout pour le travail en équipe, simultané, sur un jeu de données cartographiques. C'est un peu comme si on revenait à l'échange de fichiers de traitement de texte par mail, alors que les outils en ligne sont bien plus efficaces pour écrire à quatre mains ou gérer les versions successives d'un document. De plus, le shapefile est assez primaire sur les champs attributaires et rend délicat l'agrégation de données d'origines diverses.
Tout ça plaide pour coupler QGIS à une vraie base de données géospatiale, comme PostgreSQL/PostGIS. PostgreSQL est un SGBDR, PostGIS désigne ses extensions géospatiales.

Le connecteur PostgreSQL de QGIS

Créer une base PostGIS


Il est nécessaire de créer une nouvelle base et d'y ajouter les extensions PostGIS, on résume ici le manuel de Debian. Dans un terminal, après avoir pris les droits de l'utilisateur 'postgres', on tape:


createdb --o
createlang plpgsql -d

psql
-f /usr/share/postgresql/*/contrib/postgis-*/postgis.sql
psql
-f /usr/share/postgresql/*/contrib/postgis-*/spatial_ref_sys.sql
psql

grant all on geometry_columns to
;
grant select on spatial_ref_sys to
;
\q
# en tant qu'utilisateur normal :
psql -h
-U -d


 
QGIS rend visibles sur la carte les statistiques de toutes origines

Importer les données dans Postgres


Pour accueillir la carte des entités NUTS récupérée sur Eurostat (au format d'échange Shapefile), on emploie shp2pgsql, en rajoutant, dans le fichier de commandes sql qu'il génère, nos propres contraintes, notamment pour la clé primaire. On fait donc, dans un terminal :

shp2pgsql -c -s 3035 /chemin/vers/le/shapefile.shp > /chemin/vers/le/fichier/de/sortie.sql


La projection est EPSG 3035 (obtenue par réexport de QGIS, où l'on a aussi préparé les champs), bien adaptée à la représentation de l'ensemble de l'Europe. Plutôt que d'exécuter le fichier sql (psql < sortie.sql), on l'ouvre dans un éditeur et modifie les commandes de création de table.

CREATE TABLE eEU (
    niveau SMALLINT NOT NULL,
    nuts_id CHAR(5) PRIMARY KEY,
    shap_len DOUBLE PRECISION,
    shap_are DOUBLE PRECISION,
    cod_p CHAR(2) NOT NULL,
);
//On remarque la ligne qui rajoute la colonne de géométrie :
SELECT AddGeometryColumn('', 'eEU','geom',3035,'MULTIPOLYGON',2);


À présent, on a une carte mais il lui manque des données attributaires un peu consistantes. C'est là où on ressort le fichier des entités LAU1 et LAU2, récupéré aussi sur Eurostat. Ce fichier étant une vue exportée, il ne correspond pas nécessairement à nos besoins, ni aux critères pour la meilleure cohérence des données. Dans un premier temps, on l'a normalisé, en passant du premier schéma logique à un schéma à trois tables.

lau2(idnuts3,lau1,lau2,nom,nomlat,area) -->

lau2_2010 (nuts3,lau2,nom,area) PK (nuts3,lau2)
lau1_2010 (nuts3,lau1,nom,area) PK (nuts3,lau1)
lau_12 (nuts3,lau1,lau2) PK (nuts3,lau1,lau2)


Le modèle est peut-être plus difficile à appréhender, mais il est moins « troué » et il peut simplifier la création de vues, comme on va le voir. Le code pour créer les tables est simple et ennuyeux, on l'épargnera au lecteur.

Une vue sur la population


On a importé dans Postgres une table de population et une autre sur les entités nuts3. Puis, on a créé une vue qui calcule la surface de ces entités, à partir de ses subdivisions, et calcule la densité, en fonction de la population. La requête est sensiblement plus rapide qu'avec le schéma précédent, alors qu'il y a plus de tables.

CREATE OR REPLACE VIEW nuts3_hab_km2 AS
SELECT nuts3_2010.nuts3,nom,round(km2,2) AS superficie_km2,population,round(population/km2) AS hab_km2,pnuts2 AS parent FROM (
  select nuts3,sum(area)/1000000 AS km2
  from lau22_2010 where nuts3 not in (
    select nuts3 from lau22_2010
    where area IS NULL
    )
  group by nuts3
  union
  select nuts3,sum(area)/1000000 AS km2
  from lau1_2010 where nuts3 not in (
    select nuts3 from lau1_2010
    where area IS NULL
    )
  group by nuts3
) AS nuts_surf
JOIN nuts3_2010
ON nuts3_2010.nuts3=nuts_surf.nuts3
JOIN pop
ON nuts_id=nuts3_2010.nuts3
;

La gueule de la table résultante est intéressante.

select * from nuts3_hab_km2 limit 4;

 nuts3 |        nom         | superficie_km2 | population | hab_km2 | parent
-------+--------------------+----------------+------------+---------+--------
 ITC49 | Lodi    |    782.20    |    229082    |    293    |    ITC4
 DE22B | Straubing-Bogen    |    1201.90    |    97323    |    81    |    DE22
 EL431    |    Irakleio    |    2641.22    |    |    |    EL43
 UKG21 | Telford and Wrekin |    290.31    |    168713    |    581    |    UKG2


Jointure dans QGIS


La récréation a sonné, on lance QGIS, connecte la base Postgres (icône d'éléphant) et importe les tables utiles (carte, population, et la vue nuts3_hab_km2 fraîchement créée). Lors de cette opération, il est nécessaire de choisir un champ de clé primaire valide (ici nuts3).
Ensuite, on ouvre les propriétés de la couche multipolygones et on ajoute une jointure vectorielle (onglet jointures dans la fenêtre de propriétés) entre la table et la carte. C'est fini !

À partir de cet exemple, on peut imaginer la suite. Des données combinées entre elles avec du code SQL, des couches importées de OSM ou créées par les rédacteurs... Avec le réglage des droits d'accès, des sauvegardes, Postgres est bien fait pour bosser en groupe.

mardi 12 mai 2015

Les data au tamis de PostgreSQL

Les données pour le journalisme quantitatif, qu'elles soient le produit de scraping ou issues d'institutions, sont souvent défectueuses. Des variations de format (point ou virgule pour la marque décimale), de type ('1' est un caractère, tandis que 1 est de type numérique), les espaces en fin de champ ou mélangés aux tabulations, les champs nuls et autres coquilles rendent leur exploitation statistique ou cartographique hasardeuse.

Le tableur est assez limité mais néanmoins utile et en tous cas nécessaire pour préparer les fichiers. Les outils en ligne gratuits, comme Table Fusion, impliquent un partage des données avec le fournisseur et une dépendance à son égard. On va voir ici comment les systèmes de gestion de bases de données relationnelles (SGBDR) peuvent aider.

L'idée est de créer des tables temporaires pour accueillir les données à valider, avant de les intégrer dans des tables définitives, qui auront toutes les contraintes référentielles voulues. Les exemples sont donnés ici avec PostgreSQL mais ils devraient fonctionner sur d'autres  SGBDR.

Contraintes de type

 

On a travaillé sur le fichier des entités statistiques LAU2 de Eurostat. Le tableau, un fichier bureautique, a été enregistré sans les entêtes de colonnes et au format TSV (valeurs séparées par des tabulations), avec l'encodage de caractères de la base (UTF-8, ici). Avant d'importer ce fichier dans la base, on doit créer une table pour l'accueillir. Il faut réfléchir au type de données que contiendra chaque colonne (chaîne de caractères, de longueur fixe ou variable, numériques, entiers ou à virgule, avec quelle précision, date, booléen ... ). Le plus contraignant sera le mieux.

CREATE TABLE lau2_2010 (
idnuts3 char(5), /* les identifiants NUTS3 font exactement cinq caractères*/
lau1 varchar(15), /*les identifiants LAU1 font au maximum 15 caractères*/
lau2 varchar(15),
nom varchar, /* les noms sont de longueur variable et non spécifiée - ce dernier point est une particularité de PostgreSQL*/
area numeric
) ;

L'opération de copie du fichier TSV échoue si une seule ligne viole une contrainte. En général, l'erreur attire l'attention sur un problème commun à de nombreuses autres lignes que l'on doit résoudre avec le tableur. Une difficulté rencontrée tenait à la variété des indicateurs de données absentes, tantôt n.c.a., n.c.a, NA, etc. Sur un fichier de près de 120000 lignes, il est improbable de les déceler dès la première lecture. Les données non existantes doivent être traduites par \N pour être admises dans Postgres. Attention, le tableur peut ajouter des erreurs, au moment de l'ouverture du fichier source (s'il n'est pas dans son format naturel). On a vu 00AM et 00PM, qui sont des codes en vigueur au Royaume-Uni, interprétés en un format d'heures : minuit et midi. Même chose pour 95E15, vu comme la notation du nombre 95000000000000000.
Une fois les contraintes de type respectées, l'opération copie les 120000 lignes en deux secondes.

\copy into essai_temp from /chemin/vers/fichier.tsv

 

 À la recherche du schéma logique

 

Une fois la table peuplée, on peut rechercher des incohérences plus subtiles et chercher à comprendre le schéma logique de la table. La recherche des champs vides et les clés candidates sont au menu.

SELECT idnuts3,lau1,nom FROM lau2_2010
WHERE lau2 IS NULL;

SELECT idnuts3,lau2,nom FROM lau2_2010
WHERE lau1 IS NULL
AND lau2 IS NOT NULL;

Ces requêtes renvoient les lignes dont LAU2 est vide et dont LAU1 est vide et pas LAU2, respectivement. On comprend ainsi que certains pays possèdent des entités LAU1 qui ne contiennent aucune LAU2 (la Grèce et le Danemark), tandis que d'autres ont rangé des entités LAU2 directement sous les NUTS3, sans LAU1. Cette table est sans doute une vue, une table virtuelle produite par une requête, facile à exploiter mais pas idéale pour organiser les données dans la base. Cette table pourrait être renormalisée, décomposée en tables dépourvues de redondances ou de champs nuls.

On cherche si un identifiant est unique au niveau européen, ce qui sera bien utile pour faire des jointures spatiales dans un logiciel de cartographie. L'identifiant LAU2 est-il unique au niveau européen ? Une requête à auto-jointure affiche les lau2 communs à des entités dont les noms diffèrent.

SELECT L1.nom,L1.lau2,L2.nom
FROM lau2_2010 AS L1
JOIN lau2_2010 AS L2
ON L1.lau2 = L2.lau2
WHERE L1.nom < L2.nom;

La liste renvoyée n'est pas nulle, elle est même longue (21178 entités). LAU2 ne peut être retenu comme identifiant unique, même en ignorant les lignes où il est vide.

Le couple idnuts3-lau2 est-il alors une clé candidate ? Cherchons s'il existe plusieurs noms pour ce couple d'attributs.

La directive GROUP BY regroupe les lignes avec des attributs communs. C'est très utile pour faire des statistiques mais aussi pour trouver d'éventuels doublons dans une table brute d'importation.

SELECT L1.idnuts3,L1.lau2
FROM (
SELECT * FROM lau2_2010
WHERE lau1 IS NOT NULL
AND idnuts3 IS NOT NULL
) AS L1
GROUP BY L1.idnuts3,L1.lau2
HAVING count (*) > 1
;

La requête montre les pays qui n'ont pas d'entités lau2 (Danemark et Grèce), ce qui est attendu, mais aussi une ligne, qui s'avère être un doublon. Une ligne fautive sur 120000, introduite lors des manipulations sur le tableur ou peut-être d'origine Eurostat.

Une autre requête confirme, par son résultat vide, que le couple idnuts3-lau2 est un identifiant possible, pour les lignes où lau2 n'est pas vide. Ici, on compare les noms.

SELECT R1.idnuts3,R1.lau2,R1.nom AS nom1,R2.nom AS nom2
FROM (
SELECT * FROM lau2_2010 WHERE lau2 IS NOT NULL
AND idnuts3 IS NOT NULL
) AS R1
JOIN (
SELECT * FROM lau2_2010 WHERE lau2 IS NOT NULL
AND idnuts3 IS NOT NULL
) AS R2
ON R1.idnuts3 = R2.idnuts3
WHERE R1.lau2 = R2.lau2
AND R1.nom < R2.nom
;

 idnuts3 | lau2 | nom1 | nom2
---------+------+------+------
(0 ligne)

 

Au croisement des données

 

Une jointure sur une autre table, qui recense les entités NUTS niveau 1, 2 et 3, met en évidence trois identifiants NUTS3 non répertoriés.

SELECT DISTINCT idnuts3
FROM lau2_2010
WHERE idnuts3 NOT IN (
SELECT nuts_id FROM nuts2010
);

idnuts3
---------
N_A 
DEZZZ
FR215
(3 lignes)

N_A est encore une variante pour un champ vide, qui a échappé au tableur. DEZZZ désigne une 'Extra-Regio NUTS 3', ligne absente de la table nuts2010 et que l'on rajoute. FR215 est sans doute une coquille. Les communes françaises sous cet identifiant sont situées en Haute-Marne, soit FR214, dans la version 2010 de NUTS3. On rétablit la situation avec :

UPDATE lau2_2010
SET idnuts3 = 'FR214'
WHERE idnuts3 = 'FR215' ;

Des fonctions statistiques simples du SGBD permettent des vérifications croisées entre plusieurs sources. Avec une requête, on a calculé la surface des entités NUTS3, à partir de celle des entités LAU2 qui les constituent, et la densité de peuplement de chaque NUTS3, à partir d'une jointure sur une table de population d'origine Eurostat. En fin de requête, on demande un classement pour montrer les entités les plus densément peuplées en haut de la liste.

SELECT surf.nuts_id,surf.nom,round(1000000*(population/surface)) AS densite
FROM (
SELECT n10.nom,n10.nuts_id,sum(l10.area) AS surface
FROM (
SELECT * FROM nuts2010 EXCEPT (
SELECT * FROM nuts2010
WHERE niveau =3 AND nuts_id IN (
SELECT idnuts3 FROM lau2_2010 WHERE area IS NULL
))) AS n10
JOIN lau2_2010 AS l10
ON l10.idnuts3=n10.nuts_id
GROUP BY n10.nuts_id,n10.nom) AS surf
JOIN pop ON pop.nuts_id = surf.nuts_id
WHERE pop.population IS NOT NULL
GROUP BY surf.nuts_id,surf.nom,surf.surface,pop.population
ORDER BY densite DESC
LIMIT 50;

Le problème est apparu immédiatement. Des régions néerlandaises étaient bien plus denses que Paris (qui a plus de 21000 hab/km2). L'anomalie touchait aussi la Suède. Pour ces deux pays, la surface était exprimée en ha et non en m2, comme pour le reste de la base. Un petit correctif a remis les bons ordres de grandeur.

UPDATE lau2_2010
SET area = area * 10000
WHERE idnuts3 LIKE 'SE%' OR idnuts3 LIKE 'NL%';

Enfin, la comparaison des surfaces et des densités obtenues avec d'autres sources, comme Wikipedia, a permis de s'assurer de la cohérence de la base.

Voilà, ces quelques exemples montrent comment une base SQL peut aider une rédaction, un journaliste, à valider un grand ensemble de données.

lundi 17 novembre 2014

Écotaxe : il faudrait aussi l'appliquer en ville

En 2014, les bérets rouges ont présenté leur révolte contre l'écotaxe comme la défense d'une région face à l’État central et l'expression d'un ras-le-bol fiscal. Le mot, dont la mode a été lancée par Pierre Moscovici, est-il juste pour décrire la réalité du transport routier ? Est-il au contraire légitime de voir cette révolte comme la défense d'intérêts catégoriels ? On ne va pas trancher ici sur des questions aussi complexes. On se bornera à apporter quelques éléments factuels pour cadrer un débat qui ne fait que commencer.

La vérité des coûts

La transparence des coûts possède au moins la vertu d'éclairer les citoyens sur des choix qui ne seraient pas explicites. Certaines activités peuvent en effet être silencieusement subventionnées, lorsque leurs acteurs en font supporter les coûts à d'autres. Ces coûts sont pudiquement nommés externalités, façon de dire qu'on a refilé le Mistigri à d'autres. En matière de transport, ces coûts comprennent le bruit, les embouteillages, la mauvaise qualité de l'air, les émissions de CO2, les accidents, l'usage des infrastructures. En général, seule une partie est imputée aux usagers, au moyen de péages et de taxes sur le carburant ou les véhicules. Une autre partie reste à la charge du contribuable ou des cotisants de la Sécu et des mutuelles. Je répète qu'il n'est pas illégitime de subventionner une activité mais aussi qu'il est bon de savoir qui reçoit et combien.

Sur les externalités des transports, la direction du Trésor français fournit ses statistiques, compilées par le CGDD. Après quelques calculs, à l'aide des données de trafic du ministère des transports, on peut donner une idée de ces fameux coûts.

Les sommes sont en euros constants 2010, les coûts proportionnels à la surface des disques. Les modes de transport de marchandises sont le fluvial, le rail et la route.

Le transport de marchandises est subventionné


Le premier constat est qu'aucun des modes de transport de marchandises ne paye les externalités qu'il occasionne. La surface des disques illustre l'importance de ces coûts, auxquels on a soustrait les péages et taxes acquittées par le mode en question. C'est donc un bilan et il est négatif pour les trois modes.

Il est intéressant de détailler le bilan du transport routier, qui compte seulement les poids-lourds et ignore les utilitaires légers de moins de 3,5 tonnes. On a juxtaposé au déficit (vu plus haut) la ventilation des coûts et celle des recettes. Là encore, les surfaces sont proportionnelles aux coûts.


Au chapitre recette, la TICPE est la taxe sur les carburants. Si on considérait seules les infrastructures, on penserait que les péages d'autoroutes en couvrent l'entretien. Mais ce poste est peu important, relativement à l'environnement (pollution locale et CO2, bruit, vibrations) et surtout à la congestion du trafic.

L'importance des embouteillages

Une bonne partie du problème viendrait donc des bouchons ! La comparaison des coûts marginaux tend à le confirmer. Un poids-lourd sur une autoroute dégagée coûte 22 fois moins qu'un autre progressant par à-coups dans une zone urbaine.

Le bilan des poids-lourds est positif sur les autoroutes payantes, négatif sur les nationales (que l'écotaxe devait rendre payantes pour certaines) et très négatif en ville.


L'unité utilisée est le centime d'euro constant, corrigé de l'inflation depuis 2010, par tonne-kilomètre (déplacement d'une tonne sur un km).

Le pire : la voiture en ville

La comparaison avec le coût, pour la collectivité, du déplacement d'une personne sur un kilomètre est instructive. Ici, on assimile un passage.km à une tonne.km. C'est justifié si on considère la masse moyenne d'un véhicule (1 400 kg en France) et le taux moyen d'occupation en zone urbaine (1,2 passager/véhicule).




Se déplacer en voiture en ville produit des nuisances ruineuses pour les finances publiques.
Si ces comparaisons plaident pour un péage, c'est sans doute pour le péage urbain, appliqué aux poids-lourds et aux véhicules individuels. On peut supposer que la vérité des coûts aurait un effet sur les agents économiques. Dans ce cas, elle pourrait favoriser les logistiques urbaines nouvelles, qui font appel au mode fluvial (dans les villes traversées par un fleuve) ou au vélo-cargo. La meilleure façon de favoriser ces derniers serait donc d'abaisser les subventions cachées aux modes les plus polluants, en faisant progressivement croître leur contribution à ce qu'ils coûtent.

mercredi 4 juin 2014

Fusion des régions françaises dans QGIS

La carte des nouvelles régions françaises ! Il s'agit de la version 1.0 mise en avant par la présidence. Soyons sûrs que chacun mettra son grain de sel pour garder son siège ou donner un nom à son goût. D'ailleurs, je viens de faire une proposition. Le travail de fusion des Shapefile dans QGIS n'est pas sans détour et il m'a fallu quelques étapes. Mais c'était plié en 20 mn. Et c'est tant mieux, parce qu'il y aura sûrement d'autres versions.
Un KML est disponible ICI.



dimanche 4 mai 2014

Bio hacking et boulangerie

Le goût du pain connaît peu la diversité. Même dans un pays qui a su garder une tradition boulangère, d'un point de vente à l'autre, la baguette ou le gros "campagne" dégagent un éventail d'arômes singulièrement réduit. On doit se résoudre à constater qu'il existe des saveurs plus susceptibles que d'autres de plaire, ou de ne pas déplaire, à un grand nombre de gens. Mais comme le goût est une affaire d'éducation, le risque de suivre cette pente est d'aboutir au bout d'un certain temps à un goût uniformément tendre, moelleux et édulcoré.
L'industrie boulangère livre invariablement des miches aux saveurs légèrement maltées, avec une croûte caramélisée. Les pains de supermarchés donnent souvent l'impression d'être rehaussés d'arômes tant leurs fondamentales, celles que l'on respire après mastication, sont décharnées et proches de la farine. Même les gros de six livres, vendus à la découpe dans les chaînes bio, manquent de caractère à force de rechercher un consensus. Il y a longtemps que je n'ai pas acheté un pain aux arômes entêtants d'un levain puissant.
Le pire, c'est le pain de seigle. Généralement mal cuit, trop salé, raté par manque d'attention. Parce qu'il demanderait un traitement à part, non standard, il tend à disparaître des étals. Notable exception, le seigle complet de quatre livres de la boulangerie d'Écoles-en-Bauge est une réussite. Avec une jolie croûte, une mie cuite et dense, il assume une palette complexe et acide. Mais il est difficile à trouver.
La boulangerie, c'est un peu du bricolage bio. Ça ne devrait pas faire bon ménage avec les processus industriels labellisés ISO, ni l'ambition de plaire à la Terre entière, alors qu'on dessert trois villages. Logiquement, j'ai décidé d'aller bricoler dans mon atelier.


La fermentation doit être longue.

Ce qui donne du goût au pain, ce sont les levures, les moisissures, les bactéries, les archées qui mijotent dans le levain. Que les hypocondriaques se rassurent ici, la plupart des pains du commerce sont levés non pas au levain mais à la levure. Pour préparer celle-ci, on a sélectionné en laboratoire stérile une souche pure qui a les caractéristiques recherchées. Puis, on l'a reproduite en grand et conditionnée en petits sacs hermétiques. C'est un peu le même processus que pour le Camembert au lait pasteurisé, pour lequel on commence par tuer les micro-organismes qui se trouvent là. Ainsi, s'imposent facilement les quelques clones sélectionnées que l'on réintroduit après la pasteurisation. Le résultat sur le goût du fromage est similaire à celui obtenu avec le pain à la levure. C'est pauvre et terriblement prévisible.
Pour obtenir du levain, il faut un peu de farine, de l'eau et du temps. Dans un verre, qu'on ne couvrira pas, on délaie un peu de farine et d'eau tiède. On laisse le mélange dans une atmosphère douce pendant quelques jours. Pour aider, on peut écraser un grain de raisin ni lavé ni essuyé ou ajouter une pincée de sucre. De temps en temps, on rajoute une cuillère de farine et d'eau. Invariablement, le mélanger fermente. À force d'ajouts, on obtient une balle de pâte molle et odorante. Plus herbeux en hivers, franchement alcooliques lorsque la température monte, les tons varient et ne sont jamais purs. Il ne faut pas rejeter quelques notes amères de moisissures, pourvu qu'elles ne prédominent pas. Bien sûr, on ne fait pas le levain à chaque fournée. Avant le façonnage, on récupère une poignée de pâte pour ensemencer le pétrin suivant.
Pour la farine, j'ai choisi un seigle type 130 en mélange 50/50 avec un blé type 80. On peut remplacer le blé par le grand épeautre (spelta). Céréale de terres pauvres et froides, le seigle vient de Haute-Loire. Le blé est cultivé en Picardie. Ben si, on peut trouver des céréales bio en France. Pour le sel, on aura la main légère.
La durée de la première fermentation (le point) est l'élément déterminant, avec le levain, pour le goût du pain. Après le pétrissage, on laisse la pâte reposer en une seule boule. Le minimum, à condition d'avoir 25 °C, est de trois heures. Mais je trouve cette valeur un peu basse. En fait, le point peut durer la nuit. Plus la masse fermente, plus les arômes s'élaborent. En été, c'est une vraie cornue d'alchimiste. Après le façonnage, on laisse aux pâtons le temps nécessaire pour aérer la pâte. Deux heures, parfois beaucoup plus s'il ne fait pas chaud.



 
Le seigle forme des pains denses, qui doivent être cuits à température modérée mais assez longtemps.

Pour la cuisson, j'ai improvisé un four, une poêle en fonte épaisse ajustée à un couvercle de cocotte en fonte. Le tout est isolé par de l'alu, du papier épais et un tissu. La chaleur est ainsi confinée dans l'espace entre poêle et couvercle. Il faut bien préchauffer ce four. Une cuisson trop rapide brûlerait la croûte et laisserait l'intérieur trop humide. Il faut jouer du thermostat, l'odeur est un guide sûr pour ça. L'inertie thermique de la fonte est une alliée.
Après quelques essais, le résultat est satisfaisant et même réjouissant !

dimanche 9 mars 2014

Bitcoin : une régression monétaire

Le Bitcoin est un protocole de transactions de pair à pair - décentralisé - promu comme système de paiement. Les échanges sont libellés en bitcoins, une unité à laquelle on a un peu vite fait d'attribuer les qualités d'une devise internationale, ainsi que les atours - un symbole barré, des images de pièces en or avec un slogan latin (Vires In Numeris - La force du nombre), etc.

La monnaie est un  objet choisi par un groupe comme représentation d'une valeur. C'est un contrat social. Il peut servir, au choix, d'unité de compte, de moyen d'échange, de réserve d'épargne. C'est la promesse faite par le groupe à l'individu que le coquillage, le bout de papier ou la suite de bits, qu'il a obtenu en échange d'un travail ou d'un bien tangible, lui permettra d'acquérir un équivalent, dans le futur. C'est donc une dette.

Cette garantie d'être remboursé un jour élargit beaucoup la possibilité de commercer, y compris avec des inconnus. Et ce jeu va de pair avec des règles claires et connues de tous, à défaut d'être comprises. En zone euro, par exemple, la cible officielle d'inflation est de 2% par an, pour accompagner la croissance (potentielle) des échanges et éviter une déflation sans trop éroder l'épargne (OK, ça fait beaucoup). Pour certaines monnaies locales (le Chiemgauer, en Basse-Saxe), un système intégré d'inflation incite les acteurs à ne pas épargner, le but étant de stimuler le commerce. Les SEL (Systèmes d'échanges locaux) sont explicitement faits pour promouvoir les entreprises locales, l'action sociale (Timebanks.org), l'échange de savoirs et l'éducation (Saber au Brésil, Moniba, expérience au Mali). Les titres restaurant sont des monnaies complémentaires propres à un secteur d'activité. Leur règles d'usage sont, là encore, connues et bien définies.

Concernant le crédit (ou le compte) bancaire, qui est reconnu comme monnaie depuis 1914, le garant en dernier ressort est l'État souverain, qui impose, là aussi, ses règles.

Comment le bitcoin s'inscrit dans ce tableau ? Il a pu être présenté comme une alternative aux monnaies souveraines en apportant une garantie collective à la place de celle de l'État. Les geeks libertariens ont été séduits par cette perspective de retirer au monstre froid une de ses prérogatives. Certains libertaires nerds y voient un moyen de s'affranchir des banques capitalistes qui ont provoqué la crise financière de 2008.

Si le Bitcoin apporte du neuf, c'est sur les moyens d'échange. Jusque là, on ne savait pas comment garantir l'unicité d'une transaction sur un réseau sans base de donnée centrale - ou sans instance centrale, qui aurait autorité. On imagine déjà l'appliquer à divers aspects du réseau mondial (le nommage avec Namecoin). Sur les autres rôles de la monnaie, le bitcoin semble vraiment à côté de la plaque. Sa valeur, extrêmement variable, en fait une mauvaise réserve d'épargne et une unité de compte vraiment très volatile. Quand au moyen d'échange, une autre caractéristique du bitcoin le rend inapte, c'est la déflation programmée dans son code. Au fil du temps, la quantité de bitcoins émise décroît. Elle s'arrêtera dans un temps fini.

Fichier:Total bitcoins over time.png
 (image venant d'ici: https://en.bitcoin.it/wiki/File:Total_bitcoins_over_time_graph.png)

Si les échanges devaient se développer dans cette monnaie, le prix des marchandises ne cesserait de baisser, ce qui inciterait les acheteurs à reporter leur achat et les vendeurs à choisir une autre unité monétaire. On voit bien la contradiction.

On voudrait que le bitcoin ressemble davantage à un bien qu'à une monnaie. S'il avait une utilité en soi, comme les noms de Namecoin, ça pourrait se soutenir. La comparaison avec les métaux précieux, qui ont servi de base monétaire pendant longtemps, est encore plus sotte. Ces métaux sont utiles, dans des sociétés de l'antiquité aussi bien qu'à l'âge de l'espace. Et ils sont rares, alors qu'il suffit de créer un CoinBit pour multiplier les signes numériques. Quoi qu'il en soit, le retour à une monnaie-marchandise serait un retour au troc.

Le seul intérêt du bitcoin est pour ceux qui y sont entrés en premier, lorsque la création en était facile. À présent qu'ils en possèdent un paquet, ils s'emploient à en faire grimper la cote. C'est ainsi que j'écoute les évangélistes invités sur les plateaux (Bitcoin au Téléphone sonne - France Inter). Heureusement, il y a aussi d'excellents articles pour garder les idées claires et la tête froide.