root/branches/anton/README.routing

Revision 28, 18.7 KB (checked in by anton, 3 years ago)

cmake branch added

Line 
1pgRouting - Routing Functionalities on PostgreSQL
2
3
4INTRODUCTION
5
6This library contains following features:
7
8* Dijkstra algorithm - Shortest path algorithm, which named in honor
9  of Prof. Dr. Edsger Wybe Dijkstra who has invented it
10* A-star (A*) algorithm - Shortest path algorithm using heuristical
11  function
12* Driving distance - area person can cover in certain time from start
13  point using road network
14* TSP - Travelling Salesman Problem solution with default mazimum of
15  40 points
16* Shooting star (Shooting*) algorithm - Shortest path algorithm for
17  real road networks with turn restrictions, traffic lights and one
18  way streets.
19
20REQUIREMENT
21
22* C and C++ compilers
23* Postgresql 8.x
24* PostGIS 1.x
25* Proj 4.x
26* GEOS (Geometry Engine - Open Source) library 2.x
27  See http://geos.refractions.net/
28* The Boost Graph Library (BGL).
29  Version >= 1.33 or previous having astar.hpp
30  See http://www.boost.org/libs/graph/doc/index.html
31* The Genetic Algorithm Utility Library (GAUL).
32  See http://gaul.sourceforge.net
33* Computational Geometry Algorithms Library (CGAL) version >= 3.2.
34  See http://www.cgal.org/
35
36INSTALLATION
37
38* Edit Makefile, and set the BOOST_PATH with the location of your
39 boost library (if you are on Debian, just type
40        "apt-get install libboost-graph-dev" and you don't need to modify anything)
41
42* Type "make install"
43
44* If you have BGL installed but the version is less than 1.33.0,
45  just download the astar.hpp file from
46  http://www.boost.org/boost/graph/astar_search.hpp and copy it to
47  BOOST_PATH/graph directory.
48
49* If you have PostGIS installed, you can launch dijkstra_postgis.sql
50  which will create PostGIS import and manipulation functions.
51
52* GAUL library should be compilled with --no-slang option.
53  Otherwise make sure you have slang.h installed in /usr/include.
54  For more details please refer to corresponding README or INSTALL file.
55
56* Use interactive mode to install CGAL library. To avoid conflicts you should
57  exclude BOOST support from the installation (follow on-screen instructions).
58
59* Execute the sql file dijkstra.sql to install the functions in your database
60  (you need the plpgsql language enabled on your database.
61   Type "createlang plpgsql YOUR_DATABASE" if not)
62
63
64
65USAGE
66
67The core module is a function which computes a shortest path from a
68set of edges and vertices. The function expects data in a specific
69format in input.
70
71Some functions are provided for importing data from geometric tables,
72and for generating results as geometries.
73
74
75The shortest_path functions have the following signature:
76========================================================
77
78CREATE OR REPLACE FUNCTION shortest_path(sql text, source_id integer, target_id integer,
79                                         directed boolean, has_reverse_cost boolean)
80        RETURNS SETOF path_result
81
82Where path_result is:
83
84CREATE TYPE path_result AS (vertex_id integer, edge_id integer, cost float8);
85
86arguments are:
87
88* sql: a SQL query, which should return a set of rows with the
89following columns:
90
91- id: an int4 identifier of the edge
92- source: an int4 identifier of the source vertex
93- target: an int4 identifier of the target vertex
94- cost: double precision value of the edge traversal cost. (a negative cost
95   will prevent the edge from being inserted in the graph).
96- reverse_cost (optional): the cost for the reverse traversal of the
97 edge. This is only used when the directed and has_reverse_cost
98 parameters are true (see the above remark about negative costs).
99- directed: true if the graph is directed
100- has_reverse_cost: if true, the reverse_cost column of the SQL
101generated set of rows will be used for the cost of the traversal of
102the edge in the opposite direction.
103
104A* and Shooting* functions also need:
105- x1: double precision value of x coordinate for edge's start vertex
106- y1: double precision value of y coordinate for edge's start vertex
107- x2: double precision value of x coordinate for edge's end vertex
108- y2: double precision value of y coordinate for edge's end vertex
109
110Shooting* function also needs:
111- rule: a string with a comma separated list of edge ids which describes
112  a rule for turning restriction (if you came along these edges, you can
113  pass through the current one only with the cost stated in to_cost column)
114- to_cost: a cost of restricted passage (can be very high in a case of
115  turn restriction or comparable with an edge cost in a case of traffic light)
116
117For example,
118
119 gid | source | target | cost | x1 | y1 | x2 | y2 | to_cost | rule
120-----+--------+--------+------+----+----+----+----+---------+------
121  12 |      3 |     10 |    2 |  4 |  3 |  4 |  5 |    1000 | 14
122 
123means that the cost of going from edge 14 to edge 12 is 1000,
124 
125and
126 
127 gid | source | target | cost | x1 | y1 | x2 | y2 | to_cost | rule
128-----+--------+--------+------+----+----+----+----+---------+------
129  12 |      3 |     10 |    2 |  4 |  3 |  4 |  5 |    1000 | 14, 4
130 
131means that the cost of going from edge 14 to edge 12 through edge 4 is 1000.
132
133
134The function returns a set of rows. There is one row for each crossed
135edge, and an additional one containing the terminal vertex.
136The columns of each row are:
137
138- vertex_id: the identifier of source vertex of each edge. There is one
139more row after the last edge, which contains the vertex identifier of
140the target path.
141- edge_id: the identifier of the edge crossed
142- cost: The cost associated to the current edge. It is 0 for the row
143after the last edge. Thus, the path total cost can be computated using
144a sum of all rows in the cost column.
145
146examples:
147
148SELECT * from shortest_path('SELECT source, id, target, cost FROM edges',
1493, 7, false, false);
150
151 vertex_id | edge_id | cost
152-----------+---------+------
153         3 |       2 |    0
154         4 |      21 |    0
155         6 |       5 |    0
156         7 |      -1 |    0
157(4 rows)
158
159
160To search a path using the A* algorithm:
161
162SELECT * from shortest_path_astar('SELECT id, source, target, cost,
163x1, y1, x2, y2 FROM edges',3, 7, false, false);
164
165 vertex_id | edge_id | cost
166-----------+---------+------------------------
167         3 |       2 |    0.000763954363701041
168         4 |      21 |    0.00150254971056274
169         6 |       5 |    0.000417442425988342
170         7 |      -1 |    0
171(4 rows)
172
173
174Shooting* algorithm calculates a path from edge to edge (not from vertex to
175vertex). Column vertex_id contains start vertex of an edge from column edge_id.
176
177To search a path using the Shooting* algorithm:
178
179SELECT * from shortest_path_shooting_star('SELECT id, source, target, cost,
180x1, y1, x2, y2, rule, to_cost FROM edges', 17, 9, true, false);
181
182 vertex_id | edge_id | cost
183-----------+---------+------
184        16 |      17 |    1
185        15 |      16 |    1
186         2 |       5 |    1
187         3 |       4 |    1
188        20 |      12 |    2
189        10 |       9 |    2
190(6 rows)
191
192
193The tsp function has the following signature:
194============================================
195
196CREATE OR REPLACE FUNCTION tsp(sql text, ids varchar, source_id integer)
197RETURNS SETOF path_result
198
199arguments are:
200
201* sql: a SQL query, which should return a set of rows with the
202following columns:
203
204- source_id: an int4 identifier of the vertex
205- x: x coordinate of the vertex
206- y: y coordinate of the vertex
207
208* ids: text string containig int4 ids of vertices separated by commas
209* source_id: int 4 id of the start point
210
211The function returns a set of rows. There is one row for each crossed
212edge, and an additional one containing the terminal vertex.
213The columns of each row are:
214
215- vertex_id: the identifier of source vertex of each edge. There is one
216more row after the last edge, which contains the vertex identifier of
217the target path.
218- edge_id: unused, always 0
219- cost: unused, always 0
220
221examples:
222
223SELECT * from tsp('select distinct source as source_id, x1::double precision as x,
224y1::double precision as y from dourol where source in (83593,66059,10549,18842,13)',
225'83593,66059,10549,18842,13', 10549);
226
227 vertex_id | edge_id | cost
228-----------+---------+------
229     10549 |       0 |    0
230     83593 |       0 |    0
231     66059 |       0 |    0
232     18842 |       0 |    0
233        13 |       0 |    0
234(5 rows)
235
236Afterwards vertex_id column can be used for shortest path calculation.
237
238
239The driving_distance function has the following signature:
240=========================================================
241
242CREATE OR REPLACE FUNCTION driving_distance(sql text, source_id integer, distance float8)
243
244RETURNS SETOF path_result
245
246arguments are:
247
248* sql: a SQL query, which should return a set of rows with the
249following columns:
250
251- id: an int4 identifier of the edge
252- source: an int4 identifier of the source vertex
253- target: an int4 identifier of the target vertex
254- cost: an float8 value, of the edge traversal cost. (a negative cost
255   will prevent the edge from being inserted in the graph).
256
257* source_id: int4 id of the start point
258* distance: float8 value of distance in degrees
259
260The function returns a set of rows. There is one row for each crossed
261edge, and an additional one containing the terminal vertex.
262The columns of each row are:
263
264- vertex_id: the identifier of source vertex of each edge. There is one
265more row after the last edge, which contains the vertex identifier of
266the target path.
267- edge_id: the identifier of the edge crossed
268- cost: The cost associated to the current edge. It is 0 for the row
269after the last edge. Thus, the path total cost can be computated using
270a sum of all rows in the cost column.
271
272examples:
273
274SELECT * from driving_distance('select gid as id,source,target,
275length::double precision as cost from dourol',10549,0.01);
276
277 vertex_id | edge_id |     cost
278-----------+---------+---------------
279      6190 |  120220 | 0.00967666852
280      6205 |  118671 | 0.00961557335
281      6225 |  119384 | 0.00965668162
282      6320 |  119378 | 0.00959826176
283      .
284      .
285      .
286     15144 |  122612 | 0.00973386526
287     15285 |  120471 | 0.00912965866
288     15349 |  122085 | 0.00944814966
289     15417 |  120471 | 0.00942316736
290     15483 |  121629 | 0.00972957546
291(293 rows)
292
293
294
295
296The power of SQL can be used for more complex cost computation:
297
298SELECT shortest_path('SELECT gid as id, node1_id as source, node2_id
299as target, coalesce(CASE WHEN gid IN
300 (1956, 123) THEN 12 ELSE weights1.weight END, 99999) as cost
301        FROM lines2 LEFT JOIN weights1 USING (gid)', 12, 78, false, false);
302
303
304
305
306GRAPH IMPORTATION
307
308The shortest_path function expects edges id and vertices id to be
309integer ranging from zero to the maximum number of edges or vertices
310(holes are allowed, but it will be less efficient).
311However, you may want to compute shortest path on a table which has
312vertex identifier stored as strings, like in the following example:
313
314SELECT * FROM graph1;
315
316 gid | source_id | target_id | edge_id
317-----+-----------+-----------+---------
318   0 | A         | B         |       
319   1 | A         | C         |       
320   2 | D         | A         |       
321   3 | B         | C         |       
322(4 rows)
323
324A function called "create_graph_tables" is available which will create
325two tables for edges and vertices. Example:
326
327SELECT create_graph_tables('graph1', 'varchar');
328
329The first argument is the name of the table containing the graph, and
330the second is the type of the source and target vertex identifiers.
331
332It will create the following tables:
333
334SELECT * FROM graph1_edges;
335
336 id | source | target | cost | reverse_cost
337----+--------+--------+------+--------------
338  1 |      1 |      2 |      |             
339  2 |      1 |      3 |      |             
340  3 |      4 |      1 |      |             
341  4 |      2 |      3 |      |             
342(4 rows)
343
344And
345
346 SELECT * FROM graph1_vertices;
347
348 id | geom_id
349----+---------
350  1 | A
351  2 | B
352  3 | C
353  4 | D
354(4 rows)
355
356
357Notice the function will also update the edge_id column of graph1:
358
359 gid | source_id | target_id | edge_id
360-----+-----------+-----------+---------
361   0 | A         | B         |       1
362   1 | A         | C         |       2
363   2 | D         | A         |       3
364   3 | B         | C         |       4
365(4 rows)
366
367
368Then, you can use the shortest_path function, as below:
369
370SELECT * FROM shortest_path('SELECT id, source, target, 1::float8 AS
371                                                cost FROM graph1_edges',
372                (SELECT id FROM graph1_vertices WHERE geom_id = 'A'),
373                (SELECT id FROM graph1_vertices WHERE geom_id = 'C'),
374                                false, false);
375
376The initial table has to contain the following columns:
377
378- gid anyelement: a unique identifier for each edge in you graph
379- source_id anyelement: an identifier for the starting vertex of the line
380- target_id anyelement: an identifier for the target vertex of the line
381  (if the graph is not directed, source or target has the same
382meaning)
383- edge_id integer: this column will be filled by the allocated edge
384identifier. All data there will be overwritten, and you need to create
385this column if it does not exists before.
386
387The function "drop_graph_tables" will simply delete the edges and
388vertices associated tables. Example:
389
390SELECT drop_graph_tables('graph1');
391
392
393POSTGIS GEOMETRIES IMPORTATION
394
395Some pl/pgsql functions are available for working with geographical
396data from PostGis tables.
397
398The table containing the graph has to contain the columns described in
399the previous section, and an additional geometric column called
400"the_geom" of type MULTILINESTRING. Only the first line in the
401multiline geomety will be handled. This restriction is because the
402shp2pgsql tool provided with postgis creates MULTILINESTRING geometric
403tables for shapefiles containing a set of lines. The importation
404should however handle more that only the first line in the multi line
405geometry (see TODO).
406
407Here's an example of such a table:
408
409SELECT gid, source_id, target_id, astext(the_geom) FROM graph2 LIMIT 4;
410
411 gid | source_id | target_id |                                           astext                                           
412-----+-----------+-----------+--------------------------------------------------------------------------------------------
413   0 |           |           | MULTILINESTRING((-0.357902298850575 51.2777105057471,-0.364822129560221 51.455488954023))
414   1 |           |           | MULTILINESTRING((-0.415775862068966 51.6386587816092,-0.478232130809596 51.5784636541729))
415   2 |           |           | MULTILINESTRING((-0.478232130809596 51.5784636541729,-0.382585141804099 51.5791468469515))
416   3 |           |           | MULTILINESTRING((-0.364822129560221 51.455488954023,-0.433824600199901 51.5244914246627))
417(4 rows)
418
419
420If the graph table does not contain identifier values in the source_id
421and target_id columns, a function is able to generate such ids, by
422extracting the starting and ending points of the line, and generating
423an unique id, for all points that are in a given distance. Example:
424
425SELECT assign_vertex_id('graph2', 0.1);
426
427SELECT gid, source_id, target_id, astext(the_geom) FROM graph2 LIMIT 4;
428
429 gid | source_id | target_id |                                           astext                                           
430-----+-----------+-----------+--------------------------------------------------------------------------------------------
431   0 |         1 |         2 | MULTILINESTRING((-0.357902298850575 51.2777105057471,-0.364822129560221 51.455488954023))
432   1 |         3 |         3 | MULTILINESTRING((-0.415775862068966 51.6386587816092,-0.478232130809596 51.5784636541729))
433   2 |         3 |         3 | MULTILINESTRING((-0.478232130809596 51.5784636541729,-0.382585141804099 51.5791468469515))
434   3 |         2 |         2 | MULTILINESTRING((-0.364822129560221 51.455488954023,-0.433824600199901 51.5244914246627))
435
436
437Now that the source_id and target_id are filled, the function
438create_graph_tables() can be used to create the edges
439and vertices tables (see above for the detailed description of
440create_graph_tables):
441
442SELECT create_graph_tables('graph2', 'int4');
443
444Here's the content of the edges table:
445
446SELECT * FROM graph2_edges LIMIT 3;
447
448 id | source | target | cost | reverse_cost
449----+--------+--------+------+--------------
450  1 |      1 |      2 |      |             
451  2 |      3 |      3 |      |             
452  4 |      2 |      2 |      |             
453(3 rows)
454
455We can see that it contains NULL values for the cost column.
456
457The function update_cost_from_distance can update the cost column with
458the distance of the lines contained in the geometry table, attached to
459each edge:
460
461SELECT update_cost_from_distance('graph2');
462
463The costs are now:
464
465SELECT * FROM graph2_edges LIMIT 3;
466
467 id | source | target |       cost        | reverse_cost
468----+--------+--------+-------------------+--------------
469  1 |      1 |      2 | 0.230081516048264 |             
470  2 |      3 |      3 | 0.446760794328524 |             
471  4 |      2 |      2 | 0.174348470878483 |
472
473
474Now, all is set up correctly for using the shortest_path() on these
475data:
476
477SELECT * FROM shortest_path('SELECT id, source, target, cost FROM graph2_edges',
478                             1, 2, false, false);
479
480 vertex_id | edge_id | cost
481-----------+---------+------
482         1 |       1 |    0
483         2 |      -1 |    0
484
485An additional function shortest_path_as_geometry() can be used to
486retrieve the result as a set of rows containing the geometry
487identifier and the geometry itself:
488
489SELECT gid, astext(the_geom) FROM shortest_path_as_geometry('graph2', 1, 2);
490
491 gid |                                           astext                                           
492-----+--------------------------------------------------------------------------------------------
493   0 | MULTILINESTRING((-0.357902298850575 51.2777105057471,-0.364822129560221 51.455488954023))
494  22 | MULTILINESTRING((-0.417298850574714 51.3371070574713,-0.408546467391305 51.3885360617191))
495(2 rows)
496
497
498MAPSERVER INTEGRATION
499
500The function shortest_path_as_geometry() can be used inside mapserver
501to draw shortest path directly, as in the following example:
502
503
504LAYER
505    NAME "europe2"
506    TYPE LINE
507
508    STATUS DEFAULT
509    CONNECTIONTYPE postgis
510        CONNECTION "user=postgres host=localhost dbname=geo"
511        DATA "the_geom from (SELECT the_geom, gid from
512          shortest_path_as_geometry('bahnlinien_europa_polyline', 2629, 10171)) as
513          foo using unique gid using srid=-1"
514
515    TEMPLATE "t"
516    CLASS
517      NAME "0"
518      STYLE
519        SYMBOL "circle"
520        SIZE 10
521        COLOR 50 50 100
522      END
523    END
524END
525
526Notice however, that this function will be called at each map
527display, computing the shortest path every time.
528
529A better approach would be to generate the shortest path in a
530temporary table.
531
532
533LIMITATION / TODO
534
535Usage of the Boost graph library can certainly be optimised. Help from
536Boost/STL experts is welcomed.
537
538Might not work on very large datasets due to memory
539requirements. (Tested with sucess on a 8 million edges table).
540
541LICENCE
542
543Most features are available under GPL.
544Some Boost extesions are available under Boost license (see LICENSE_1_0.txt)
545
546AUTHORS
547
548Anton A. Patrushev <anton@orkney.co.jp>
549Mario H. Basa <mbasa@orkney.co.jp>
550
551Dijkstra part was made by
552Sylvain Pasche <sylvain.pasche@camptocamp.com>
Note: See TracBrowser for help on using the browser.