35
PGRouting for dummies Julien-Samuel Lacroix Mapgears @juliensam

PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

  • Upload
    others

  • View
    71

  • Download
    0

Embed Size (px)

Citation preview

Page 1: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

PGRouting for dummiesJulien-Samuel Lacroix

Mapgears@juliensam

Page 2: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

PGRouting

➔ Installation➔ Configuration➔ Querying➔ Integration

Page 3: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Quick Installation

http://pgrouting.org/download.html

Available for:➔ Linux➔ Mac➔ Windows

As simple as:$ sudo apt­get install postgresql­9.1­pgrouting

Page 4: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Prepare the Database

Load PostGIS:createdb routing

psql -f postgis.sql routing

psql -f spatial_ref_sys.sql routing

psql -f legacy.sql routing

Load PGRouting:psql -f routing_core.sql routing

psql -f routing_topology.sql routing

psql -f routing_core_wrappers.sql routing

Page 5: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Load the data

Load the data normally in PostGIS

shp2pgsql your_shp_file.shp > psql routing

The network segments need to be linked together at intersection.

Page 6: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Connecting network

Page 7: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Route the data

PGRouting:

- node -> node

- segment -> segment

ALTER TABLE ways ADD COLUMN "source" integer;

ALTER TABLE ways ADD COLUMN "target" integer;

SELECT assign_vertex_id('ways', 1, 'the_geom', 'gid');

CREATE INDEX source_idx ON ways("source");

CREATE INDEX target_idx ON ways("target");

Page 8: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Source and target

Page 9: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Route on what?

Define the cost of each segment in the network.

It can be anything or a combinaison of things:

➔ Length➔ Road type➔ Topology➔ Speed limit➔ Toll➔ etc...

Page 10: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

$$$ Cost $$$-- Add cost column

ALTER TABLE ways ADD COLUMN length double precision;

UPDATE ways SET length = ST_LENGTH(the_geom);

-- Make the cost column different depending on road type

UPDATE

ways

SET length =

CASE

WHEN class='motorways' THEN

ST_LENGTH(the_geom)/4

WHEN class='railways' THEN

99999999

ELSE

ST_LENGTH(the_geom)

END;

Page 11: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

The OSM case

● OSM data needs to to be splitted at intersection

● osm2pgrouting split and give you most of the information for basic routing

osm2pgrouting \

-file nottinghamshire-latest.osm \

-dbname routing \

-clean \

-user jlacroix \

-passwd ttt123 \

-conf ./osm2pgrouting-master/mapconfig.xml

Page 12: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Choose your algorithm

Dijkstra

More precise

shortest_path()

A*

Faster

shortest_path_astar()

Others available in 2.0

Page 13: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Query the data

SELECT *

FROM

shortest_path(

'SELECT

gid as id,

source::integer,

target::integer,

length::double precision as cost

FROM ways',

37725,

37720,

false,

false);

Page 14: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Visualize the result

seq | node | edge | cost

-----+------+------+---------------------

0 | 30 | 53 | 0.0591267653820616

1 | 44 | 52 | 0.0665408320949312

2 | 14 | 15 | 0.0809556879332114

...

6 | 10 | 6869 | 0.0164274192597773

7 | 59 | 72 | 0.0109385169537801

8 | 60 | -1 | 0

(9 rows)

Page 15: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Visualize the result

SELECT

*

FROM

shortest_path(

'SELECT

gid as id,

source::integer,

target::integer,

length::double precision as cost

FROM

Ways',

37725, 37720, false, false) as route,

ways

WHERE

ways.gid=route.edge_id;

Page 16: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Visualize the result

seq | geom | edge | cost | name

-----+------+------+---------------------+------

0 | ... | 53 | 0.0591267653820616 | ...

1 | ... | 52 | 0.0665408320949312 | ...

2 | ... | 15 | 0.0809556879332114 | ...

...

6 | ... | 6869 | 0.0164274192597773 | ...

7 | ... | 72 | 0.0109385169537801 | ...

8 | ... | -1 | 0 | ...

(9 rows)

Page 17: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Visualize the result

MapServer:DATA “geom FROM (SELECT * FROM shortest_path(...) as ... )”

Page 18: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Be smart

From lat/lon to lat/lon

Load the smart file:psql -f routing_core_smart.sql routing

select add_network_info('ways');

Get it from:https://github.com/pgRouting/pgrouting-contrib/blob/master/functions-v1.x/routing_core_smart.sql

Page 19: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Query the data (again)

SELECT *

FROM

sp_smart_directed(

'ways',

true,

-131675, 6976548,

-131475, 6976431,

10000,

'length',

'length',

false,

false) JOIN ...;

Page 20: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Visualize the result

With Openlayers:

Page 21: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

One-way

SELECT *

FROM

sp_smart_directed(

'ways',

true,

-131675, 6976548,

-131475, 6976431,

10000,

'cost_column',

'reverse_cost_column',

true,

true) JOIN ...;

It's also possible to get left-turn based cost

Page 22: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Get the tools

➔ OpenLayers➔ GeoExt➔ Server-side routing service

Page 23: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Get a map up and running

// create the map panel

var panel = new GeoExt.MapPanel({

renderTo: "gxmap",

map: {

Layers: [

new OpenLayers.Layer.WMS("My route WMS",...)

]},

center: [-112000, 7000000],

zoom: 8,

height: 400,

width: 600,

title: "A Simple GeoExt Map"

});

var map = panel.map;

Page 24: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Add the route layers

// create the layer where the route will be drawn

var route_layer = new OpenLayers.Layer.Vector("route");

//create the layer where the start and final points will be drawn

var points_layer = new OpenLayers.Layer.Vector("points");

// add the layers to the map

map.addLayers([points_layer, route_layer]);

Page 25: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Add the routing tools

// when a new point is added to the layer,

// call the pgrouting function

points_layer.events.on({

featureadded: function() {

pgrouting(store, points_layer, '');

}

});

// create the control to draw the points

// (see the DrawPoints.js file)

var draw_points = new DrawPoints(points_layer);

Page 26: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Add the routing tools

// create the control to move the points

var drag_points = new OpenLayers.Control.DragFeature(

points_layer, {autoActivate: true});

// when a point is moved, call the pgrouting function

drag_points.onComplete = function() {

pgrouting(store, points_layer, '');

};

// add the controls to the map

map.addControls([draw_points, drag_points]);

Page 27: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

The routing functionfunction pgrouting(store, layer, method) {

if (layer.features.length == 2) {

store.removeAll(); // erase the previous route

// transform the two geometries from EPSG:900913 to EPSG:4326

var startpoint = layer.features[0].geometry.clone();

startpoint.transform(epsg_900913, epsg_4326);

finalpoint = ...;

// load to route

store.load({

params: {

startpoint: startpoint.x + " " + startpoint.y,

finalpoint: finalpoint.x + " " + finalpoint.y,

method: method

}});

...

Page 28: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

The store

// create the store to query the web service

var store = new GeoExt.data.FeatureStore({

layer: route_layer,

fields: [

{name: "length"}

],

proxy: new GeoExt.data.ProtocolProxy({

protocol: new OpenLayers.Protocol.HTTP({

url: "route.php",

format: new OpenLayers.Format.GeoJSON({

internalProjection: epsg_900913,

externalProjection: epsg_4326

})

})

})

});

Page 29: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

The server-side

// Build the query

$sql = "

SELECT

*, ST_AsGeoJSON(the_geom) as geojson, ST_Length(the_geom) as length

FROM

sp_smart_directed(

'".TABLE."',

true,

".$startPoint[0].",

".$startPoint[1].",

".$endPoint[0].",

".$endPoint[1].",

1000, 'cost', 'cost', false, false

);";

Page 30: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

The server-side

// Execute the query

psql_query(...);

// Return routing result

header('Content-type: application/json',true);

echo json_encode($geojson);

Page 31: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Demo!

Page 32: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Get some style for the line

// create the layer where the route will be drawn

var route_layer = new OpenLayers.Layer.Vector("route", {

styleMap: new OpenLayers.StyleMap(new OpenLayers.Style({

strokeColor: "#ff3333",

strokeOpacity: 0.7,

strokeWidth: 3

}))

});

Page 33: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Get some style for the points

// create the layer where the start and final points will be drawn

var points_layer = new OpenLayers.Layer.Vector("points", {

styleMap: new OpenLayers.StyleMap(new OpenLayers.Style({

"fillColor": "${getColor}",

"strokeColor": "${getColor}",

"pointRadius": 7,

"fillOpacity": 0.5

}, {context: {

"getColor": function(feature) {

return (feature.layer.features[0] == feature) ?

'green' : 'red';

}

}}))

});

Page 34: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

What’s next?

➔ PGRouting 2.0➔ API refactoring➔ Tests➔ Documentation➔ Examples➔ See the presentation a 2:30PM in this

same room

Page 35: PGRouting for dummies · Load the data Load the data normally in PostGIS shp2pgsql your_shp_file.shp > psql routing The network segments need to be linked together at intersection

Questions?The code is available at:

http://dl.mapgears.com/pgrouting/foss4g2013/routing.tar.gz