routing first shot

This commit is contained in:
MaelReboux 2019-03-17 19:07:55 +01:00
parent e369c275a9
commit 0e7b42ea05
4 changed files with 196 additions and 12 deletions

View file

@ -15,13 +15,35 @@ Ceci afin d'avoir un tracé le plus précis possible par rapport aux longueurs e
### Préparer la base de données
Créer un rôle 'redadeg'.
Créer une base 'redadeg' et mettre le rôle 'redadeg' en propriétaire.
Installer les extensions postgis et pgrouting.
Avec un compte administrateur PostgreSQL :
* Créer un rôle 'redadeg'
* Créer une base 'redadeg' et mettre le rôle 'redadeg' en propriétaire
```sql
CREATE USER redadeg WITH LOGIN PASSWORD 'redadeg';
CREATE DATABASE redadeg WITH OWNER = redadeg;
```
Ouvrir une connexion sur la base redadeg, toujours avec un compte administrateur pour installer les extensions :
* postgis
* postgis_topology
* pgrouting
```sql
CREATE EXTENSION postgis ;
CREATE EXTENSION postgis_topology;
CREATE EXTENSION pgrouting;
-- permissions
ALTER SCHEMA topology OWNER TO redadeg ;
ALTER TABLE topology.layer OWNER TO redadeg ;
ALTER TABLE topology.topology OWNER TO redadeg ;
```
Si on veut vérifier : `select * from pgr_version()`
(2.6.2)
Note : l'extension postgis_topology crée forcément un schéma *topology* dans la base de données.
On prépare également la connexion à la base dans son pgpass

View file

@ -167,7 +167,7 @@ CREATE VIEW phase_1_tdb AS
*/
-- la table qui contient le graphe routier de OSM
-- la table qui contient les lignes des routes venant de OSM
DROP TABLE IF EXISTS osm_roads ;
CREATE TABLE osm_roads
(
@ -186,6 +186,37 @@ CREATE TABLE osm_roads
);
-- la table en version routable
DROP TABLE IF EXISTS osm_roads_pgr ;
CREATE TABLE osm_roads_pgr
(
id bigint,
osm_id bigint,
highway text,
type text,
oneway text,
ref text,
name_fr text,
name_br text,
source bigint,
target bigint,
the_geom geometry,
CONSTRAINT osm_roads_pgr_pkey PRIMARY KEY (id),
CONSTRAINT enforce_geotype_the_geom CHECK (geometrytype(the_geom) = 'LINESTRING'::text OR geometrytype(the_geom) = 'MULTILINESTRING'::text),
CONSTRAINT enforce_srid_the_geom CHECK (st_srid(the_geom) = 2154)
);
CREATE INDEX osm_roads_pgr_source_idx ON osm_roads_pgr (source);
CREATE INDEX osm_roads_pgr_target_idx ON osm_roads_pgr (target);
-- dans la base redadeg on chargera la couche osm_roads qui a été calculée
-- à partir de données OSM
-- 1. création d'un schéma qui va accueillir le réseau topologique de la couche osm_roads
SELECT topology.CreateTopology('osm_roads_topo', 2154);

80
scripts/routing.sql Normal file
View file

@ -0,0 +1,80 @@
/*
==========================================================================
phase 2 : préparation pour le calcul d'itinéraires en appui du réseau routier OSM
==========================================================================
*/
-- dans la base redadeg on a chargé la couche osm_roads qui a été calculée
-- à partir de données OSM
-- 1. création d'un schéma qui va accueillir le réseau topologique de la couche osm_roads
SELECT topology.CreateTopology('osm_roads_topo', 2154);
-- on a donc un nouveau schéma osm_roads_topo qui contient 4 tables : edge_data, face, node, relation
-- et un nouvel enregistrement dans la table topology.layer
-- logiquement : c'est 1
-- SELECT * FROM topology.layer ORDER BY layer_id desc ;
-- 2. ajout d'un nouvel attribut sur la table osm_roads
SELECT topology.AddTopoGeometryColumn('osm_roads_topo', 'public', 'osm_roads', 'topo_geom', 'LINESTRING');
-- 3. on calcule le graphe topologique
-- en remplissant le nouvel attribut géométrique
-- le 1er chiffre est l'identifiant du layer dans la table topology.layer
-- le 2e chiffre est la tolérance en mètres
UPDATE osm_roads SET topo_geom = topology.toTopoGeom(the_geom, 'osm_roads_topo', 1, 0.01);
-- à ce stade on a un graphe topolgique dans le schema osm_roads_topo
-- 4. remplissage de la couche routable depuis la couche d'origine et la topologie
INSERT INTO osm_roads_pgr
( SELECT
e.edge_id as id,
o.osm_id,
o.highway,
o.type,
o.oneway,
o.ref,
o.name_fr,
o.name_br,
o.source,
o.target,
e.geom as the_geom
FROM osm_roads_topo.edge e,
osm_roads_topo.relation rel,
osm_roads o
WHERE e.edge_id = rel.element_id
AND rel.topogeo_id = (o.topo_geom).id
);
-- 5. calcul du graphe routier par pgRouting
SELECT pgr_createTopology('osm_roads_pgr', 1.0);
-- vérification
SELECT pgr_analyzegraph('osm_roads_pgr', 1.0);
SELECT pgr_nodeNetwork('osm_roads_pgr', 1.0);
-- il ne reste plus qu'à faire des calculs d'itinéraires
-- test de calcul de plus court chemin
SELECT * FROM pgr_dijkstra(
'SELECT id, source, target, st_length(the_geom) as cost FROM osm_roads_pgr',
6, 1
);
-- si besoin : nettoyage par Drop du schéma
SELECT topology.DropTopology('osm_roads_topo');

View file

@ -11,13 +11,64 @@
-- 1. Préparation des données pour pouvoir utiliser pgRouting
-- on modifie la table osm_roads
ALTER TABLE osm_roads ADD COLUMN source integer ;
ALTER TABLE osm_roads ADD COLUMN target integer ;
-- calcul de la topologie
SELECT pgr_createTopology('osm_roads', 0.000001);
-- 2. ajout d'un nouvel attribut sur la table osm_roads
-- normalement il existe déjà mais au cas où on a rechargé un nouveau réseau routier
SELECT topology.AddTopoGeometryColumn('osm_roads_topo', 'public', 'osm_roads', 'topo_geom', 'LINESTRING');
-- 3. on calcule le graphe topologique
-- en remplissant le nouvel attribut géométrique
-- le 1er chiffre est l'identifiant du layer dans la table topology.layer
-- le 2e chiffre est la tolérance en mètres
UPDATE osm_roads SET topo_geom = topology.toTopoGeom(the_geom, 'osm_roads_topo', 1, 1.0);
-- 18 min
-- à ce stade on a un graphe topologique dans le schema osm_roads_topo
-- 4. remplissage de la couche routable depuis la couche d'origine et la topologie
-- on commence par vider avant de remplir
TRUNCATE TABLE osm_roads_pgr ;
-- reset des séquences
ALTER SEQUENCE osm_roads_pgr_vertices_pgr_id_seq RESTART WITH 1;
ALTER SEQUENCE osm_roads_pgr_noded_id_seq RESTART WITH 1;
INSERT INTO osm_roads_pgr
( SELECT
row_number() over() as id,
o.osm_id,
o.highway,
o.type,
o.oneway,
o.ref,
o.name_fr,
o.name_br,
NULL as source,
NULL as target,
e.geom as the_geom
FROM osm_roads_topo.edge e,
osm_roads_topo.relation rel,
osm_roads o
WHERE e.edge_id = rel.element_id
AND rel.topogeo_id = (o.topo_geom).id
);
-- 5. calcul du graphe routier par pgRouting
SELECT pgr_createTopology('osm_roads_pgr', 1.0);
-- 35 s
-- vérification
SELECT pgr_analyzegraph('osm_roads_pgr', 1.0);
SELECT pgr_nodeNetwork('osm_roads_pgr', 1.0);
-- il ne reste plus qu'à faire des calculs d'itinéraires