root/branches/workshop/FOSS4G2008/Docs/11_pgrouting.weighted.chapter

Revision 245, 4.8 KB (checked in by anton, 2 years ago)

Index creation added to the last chapter

Line 
1= Advanced usage of pgRouting shortest path search =
2
3An ordinary shortest path query with result usualy looks like this:
4
5{{{
6SELECT * FROM shortest_path_shooting_star(
7        'SELECT gid as id, source, target, length as cost, x1, y1, x2, y2, rule,
8        to_cost, reverse_cost FROM ways', 1955, 5787, true, true);
9       
10 vertex_id | edge_id |        cost         
11-----------+---------+---------------------
12      8134 |    1955 | 0.00952475464810279
13      5459 |    1956 |  0.0628075563112871
14      8137 |    1976 |  0.0812786367080268
15      5453 |     758 |  0.0421747270358272
16      5456 |    3366 |  0.0104935732514831
17     11086 |    3367 |   0.113400030221047
18      4416 |     306 |   0.111600379959229
19      4419 |     307 |  0.0880411972519595
20      4422 |    4880 |  0.0208599114366633
21      5101 |     612 |  0.0906859882381495
22      5102 |    5787 |    80089.8820919459
23(11 rows)
24}}}
25
26That is usually called SHORTEST path, which means that a length of an edge is
27its cost.
28
29== Costs can be anything ("Weighted costs") ==
30
31But in real networks we have different limitations or preferences for different
32road types for example. In other words, we want to calculate CHEAPEST path - a
33path with a minimal cost. There is no limitation in what we take as costs.
34
35When we convert data from OSM format using the osm2pgrouting tool, we get these
36two additional tables for road types and classes:
37{{{     
38\d classes
39                                                                       
40  id |   name   
41-----+------------
42   2 | cycleway
43   1 | highway
44   4 | junction
45   3 | tracktype
46}}}
47
48{{{
49\d types
50
51 id  | type_id |        name        |  cost
52-----+---------+--------------------+--------
53 201 |       2 | lane               |   1 
54 204 |       2 | opposite           |   1 
55 203 |       2 | opposite_lane      |   1 
56 202 |       2 | track              |   1 
57 117 |       1 | bridleway          |   1 
58 113 |       1 | bus_guideway       |   1 
59 118 |       1 | byway              |   1 
60 115 |       1 | cicleway           |   1 
61 116 |       1 | footway            |   1 
62 108 |       1 | living_street      |   1 
63 101 |       1 | motorway           |   0.2 
64 103 |       1 | motorway_junction  |   0.2 
65 102 |       1 | motorway_link      |   0.2 
66 114 |       1 | path               |   100 
67 111 |       1 | pedestrian         |   100 
68 106 |       1 | primary            |   100 
69 107 |       1 | primary_link       |   100 
70 107 |       1 | residential        |   100 
71 100 |       1 | road               |   0.7 
72 100 |       1 | unclassified       |   0.7 
73 106 |       1 | secondary          |   10 
74 109 |       1 | service            |   10 
75 112 |       1 | services           |   10 
76 119 |       1 | steps              |   10 
77 107 |       1 | tertiary           |   10 
78 110 |       1 | track              |   10 
79 104 |       1 | trunk              |   10 
80 105 |       1 | trunk_link         |   10 
81 401 |       4 | roundabout         |   10 
82 301 |       3 | grade1             |   15 
83 302 |       3 | grade2             |   15 
84 303 |       3 | grade3             |   15 
85 304 |       3 | grade4             |   15 
86 305 |       3 | grade5             |   15 
87}}}
88
89Road class is linked with the ways table by class_id field. Cost values for
90classes table are assigned arbitrary.
91
92{{{
93UPDATE classes SET cost=15 WHERE id>300;
94}}}
95
96For better performance it is worth to create an index on id field of classes table.
97{{{
98CREATE INDEX class_idx ON ways (id);
99}}}
100
101The idea behind these two tables is to specify a factor to be multiplied with
102the cost of each link (usually length):
103
104{{{
105SELECT * FROM shortest_path_shooting_star(
106        'SELECT gid as id, class_id, source, target, length*c.cost as cost,
107                x1, y1, x2, y2, rule, to_cost, reverse_cost*c.cost as reverse_cost
108        FROM ways w, classes c
109        WHERE class_id=c.id', 1955, 5787, true, true);
110 vertex_id | edge_id |        cost         
111-----------+---------+---------------------
112      8134 |    1955 | 0.00666732825367195
113      5459 |    1956 |   0.043965289417901
114      8137 |    1992 |   0.126646230936747
115      5464 |     762 |   0.827868704808978
116      5467 |     763 |    0.16765902528648
117       ... |     ... |                 ...
118      9790 |    5785 | 0.00142107468268373
119      8548 |    5786 | 0.00066608685984761
120     16214 |    5787 |  0.0160179764183892
121(69 rows)
122}}}
123
124We can see that the shortest path result is completely different from the
125example before. We call this "weighted costs".
126
127Another example is to restrict access to roads of a certain type:
128{{{
129UPDATE classes SET cost=100000 WHERE name LIKE 'motorway%';
130}}}
131
132Through subqueries you can "mix" your costs as you like and this will change
133the results of your routing request immediately. Cost changes will affect the
134next shortest path search, and there is no need to rebuild your network.
Note: See TracBrowser for help on using the browser.