Introduction

J'ai enfin terminé "The complete book of self-sufficiency" de John Seymour. J'en avais entendu parler lors d'un reportage de la chaîne télévisée Arte (ce devait être un "28 minutes" je crois). L'invitée de cette chronique était Perrine Hervé-Gruyer de la ferme du Bec-Hellouin, figure maintenant à peu près bien connue et reconnue du mouvement permaculture français. John Seymour y était cité comme étant un des inspirateurs des fondateurs de la ferme du Bec-Hellouin.

N'en ayant jamais entendu parlé et étant quand même à la base ingénieur agricole, je me suis penché sur le personnage dont vous pouvez consulter la biographique sur Wikipedia. J'ai été assez estomaqué par la production d'écrits de John Seymour et aussi par le nombre important de ses séjours à l'étranger. Aussi, je me suis mis à essayer de trouver son oeuvre la plus connue qui traite d'agriculture pour voir ce que ce monsieur racontait dans les années 70 et de quelle manière les méthodes agricoles qu'il avait mises au point pouvaient constituer une référence pour d'autres personnes, notamment des personnes du 21ème siècle.

Assez facilement, j'ai été guidé sur "The complete book of self-sufficiency", cité comme une référénce déjà à l'époque et étant, en 1976, date de sa publication, un condensé de plusieurs écrits sur ce thème, rédigés et publiés plusieurs années auparavant par John Seymour. Par bonheur, j'ai pu trouver ce livre sur archive.org, dans sa langue originelle (l'anglais) et je me suis fait un plaisir certain à le lire directement.

A la fin de cette lecture, je dois dire que je suis un peu estomaqué et je prends donc la peine de coucher par écrit ce qui m'a frappé chez John Seymour et surtout dans le contenu de son oeuvre écrite.

A propos de John Seymour et de l'auto-suffisance

Je ne vais pas vous remettre une biographie autorisée de John Seymour, ça n'aurait pas plus de valeur ajoutée que de remettre un lien vers Wikipedia.

Mais pour résumer, John Seymour est le précurseur du mouvement d'auto-suffisance au Royaume-Uni, dans les années 60 et 70. J'avais déjà vaguement entendu parler de ce mouvement qui a fait quelques adeptes dans son pays d'origine toujours via un reportage de la chaîne télévisée Arte sur différents modes de vie plus sains et plus simples. J'étais tombé sur une interview d'un citoyen britannique qui vivait dans une petite ferme avec une surface agricole assez réduite (je pense à moins d'une dizaine d'hectares). Il avait une seule vache dont il faisait la traite à la main. Il décrivait une vie simple, sans stress où il était parfaitement heureux. Par ailleurs, il soulignait combien il se sentait indépendant et libre. Il savait que le système qu'il avait mis en place pour assurer sa subsistance était fiable et robuste et qu'il pouvait compter sur cette expérience pour rester résilient et finalement très stable. Je me souviens aussi, à cette occasion, d'avoir remarqué que sa ferme était super bien tenue: tout était vraiment propre, bien rangé, pas une seule trace de merde nulle part, pas de bâtiment pourri en délabrement, pas de saleté nulle part et un potager vraiment bien garni. Ce qui m'avait frappé déjà était à quel point ce type allait à contre courant de l'agriculture contemporaine et combien il semblait heureux de son auto-suffisance.

Je ne vais pas me lancer dans une définition détaillée et absolue du mouvement d'auto-suffisance mais je me risquerai à dire que l'objectif de l'auto-suffisance est l'élaboration d'un système qui permet la liberté d'un individu par l'action de son travail sans devoir entretenir un réseau de relations commerciales mettant en péril cette liberté. De fait, un être auto-suffisant se caractérise par le fait de cultiver une certaine forme d'indépendance par rapport à la société qui l'entoure. Il cultive donc la terre car il produit lui-même l'essentiel de sa nourriture avec des moyens techniques qu'il maîtrise et qu'il peut utiliser sans recourrir à d'autres.

John Seymour précise que ce mode de vie est loin d'être un retour en arrière mais bien l'inverse, de progresser vers une vie qui fait sens, une vie loin de la routine ultra-spécialisée du mode de vie occidentale. Une vie faîte de défis, d'initiative, d'innovation dans la manière d'appréhender le monde. Il faut dépasser le sentiment de super-pouvoir offert par la technique. C'est finalement assez vrai si l'on considère l'agriculture moderne où les hommes sont ultra-équipés par des machines qui font le café ou qui conduisent toutes seules mais qui, au final, sont incapables de produire à un rendement correct sans recours à des produits dangereux pour la santé humaine. Super technique mais aussi super-cancer. Qu'est-ce-qui est mieux finalement ?

J'ai bien aimé aussi l'expression de John Seymour à propos du comportement d'un être auto-suffisant: se comporter comme un travailleur du sol (husbandman) plutôt qu'un exploitant. Il est à noter que "husbandman" signifie aussi quelqu'un qui fait oeuvre de parcimonie dans sa gestion. Cela correspond finalement assez bien à la philosophie de l'auto-suffisance.

Les techniques de John Seymour

Dès les premiers chapitres, John Seymour décrit un système agricole assez atypique pour l'époque et encore plus pour aujourd'hui. Il s'agit d'un système à haute valeur ajoutée et à production intensive, le tout sans intrant chimique, en accord avec les valeurs de l'agriculture biologique. Effectivement, écrire agriculture biologique et intensif dans la même phrase peut sembler incompatible mais en fait, à bien y réfléchir, ce n'est pas vraiment le cas.

En effet, si vous vous lancez dans des pratiques culturales qui respectent la biologie (du sol, des plantes, des autres êtres vivants), toutes les conditions sont réunies pour que vous fassiez plutôt du bon travail et que votre production soit finalement assez intensive. John Seymour affirme sans détour qu'il est capable de produire du blé à près au même rendement que dans un système d'agriculture convetionnelle des années 70.

Par ailleurs, menée sur une surface réduite, le système auto-suffisant permet de concentrer l'action du travail tout au long de l'année par le fait de toujours vouloir couvrir le sol de quelque-chose et, ce faisant, pas un truc productif qui sera utilisé ultérieurement.

Pour parfaire le tableau et pour redonner un vrai retour ancestral à cette technique, John Seymour déclare qu'il s'inspire d'une méthode très ancienne de culture, établie en Europe au siècle dernier qu'il nomme "High Farming". Un système mélant habilement plantes et animaux ainsi que leurs interactions. Je vous laisse lire le livre pour avoir plus détails sur ce sujet mais ça mérite de pouvoir affirmer que, avec un peu de recul, la permaculture de ce début de siècle remonte en fait aux débuts du siècle dernier.

Pour étayer ses propos, John Seymour propose dès le début du livre de montrer ce qu'il est possible de faire sur une exploitation de taille très limitée. Il étudie la vie en auto-suffisance sur 1 acre (à peu près la moitié d'un hectare, soit 5000m2). Il montre qu'il est impossible d'être complètement autonome en alimentation sur une aussi petite surface mais qu'en ajoutant quelques ressources extérieures, il est possible de maximiser cette autonomie.

De nos jours, une étude menée conjointement par l'INRA, AgroParisTech et l'institu Sylva de la ferme du Bec-Hellouin montre que, sous certaines conditions, il est possible de dégager l'équivalent d'un salaire minimum français avec seulement 1000m2 de surface utile. John Seymour prend ensuite l'exemple d'une ferme de 5 acres (moins de 2,5 hectares) qui permet l'autonomie d'une famille de 6 personnes ainsi que la revente d'un peu de surplus de production.

Le reste du livre détaille les techniques utilisées. Globalement elles se basent sur:

  • le respect des saisons.
  • le respect de la biologie.
  • la rotation des cultures.
  • mais aussi la rotation des animaux sur l'espace agricole.
  • les associations entre plantes, notamment avec les légumineuses.
  • une lutte biologique contre les parasites.
  • un travail intense et permanent mais très varié.
  • une mécanisation assez légère du travail.

Sur 250 pages environ, tout est détaillé avec force d'illustrations. Comme son système John Seymour a su condenser l'essentiel de ses exemples dans un livre finalement assez compact. Un chef d'oeuvre d'intensité d'idées dans une surface limitée.

Bien loin du mouvement hippie de retour à la terre, John Seymour met en garde les adeptes de ce système sur le fait qu'il implique une charge de travail assez intense. L'être humain, pour assurer sa subsistance doit forcément fournir un effort constant. Mais Seymour tempère en avouant que l'effort est louable et qu'il permet une rétribution inconsciente lors de la récolte des fruits du labeur. De plus, combiné à l'amélioration de l'indépendance, le sentiment de liberté croît et avec lui une certaine forme d'auto-reconnaissance et de solidité. Et John Seymour de conclure qu'il n'y a pas de meilleur moment que celui de pouvoir siroter sa propre bière juste après la récolte des céréales en été et, il a sans doute raison, cette bière n'aurait pas du tout le même goût si elle avait été achetée dans le commerce avec les mêmes qualités organoleptiques.

Au désespoir des végétariens (que je respecte évidemment), le système de John Seymour implique d'utiliser des animaux car ils contribuent fortement à l'amélioration de la fertilité des sols tout en diminuant une partie du travail du paysan. Quelques exemples me viennent rapidement. D'abord John Seymour indique qu'il n'a trouvé aucun moyen plus efficace de transformer à peu près n'importe quelle plante en matière fertile et de la distribuer sur une surface à moindre frais qu'en exploitant les cycles digestifs des animaux et leur capacité à se mouvoir sur un terrain. Il y a bien le compostage mais il faut ensuite manipuler le produit fini.

C'était aussi assez bien pensé et très malin de trouver quelquechose qui puisse concilier le fait qu'un porc évolue naturellement en plein air et qu'il a tendance à retourner le sol pour trouver sa nourriture. Ce faisant, il assure une production de viande, un travail du sol sans tassement de ce dernier, un désherbage gratuit, y compris des graines et racines qui peuvent rester dans le sol ainsi qu'une réduction des larves et insectes nuisibles dont il se régale (du à sa condition d'omnivore) tout en contribuant à fertiliser le sol par ses déjections, le tout sans une goutte de pétrole ni trop de temps passé par le paysan pour parvenir à ses fins.

Néanmoins, le fait d'avoir des animaux sur la ferme implique de les consommer directement. Et John Seymour détaille même des techniques pour découper des carcasses et aussi des méthodes de préparation et de conservation de viande, afin de minimiser la perte.

Car, au delà du discours technique, on découvre qu'il n'y a une profonde humanité chez John Seymour qui s'applique à une forme de bienveillance envers les animaux. En effet ces derniers permettent d'améliorer la performance et donc l'auto-suffisance du système. Ils méritent donc un respect profond. Dans les phases d'abattage, Seymour décrit toujours la technique la plus efficace du point de vue de la minimisation de la souffrance animale. C'est souvent une méthode basée sur un coup de 22 dans la tête, dans un lieu connu de l'animal, alors qu'il est dans un état calme et qu'il n'y a aucune tension ni aucun changement par rapport à l'habitude qui pourrait le déranger. Enfin, John Seymour évoque le fait qu'il n'est jamais facile de passer du temps avec un animal pour ensuite le tuer, quoiqu'il arrive, une relation fini toujours par se tisser.

Pour conclure sur ce point, n'étant pas moi-même végétarien, je crois qu'effectivement, élever un animal domestique et devoir le tuer pour le consommer ne peut se faire sans un respect profond et une certaine forme de déchirement. J'y pense à chaque fois que je vois quelqu'un qui jette un reste de viande à la poubelle. Un moment difficile à vivre, tout ça pour finir sous forme de déchet. Quel gachis !

Même si Seymour décrit un système avec animaux, je crois qu'il est possible de se baser sur un système sans contribution animale. Ce serait sans doute plus long, plus complexe, plus fragile mais dans tous les cas, loin d'être impossible.

Conclusions

Une fois le livre terminé je me suis demandé pourquoi je n'avais jamais entendu parler de John Seymour pendant tout mon cursus post-baccalauréat ! J'ai passé près de 5 années à étudier l'agriculture dans toutes ses composantes et je n'ai jamais trouvé trace du système de John Seymour. C'est franchement dommage car c'est un système d'un grand intérêt qui mérite d'être enseigné, décrit ou, tout au moins cité comme exemple alternatif.

C'est assez génial d'avoir trouvé les meilleures techniques pour maximiser la production sur des surfaces réduites. J'ai d'ailleurs été assez scotché par l'emploi des cochons comme outil de préparation du sol. C'est très astucieux et ça me plaît.

Bien sûr les détracteurs de ce système diront que ce n'est pas suffisant, que le sol est mal préparé, que ça prend du temps, que ce n'est pas adapté à une production industrialisée, etc. Mais pour une approche auto-suffisante, c'est très bien et très adapté.

Au delà de l'aspect technique, j'aime également le ton assez pragmatique de l'auteur qui, sans faire de longues phrases ou d'envolées lyriques, parvient à instiller l'intérêt qu'il porte à cette vie significative et pleine de sens de l'auto-suffisance. Mais les britanniques ont un sens assez aiguisé (et une langue qui le permet) de pouvoir faire passer une philosophie avec toujours une petite pointe d'auto-dérision, n'est-ce-pas ?

John Seymour me donne l'envie de continuer sur la découverte ou la re-découverte de ces techniques agricoles plus clairvoyantes que celles d'aujourd'hui. Le sujet de la permaculture sera, à n'en pas douter, un de mes sujets de l'année 2019. Il n'y a rien qui me plaise plus qu'un truc compliqué mais efficace où tout a été pensé, expérimenté et évalué, en faisant fi des systèmes actuels tout en étant un tantinet en décalage avec. C'est sans doute mon côté Aspeger qui reprend le dessus.

Dans tous les cas, si vous êtes intéressés par l'agriculture, je vous invite à lire The complete book of self-sufficency de John Seymour. Vous découvrirez, à n'en pas douter, la beauté d'un monde nouveau qui n'attend que vous pour le découvrir.

Posted mar. 22 janv. 2019 19:25:30 Tags:

Introduction

Cela fait quelques temps que j'ai vu passer le logiciel Wireguard. Étant donné qu'il est créé et maintenu par zx2c4, dont j'utilise l'excellent cgit, je me suis dit que ça valait le coup d'y passer un temps certain.

Qu'est-ce-que Wireguard ? Pour faire simple, c'est un VPN. Il est écrit en C avec quelques lignes (5000) de code et semble prometteur pour l'avenir, tant du point de vue de la sécurité que des performances.

Dans cet article, nous allons simplement installer et configurer Wireguard sur une série de machines qui formeront notre VPN.

Installer Wireguard sur une machine Debian Buster

Wireguard est composé de deux éléments:

  • un module pour le noyau Linux.
  • un ensemble d'outils en espace utilisateur.

Sous une machine Debian classique, on peut utiliser la dernière version de Wireguard en installant:

# apt install wireguard-dkms wireguard-tools

Normalement, ces actions devraient vous conduire à installer de quoi compiler le module noyau en live (DKMS), c'est à dire le compilateur gcc en version 7 ainsi que les fichiers d'en-tête du noyau Linux. Sur une station de travail, ce n'est pas si lourd.

Installer WireGuard sur un Scaleway C1

J'ai un serveur Scaleway C1. Comme pour n'importe quel fournisseur de serveur dédié, vous ne pouvez pas forcément faire ce que vous voulez. Hé oui, ce n'est pas votre matériel. Forcément, ça s'en ressent aussi dans la partie logicielle.

Je me suis inspiré de ce document. Mais j'ai du fortement améliorer mes compétences en gestion de noyau pour faire fonctionner réellement Wireguard sur cette machine. Car, il faut bien l'avouer, ma dernière compilation de kernel Linux doit dater d'il y a au moins 10 ans.

Si vous suivez la documentation sus-hyperliée, vous n'obtiendrez rien de satisfaisant. En effet, il existe des petites subtilitées qui font que ça ne fonctionnera pas directement.

Le premier problème auquel j'ai dû me confronter est le fait que ma compilation de noyau ne donnait rien d'utilisable en termes de modules. J'ai même réussi à bloater une partie du C1 pendant quelques jours avec des modules qui ne se chargeaient plus. J'ai finalement pris le parti d'essayer de comprendre quelques options, notamment celle de CONFIG_MODULE_SRCVERSION

Ensuite, après avoir réglé ce premier problème et réussi à charger mes modules compilés avec modprobe, j'ai eu beaucoup de mal pour faire fonctionner le module Wireguard qui ne se chargeait tout simplement pas. Après quelques jours de repos (quand un truc ne marche pas, il faut le laisser se reposer, l'éviter pendant un temps. Quand on y revient, c'est souvent la voie du succès alors), je me suis rendu compte que le CPU/SOC du Scaleway C1 est un Marvell Armada 370 et que ce dernier ne gère pas les extensions NEON.

Malheureusement, Wireguard impose d'utiliser les extensions NEON dans le noyau si vous avez un CPU sous ARMv7, ce qui est le cas du CPU du Scaleway C1. J'ai donc dû modifier le fichier Kconfig de Wireguard pour modifier la ligne:

select KERNEL_MODE_NEON if CPU_V7

en

select KERNEL_MODE_NEON if (CPU_V7 && !MACH_ARMADA_370)

et le tour était joué. Je ne pensais pas devoir aller si loin mais j'avoue que quand j'ai réussi à faire un modprobe wireguard sans aucun message d'erreur, j'ai jubilé !

J'en remet le contenu à ma sauce:

# On récupère les éléments de version du Kernel de la machine
arch="$(uname -m)"
release="$(uname -r)"
upstream="${release%%-*}"
local="${release#*-}"

# On récupère les sources
mkdir -p /usr/src
wget -O "/usr/src/linux-${upstream}.tar.xz" "https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-${upstream}.tar.xz"
tar xf "/usr/src/linux-${upstream}.tar.xz" -C /usr/src/
ln -fns "/usr/src/linux-${upstream}" /usr/src/linux
ln -fns "/usr/src/linux-${upstream}" "/lib/modules/${release}/build"

# On récupère la configuration du kernel utilisé
zcat /proc/config.gz > /usr/src/linux/.config
printf 'CONFIG_LOCALVERSION="%s"\nCONFIG_CROSS_COMPILE=""\n' "${local:+-$local}" >> /usr/src/linux/.config
echo "CONFIG_MODULE_SRCVERSION=y" >> /usr/src/linux/.config
wget -O /usr/src/linux/Module.symvers "http://mirror.scaleway.com/kernel/${arch}/${release}/Module.symvers"

# On prépare la configuration
make oldconfig

# On patche Wireguard in-tree 
/home/medspx/WireGuard/contrib/kernel-tree/create-patch.sh | patch -p1
sed 
make menuconfig

make prepare modules_prepare
make CFLAGS_MODULE=-fno-pic -j9
make CFLAGS_MODULE=-fno-pic -j9 modules
make modules_install

Configurer le VPN

Ok, nous avons maintenant deux bécanes avec Wireguard. Construisons donc un VPN avec. Je pars du principe que vous n'avez pas de firewall entre les deux, pour simplifier les commandes.

Avec Wireguard, ce qui est bien, c'est qu'on peut construire le VPN en live puis balancer la configuration finale dans un fichier de configuration avec une seule commande. Tout se passe avec les commandes classiques ip et wg.

-- Génération des clefs privées/publiques
# wg genkey > /etc/wireguard/private

-- Ajout de l'interface wireguard (wg0)
# ip link add dev wg0 type wireguard

-- Affectation d'une IP virtuelle sur l'interface wireguard
# ip addr add 192.168.3.4/24 dev wg0

-- On ajoute notre clef privée
# wg set wg0 private-key /etc/wireguard/private

-- On peut maintenant voir la configuration en dynamique
# wg showconf wg0

-- On va maintenant ajouter la définition d'un autre client
-- Vous avez besoin de sa clef publique que vous pouvez
-- obtenir avec wg show wg0
# wg set wg0 peer LHqF7DAsJoRftEWmj+b2HnBKonZqLwJwdO9eLQYx+lI=
-- allowed-ips 192.168.3.1/32 endpoint medspx.fr:54003

-- Ensuite, il suffit d'activer l'interface réseau
ip link set wg0 up

-- Sur l'autre machine, il faut également ajouter ce nouveau peer
# wg set wg0 peer clef_publique allowed-ips 192.168.3.4/32

-- et maintenant, la connexion devrait être effective
# wg show wg0

-- On peut maintenant stocker la configuration en dur
# wg showconf wg0 > /etc/wireguard/wg0.conf

-- Un peu plus tard, vous pouvez recharger cette configuration
# wg setconf wg0 /etc/wireguard/wg0.conf

Configuration avec systemd-networkd

Une fois la configuration dynamique passée, il peut être intéressant d'utiliser systemd pour garder cette configuration. Pour ma part, je n'utilise que systemd pour la configuration de mes interfaces réseaux. Wireguard est géré par systemd-networkd depuis systemd 237. Cela signifie que c'est présent dans Debian Buster mais également dans Debian Stretch si vous avez activé les dépôts backports.

Vous devez créer un fichier /etc/systemd/networkd/30-wg0.netdev:

[NetDev]
Name = wg0
Kind = wireguard
Description = Wireguard

[WireGuard]
ListenPort = auto
PrivateKey = [CLIENT PRIVATE KEY]

[WireGuardPeer]
PublicKey = [SERVER PUBLIC KEY]
PresharedKey = [PRE SHARED KEY]
AllowedIPs = 192.168.3.1/32
Endpoint = medspx.fr:54003
PersistentKeepalive = 60

Le ListenPort à auto indique que le port change chaque fois que vous lancez l'interface. C'est une configuration plutôt intéressante pour des stations en mode client sans configuration spécifique de parefeu.

Si vous avez un serveur publique avec une IP fixe, je vous conseille de déclarer un port spécifique et de l'ouvrir dans votre firewall.

Le PersistentKeepalive est également intéressant si vous êtes derrière un NAT (donc plutôt réservé aux stations de type client). Avec cette configuration, Wireguard envoi un petit paquet réseau de temps en temps (selon l'intervalle indiqué) pour réouvrir l'interface vers l'extérieur depuis le réseau interne. Cela permet de laisser la connexion ouverte au niveau du routeur NAT et donc de laisser votre client disponible pour le reste du VPN.

Si vous configurez une sorte de serveur VPN, vous devez indiquer tous les clients enregistrés en ajoutant autant de directives [WireGuardPeer] que de clients, afin de partager les clefs publiques.

Puis, vous aurez besoin d'un fichier pour configurer votre interface dans /etc/systemd/networkd/30-wg0.network:

[Match]
Name = wg0

[Link]
RequiredForOnline = no

[Network]
Address = 192.168.3.4/24

[Route]
Gateway = 192.168.3.1
Destination = 192.168.3.0/24

J'ai indiqué la directive RequiredForOnline à no car, pour certaines machines (typiquement un portable avec une connexion erratique), cela permet de démarrer le système sans attendre que Wireguard soit activé.

Aller un peu plus loin que le test du ping

Nous allons mettre en place ssh derrière une machine du VPN. L'astuce consiste simplement à mettre la ligne suivante dans /etc/ssh/sshd_config:

# L'adresse publique
ListenAddress 10.0.0.1:2222

# On écoute sur l'adresse Wireguard
ListenAddress 192.168.3.1:22

A partir de cet instant, vous pouvez utiliser un client ssh depuis une des machines du VPN pour attaquer directement le serveur via Wireguard.

On le voit, la grande force de Wireguard est d'utiliser une interface réseau virtuelle dédiée. De fait, n'importe quelle configuration classique d'un logiciel serveur peut être utilisée sans commandes spéciales.

Si vous avez un firewall

Pour ma part, mon C1 a un firewall configuré avec nftables. J'ai choisi de laisser passer tout ce qui vient ou va vers wg0.

Globalement ma configuration est la suivante:

#!/usr/sbin/nft -f

# Configuration NFT de debianplug

# On vide toutes les règles
flush ruleset

# Table pour un serveur public un peu fermé
table inet public_server {
  # Chaîne de gestion de tout ce qui rentre
  chain entree {
    # Chaîne de type filtre, en entrée
    type filter hook input priority 0;

    # Accepter tout ce qui vient de l'interface loopback
    meta iif lo accept

    # Accepter tout ce qui vient de Wireguard
    meta iif wg0 accept

    # Accepte le trafic qui vient de la machine
    ct state established,related accept

    # Réponse au ping IPv4
    ip protocol icmp accept

    # Ouverture des ports publics
    # Le port 54003 est celui de Wireguard
    tcp dport { 25,53,80,143,443,1376,4416,4444,5222,5269,9714,54003 } accept
    udp dport { 53, 9714, 54003 } accept

    # Ouverture du port nbd
    tcp sport { 4416 } accept

    # Compter et journaliser ce qui est rejeté
    counter log prefix "Connexion entrante rejetée: " level warn drop
  }

  # Chaîne de gestion de tout ce qui sort
  chain sortie {
    type filter hook output priority 0;

    # On accepte les sorties vers l'interface loopback
    meta oif lo accept

    # On accepte les sorties vers Wireguard
    meta oif wg0 accept

    # Réponse au ping IPv4
    ip protocol icmp accept

    # Ouverture des ports publics
    tcp sport { 25,53,80,143,443,1376,4444,5222,5269,9714,54003  } accept
    udp sport { 53,9714,54003 } accept

    # Ouverture des ports externes classiques utilisés par le système
    tcp dport { 25,53,80,143,443,995,4416,8443 } accept
    udp dport { 53,67,68,123 } accept

    # count and drop any other traffic
    counter log flags skuid prefix "Connexion sortante rejetée: " level warn drop
    }
}

Dans cette configuration, j'ouvre le port 54003 de Wireguard sur cette machine et j'autorise tout ce qui passe par l'interface wg0. De cette manière, tout marche !

Conclusions

Ce truc est vraiment extra ! D'abord, ça marche et ça passe pas mal de caca. Le code est super light. J'ai eu l'occasion de le parser rapidement pour trouver mes erreurs de symboles de Kernel et j'ai été étonné du nombre ultra limité de fichiers et de lignes (5000 seulement, sachant que mon programme de base pgMitm en fait près de 1000 à lui tout seul pour pas grand chose). L'implémentation est vraiment élégante et fine. Je ne parle pas de la configuration en live qui témoigne d'un vrai réalisme dans la mise en place de réseaux qui se solde généralement par un nombre impressionnant de systemctl restart systemd-networkd.

Comme d'habitude, Jason Donenfield et zx2c4 sortent un truc de qualité et je suis fier de leur rendre un hommage appuyé.

Posted dim. 23 déc. 2018 19:06:30 Tags:

Introduction

Il y a quelques temps, j'ai décidé de quitter Github, en fermant mon compte. Depuis, j'expérimente des modes de contribution au logiciel libre de manière à peu près décentralisées.

Aujourd'hui, nous allons voir comment contribuer à un développement avec l'aide de git et du bon vieux courrier électronique via la commande git send-email !

Comment ça marche ?

Globalement le mode opératoire est asez simple:

  • Vous avez un clone du dépôt central.
  • Vous faîtes des modifications donc des commits.
  • Une fois que vous estimez que vos changements sont dignes d'êtres soumis au(x) responsable(s) du projet, vous utilisez git send-email.
  • De son côté, le responsable du projet utilise git am pour récupérer vos modifications.
  • S'il a des remarques à faire, il vous les renvoie en réponse à votre courrier électronique où finalement toute l'action de négociation se déroule (en privé par défaut).
  • Une fois que tout est ok pour le responsable projet, il intègre vos changements (ou non) et votre contribution est intégrée au projet (ou non).

Pour faire simple, git send-email propose un système proche des pull-requests de Github mais en passant par le canal complètement décentralisé du courrier électronique.

C'est plutôt une proposition intéressante car elle permet un développement immédiat avec quelques outils dont, à peu près tout le monde est équipé (git et une adresse de courrier électronique).

Quelques éléments de configuration

Avant de commencer, sachez que sous Debian, git email-send n'est pas installé par défaut avec le paquet git (ce qui est sans doute dommage). Vous pouvez l'installer via:

# apt install git-email

Ensuite, avant de pouvoir utiliser git send-email, il faut configurer git pour accéder à votre serveur de courrier électronique.

  • D'abord, vous devez savoir à quelle adresse de courrier électronique envoyer vos modifications (project@thesuperproject.example dans la suite de l'article). Cette configuration sera bien entendu différente pour chaque projet et elle doit être locale au dépôt git.
    git config --local sendemail.to project@thesuperproject.example
  • Ensuite, vous aurez besoin d'indiquer quel serveur SMTP sera utilisé pour réaliser l'envoi du courrier électronique proprement dit. Ces éléments de configuration seront sans doute indépendants du projet sur lequel vous travaillez. Vous pouvez donc les déclarer en global:
    git config --global sendemail.smtpServer smtpserver.example
    git config --global sendemail.smtpServerPort 25
    git config --global sendemail.smtpEncryption tls
    git config --global sendemail.from myaccount@smtpserver.example
    git config --global sendemail.smtpUser myaccount
  • Enfin, vous avez besoin de configurer quelques options générales de git send-email, notamment le fait d'annoter systématiquement vos patches (via annotate) ainsi que la configuration de l'encodage de vos messages:
    git config --global sendemail.verify on
    git config --global sendemail.annotate yes
    git config --global sendemail.transferEncoding 8bit

Un exemple concret

Du point de vue du contributeur externe

Ok, vous êtes un contributeur externe. Vous avez réalisé quelques commits sur la branche master et vous souhaitez les soumettre au responsable du projet. Vous avez configuré git send-email comme indiqué ci-dessus.

Dans vos changements, vous avez dépassé la référence origin/master de quelques commits. Vous avez juste à lancer la commande suivante:

$ git send-email origin/master

Votre éditeur de texte configuré dans git va s'ouvrir en vous permettant d'écrire un message au début du courrier électronique. C'est là que vous remplissez la description de votre soumission de patch.

Ensuite, après l'enregistrement, git send-email vous demande une confirmation ainsi que le mot de passe du serveur SMTP (car nous ne l'avons pas renseigné en dur dans la configuration de git pour des raisons de sécurité).

Si tout se passe bien, votre courrier électronique est envoyé ! S'il y a des problèmes dans l'authentification, vérifiez votre configuration SMTP. Par exemple, dans mon cas j'utilise STARTTLS sur mon serveur SMTP et j'ai dû configurer l'option sendemail.smtpEncryption à tls pour pouvoir faire l'authentification de manière correcte.

Si vous voulez envoyer un truc différent, vous pouvez utiliser le vocable des révisions git. Par exemple, si vous souhaitez envoyer uniquement un commit précis, vous pouvez mettre son uid:

$ git send-email 1bea5dff495173beb9b93e6e0ea7df6e2435a283

Du point de vue du développeur interne

Ok, vous êtes un développeur du projet et vous avez reçu un courrier électronique avec un patch dedans. Vous devez appliquer ce patch, le tester, faire d'éventuels réponses avec l'auteur du patch puis quelques aller-retours. Néanmoins, en dehors de l'application du patch sur le dépôt, tout ces éléments se dérouleront dans votre application de courrier électronique.

Pour appliquer le patch soumis, vous devez le sauvegarder et appliquer le patch avec git am.

Dans mon cas, je sauvegarde le message au format eml depuis Roundcube dans un fichier dédié. Ensuite, je lance la simple commande:

$ git am chemin/vers/fichier.eml

Ce qui est assez intéressant, c'est que git am reprend le sujet du courrier électronique comme sujet du commit ainsi que les commentaires globaux du patch.

Il y aura forcément des conflits, des trucs pas terribles mais, comme d'habitude dans git, vous aurez besoin de gérer les choses... ou de renvoyer à l'auteur du patch, à votre discrétion.

Conclusions

git send-email fait les choses très bien. Après avoir passé 5 minutes à le configurer correctement et compris comment ça marchait, vous avez maintenant un outil bien intégré pour faire des propositions d'évolution sur des projets externes. Et ce, sans avoir besoin d'avoir un compte sur cette plate-forme externe, ni d'utiliser votre navigateur web pour écrire des messages. C'est plutôt efficace et en plus, tout reste dans git. Pas besoin d'outil externe.

Bien entendu, votre "pull-request" n'est pas connue du grand public par défaut. Néanmoins si l'équipe de développement a mis en place une bonne vieille mailing-list des familles, votre soumission devrait être disponible dessus. Ce n'est pas mon cas sur medspx.fr car je préferre rester dans un mode plus discret et que je n'ai pas vraiment de contributeurs externes.

Pour information, j'ai trouvé trace de git send-email sur le blog de Drew Devault, le développeur principal du projet Sway.

Je vous invite aussi à lire le guide des contributions via git send-email sur la plate-forme sr.ht. Il est plein d'exemples assez intéressants...

Posted dim. 25 nov. 2018 13:09:00 Tags:

Introduction

Il y a quelques temps, j'ai décidé de quitter Github, en fermant mon compte. Après tout, ça va dans le sens de mes convictions. Pour l'instant, ça me va très bien mais je reconnais que ce n'est pas très pratique pour travailler sur des projets de logiciels libres.

L'acquisition de Github par Microsoft et le fait qu'on trouve maintenant des millions de projets de logiciels libres, tous centralisés sur Github pose clairement la question du risque de tout mettre ses yeux dans le même panier. Que se passe-t-il si Github devient trop puissant et impose ses conditions ?

Néanmoins, nous sommes en 2018 et ne pas utiliser des outils modernes pour partager du code impose de revenir en arrière et d'exclure certaines bonnes pratiques. Aussi, je me devais de trouver un système adapté à mes moyens et à mes ambitions pour partager le code source libre qu'il m'arrive de produire.

Cet article tente d'améliorer l'aspect partage des choses en présentant une installation de gitolite, un logiciel de référence pour gérer les droits d'accès à des dépôts Git.

Principes de Gitolite

Avant d'utiliser un logiciel, c'est bien de savoir comment il fonctionne, du moins dans ses grandes lignes.

  • gitolite utilise un compte UNIX standard pour opérer. De cette manière, la compromission de ce compte ne vient perturber que ce compte et pas le reste du système (du moins, de prime abord).
  • le compte gitolite utilise un répertoire dédié qui contient deux ensembles:
    • un répertoire de dépôts git (bare), c'est là qu'on mettra nos dépôts git. Ce répertoire ce nomme repositories.
    • un répertoire caché (.gitolite) qui contient la logique de gitolite avec les scripts Perl à lancer dans les hooks. Il contient également les clefs publiques SSH des utilisateurs qui ont accès aux dépôts gits.
  • Il existe un dépôt de base nommé gitolite-admin qui permet d'interagir avec la configuration de gitolite. De fait, toute la conf de gitolite se fait à l'aide de ce dépôt qui contient des hooks spécifiques. Il est même déconseillé d'utiliser une autre méthode.
  • Par défaut, gitolite permet l'accès aux dépôts git via SSH. Il est toutefois possible d'autoriser un accès via HTTP(S).
  • Les utilisateurs déclarés dans gitolite son des utilisateurs indépendants du système d'exploitation.

Installation de gitolite sous Debian

Vous devez disposer d'une clef publique SSH pour le compte "administrateur" de gitolite. Pour ma part, j'y fous ma clef publique de GNUPG au format ssh-rsa que j'obtiens avec la commande gpg (voir ci-dessous).

Ensuite, vous pouvez installer le paquer Debian gitolite3. Ce dernier vous demandera où placer le répertoire spécifique à gitolite. Pour ma part, je le place dans /var/local/gitolite.

$ gpg --export-ssh-key mon_compte_gpg > medspx.pub
$ scp medspx.pub compte@srv.example.org:/tmp/
# apt install gitolite3
  - clef SSH de l'administrateur: `/tmp/medspx.pub`
# mv /var/lib/gitolite3 /var/local/gitolite
# usermod --home /var/local/gitolite gitolite3

Voilà, c'est fait...

Après installation du paquet, debconf créé un utilisateur dédié. Il se nomme gitolite3 et a pour HOME le répertoire d'installation de gitolite que vous avez renseigné en amont.

Ce répertoire contient tout ce que j'ai expliqué dans les principes de gitolite sous la forme suivante:

  • .ssh => le répertoire de conf SSH de l'utilisateur gitolite3. On y trouve un fichier de clefs autorisées, modifié par un hook de gitolite.
  • repositories => notre répertoire de dépôts qui contient le dépôt de configuration de gitolite (gitolite-admin.git) ainsi qu'un dépôt de test (testing.git).
  • .gitolite => le répertoire "interne" de gitolite.
  • .gitolite.rc => le fichier de conf globale de gitolite (qui point vers /etc/gitolite3/gitolite.rc.
  • projects.list => un fichier pour gitweb dont on se fout (parce que je n'utilise pas gitweb).

Utiliser gitolite

Maintenant que gitolite est installé, il convient de l'utiliser et de commencer à le configurer correctement.

Tout commence par le clonage du dépôt gitolite-admin. Vous pouvez le cloner en utilisant le compte dédié gitolite (donc gitolite3 sous Debian). Comme vous avez renseigné votre clef SSH, vous avez le droit d'y avoir accès. Un simple clone via SSH donne la commande suivante:

$ git clone gitolite3@srv.example.org:gitolite-admin

Le dépôt contient deux répertoires:

  • keydir: qui contient les fichiers de clefs publiques.
  • conf: qui contient les fichiers de configuration de gitolite. Pour l'instant, il ne devrait y avoir que le fichier gitolite.conf.

Ajouter un utilisateur est assez simple: il suffit de récupérer sa clef publique dans un fichier avec le nom du compte suffixé avec l'extension .pub dans le répertoire keydir, de commiter le dépôt et de pousser la modification pour que la clef soit ajustée.

Pour gérer les droits des dépôts, il suffit de modifier le fichier de configuration: conf/gitolite.conf. Sa syntaxe est assez simple à comprendre même si elle peut se complexifier avec des includes et d'autres éléments.

Néanmoins, il y a un élément que vous devez bien noter ! Vous devez toujours utiliser le compte SSH de l'utilisateur gitolite (donc gitolite3 sous Debian). En effet, SSH n'est pas automagique: il ne va pas créer un compte utilisateur POSIX à la volée pour vous permettre de vous connecter. Au contraire, c'est l'utilisateur gitolite3 qui, avec son shell spécial (le binaire de gitolite), va s'occuper de faire la gestion des droits. C'est bien noté ?

Import de dépôts existants

Pour ma part, j'ai beaucoup de dépôts sur mon serveur et il convient de les référencer/importer sous Gitolite. La doc sur le sujet est assez bien faîte:

# cd /var/local/gitolite/repositories
# rm -r testing.git
# cp -r ../..git/*.git .
# chown -R gitolite3:gitolite3 *.git
# su gitolite3
$ gitolite compile
$ gitolite setup --hooks-only
$ gitolite trigger POST_COMPILE

Ensuite, il reste à ajouter les dépôts dans le fichier de conf et le tour est joué.

Mise en place de l'accès via HTTP

Ok, maintenant, vous avez un accès à des dépôts git via SSH, de manière sécurisée pour l'authentification et le contrôle d'accès (qui sont deux choses différentes).

Mais bon, vous êtes ambitieux et vous voulez faire cool comme github et utiliser un service en HTTPS ! Et là, c'est le drame: gitolite ne gère pas super bien l'accès HTTP. En effet, gitolite ne gère pas du tout l'authentification mais uniquement le contrôle d'accès. Dans ce que nous avons vu, c'est SSH qui gère l'authentification, gitolite s'occupe du reste.

Pour la partie HTTP, c'est donc Apache qui va s'occuper de l'authentification et transférer ce qui va bien à gitolite. Mais, nous avons un problème majeur: Apache ne sait pas authentifier avec une clef SSH. Ce n'est pas prévu pour, ce n'est pas fait pour ! Il faut donc broder et c'est que nous propose la documentation de gitolite sur le sujet. Je vous invite aussi à lire cet article que j'ai finalement utilisé.

Comme on doit broder, autant le faire intelligemment, c'est à dire en comprenant ce qu'on fait. Nous devons faire les choses suivantes:

  • Authentifier les utilisateurs depuis Apache.
  • Lancer gitolite-shell depuis un process Apache via CGI.
  • gitolite requière d'utiliser le compte gitolite3, il faut donc un mécanisme qui permette de le faire.
  • Il y a des variables d'environnement à configurer pour que gitolite retrouve ses petits.
  • Il faut un mécanisme pour que les utilisateurs puissent gérer leur mot de passe Apache.

D'un point de vue administration système, j'ai choisi d'utiliser au maximum ce qui est fourni par la distribution Debian. Ainsi, tout le système gitolite est géré par l'utilisateur gitolite3. J'aurais pu installer une version indépendante de gitolite, en plus du paquet Debian. C'est ce qui est recommendé dans la documentation sur l'accès HTTPS.

Le fait d'utiliser l'utilisateur gitolite3 via Apache implique d'utiliser le module suexec de ce dernier. Ceci n'est pas sans conséquence pour certains déploiements de sites web car pour le virtualhost, l'utilisateur qui lancera tous les scripts CGI sera maintenant gitolite3 et non www-data. Si vous utilisez cgit, vous serez impacté.

Mise en place du socle HTTP de base

Pour ma part, voici ce que j'ai fait:

  • Installer le module Apache suexec et l'activer:
    # apt install apache2-suexec-pristine
    # e2enmod suexec
  • Créer un répertoire dans /var/www:
    # mkdir /var/www/bin
    # chown gitolite3:gitolite3 bin
  • Créer un fichier de script shell qui encapsule le lancement de gitolite:
#!/bin/bash
#
# Suexec wrapper for gitolite-shell
#

export GIT_PROJECT_ROOT="/var/local/gitolite/repositories"
export GITOLITE_HTTP_HOME="/var/local/gitolite"

exec /usr/share/gitolite3/gitolite-shell
  • Modifier ses droits/appartenance
    # chown gitolite3:gitolite3 /var/www/bin/gitolite-suexec.sh
    # chmod 0700 /var/www/bin/gitolite-suexec.sh
  • Mettre la configuration suivante dans un fichier de conf d'Apache: [[!format Erreur: Format de page non reconnu apache]]

Une fois votre serveur Apache redémarré, vous devriez pouvoir accéder à vos dépôts en suivant les règles d'accès de gitolite.

Gestion des mots de passe par les utilisateurs

Dans tous les cas, retenez que vous allez devoir gérer des mots de passe Apache pour vos utilisateurs externes, en plus de leur clef SSH. Bon, je vous rassure, GitHub le fait aussi: vous créez un compte Github puis vous uploadez vos clefs SSH.

A notre niveau, gitolite est plutôt fait pour créer des comptes à partir d'une clef SSH publique. Le processus est plutôt inversé par rapport à Github. Mais pourquoi pas !

Néanmoins, une fois que vos utilisateurs ont une clef SSH référencée dans le système gitolite que vous avez mis en place, ils ont la liberté d'utiliser le binaire gitolite-shell qui fait un peu plus que de servit du git. En effet, gitolite-shell permet de lancer quelques commandes de gestion. Parmi celles-ci, il y en a une qui est très intéressante car elle se nomme htpasswd et sa fonction est de gérer un mot de passe HTTPS pour Apache. Avec un peu de configuration, on peut tout à fait permettre aux utilisateurs de lancer cette commande.

Avant de commencer, il convient de modifier le fichier de configuration globale de gitolite. Ce dernier est situé dans /etc/gitolite3/gitolite.rc.

Vous devez ajouter 'htpasswd' à la liste des commandes autorisées (ENABLED). Ensuite, définissez la variable HTPASSWD_FILE avec le bon nom de fichier associé:

    HTPASSWD_FILE => '/var/local/gitolite/gitolite-http-authuserfile',

Voilà, c'est fait.

Pour que vos utilisateurs puissent modifier leur mot de passe HTTP, il leur suffit de faire:

    $ ssh gitolite3@sr.example.org htpasswd
    Please type in your new htpasswd at the prompt.  You only have to type it once.

    NOTE THAT THE PASSWORD WILL BE ECHOED, so please make sure no one is
    shoulder-surfing, and make sure you clear your screen as well as
    scrollback history after you're done (or close your terminal instance).
    
    new htpasswd:

Et le tour est joué. Retenez bien que vous devrez maintenir deux choses:

  • Votre clef SSH
  • Votre mot de passe et compte HTTP.

Mais, c'est déjà ce que vous faîtes si vous êtes sous Github !

Accès non authentifiés via HTTP

Pour l'instant, nous n'avons fait que gérer les accès authentifiés via Apache. Il nous reste à permettre l'accès anonyme, sans authentification. Mais je ne vais pas traiter cet accès dans cet article car plein de solutions s'offrent à vous, d'un répertoire distinct pour les dépôts publics à l'utilisation d'un autre logiciel qui réalise l'accès HTTP pour vous (cgit peut le faire par exemple).

Conclusions

Pour résumer, si la mise en place de l'accès SSH via gitolite est assez simple, l'accès via HTTPS se révèle un poil plus complexe et source de compromis. Mais dans l'ensemble ça fonctionne correctement. N'oubliez seulement pas de lire régulièrement le

Le seul point négatif de gitolite, c'est le fait qu'il soit codé en Perl. Je sais par avance que jamais je ne pourrais me plonger dans le code interne de Gitolite à cause de ce facteur. En dehors de ce point qui m'oblige à faire confiance au développeur de ce logiciel, je dois dire que Gitolite est simple, plutôt robuste et qu'il ne consomme pas beaucoup de ressources.

Néanmoins, la partie HTTP est un poil complexe à gérer et je pense qu'il existe une marge de progrès dans l'application sur ce point. Après tout, l'accès par HTTPS est pratiquement un pré-requis de nos jours si on souhaite favoriser les échanges (surtout derrière des firewalls nazis).

Posted sam. 17 nov. 2018 11:06:30 Tags:

QGIS Processing Grass Provider explanations

Last year (2017) I worked on the QGIS Grass Processing Provider. With time, I finally found how it worked. It is not so complicated but it is not so easy to understand because there is a "trick" on what is called the ext mechanism. Sometimes, developpers contact me by asking for help on this mechanism.

Here is my last email response about this subject. I also put it on my blog for people who want to understand or work on this part of QGIS.

Hello,

it's been a little bit more than one year since I have "retired" from
the QGIS project. It's just because I do have other projects that I am
working for and I had to cut down from some projects.

Well, I can only tell you about the GRASS Processing from QGIS 2.18
(but I bet that this is still the same in QGIS 3).
If you want to use the QGIS GRASS plugin, it is completely different
and I can't help you on this part.

All you have to know is that:

* The GRASS provider for QGIS Processing is just a graphical interface
  in QGIS towards GRASS.
* There is an on-the-fly creation of a GRASS database in a temporary
  directory. Then all the input layers/rasters are imported (or
  referenced) into this GRASS database.
* When you launch an algorithm from the GRASS provider, QGIS launch
  (via the shell or a system call) GRASS command line with the right
  parameters onto the temporary GRASS database. You can read this
  command line in the log.
* If the algorithm returns some results, those are extracted from the
  GRASS temporary database and converted into layers/rasters (and
  directly opened into QGIS if option has been enabled). Then the
  GRASS temporary database is deleted.

To add your add-on in the GRASS provider, you need to:

* Build a description file in
  python/plugins/processing/algs/grass7/description/. Those files just
  describe the different parameters of your algorithm (add-on). You
  can read some of those files to understand the different
  options. The description file filename must respect the algorithm
  name. 
* If your algorithm doesn't require something else than: import input
  data/launch the algorithm/extract data, then you are done. There is
  nothing more to do than the description file. 
* If your algorithm need more actions like a preliminary check on
  data, more than one GRASS command involved or a transformation on
  output data before extracting them, then you need to use the ext
  mechanism. 

The 'ext' mechanism is a (some say kind of dirty) way to add per
algorithm additional logic. There are 4 different levels where you can
add logic: 
- Checking the input parameters, if you want to verify that two
  excluding options have been both enabled. 
- Processing inputs import: if you need to do more than importing
  input layers. 
- Processing the command by itself: if you need to chain more than one
  GRASS command for your algorithm. 
- Processing the outputs export: if you need to do special things
  before exporting layers or if you need special export methods. 

Whenever you want to add some logic on one (or more) level(s), you
have to create a .py file named accordingly to the algorithm name
(modify '.' with '_'), into
python/plugins/processing/algs/grass7/ext. Then you need to create
methods that will respect names:
- Input parameters: checkParameterValuesBeforeExecuting
- Inputs import: processInputs
- Command: processCommand
- Outputs: processOutputs

If there is a Python file with the algorithm name in the ext
directory, methods will be imported from the file and run instead of
the common methods (there are "standard"
processCommand/processInputs/processOutputs/checkParameterValuesBeforeExecuting
in the code of the GRASS provider for QGIS Processing, in
python/plugins/processing/algs/grass7/Grass7Algorithm.py).

If we take the example of v.what.rast, there is an ext file:
ext/v_what_rast.py. In this file there is a processCommand method. It
just launch the standard processCommand but with the
delOutputs option set to True (we do not want to have standard
outputs). Then there is also a customized processOutputs which export
the input vector as an output for QGIS. We need to do this because
v.what.rast modify values directly into the input vector layer. It
doesn't generate dedicated output so we have to build this output
ourself. 

Clearly, if you want to do special things in the ext mechanism, you
will need to read (and understand) the GRASS provider code standard
methods in Grass7Algorithm.py.

I hope that these explanations will ease your work...
Posted ven. 02 nov. 2018 18:16:30 Tags:

Introduction

It's been 7 years since I have installed and used everyday the i3 tile window manager. I have never used something else and it proved to be a good choice. I can now focus on keyboard commands and I don't have to handle windows positions on the screen anymore.

Whenever I am forced to use another old fashioned hand positionning window manager, I fulminate against it. I am just waisting my time trying to focus on the program I need to use.

So far I have been very satisfied about my i3 usage. I just wrote a configuration file years ago and I never had to look at it. I just copy it to any new desktop computer that I own. It is a very stable window manager.

But last month, I found an alternative to i3 and I want to tell you how I use it as a replacement of i3. It is called sway and it aims to become an i3 replacement on the wayland graphical stack.

It's been years since everybody is using the Xorg graphical stack under GNU/Linux systems. It is very old as it predates the micro-computers era of the 80's. While being improved one small feet at a time, Xorg architecture has some drawbacks, inheritated from its beginnings.

Wayland has emerged a couple of years ago in order to completely get rid of the old Xorg stack principles. As an abstract, I can say that Wayland is the future of GNU/Linux desktop systems! For more information about the differences between Wayland and X, read this page.

Sway is a tiling window manager that works under Wayland. It aims to mimic i3, in its usage and even in it's configuration file. You just have to stick it into the right directory (~/.config/sway/config) and voila. Sway is coded in C and it is very efficient, compact and fast. Even if it hasn't reach version 1.0, my tests have shown that it is perfectly usable everyday.

I have use it for a month at home, on my laptop and even on my office job workstation and it just does work.

How to install Sway under Debian?

First things first, you need to be under Debian Buster because compiling sway from sources requires some packages that do not exist in Debian Stretch (like meson).

Debian Packages Dependencies

# apt install libgles2-mesa-dev libdrm2 libdrm-dev libegl1-mesa-dev xwayland\
  libgbm-dev libinput-dev libsystemd-dev libcap-dev libxcb-composite0-dev \
  libxcb-image0-dev libxcb-icccm4-dev libxcb-xkb-dev libpam0g-dev

Manual Dependencies

json-c

Unfortunately, json-c isn't in the required version, even on Debian Buster. We need to compile it by hand:

$ git clone https://github.com/json-c/json-c.git
$ cd json-c
$ sh autogen.sh
$ ./configure --prefix=/usr/local
$ make
# make install

wlroots

wlroot is a generic library for Wayland compositors. It has been developed focusing primarily Sway but it can also be used with other projects.

$ git clone https://github.com/swaywm/wlroots.git
$ cd wlroots
$ meson build
$ ninja -C build
# ninja -C build install

Sway building

Now it is time to build Sway.

$ git clone https://github.com/swaywm/sway.git
$ cd sway
$ meson build
$ ninja -C build
# ninja -C build install

Configuring Sway

You just need to copy your i3 configuration file into ~/.config/sway/config. Here is mine as an example with some adjustments for multiscreen and input configuration:

# Sway config file

# Keyboard configuration
input "5426:267:Razer_Razer_Arctosa" {
  xkb_layout fr
  xkb_variant latin9
  xkb_model pC105
  xkb_numlock enabled
}

# Dual screen configuration
output DP-1 pos 0 0 mode 1920x1080 background /usr/local/share/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png center
output DVI-I-2 pos 1920 0 mode 1680x1050 background /usr/local/share/backgrounds/sway/Sway_Wallpaper_Blue_1366x768.png center

set $mod Mod4

# Set font for lower bar
font pango:DejaVu Sans Mono 10

# Use Mouse+$mod to drag floating windows to their wanted position
floating_modifier $mod

# Start a terminal. I use terminology, the enlightenment terminal.
# It does work natively under Wayland.
# See https://www.enlightenment.org/about-terminology
bindsym $mod+Return exec terminology -B

# Lock the screen
bindsym $mod+m exec swaylock

# kill focused window
bindsym $mod+Shift+Q kill

# start dmenu (a program launcher)
bindsym $mod+d exec dmenu_run

# change focus
bindsym $mod+j focus left
bindsym $mod+k focus down
bindsym $mod+i focus up
bindsym $mod+l focus right

# alternatively, you can use the cursor keys:
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right

# move focused window
#bindsym $mod+Shift+J move left
#bindsym $mod+Shift+K move down
#bindsym $mod+Shift+L move up
#bindsym $mod+Shift+M move right

# alternatively, you can use the cursor keys:
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right

# split in horizontal orientation
bindsym $mod+h split h

# split in vertical orientation
bindsym $mod+v split v

# enter fullscreen mode for the focused container
bindsym $mod+f fullscreen

# change container layout (stacked, tabbed, default)
bindsym $mod+s layout stacking
bindsym $mod+z layout tabbed
bindsym $mod+e layout default

# change screen
bindsym $mod+x move container to output DVI-I-2
bindsym $mod+w move container to output DP-1

# toggle tiling / floating
bindsym $mod+Shift+space floating toggle

# change focus between tiling / floating windows
bindsym $mod+space focus mode_toggle

# focus the parent container
bindsym $mod+q focus parent

# focus the child container
#bindcode $mod+d focus child

# workspaces definition
workspace 1: Mail output DVI-I-2
workspace 2: Web output DP-1
workspace 3: Terminal output DP-1
workspace 4: Emacs output DP-1
workspace 5: Music output DVI-I-2

# switch to workspace
bindsym $mod+ampersand workspace 1: Mail
bindsym $mod+eacute workspace 2: Web
bindsym $mod+quotedbl workspace 3: Terminal
bindsym $mod+apostrophe workspace 4: Emacs
bindsym $mod+parenleft workspace 5: Music
bindsym $mod+minus workspace 6
bindsym $mod+egrave workspace 7
bindsym $mod+underscore workspace 8
bindsym $mod+ccedilla workspace 9
bindsym $mod+agrave workspace 10

# move focused container to workspace
bindsym $mod+Shift+ampersand move workspace 1: Mail
bindsym $mod+Shift+eacute move workspace 2: Web
bindsym $mod+Shift+quotedbl move workspace 3: Terminal
bindsym $mod+Shift+apostrophe move workspace 4: Emacs
bindsym $mod+Shift+parenleft move workspace 5: Music
bindsym $mod+Shift+minus move workspace 6
bindsym $mod+Shift+egrave move workspace 7
bindsym $mod+Shift+underscore move workspace 8
bindsym $mod+Shift+ccedilla move workspace 9
bindsym $mod+Shift+agrave move workspace 10

# reload the configuration file
bindsym $mod+Shift+C reload
# restart sway inplace (preserves your layout/session, can be used to upgrade sway)
bindsym $mod+Shift+R restart
# exit sway (logs you out of your X session)
bindsym $mod+Shift+E exit

# resize window (you can also use the mouse for that)
mode "resize" {
  # These bindings trigger as soon as you enter the resize mode
  # They resize the border in the direction you pressed, e.g.
  # when pressing left, the window is resized so that it has
  # more space on its left

  bindsym j resize shrink left 10 px or 10 ppt
  bindsym Shift+J resize grow   left 10 px or 10 ppt

  bindsym k resize shrink down 10 px or 10 ppt
  bindsym Shift+K resize grow   down 10 px or 10 ppt

  bindsym l resize shrink up 10 px or 10 ppt
  bindsym Shift+L resize grow   up 10 px or 10 ppt

  bindsym m resize shrink right 10 px or 10 ppt
  bindsym Shift+M resize grow   right 10 px or 10 ppt

  # same bindings, but for the arrow keys
  bindsym Left resize shrink left 10 px or 10 ppt
  bindsym Shift+Left resize grow   left 10 px or 10 ppt

  bindsym Down resize shrink down 10 px or 10 ppt
  bindsym Shift+Down resize grow   down 10 px or 10 ppt

  bindsym Up resize shrink up 10 px or 10 ppt
  bindsym Shift+Up resize grow   up 10 px or 10 ppt

  bindsym Right resize shrink right 10 px or 10 ppt
  bindsym Shift+Right resize grow   right 10 px or 10 ppt

  # back to normal: Enter or Escape
  bindsym Return mode "default"
  bindsym Escape mode "default"
  bindsym $mod+r mode "resize"
}

# lower bar configuration
bar {
    status_command i3status
    output DP-1
}

bar {
    output DVI-I-2
    status_command i3status
}

# assign workspaces
assign [title="mutt"] 1: Mail
assign [class="Firefox"] 2: Web
assign [title="Terminal" title="Terminal" app_id="terminology"] 3: Terminal
assign [title="Emacs"] 4: Emacs
assign [title="Cantata"] 5: Music

# Start my main tools when the session opens
exec terminology -B -T=mutt -n=Mutt -r=Mutt -e mutt
exec terminology -B -T=Terminal -n=Terminal -r=Terminal
exec terminology -B -T=Emacs -n=Emacs -r=Emacs -e emacs
exec cantata
exec firefox

Launch a sway session

Sway doesn't have a session manager. As Sway is a Wayland compositor it requires to be started whenever you start a session. For the moment, I have just modified my .bashrc configuration to start sway whenever I am login under tty1 and then configure the different graphical libraries (GTK/QT/EFL/etc.) to use Wayland instead of Xorg:

...
# Sway configuration
export LD_LIBRARY_PATH="/usr/local/lib"
# you can also configure your keyboard this way
#export XKB_DEFAULT_LAYOUT=fr
#export XKB_DEFAULT_VARIANT=latin9
#export XKB_DEFAULT_MODEL=pc105
export QT_QPA_PLATFORM=wayland
export QT_WAYLAND_DISABLE_WINDOWDECORATION="1"
export ELM_DISPLAY=wl
export ECORE_EVAS_ENGINE=wayland_shm

# Launch Sway when logging under tty1
if [ $(tty) = "/dev/tty1" ]; then
    sway
    exit 0
fi

I have gotten rid of all the session managers on my system (no more slim nor gnome-session). I am prompted ot log under the text mode console. OldSchoolCool!

What doesn't work very well?

Even if Sway is working very well on three of my computers there are still some problems around.

On some computers I have lots of glitches with firefox. This is my main problem for the moment. Firefox can only be compiled under Xorg, there is nothing official for Wayland. So it relies on XWayland and for some graphical cards, it seems to have some problems.

The second problem I have faced is a keyboard problem. On my laptop I could not use the traditionnal keys for moving a window towards a screen (mod+shift+number of the screen). I had to.modify the comfiguration file to reflect the base (without shift pressed) character of the key (eg: aecute for 3 on a french keyboard).

I had also some problems with (proprietary) games that required a full Xorg session. But as long as I am able to play to Stardew Valley, it is not really a problem. Furthermore, I can log in tty2 and launch Xorg by hand (startx).

The last problem is probably the fact that I have to compile sway every week because it is not already available in Debian...

As long as you use Gnome softwares, you will enjoy the Wayland experience. Same thing for Qt5 (with the configuration above).

Conclusion

As a conclusion, Sway impressed me. It is a Wayland replacement for i3. There is nearly no new features. I am not lost nor do I need to learn something new. Furthermore it is coded in C, a language I really enjoy and which is able to build a complete tile window manager in a robust, compact and fast way. If you are an i3 enthousiast, you will enjoy Sway whenever you will migrate to Wayland.

Posted dim. 14 oct. 2018 17:25:30 Tags:

Cela fait bien des années que je circule à vélo. Depuis l'âge d'environ 8 ans, jusqu'à maintenant, soit 32 ans d'expérience avec un rythme plus ou moins régulier.

Jusqu'à récemment, je n'avais jamais cédé face aux cris alarmant sur le port du casque à vélo. Comme beaucoup, je me suis toujours dit que ça ne servait à rien. Pire, j'étais même assez militant pour lutter contre le port obligatoire du casque. J'ai souvent repris les arguments de la FUB sur ce sujet, à savoir que le port du casque réduirait le nombre de personnes qui ferait du vélo, que ce n'était pas pratique à trimballer, que ce sont les membres les plus souvent touchés, etc.

J'avais même mon propre argumentaire:

  • le vélo, c'est la liberté. Mettre un casque réduit cette liberté.
  • le casque ce n'est pas pratique à gérer.
  • ça fait 30 ans que je fais du vélo sans casque. Je n'en ai jamais eu besoin.
  • si on a besoin d'un casque pour un engin qui se meut à une vitesse de 20km/h max de moyenne, ça veut dire que c'est un moyen de transport trop dangereux et il vaut mieux ne pas en faire.
  • tomber d'un vélo, c'est comme tomber de sa hauteur. Pourtant, je ne porte pas de casque dans la rue.
  • quand je vais courir, je fais des pointes à 20km/h. Je ne me vois pas mettre un casque pour courir et aucun coureur de fond n'a de casque pour courir.
  • le casque, c'est chiant, ça fait transpirer la tête. Et puis il faut pouvoir le stocker quelquepart.

Clairement, je trouvais que le port du casque en vélo était exagéré. J'étais assez fermement opposé à son utilisation. Mais tout ça a profondément changé il y a quelques mois...

D'abord, je me suis acheté un nouveau vélo l'année dernière. Après avoir fait une petite étude de marché, mon choix s'est porté sur un vélo de course (hé oui, c'est un b'twin mais c'était le meilleur rapport qualité/prix/matos utilisé). Dès la première ballade, je me suis dit intérieurement que j'allais devoir acheter un casque parce que je voyais bien que ma vitesse commençait à prendre son envol. Quand tu tapes les 40km/h sur du plat au radar pour voiture sans être à fond, effectivement, il y a de quoi se poser des questions.

Néanmoins, j'ai finalement oublié de m'acheter un casque. J'ai eu un autre signe d'alerte sur ce nouveau vélo lors du printemps 2018. Un soir de flotte en rentrant du boulot, j'ai fait un aqua-planning à environ 25km/h. Je suis tombé sur la flaque d'eau sur laquelle j'ai glissé sur environ 40m. Incroyable et impossible de maîtriser quoique ce soit. Le vélo de 9kg lui a filé comme une flèche, couché sur le flanc. Je l'ai vu glisser en parallèle de moi, sur quelques mètres. C'était impressionant toute cette énergie cinétique avec peu de frottements. Je ne me suis rien cassé, j'ai juste eu quelques dermabrasions bégnines.

Néanmoins, je n'ai toujours pas pris le temps d'acheter un casque. Jusqu'au fatidique jour du 5 juillet 2018. Sur le chemin du travail, dans un endroit exclusivement piéton et vélo sans trop de trafic, en plein milieu de la ville de Nantes, j'ai fait une chute un peu sévère. Je ne connais pas la cause réelle de la chute car ma tête a heurté le sol et j'ai perdu connaissance. Je peux compter sur les doigts d'une seule main les moments où je me suis évanoui dans ma vie. Et pourtant, c'est arrivé en vélo !

A propos de l'accident, disons que je ne me souviens de pas grand chose. A un instant, je voyais mon vélo se pencher sérieusement et l'instant d'après quelqu'un me disait: "Monsieur, serrez ma main s'il vous plaît !". La perte de conscience a complètement effacé le souvenir à court terme. D'après les passants, j'ai dû rester inconscient 1 à 2 minutes. Au niveau des dégâts, c'est ma tête qui a tout pris comme le montre cette photo prise peu après l'accident:

t'as vu ta tête !

J'ai été emmené par les pompiers au CHU pour suturer ma plaie à l'arcade sourcillière et au menton. Je m'en sort pas trop mal au final car je n'ai aucune fracture, rien à la machoire et surtout pas de traumatisme cranien important. J'ai eu de la chance cette fois encore.

Après être revenu sur les lieux de l'accident, je n'ai vu aucune trace de freins nulle part. L'endroit était complètement dégagé, sans obstacle. De plus, ça fait 4 ans que je prends cette voie pour aller travailler tous les jours et jusqu'à présent, je n'avais jamais eu le moindre incident. Quand j'ai pu récupérer mon vélo, pris en main par un bon samaritain (libriste qui plus est) que je remercie publiquement, j'ai compris que, pour une raison inexpliquée, j'ai penché un peu trop mon guidon vers la gauche. Je circulais assez rapidement, sans doute à 25km/h. Mon vélo à perdu l'équilibre, ma tête a heurté le sol en premier et j'ai tout de suite perdu connaissance. Ensuite, le vélo a fait des tonneaux sur lui même car il est erraflé des deux côtés alors qu'il n'y avait aucune trace avant l'accident. L'alignement du guidon avec les roues a été faussé avec la violence du choc. Pour ma part, j'ai également fait des tonneaux car ma tête présente des dermabrasions sur les deux côtés. Mon genou gauche est également abimé.

Quels enseignements tirer de cet acident ?

D'abord qu'on peut chuter d'un vélo qu'on maîtrise depuis un an, sur une zone dégagée sans voiture ni passant, sur un revêtent sec, en milieu urbain.

Ensuite qu'une chute de ma hauteur suffit à bien me faire tomber dans les pommes. Que ça peut arriver à n'importe lequel d'entre-nous. Sachez que je n'avais même pas de pédales automatiques qui peuvent poser un problème pour poser les pieds. Dans mon cas, je n'ai rien pu faire: impossible de redresser le guidon ou de poser le pied par terre pour réaligner le vélo. Je n'ai même pas pu compter sur la force gyroscopique pour maintenir l'équilibre.

Enfin, si j'avais eu un casque de vélo, j'aurais sans doute eu quelques séquelles, notamment au niveau du menton et de la joue mais, je n'aurais pas eu de trauma cranien et je n'aurais pas perdu connaissance. Les conséquences auraient été forcément moins graves.

En conclusion, j'ai enfin acheté un casque de vélo... Et je n'utiliserai plus aucun vélo sans le mettre. J'ai compris que même dans des circonstances favorables, même à l'arrêt, on peut tomber et se faire mal au point de perdre connaissance. Mon trauma cranien aurait pu être bien plus sévère.

Par ailleurs, utiliser un casque a finalement des inconvénients négligeables. Il rentre facilement dans un sac, on peut le laisser pendre dans le train ou au bureau. Il est souvent aéré et on ne transpire pas trop avec. Enfin, il coûte peu cher comparé au temps perdu à devoir aller au CHU et rester en observation après un traumatisme cranien.

Voilà, je suis passé du stade d'opposant au port du casque à vélo au stade de ne plus vouloir m'en passer. Je me dis aussi qu'avec un casque, je peux continuer à rouler au même rythme qu'avant sans avoir trop d'appréhension ce qui est quand même plus confortable que de devoir toujours redoubler d'attention et d'avoir perdu confiance dans ce formidable moyen de déplacement qu'est le vélo.

Tous les arguments des anti-casques sont tombés en même temps que ma tête sur le sol, ce 05/07/2018...

Posted jeu. 11 oct. 2018 21:37:10 Tags:

Même si je suis un libriste convaincu, j'ai parfois des défaillances ! Notamment en ce qui concerne les jeux vidéos. Et oui, on ne se refait pas. En 1988, j'avais 10 ans et tout ce qui concernait l'informatique me semblait déjà un monde extraordinaire. Il faut dire, j'ai commencé à utiliser un ZX81 quand j'avais 8 ans environ. Je remercie d'ailleurs mon père pour ça car je ne crois pas que tous les pères de famille des années 80 s'intéressaient aux ordinateurs dans les années 80.

En ces années, le logiciel libre n'en était qu'à ses balbutiements et sans accès à Internet, difficile de récupérer la connaissance. Donc, dans les années 80, j'ai fait à peu près tout ce qui était possible pour un enfant de 10 ans avec forcément des moyens limités: j'ai acheté une NES et les jeux vidéos propriétaires avec.

Et croyez-moi, j'ai passé du beau temps dessus. C'était très sympathique même si ça consommait beaucoup de temps libre. Avec les années, j'ai peu à peu réduit mon rythme de jeux vidéos pour passer plus de temps sur de l'administration système et sur du développement. Mais, j'ai toujours gardé un petit peu de temps pour continuer à jouer aux jeux vidéos. Il y a 10 ans, je me suis même acheté une Wii. Tout ça pour dire que j'achète environ un ou deux jeux vidéos propriétaires par an.

Dernièrement, j'ai enfin craqué pour une promotion sur GOG.com du jeu Firewatch dans sa version pour GNU/Linux. Je l'avais déjà entre aperçu auparavant, en surfant sur Internet. Le concept m'avait bien plus, moi qui aime la randonnée dans des espaces sauvages, dans la vie réelle. Pour vous faire le pitch, dans Firewatch, vous êtes un gardien d'une tour de vigie pour la défense incendie de forêt dans le Wyoming. Votre boulot consiste à surveiller la forêt et à en faire respecter le règlement. Le jeu est du type aventure à la première personne, tout en 3D.

Le concept me plaisait beaucoup, le milieu aussi ainsi que la réalisation graphique qui semblait sympathique. Le fait d'avoir un monde assez ouvert (où on peut se balader à peu près où on veut) était aussi un vrai plus. Et puis, à 4€ au lieu de 20€ lors de sa sortie, le risque était assez limité. Donc, j'ai craqué.

Dimanche dernier, il pleuvait et j'ai consacré mon après-midi à Firewatch. Malheureusement, à 20h30, le jeu était déjà terminé, soit environ 4-5h de jeu. Le lendemain soir, j'ai essayé de rejouer une partie en ne suivant pas du tout le scénario. Mais au bout d'une heure, je me suis rendu compte que peu importe les choix qui sont faits dans le jeu, le scénario est très linéaire. Par ailleurs, certains emplacements sont interdits d'accès (par des branches ou des obstacles) tant qu'on est pas arrivé au bon moment du scénario.

Enfin, d'un point de vue technique, le logiciel en lui-même est assez moyen. D'abord je n'ai pas réussi à afficher quoi que ce soit sous Wayland. Il a fallu que je repasse dans un environnement Xorg complet (ce que je peux faire facilement mais c'est dommage). Ensuite, ce machin repose sur Mono et donc, c'est lourd au démarrage. Enfin, c'est bien la première fois que j'ai entendu les ventilateurs de ma carte graphique tourner aussi fort. J'ai même cru que j'avais un problème de poussière dans la tour tellement ça chauffait. Pourtant, le graphisme qui reste pas mal est franchement en dessous de ce que j'ai pu tester dans Doom3 pourtant sorti il y a 14 ans ! En plus de ça l'équipe de développement a utilisé un moteur tout fait (unity il me semble). Ils ont donc réduit leurs coûts par rapport à ce point technique d'importance.

Ma conclusion, vous l'aurez compris, est sans appel: Firewatch est une bonne démo mais sans doute pas un jeu à la hauteur de 20€. En comparaison, en 2017, j'ai joué à Thimbleweed Park pendant au moins 40h et à Stardew Valley pendant 100h. Certes, ce ne sont pas les mêmes types de jeux mais le rapport prix/temps passé à jouer est trop important pour Firewatch.

Le concept de ce jeu reste pourtant d'un grand intérêt. Le studio aurait eu intérêt à allonger la durée de vie du produit. J'aurais bien aimé avoir un peu plus de temps pour me ballader dans le secteur. Il aurait sans doute été bon de donner aussi plus de travail à Henry que de s'occuper uniquement de son affaire d'espionnage. Il aurait pu herboriser, piéger des nuisibles, essayer de compter les ours, faire des prélèvements à droite à gauche pour une mission scientifique. Il y aurait pu également avoir des défis de randonneur, du repérage de nouveaux chemins à construire, du travail d'arpentage, de la constitution de cartes, des trucs à réparer. Même la simulation de chier dans les bois aurait été une excellente idée !

Donc, c'est bien dommage mais je vous conseille de ne pas acheter Firewatch en dehors des périodes de soldes ou de vous le faire prêter par un ami avant d'essayer de l'acquérir. Car vous risquez d'être un peu frustré et d'avoir le sentiment d'avoir jeté un peu de fric par les fenêtres.

Pour conclure, si Firewatch avait été un jeu libre, j'y aurais volontiers contribué pendant de longues heures. J'aurais sans doute aussi fait un don sans doute un peu plus conséquent que ce que j'ai payé sur GOG.com. J'aurais aussi pardonné le peu de contenu et une piètre réalisation technique. Mais comme Firewatch n'est pas un logiciel libre, tout ce que je peux faire c'est noyer mon amertume dans cet article de blog ;-)

Posted mar. 09 oct. 2018 19:25:30 Tags:

Tracer des isochrones avec des données et des logiciels libres

Introduction

Ça fait bien longtemps que je n'ai pas discuté de SIG sur ce blog. Il faut dire que j'en fait un peu tous les jours, dans le cadre de mon activité professionnelle. Mais de temps en temps, c'est bien de se remettre dans un cadre plus libre.

Cet article a pour objectif de présenter une méthode pour tracer des isochrones: des courbes qui indiquent à quelle distance on peut aller dans une enveloppe de temps à partir d'un ou plusieurs points de départ différents.

Nous allons utiliser des outils libres mais également des données libres, avec toutes leurs contraintes. Notre objectif est de voir , en partant des gares d'un département, quelles sont les zones où l'on peut se rendre en voiture pendant un laps de temps donné. Nous allons retenir les plages de 5 minutes/10 minutes/18 minutes et 20 minutes.

Cet article n'a pas pour but d'être une référence de ce genre de calcul. Il présente juste une méthode parmi d'autres. Elle peut d'ailleurs se révéler très approximative et non adaptée à certains besoins. Voilà vous êtes prévenus...

Capture de données géographiques

Qu'est-ce-qu'il nous faut ?

Avant de procéder, il faut disposer de données géographiques. C'est la base. Voici une petite liste de ce dont nous avons besoin:

  • Le tracé des routes, c'est la base. C'est ce qui va constituer notre réseau de déplacement.
  • Les limites de comunes et de département pour pouvoir se situer plus facilement.
  • Les zones résidentielles pour compléter les indications de vitesse des routes.
  • Les gares et arrêts SNCF, ce seront nos points de départ ou d'arrivée. C'est ce qui va constituer les noeuds d'intérêt de notre réseau de déplacement.

Pour nos besoins, nous allons utiliser la base de données OpenStreetMap. Cette dernière est libre de droits et elle est assez complète même si, comme nous le verrons, elle pourrait être améliorée fortement.

Les données via l'API overpass

L'intérêt d'OpenStreetMap, c'est qu'on peut effectuer des requêtes via une API. Le language est assez complexe mais on peut vraiment récupérer ce qu'on veut.

Un moyen simple d'effectuer des requêtes est d'utiliser le requêteur overpass-turbo. Il permet de faire des requêtes à partir d'un navigateur web et, surtout, de visualiser les résultats avant de pouvoir les télécharger.

Voici un exemple commenté de requête pour récupérer des routes:

// On veut une sortie au format JSON
// Au bout de 155 secondes, on arrête la requête.
[out:json][timeout:155];
// On indique que la zone de recherche est identifié par le polygone
// dont le nom est "Le Loroux-Bottereau", une commune du département
// de Loire-Atlantique.
{{geocodeArea:"Le Loroux-Bottereau"}}->.searchArea;
(
  // On indique qu'on veut récupérer les routes
  way["highway"](area.searchArea);
);
// Les options pour la sortie.
out body;
>;
out skel qt;

Avec cette requête, on peut récupérer les routes d'une commune. Néanmoins, pour notre exemple, il nous faut télécharger les routes de toutes les communes d'un département. Le faire à la main est forcément fastidieux.

Certains penseront à modifier le nom de recherche en y placant celui du département. Néanmoins, ils atteindront les limites de l'API. En effet, les serveurs qui fournissent le service de l'API sont partagés et ne peuvent passer trop de temps à effectuer une requête.

Dépasser les limites de l'API

Pour récupérer l'ensemble de nos routes, nous avons deux solutions:

Et si on faisait quand même un petit script ?

Même si c'est la méthode la moins rapide, ça vaut toujours le coup de disposer d'une méthode alternative, par exemple pour le cas où vos données ne sont pas disponibles dans le téléchargement en masse.

Concrètement, l'avantage de l'API overpass, c'est que c'est une API HTTP. On peut donc l'utiliser avec un simple client HTTP en ligne de commande comme wget ou curl (ce dernier a ma préférence).

Dans notre cas, nous avons deux choses à régler: * Déterminer le code de la zone de recherche: sur le site overpass-turbo, on peut utiliser un nom comme zone de recherche mais, en vérité, une première requête est lancée sur nominatim pour transformer ce nom en identifiant de zone. * Lancer une boucle de requêtes qui sont suffisamment lentes pour ne pas effrayer les serveurs de l'API.

Voici un exemple de script shell commenté qui répond à ces problèmes:

#!/bin/bash

echo "Récupération des routes des communes..."
# Notre fichier d'entrée est un fichier csv qui contient deux
# colonnes: le code osm_id et le nom de la commune.
# Vous pouvez créer ce fichier en téléchargeant les communes du
# département via l'API overpass et en utilisant QGIS pour fabriquer le CSV.
INPUT=communes.csv
OLDIFS=$IFS
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
# Le début de notre boucle
while read comid comname
do
    # On complémente à 8 chiffres l'identifiant OSM
    comid=$(printf "%08d" $comid)
    echo "Dowloading roads for $comname... ($comid)"
    # On précise notre requête OverPass
    request="[out:xml][timeout:155];area(36"${comid}')->.searchArea;(way["highway"](area.searchArea););(._;>;);out
   body;'
    # et on la joue
    curl 'https://overpass-api.de/api/interpreter' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Origin:https://overpass-turbo.eu' --data "$request" -o "roads_${comname}.osm"
    # Une méthode bourrine pour gérer les limite de l'API: on attend 10 secondes entre chaque requête.
    sleep 10
done < $INPUT
IFS=$OLDIFS

# Un script shell se termine toujours par une valeur de retour !
exit 0

Limites de département

Voici la requête overpass qui permet de récupérer la limite du départment:

[out:xml][timeout:155];
{{geocodeArea:"Loire-Atlantique"}}->.searchArea;
(
  rel["admin_level"="6"](area.searchArea);
);
(._;>;);out body;

Limites des communes

Voici la requête overpass qui permet de récupérer les limites de communes:

[out:xml][timeout:155];
{{geocodeArea:"Loire-Atlantique"}}->.searchArea;
(
  rel["admin_level"="8"](area.searchArea);
);
(._;>;);out body;

Pour l'extraction depuis OSM, utiliser grabCommunes qui utilise l'API Overpass. Pour l'import

Les gares

Voici la requête overpass qui permet de récupérer les gares et arrêts de train du départment:

[out:json][timeout:155];
{{geocodeArea:"Loire-Atlantique"}}->.searchArea;
( 
  node["railway"="station"](area.searchArea);
  node["railway"="stop"](area.searchArea);
);
(._;>;);out body;

Les zones résidentielles

Voici la requête overpass qui permet de récupérer les zones résidentielles:

[out:json][timeout:155];
{{geocodeArea:"Loire-Atlantique"}}->.searchArea;
(
  way["landuse"="residential"](area.searchArea);
);
(._;>;);out body;

Traitement des données

Chargement

Avant de pouvoir réaliser des traitements et des analyses sur les données que nous venons de récupérer, il faut pouvoir les stocker dans un endroit adapté. En effet, nous disposons de fichiers XML qui sont certes utilisables directement dans des logiciels comme QGIS, mais qui se révèlent peu performants (pour cause d'absence d'index spatial par exemple).

De plus, nous allons devoir réaliser des traitements spécifiques qui ne sont pas accessibles à tous les formats de stockage. Pour pouvoir aller plus vite, autant prendre ce qui est le plus performant, le plus complet: PostGIS.

Je vous laisse le soin de monter un serveur PostgreSQL avec l'extension PostGIS sur votre bécane. Pour ma part, je travaille avec un serveur qui écoute sur localhost, la base de données se nomme geobase, l'utilisateur se nomme geoadmin et il n'a pas besoin de mot de passe pour se connecter (c'est mal mais rapide).

Pour le chargement des XML, j'utilise ogr2ogr sur cette forme:

ogr2ogr -overwrite -f "PostgreSQL" "PG:host=localhost dbname=geobase user=geoadmin" -t_srs EPSG:2154 -lco "OVERWRITE=YES" -lco "SPATIAL_INDEX=YES" -lco "GEOMETRY_NAME=geom" -nlt MULTILINESTRING -nln communes -progress initCommunes.osm lines

Cette commande permet de créer une couche PostGIS nommée communes dans la base indiquée, dans la projection Lambert93 (2154), avec des index spatiaux, où le champ de géométrie se nomme geom.

Si vous avez plusieurs fichiers à charger, je vous conseille d'utiliser la technique suivante: * Renommer un des fichiers que vous avez à importer en initCommunes.osm * Utilisez le script suivant:

#!/bin/bash

# Import initial, permet de créer la structure
ogr2ogr -overwrite -f "PostgreSQL" "PG:host=localhost dbname=geobase user=geoadmin" -t_srs EPSG:2154 -lco "OVERWRITE=YES" -lco "SPATIAL_INDEX=YES" -lco "GEOMETRY_NAME=geom" -nlt MULTIPOLYGONS -nln communes -progress initCommunes.osm multipolygons

# Boucle d'ajout !
find ./ -name 'communes_*.osm' | while read com
do
  echo "$com"
  ogr2ogr -append -f "PostgreSQL" "PG:host=localhost dbname=geobase user=geoadmin" -t_srs EPSG:2154  -nlt MULTIPOLYGONS -nln communes -progress "$com" multipolygons
done

exit 0

Attention, pour les données des gares, je vous conseille de supprimer les données en double: certaines gares ont également des points d'arrêt.

Amélioration des données de routes: phase 1

Les données brutes sont chargées mais il reste néanmoins à les retravailler:

  • D'abord, il y a des chances que les données de routes soient en doublons dans certains cas.
  • Ensuite, il faut faire un peu de ménage dans les champs de cette couche.
  • Il faut croiser cette donnée avec les zones résidentielles.
  • Enfin, il faut s'assurer de disposer d'un réseau topologique correct.

Pour ces opérations de corrections, nous allons utiliser PostGIS et GRASS.

Dans un premier temps, il faut faire un peu de ménage, dans PostGIS:

-- Nettoyage des données de routes

---- Suppression des doublons géographiques
DELETE FROM routes WHERE ogc_fid IN (select ogc_fid from (
SELECT ogc_fid, ROW_NUMBER() OVER(PARTITION BY geom ORDER BY ogc_fid asc) AS Row,
geom FROM ONLY public.routes
) dups where dups.Row > 1
order by ogc_fid);

---- Un peu de ménage, on supprime les routes non utiles dans notre étude
DELETE FROM routes WHERE highway IN
  ('track', 'bus_stop', 'bus_guideway', 'construction', 'crossing', 'cycleway',
   'disused', 'footway', 'proposed', 'raceway', 'rest_area', 'service', 'access',
   'bridleway', 'path', 'pedestrian', 'platform','steps', 'road');

---- Modification du champ nom s'il est vide
UPDATE routes SET name = substring(other_tags from '"ref"=>"([^\"]+)".*$')
WHERE name IS NULL
  AND other_tags ~ '.*"ref"=>".*';

---- Un peu de ménage dans les champs
ALTER TABLE routes DROP COLUMN IF EXISTS waterway;;
ALTER TABLE routes DROP COLUMN IF EXISTS aerialway;
ALTER TABLE routes DROP COLUMN IF EXISTS z_order;
ALTER TABLE routes DROP COLUMN IF EXISTS barrier;
ALTER TABLE routes DROP COLUMN IF EXISTS man_made;
ALTER TABLE routes ADD COLUMN maxspeed NUMERIC(10,2);

---- Pré-affectation des vitesses en fonction du type de route
---- Récupération de la donnée OSM
UPDATE routes SET maxspeed = substring(other_tags from '"maxspeed"=>"([^\"]+)".*$')::NUMERIC(10,2)
WHERE other_tags ~ '.*"maxspeed"=>".*' 
  AND substring(other_tags from '"maxspeed"=>"([^\"]+)".*$') ~ '^\d+$';

---- Les cas spéciaux sont à 50 km/h
UPDATE routes SET maxspeed = 50.0
WHERE other_tags ~ '.*"maxspeed"=>".*' 
  AND maxspeed IS NULL;

UPDATE routes SET maxspeed = 130.0 WHERE highway IN ('motorway') AND maxspeed IS NULL;
UPDATE routes SET maxspeed = 90.0 WHERE highway IN ('motorway_link', 'trunk_link') AND maxspeed IS NULL;
UPDATE routes SET maxspeed = 50.0 WHERE highway IN ('residential') AND maxspeed IS NULL;

-- Croisement avec les zones résidentielles
---- Aggrégation des zones résidentielles
DROP TABLE IF EXISTS agg_resi;
CREATE TABLE agg_resi AS SELECT 1 as gid, ST_Union(p.geom) as geom from residentials p;
CREATE INDEX agg_resi_geomidx
  ON public.agg_resi
  USING gist
  (geom);

-- On créé une colonne pour indiquer qu'on veut supprimer des lignes
ALTER TABLE routes DROP COLUMN IF EXISTS todelete;
ALTER TABLE routes ADD COLUMN todelete BOOLEAN DEFAULT False;
-- On remplit cette colonne avec l'information 
UPDATE routes a SET todelete = True
  FROM residentials p
 WHERE ST_Intersects(a.geom, p.geom)
  AND a.highway IN ('primary','secondary','tertiary', 'unclassified');

-- On ajoute les routes découpées
--- Attention, cette requête prend beaucoup de temps...
INSERT INTO routes (osm_id, name, highway, other_tags, maxspeed, todelete, geom)
  SELECT a.osm_id, a.name, a.highway, a.other_tags, a.maxspeed, a.todelete,
         ST_Multi(a.clipped_geom)
  FROM (
  SELECT l.osm_id, l.name, l.highway, l.other_tags, 50::integer AS maxspeed, False As todelete,
         (ST_Dump(ST_Intersection(p.geom, l.geom))).geom As clipped_geom
    FROM routes l
      INNER JOIN agg_resi p ON ST_Intersects(l.geom, p.geom)
  WHERE l.highway IN ('primary','secondary','tertiary', 'unclassified')
  UNION
  SELECT l.osm_id, l.name, l.highway, l.other_tags, 80::integer AS maxspeed, False As todelete,
         (ST_Dump(ST_Difference(l.geom, p.geom))).geom As clipped_geom
    FROM routes l
      INNER JOIN agg_resi p ON ST_Intersects(l.geom, p.geom)
  WHERE l.highway IN ('primary','secondary','tertiary', 'unclassified')
  ) a
  WHERE ST_Dimension(a.clipped_geom) = 1;

-- On retire les routes à supprimer
DELETE FROM routes WHERE todelete = True;
-- On supprime la colonne todelete
ALTER TABLE routes DROP COLUMN todelete;
-- On vire la table d'aggrégation
DROP TABLE IF EXISTS agg_resi;

Amélioration des données de routes: phase 2

Ensuite, il nous faut créer un vrai réseau topologique. En effet, ce qui sort d'OSM est un ensemble de routes qui ne se coupent pas forcément au niveau des intersections. Globalement, ça peut poser des problèmes pour les traitements futurs de GRASS.

Pour y pallier, il va nous falloir faire un peu de ménage avec GRASS. Vous devez donc disposer d'une DB GRASS et avoir GRASS7 de lancé. Nous allons juste lancer un script de nettoyage qui a la forme suivante:

#!/bin/bash

# Nettoyage du réseau routier dans GRASS
## On effectue un lien vers les données PostGIS
echo "Import des données de route depuis PostGIS..."
g.remove -f type=vector name=routes
g.remove -f type=vector name=c_routes
v.in.ogr --overwrite -o input="PG:dbname=geobase user=geoadmin host=localhost" layer=routes output=routes type=line

# Nettoyage des routes (on recalcule la topologie et on vire les doublons)
v.clean --overwrite -c input=routes output=c_routes type=line tool=break,rmline,rmdupl
# On exporte en GPKG car GRASS a un problème pour écrire directement
# dans la base PostgreSQL
v.out.ogr --overwrite input=c_routes output="data.gpkg" format=GPKG layer=1 type=line output_layer=c_routes
# puis on utilise ogr2ogr pour faire le transfert
ogr2ogr -overwrite -f "PostgreSQL" "PG:host=localhost dbname=geobase user=geoadmin" -t_srs EPSG:2154 -lco "OVERWRITE=YES" -lco "SPATIAL_INDEX=YES" -lco "GEOMETRY_NAME=geom" -nlt MULTILINESTRING -nln croutes -progress data.gpkg c_routes

exit 0

En sortie, on dispose de la couche croutes dans PostGIS. Il nous reste à calculer les coûts de déplacement.

Amélioration des données de routes: phase 3

Maintenant qu'on dispose d'un réseau topologique correct, il reste une dernière étape de calcul des coûts de déplacement. Comme nous souhaitons réaliser des isochrones, le coût va être exprimé dans une unité de temps (secondes dans notre cas).

J'ai pris l'hypothèse fortement discutable de prendre un temps de trajet par tronçon égal au temps de parcours à la vitesse maximale du tronçon.

Néanmoins, pour pondérer un peu les résultats, j'ai délibérément abaissé les vitesses en suivant les règles suivantes:

  • Vitesse limitée à 90 km/h => 80 km/h
  • Vitesse limitée à 80 km/h => 70 km/h
  • Vitesse limitée à 50 km/h => 40 km/h
  • Vitesse limitée à 30 km/h => 25 km/h

Mettons tout ça en musique via PostGIS:

-- Calcul des coûts de déplacement

-- On va dire que toutes les routes qui n'ont pas de maxspeed sont à 50 km/h pour les non classées
UPDATE croutes SET maxspeed = 50.0 WHERE maxspeed IS NULL AND highway IN ('unclassified', 'living_street');
-- On va dire que toutes les routes qui n'ont pas de maxspeed sont à 80 km/h pour les non classées
UPDATE croutes SET maxspeed = 80.0 WHERE maxspeed IS NULL AND highway NOT IN ('unclassified', 'living_street');

-- On abaisse les vitesses suivant les règles sus-citées
UPDATE croutes SET maxspeed = 80.0 WHERE maxspeed = 90.0;
UPDATE croutes SET maxspeed = 70.0 WHERE maxspeed = 80.0;
UPDATE croutes SET maxspeed = 50.0 WHERE maxspeed = 50.0;
UPDATE croutes SET maxspeed = 25.0 WHERE maxspeed = 30.0;

-- Enfin, on calcule les coûts de déplacement.
ALTER TABLE croutes DROP COLUMN IF EXISTS cost;
ALTER TABLE croutes ADD COLUMN cost NUMERIC(10,2);
UPDATE croutes set cost = (ST_Length(geom)/(maxspeed/3.60)) where maxspeed > 0;

Ok, nous avons de quoi calculer des isochrones.

Calcul des isochrones

Ce calcul va se faire dans GRASS, non pas parce que c'est l'optimum, mais juste parce que c'est la seule méthode que je connaisse, en plus de PgRouting.

Pour le calcul des isochrones, nous allons utiliser nos données de routes qui vont constituer le réseau et nos données de gares qui vont constituer des centres de départ sur ce réseau.

GRASS dispose de fonctions dédiées au réseau (les fonctions v.net), que nous allons utiliser.

Le script suivant contient ce qu'il faut pour réaliser le calcul d'isochrones. Il doit être lancé dans l'environnement shell de GRASS:

#!/bin/bash

# Calcul d'isochrones dans GRASS

# On relie les données utiles dans la base GRASS sans faire d'import.
# C'est inutile dans notre cas car les fonctions de réseau vont dupliquer les données à leur sauce.
echo "Import des données depuis PostGIS..."
v.external -o --quiet --overwrite input="PG:host=localhost user=geoadmin dbname=geobase" layer=gares output=gares
v.external -o --quiet --overwrite input="PG:host=localhost user=geoadmin dbname=geobase" layer=croutes output=croutes

# Nettoyage des routes
# v.clean --overwrite -c input=routes output=c_routes type=line tool=break,rmline,rmdupl

# Construction du réseau
## Ici, on va construire un réseau au sens GRASS du terme. On part de notre couche de routes, on la convertie en réseau et on y adjoint les centres (les gares). Elles sont ajoutées au réseau par un trait de base.
echo "Construction du réseau..."
v.net --quiet -s --overwrite input=croutes points=gares output=thenetwork operation=connect arc_type=line threshold=50

# lier les bases de données des routes et des noeuds (uniquement si v.in.ogr):
#v.db.connect -o map=thenetwork@PERMANENT table=gares layer=2
# v.db.connect -o map=network@PERMANENT table=routes layer=1
# Calcul des isochrones
echo "Calcul des isochrones..."
## Ici, on prend toutes les gares et on calcule les isochrones sur des limites de coûts de 300, puis de 600 puis de 1080 puis de 1200.
## Cette opération casse le réseau selon les limites. Comme notre coût est un temps, 300 correspond donc à 5 minutes (300 secondes).
v.net.iso -u --overwrite input=thenetwork@PERMANENT output=isochrones@PERMANENT center_cats=1-1000 costs=300,600,1080,1200 arc_column=cost
# Nettoyage des valeurs à -1 dans les isochrones
echo "Suppression des valeurs inutiles..."
v.edit --quiet map=isochrones tool=delete layer=1 type=line where="center=-1 or isonr>=5"
# Exporter les données dans PostGIS (rapide) mais doit être défini dans db.connect.
echo "Export des données..."
v.out.ogr --overwrite  -c input=isochrones output="PG:dbname=geobase" format=PostgreSQL layer=1 type=line lco="OVERWRITE=YES,SCHEMA=public,GEOMETRY_NAME=geom,FID=fid" output_layer=isochrones
exit 0

Créer les polygones des zones

Vous devriez pouvoir afficher les polylignes des isochrones. Concrètement, chaque coût cumulé a été injecté dans chaque tronçon de route suivant les 4 classes énoncées plus haut (300,600,1080,1200).

Il reste à générer des polygones à partir de ces éléments. Pour ça, le plus simple consiste à utiliser PostGIS avec les requêtes qui suivent:

-- Calcul des zones d'isochrones
---- On commence par créer la tables des zones iso
DROP TABLE IF EXISTS isozones;
CREATE TABLE public.isozones
(
  fid serial,
  center integer,
  classe integer,
  geom geometry(MultiPolygon, 2154),
  CONSTRAINT isonzones_pk PRIMARY KEY (fid)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.isozones
  OWNER TO geoadmin;

CREATE INDEX isozones_geom_idx
  ON public.isozones
  USING gist
  (geom);

-- Remplissage de la table des zones
INSERT INTO isozones (center, classe, geom) SELECT center, isonr, ST_Multi(ST_ConvexHull(ST_Collect(geom))) as geom FROM isochrones GROUP BY center, isonr;

-- Zones fusionnées
---- Ensuite, on va aggréger les zones par classe
DROP TABLE IF EXISTS merged_isozones;
CREATE TABLE public.merged_isozones
(
  fid serial,
  classe integer,
  geom geometry(MultiPolygon, 2154),
  CONSTRAINT merged_isozones_pk PRIMARY KEY (fid)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.merged_isozones
  OWNER TO geoadmin;

CREATE INDEX merged_isozones_geom_idx
  ON public.merged_isozones
  USING gist
  (geom);

-- Remplissage de la table des zones
TRUNCATE TABLE merged_isozones;
INSERT INTO merged_isozones (classe, geom) SELECT classe, ST_Multi(ST_Union(geom)) as geom FROM isozones GROUP BY classe;
-- Découpage manuel des classes
---- Je sais, c'est crade mais c'est rapide.
UPDATE merged_isozones SET geom = ST_Multi(ST_Difference(b.geom, a.geom))
FROM (SELECT geom FROM merged_isozones WHERE classe = 1) a,
     (SELECT geom FROM merged_isozones WHERE classe = 2) b
WHERE classe = 2;
UPDATE merged_isozones SET geom = ST_Multi(ST_Difference(b.geom, a.geom))
FROM (SELECT ST_Union(geom) as geom FROM merged_isozones WHERE classe IN (1,2)) a,
     (SELECT geom FROM merged_isozones WHERE classe = 3) b
WHERE classe = 3;
UPDATE merged_isozones SET geom = ST_Multi(ST_Difference(b.geom, a.geom))
FROM (SELECT ST_Union(geom) as geom FROM merged_isozones WHERE classe IN (1,2,3)) a,
     (SELECT geom FROM merged_isozones WHERE classe = 4) b
WHERE classe = 4;

Affichage dans QGIS

Les données sont maintenant disponibles pour visualisation dans QGIS. En guise de fond de plan, vous pouvez utiliser les tuiles TMS d'OpenStreetMap:

https://a.tile.openstreetmap.org/{z}/{x}/{y}.png

Avec les éléments présentés précédemment, j'arrive à constituer la carte suivante:

Le résultat final: une couche d'isochrones !

Tout ça pour ça ? Oui mais maintenant vous savez faire. A vous de l'adapter à vos besoins.

Conclusions

Bon, c'était assez compliqué et ce, pour plusieurs raisons. La première c'est que les données d'OpenStreetMap ne sont pas encore assez fines, notamment au niveau des limites de vitesse. J'ai dû batailler pour trouver quelques techniques pour les déduires d'autres couches.

Par ailleurs, les routes OpenStreetMap ne forment pas du tout un réseau topologique (enfin du moins, en sortie de l'API overpass) ce qui pose de nombreux problèmes pour GRASS. Nous arrivons à contourner ces éléments mais cela impose d'ajouter quelques requêtes.

Enfin, ça fait longtemps que je n'ai pas vraiment fait de SIG libre: je suis donc un peu rouillé et il doit y avoir des techniques pour aller plus vite, avec d'autres opérateurs.

Le choix de PostGIS peut sembler bizarre de prime abord, essentiellement parce que finalement, tous les traitements se font sur la même machine. Au départ, j'avais commencé avec le format standard GPKG qui est vraiment bien géré par QGIS et GDAL. Mais finalement, vu les traitements imposés pour le nettoyage des données, je me suis retrouvé à court de fonctions géométriques dans Spatialite (GPKG est une surcouche de Spatialite). Je me suis rabattu vers PostgreSQL/PostGIS qui a effectivement tenu ses promesses.

Au final, on obtient des isochrones avec tous les détails pour rejouer les calculs avec d'autres classes de coût de déplacement. On pourrait aussi aller plus loin en recalculant les coûts en fonction de la présence d'éléments de signalisation qui imposent ou non un arrêt.

Mais d'ici là, et en restant approximatif, on obtient des zones pas si délirantes que ça en comparant avec ce que peuvent produire OSRM ou même Google Maps dans leur calcul de distance.

Pour terminer, on aurait pu s'affranchir de GRASS si nous avions utilisé PgRouting. Mais je souhaitais aussi montrer que le SIG GRASS avait encore des atouts sur la partie des réseaux.

Posted dim. 10 juin 2018 18:16:30 Tags:



After about 7 years of thruthful service, I need a new e-reader!

My Kindle3 is dead. Well, It's only the screen that has been fractured. Perhaps too much compression on my bag:

RIP Kindle3

It has been really good to read books on it. The eInk screen was really soft for my eyes and with time, I finally got rid of nearly all of my physical books (I own now fewer than 30 paper books vs 250 ebooks).

This Kindle has never been connected to a Wifi Network because I was (and I am still) too much paranoid to use an operating system I don't have installed myself. It never prevents me to read books on it: I simply downloaded them on my main computer and pushed them on the device via USB.

What annoyed me the most was the library software from Amazon. It was really painful to navigate through my growing ebooks collection.

I jailbreaked it as soon as I got it but I did not do so much things with all of this privileges because there was (and it still is) not so much softwares for it. I think that the eInk screen is too much complicated to use as a true screen for an operating system.

Clearly I should have tried to install something like FBReader on it. If I got more free time, I may try to install Debian on it... after all, the main board is still working and I have kept the battery.

Until this moment, well, RIP eReader!

Posted sam. 09 juin 2018 11:16:30