Other kind of functions are pl/pgsql. As applications requirements become more complex, using previously defined functions becomes necessary.
Chapter Contents
The following function takes latitude/longitude points as input parameters and returns a route that can be displayed in QGIS or WMS services such as Mapserver and Geoserver:
Input parameters
x1
, y1
for start point and x2
, y2
for end pointOutput columns
column | Description |
---|---|
seq | For ordering purposes |
gid | The edge identifier that can be used to JOIN the results to the ways table |
name | The street name |
azimuth | between start and end node of a and edge |
length | In kilometers |
costs | Costs in minutes |
route_geom | The road geometry with corrected directionality. |
Graphs have a set of edges and set of vertices associated to it.
osm2pgrouting provides the ways_vertices_pgr table which is associated with
the ways table.
When a subset of edges is used like in vehicle_net
or in small_net
,
the set of vertices associated to each one must be used in order to, for example,
locate the nearest vertex to a lat/lon location.
Calculate the number of vertices in a graph
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | -- Number of vertices in the original graph
SELECT count(*) FROM ways_vertices_pgr;
-- Number of vertices in the vehicles_net graph
SELECT count(*) FROM ways_vertices_pgr
WHERE id IN (
SELECT source FROM vehicle_net
UNION
SELECT target FROM vehicle_net);
-- Number of vertices in the little_net graph
SELECT count(*) FROM ways_vertices_pgr
WHERE id IN (
SELECT source FROM little_net
UNION
SELECT target FROM little_net);
|
Calculate the osm_id of the nearest vertex to -71.04143, 42.35126
.
-71.04143, 42.35126
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | -- Closest osm_id in the original graph
SELECT osm_id FROM ways_vertices_pgr
ORDER BY the_geom <-> ST_SetSRID(ST_Point(-71.04143, 42.35126), 4326) LIMIT 1;
-- Closest osm_id in the vehicle_net graph
WITH
vertices AS (
SELECT * FROM ways_vertices_pgr
WHERE id IN (
SELECT source FROM vehicle_net
UNION
SELECT target FROM vehicle_net)
)
SELECT osm_id FROM vertices
ORDER BY the_geom <-> ST_SetSRID(ST_Point(-71.04143, 42.35126), 4326) LIMIT 1;
-- Closest osm_id in the little_net graph
WITH
vertices AS (
SELECT * FROM ways_vertices_pgr
WHERE id IN (
SELECT source FROM little_net
UNION
SELECT target FROM little_net)
)
SELECT osm_id FROM vertices;
|
Incorporating all the requirements into the function wrk_fromAtoB
.
Additionally, it will show the query that is being executed, with the NOTICE
statement.
Create the function wrk_fromAtoB
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | -- DROP FUNCTION wrk_fromAtoB(varchar, numeric, numeric, numeric, numeric);
CREATE OR REPLACE FUNCTION wrk_fromAtoB(
IN edges_subset regclass,
IN x1 numeric, IN y1 numeric,
IN x2 numeric, IN y2 numeric,
OUT seq INTEGER,
OUT gid BIGINT,
OUT name TEXT,
OUT length FLOAT,
OUT the_time FLOAT,
OUT azimuth FLOAT,
OUT geom geometry
)
RETURNS SETOF record AS
$BODY$
DECLARE
final_query TEXT;
BEGIN
final_query :=
FORMAT( $$
WITH
vertices AS (
SELECT * FROM ways_vertices_pgr
WHERE id IN (
SELECT source FROM %1$I
UNION
SELECT target FROM %1$I)
),
dijkstra AS (
SELECT *
FROM wrk_dijkstra(
'%1$I',
-- source
(SELECT osm_id FROM vertices
ORDER BY the_geom <-> ST_SetSRID(ST_Point(%2$s, %3$s), 4326) LIMIT 1),
-- target
(SELECT osm_id FROM vertices
ORDER BY the_geom <-> ST_SetSRID(ST_Point(%4$s, %5$s), 4326) LIMIT 1))
)
SELECT
seq,
dijkstra.gid,
dijkstra.name,
ways.length_m/1000.0 AS length,
dijkstra.cost AS the_time,
azimuth,
route_geom AS geom
FROM dijkstra JOIN ways USING (gid);$$,
edges_subset, x1,y1,x2,y2); -- %1 to %5 of the FORMAT function
RAISE notice '%', final_query;
RETURN QUERY EXECUTE final_query;
END;
$BODY$
LANGUAGE 'plpgsql';
|
Solution to Chapter 8 Exercise 3
Save the function in the file wrk_fromAtoB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | SELECT * FROM wrk_fromAtoB(
'vehicle_net',
-71.04136, 42.35089,
-71.03483, 42.34595);
SELECT * FROM wrk_fromAtoB(
'little_net',
-71.04136, 42.35089,
-71.03483, 42.34595);
SELECT * FROM wrk_fromAtoB(
'ways',
-71.04136, 42.35089,
-71.03483, 42.34595);
|
Solution to Chapter 8 Exercise 4
Note
A Notice will show while executing the function, for example:
NOTICE:
WITH
vertices AS (
SELECT * FROM ways_vertices_pgr
WHERE id IN (
SELECT source FROM vehicle_net
UNION
SELECT target FROM vehicle_net)
),
dijkstra AS (
SELECT *
FROM wrk_dijkstra(
'vehicle_net',
-- source
(SELECT osm_id FROM vertices
ORDER BY the_geom <-> ST_SetSRID(ST_Point(-71.04136, 42.35089), 4326) LIMIT 1),
-- target
(SELECT osm_id FROM vertices
ORDER BY the_geom <-> ST_SetSRID(ST_Point(-71.03483, 42.34595), 4326) LIMIT 1))
)
SELECT
seq,
dijkstra.gid,
dijkstra.name,
ways.length_m/1000.0 AS length,
dijkstra.cost AS the_time,
azimuth,
route_geom AS geom
FROM dijkstra JOIN ways USING (gid);