Chapter Contents
While pgRouting functions provide a low-level interface, developing for a higher-level application requires these requirements to be represented directly in the SQL queries. As these SQL queries get more complex, it is desirable to store them in PostgreSQL stored procedures or functions. Stored procedures or functions are an effective way to wrap application logic, in this case, related to routing logic and requirements.
The function will wrap pgr_dijkstra.
The function needs to work on any of the networks designed:
vehicle_nettaxi_net
The function needs to return the following routing information:
seq- A unique identifier of the rowsid- The segment's identifiername- The segment's namelength- The segment's lengthseconds- Number of seconds to traverse the segmentazimuth- The azimuth of the segmentroute_geom- The routing geometryroute_readable- The geometry in human readable form.
Design of the function
The function to be created wrk_dijkstra with the following input parameters and
output columns:
Input parameters
| Parameter | Type | Description |
|---|---|---|
edges_subset |
REGCLASS | The table/view that is going to be used for processing |
source |
BIGINT | The identifier of the departure location. |
target |
BIGINT | The identifier of the destination location. |
output columns
| Name | Type | Description |
|---|---|---|
seq |
INTEGER | A unique number for each result row. |
id |
BIGINT | The edge identifier. |
name |
TEXT | The name of the segment. |
seconds |
FLOAT | The number of seconds it takes to traverse the segment. |
length |
FLOAT | The length in meters of the segment. |
azimuth |
FLOAT | The azimuth of the segment. |
route_readable |
TEXT | The geometry in human readable form. |
route_geom |
geometry | The geometry of the segment in the correct direction. |
When the application needs additional information, like the name of the street,
JOIN the results with other tables.
Problem
- From |ch7_place_1| to |ch7_place_2|
- Get the following information:
seqidnamesecondslength
Solution
- The function returns the columns asked. (line 4)
- Rename
pgr_dijkstraresults to application requirements names. (line 12). LEFT JOINthe results withvehicle_netto get the additional information. (line 17)LEFTto include the row withid = -1because it does not exist onvehicle_net
- Test from |ch7_id_1| to |ch7_id_2| on
vehicle_net. (Last line)
.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql :linenos: :force: :emphasize-lines: 4,12,17 :start-after: get_more_info.txt :end-before: get_read_geom.txt
.. collapse:: Query results .. literalinclude:: ../scripts/basic/sql_function/get_more_info.txt
From pgRouting point of view, the geometry is part of the additional
information needed on the results for an application. Therefore JOIN the
results with other tables that contain the geometry and for further processing
with PostGIS functions.
Problem
Route from the |ch7_place_1| to |ch7_place_2|
- Additionally to the previous exercise, get the
- geometry
geomin human readable form named asroute_readable
- geometry
Solution
- The function returns
route_readable. (line 6) - The routing query named
resultsin a WITH clause. (line 11) - The
geomprocessed withST_AsTextto get the human readable form. (line 19). - Test from |ch7_id_1| to |ch7_id_2| on
vehicle_net. (Last line)
.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql :linenos: :force: :emphasize-lines: 6,11,19 :start-after: get_read_geom.txt :end-before: get_geom.txt
.. collapse:: Query results .. literalinclude:: ../scripts/basic/sql_function/get_read_geom.txt
Problem
Route from the |ch7_place_1| to |ch7_place_2|
- Additionally to the previous exercise, get the
geomin binary format with the nameroute_geom
Solution
- The function returns
route_geom. (line 7) - The geometry
geomof the segments (line 21) - Test from |ch7_id_1| to |ch7_id_2| on
vehicle_net. (Last line)
.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql :emphasize-lines: 7,21 :force: :linenos: :start-after: get_geom.txt :end-before: wrong_directionality.txt
.. collapse:: Query results .. literalinclude:: ../scripts/basic/sql_function/get_geom.txt
Visually, with the route displayed with arrows, it can be found that there are arrows that do not match the directionality of the route.
To have correct directionality, the ending point of a geometry must match the starting point of the next geometry
- Inspecting the detail of the results of Exercise 2: Route geometry (human readable)
.. collapse:: Query: Rows where criteria is not met
.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql
:language: sql
:start-after: wrong_directionality.txt
:end-before: fix_directionality.txt
.. literalinclude:: ../scripts/basic/sql_function/wrong_directionality.txt :language: sql
Problem
Route from the |ch7_place_1| to |ch7_place_2|
- Fix the directionality of the geometries of the previous exercise
geomin human readable form named asroute_readablegeomin binary format with the nameroute_geom- Both columns must have the geometry fixed for directionality.
Solution
To get the correct direction some geometries need to be reversed:
- Reversing a geometry will depend on the
nodecolumn of the query to Dijkstra. - A conditional
CASEstatement that returns the geometry in human readable form:- Of the geometry when
nodeis thesourcecolumn. - Of the reversed geometry when
nodeis not thesourcecolumn.
- Of the geometry when
- A conditional
CASEstatement that returns:- The geometry when
nodeis thesourcecolumn. - The reversed geometry when
nodeis not thesourcecolumn.
- The geometry when
.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql :linenos: :force: :start-after: fix_directionality.txt :end-before: good_directionality.txt
.. collapse:: results .. literalinclude:: ../scripts/basic/sql_function/fix_directionality.txt
Inspecting the problematic rows, the directionality has been fixed.
.. collapse:: Query: Rows where criteria is not met
.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql
:language: sql
:start-after: good_directionality.txt
:end-before: use_directionality.txt
.. literalinclude:: ../scripts/basic/sql_function/good_directionality.txt
There are many geometry functions in PostGIS, the workshop already covered some of them like
ST_AsText, ST_Reverse, ST_EndPoint, etc.
This exercise will make use an additional function ST_Azimuth.
Problem
Modify the query from the previous exercise
- Additionally obtain the azimuth in degrees of the corrected geometry.
Solution
- The function returns
aximuth. (line 8) - The query from previous exercise is wrapped under additional subquery. (line 18)
- The
azimuthis processed in degrees. (line 35). - Test from |ch7_id_1| to |ch7_id_2| on
vehicle_net. (Last line)
.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql :force: :linenos: :emphasize-lines: 8,18,35 :start-after: use_directionality.txt :end-before: using_fn1.txt
.. collapse:: results .. literalinclude:: ../scripts/basic/sql_function/use_directionality.txt
Try the function with a combination of the interesting places:
Using different networks:
vehicle_nettaxi_netwalk_net
Names of the streets in the route
.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql :start-after: using_fn1.txt :end-before: using_fn2.txt
.. collapse:: Query results .. literalinclude:: ../scripts/basic/sql_function/using_fn1.txt
Total seconds spent in each street
.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql :start-after: using_fn2.txt :end-before: using_fn3.txt
.. collapse:: Query results .. literalinclude:: ../scripts/basic/sql_function/using_fn2.txt
Why it does not fully work with walk_net?
.. literalinclude:: ../scripts/basic/sql_function/sql_function.sql :language: sql :start-after: using_fn3.txt
.. collapse:: Query results .. literalinclude:: ../scripts/basic/sql_function/using_fn3.txt




