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 ### Préparer la base de données
Créer un rôle 'redadeg'. Avec un compte administrateur PostgreSQL :
Créer une base 'redadeg' et mettre le rôle 'redadeg' en propriétaire. * Créer un rôle 'redadeg'
Installer les extensions postgis et pgrouting. * 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()` Si on veut vérifier : `select * from pgr_version()`
(2.6.2) (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 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 ; DROP TABLE IF EXISTS osm_roads ;
CREATE TABLE 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 -- 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
-- on modifie la table osm_roads SELECT topology.AddTopoGeometryColumn('osm_roads_topo', 'public', 'osm_roads', 'topo_geom', 'LINESTRING');
ALTER TABLE osm_roads ADD COLUMN source integer ;
ALTER TABLE osm_roads ADD COLUMN target integer ;
-- 3. on calcule le graphe topologique
-- calcul de la topologie -- en remplissant le nouvel attribut géométrique
SELECT pgr_createTopology('osm_roads', 0.000001); -- 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