pgRouting comprend une fonction appelée pgr_drivingDistance, qui, en conjonction avec trois autres fonctions, pgr_withPointsDD, pgr_alphaShape et pgr_pointsAsPolygon, permet de déterminer quels chemins ont un certain coût par rapport à un point de départ ou d’arrivée.
La zone qui entoure ces chemins est désignée comme une zone de chalandise. pgr_drivingDistance, en conjonction avec pgr_pointsAsPolygon est souvent utilisée pour déterminer les exigences de couverture d’un service ou pour déterminer les emplacements optimaux pour de nouvelles installations.
Par exemple, si vous avez une caserne de pompiers, vous devez déterminer toutes les parties de la ville qui peuvent être atteintes dans les cinq minutes. Un problème inverse serait de trouver toutes les parties de la ville où les résidents peuvent conduire jusqu’à un hôpital dans les cinq minutes.
La fonction qui calcule les chemins pour les deux problèmes est appelée pgr_drivingDistance car elle est souvent utilisée lorsque le coût est mesuré en temps de conduite. Cependant, les coûts ne sont pas forcément limités à un temps ou une distance.
Pour ce type d’application, connaître tous les itinéraires vers ou à partir d’un point n’est pas très utile. C’est là que les fonctions pgr_alphaShape et pgr_pointsAsPolygon entrent en jeu. Le pgr_alphaShape prend en entrée un ensemble de coordonnées x, y et renvoie un ensemble de x, y qui correspondent aux sommets d’un polygone qui englobe tous les points en entrée.
pgr_pointsAsPolygon est similaire à pgr_alphaShape, elle prend en entrée un ensemble de coordonnées x, y, mais au lieu de retourner une autre série de points, renvoie un polygone qui entoure l’ensemble des points d’entrée . En interne, il utilise la fonction pgr_alphaShape.
Utilisation de pgr_drivingDistance
Penons le cas d’une caserne de pompiers et cherchons la zone couverte en 5 minutes. La commande sql correspondant à ces critères se traduit par:
SELECT * FROM pgr_drivingDistance(‘SELECT gid as id, source, target , cost_s as cost, reverse_cost_s as reverse_cost FROM public.ways’, 25736, 300, true)
Pour cette requête nous utilisons dans la clause SELECT le coût d’un tronçon en secondes (cost_s), et nous indiquons le reverse_cost_s car même les camions de pompiers ne peuvent pas prendre les rues à contresens. 25736 est le nœud correspondant à la caserne de pompiers, 300 est le coût recherché (5 minutes x 60 secondes), et la valeur true indique que le graphe est directionnel (prise en compte des sens interdits).
Le résultat de la requête retourne 6948 nœuds qui sont dans un rayon de 5 minutes de la caserne de pompiers. Par contre le résultat de la requête n’ayant pas de géométrie, nous ne pouvons pas les visualiser dans QGis.
Pour pouvoir le faire il suffit de modifier la requête comme suit:
SELECT * FROM pgr_drivingDistance(‘SELECT gid as id, source, target , cost_s as cost, reverse_cost_s as reverse_cost FROM public.ways’, 25736, 300, true) as di JOIN ways_vertices_pgr on di.node=ways_vertices_pgr.id
Nous effectuons une jointure avec la table des nœuds (ways_vertices_pgr) et le résultat de la requête contient alors les géométries:
Nous pouvons alors visualiser le résultat dans QGis:
Création de l’aire de chalandise avec pgr_pointsAsPolygon
Pour créer l’aire de chalandise, nous utilisons la requête précédente comme sql de la fonction pgr_pointsAsPolygon, en créant un polygone en sortie que nous pouvons charger dans QGis:
SELECT 1 As id, ST_SetSRID(pgr_pointsAsPolygon(
$$SELECT di.seq AS id, ST_X(v.the_geom) AS x, ST_Y(v.the_geom) As y
FROM pgr_drivingDistance( »SELECT gid As id, source, target,
cost_s AS cost, reverse_cost_s AS reverse_cost
FROM public.ways »,25736 , 300, true
) AS di INNER JOIN public.ways_vertices_pgr AS v ON di.node = v.id$$
), 4326) As geom;
pgr_pointAsPolygon utilise les id,x et y des points générés par pgr_drivingDistance. Pour les x et y on utilise les fonctions St_x et St_y sur la géométrie des points.
Le résultat, une fois chargé dans QGis est le suivant:
Construction d’isochrones
Les isochrones correspondent aux zones atteignables en une série de pas de temps. On peut, dans cet exemple, vouloir connaître quelles sont les zones qu’on peut atteindre en 1, 2, 3, 4 et 5 minutes.
Pour cela nous allons procéder en deux étapes.
La première consiste à créer une table avec nos noeuds résultant de pgr_drivingDistance pour le pas de temps le plus fort (5 minutes). Logiquement, dans cette table on trouvera aussi les nœuds atteignables dans les laps de temps plus courts.
Nous créons cette table (dd_caserne) avec la commande sql suivante:
CREATE TABLE dd_caserne AS
SELECT di.seq As id, di.node, di.edge,
di.agg_cost As temps_acces, v.the_geom As geom
FROM pgr_drivingDistance(‘SELECT gid As id, source, target,
cost_s AS cost, reverse_cost_s AS reverse_cost
FROM public.ways’,25736 , 300, true
) AS di INNER JOIN public.ways_vertices_pgr AS v ON di.node = v.id;
La table résultante est la suivante:
A partir de cette table nous allons construire une série de polygones avec pgr_pointsAsPolygon, pour les points situés à 60, 120,180,240 et 300 secondes de temps d’accès en utilisant generate_series
SELECT i As temps_acces,ST_SetSRID(pgr_pointsAsPolygon(
‘SELECT id, ST_X(geom) AS x, ST_Y(geom) As y
FROM dd_caserne
WHERE temps_acces <= ‘ || i::text ) ,4326) As geom
FROM generate_series(60,300,60) As i
ORDER BY i DESC
Le résultat comprend les 5 polygones isochrones, que nous pouvons maintenant visualiser dans QGis:
Bonjour,
Merci pour cette article. Je cherchais depuis un article pour m’expliquer a bien concevoir ma zone de chalandise.
En tout cas je vais grace à vous pouvoir faire une zone de chalandise gratuite, en faisant mon propre programme.
Merci encore.