pgRouting

root/tags/release-1.0-beta/boost_drivedist.cpp

Revision 39, 4.6 kB (checked in by anton, 1 year ago)

1.0.0b tag added

Line 
1 /*
2  * Drivedist algorithm for PostgreSQL
3  *
4  * Copyright (c) 2006 Mario H. Basa, Orkney, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  */
21
22 #include <boost/config.hpp>
23 #include <iostream>
24 #include <fstream>
25
26 #include <boost/graph/graph_traits.hpp>
27 #include <boost/graph/adjacency_list.hpp>
28 #include <boost/graph/dijkstra_shortest_paths.hpp>
29
30 #include "drivedist.h"
31
32 using namespace std;
33 using namespace boost;
34
35
36 // Maximal number of nodes in the path (to avoid infinite loops)
37 #define MAX_NODES 1000000
38
39 struct Edge
40 {
41   int id;
42   float8 cost;
43 };
44
45 struct Vertex
46 {
47   int id;
48   int edge_id;
49 };
50
51 template <class G, class E>
52 static void
53 graph_add_edge(G &graph, int id, int source, int target, float8 cost)
54 {
55   E e;
56   bool inserted;
57  
58   if (cost < 0) // edges are not inserted in the graph if cost is negative
59     return;
60  
61   tie(e, inserted) = add_edge(source, target, graph);
62  
63   graph[e].cost = cost;
64   graph[e].id = id;
65
66   typedef typename graph_traits<G>::vertex_descriptor Vertex;
67   Vertex s = vertex(source, graph);
68   Vertex t = vertex(target, graph);
69   graph[s].id = source;
70   graph[t].id = target;
71   graph[s].edge_id = id;
72   graph[t].edge_id = id;
73
74 }
75
76 int
77 boost_dijkstra_dist(edge_t *edges, unsigned int count, int source_vertex_id,
78                     double rdistance, bool directed, bool has_reverse_cost,
79                     path_element_t **path, int *path_count, char **err_msg)
80 {
81   typedef adjacency_list < listS, vecS, undirectedS, Vertex, Edge > graph_t;
82   typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor;
83   typedef graph_traits < graph_t >::edge_descriptor edge_descriptor;
84
85   const unsigned int num_nodes = 1;
86  
87   graph_t graph( num_nodes );
88  
89   property_map<graph_t, edge_weight_t>::type weightmap =
90     get(edge_weight, graph);
91  
92   for (std::size_t j = 0; j < count; ++j)
93     {
94       graph_add_edge<graph_t, edge_descriptor>
95         (graph, edges[j].id, edges[j].source,
96          edges[j].target, edges[j].cost);     
97                                        
98       if (!directed || (directed && has_reverse_cost))
99         {
100           if (has_reverse_cost)
101             {
102               graph_add_edge<graph_t, edge_descriptor>
103                 (graph, edges[j].id, edges[j].target,
104                  edges[j].source, edges[j].reverse_cost);     
105             }
106           else
107             {
108               graph_add_edge<graph_t, edge_descriptor>
109                 (graph, edges[j].id, edges[j].target,
110                  edges[j].source, edges[j].cost);     
111             }
112         }
113     }
114
115   vertex_descriptor source_vertex = vertex( source_vertex_id, graph );
116  
117   std::vector<vertex_descriptor> predecessors(num_vertices(graph));
118   std::vector<float8> distances(num_vertices(graph));
119  
120   dijkstra_shortest_paths(graph, source_vertex,
121                           predecessor_map(&predecessors[0])
122                           .weight_map(get(&Edge::cost, graph))
123                           .distance_map(&distances[0]));
124
125  
126   graph_traits < graph_t >::vertex_iterator vi, vend;
127   vector<path_element> path_vector;
128   int j=0;
129  
130   for(tie(vi, vend) = vertices(graph); vi != vend; vi++) {
131                
132     if( (double)distances[*vi] <= rdistance ) {
133      
134       path_element pe;
135
136       graph_traits<graph_t>::vertex_descriptor s;
137
138       s = vertex(*vi, graph);
139
140       pe.vertex_id = graph[s].id;
141       pe.edge_id   = graph[s].edge_id;
142       pe.cost      = distances[*vi];
143        
144       path_vector.push_back( pe );
145     }   
146   }
147  
148   if( path_vector.size() == 0 ) {
149     *err_msg = "No path found";
150     return 0;         
151   }
152  
153   vector<path_element>::iterator itr;
154   *path = (path_element_t *) malloc( sizeof(path_element_t) *
155                                      (path_vector.size() + 1) );
156   *path_count = path_vector.size();
157  
158   for(j=0,itr=path_vector.begin();itr != path_vector.end();itr++,j++) {
159     path_element pe = *itr;
160     (*path)[j].vertex_id = pe.vertex_id;
161     (*path)[j].edge_id   = pe.edge_id;
162     (*path)[j].cost      = pe.cost;
163   }
164  
165   return EXIT_SUCCESS;
166 }
167
Note: See TracBrowser for help on using the browser.