1 /*PGR-GNU*****************************************************************
2 File: dijkstraViaVertex_driver.cpp
3 
4 Generated with Template by:
5 Copyright (c) 2015 pgRouting developers
6 
7 Function's developer:
8 Copyright (c) 2015 Celia Virginia Vergara Castillo
9 
10 ------
11 
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16 
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21 
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 
26  ********************************************************************PGR-GNU*/
27 
28 #include "drivers/dijkstra/dijkstraVia_driver.h"
29 
30 #include <sstream>
31 #include <deque>
32 #include <vector>
33 
34 #include "dijkstra/pgr_dijkstraVia.hpp"
35 
36 #include "cpp_common/pgr_alloc.hpp"
37 #include "cpp_common/pgr_assert.h"
38 
39 
40 static
41 void
get_path(int route_id,int path_id,const Path & path,Routes_t ** postgres_data,double & route_cost,size_t & sequence)42 get_path(
43         int route_id,
44         int path_id,
45         const Path &path,
46         Routes_t **postgres_data,
47         double &route_cost,
48         size_t &sequence) {
49     size_t i = 0;
50     for (const auto e : path) {
51         (*postgres_data)[sequence] = {
52             route_id,
53             path_id,
54             static_cast<int>(i),
55             path.start_id(),
56             path.end_id(),
57             e.node,
58             e.edge,
59             e.cost,
60             e.agg_cost,
61             route_cost};
62         route_cost += path[i].cost;
63         ++i;
64         ++sequence;
65     }
66 }
67 
68 
69 static
70 size_t
get_route(Routes_t ** ret_path,std::deque<Path> & paths)71 get_route(
72         Routes_t **ret_path,
73         std::deque< Path > &paths) {
74     size_t sequence = 0;
75     int path_id = 1;
76     int route_id = 1;
77     double route_cost = 0;  // routes_agg_cost
78     for (auto &p : paths) {
79         p.recalculate_agg_cost();
80     }
81     for (const Path &path : paths) {
82         if (path.size() > 0)
83             get_path(route_id, path_id, path, ret_path, route_cost, sequence);
84         ++path_id;
85     }
86     return sequence;
87 }
88 
89 void
do_pgr_dijkstraVia(pgr_edge_t * data_edges,size_t total_edges,int64_t * via_vidsArr,size_t size_via_vidsArr,bool directed,bool strict,bool U_turn_on_edge,Routes_t ** return_tuples,size_t * return_count,char ** log_msg,char ** notice_msg,char ** err_msg)90 do_pgr_dijkstraVia(
91         pgr_edge_t* data_edges,    size_t total_edges,
92         int64_t* via_vidsArr,     size_t size_via_vidsArr,
93         bool directed,
94         bool strict,
95         bool U_turn_on_edge,
96         Routes_t** return_tuples,   size_t* return_count,
97 
98         char** log_msg,
99         char** notice_msg,
100         char** err_msg) {
101     std::ostringstream log;
102     std::ostringstream err;
103     std::ostringstream notice;
104 
105     try {
106         pgassert(total_edges != 0);
107         pgassert(!(*log_msg));
108         pgassert(!(*notice_msg));
109         pgassert(!(*err_msg));
110         pgassert(!(*return_tuples));
111         pgassert(*return_count == 0);
112 
113         graphType gType = directed? DIRECTED: UNDIRECTED;
114 
115         std::deque< Path >paths;
116         log << "\nInserting vertices into a c++ vector structure";
117         std::vector< int64_t > via_vertices(
118                 via_vidsArr, via_vidsArr + size_via_vidsArr);
119 
120         if (directed) {
121             log << "\nWorking with directed Graph";
122             pgrouting::DirectedGraph digraph(gType);
123             digraph.insert_edges(data_edges, total_edges);
124             pgRouting::pgr_dijkstraVia(
125                     digraph,
126                     via_vertices,
127                     paths,
128                     strict,
129                     U_turn_on_edge,
130                     log);
131         } else {
132             log << "\nWorking with Undirected Graph";
133             pgrouting::UndirectedGraph undigraph(gType);
134             undigraph.insert_edges(data_edges, total_edges);
135             pgRouting::pgr_dijkstraVia(
136                     undigraph,
137                     via_vertices,
138                     paths,
139                     strict,
140                     U_turn_on_edge,
141                     log);
142         }
143 
144         size_t count(count_tuples(paths));
145 
146         if (count == 0) {
147             (*return_tuples) = NULL;
148             (*return_count) = 0;
149             notice <<
150                 "No paths found";
151             *log_msg = pgr_msg(notice.str().c_str());
152             return;
153         }
154 
155         // get the space required to store all the paths
156         (*return_tuples) = pgr_alloc(count, (*return_tuples));
157         log << "\nConverting a set of paths into the tuples";
158         (*return_count) = (get_route(return_tuples, paths));
159         (*return_tuples)[count - 1].edge = -2;
160 
161         *log_msg = log.str().empty()?
162             *log_msg :
163             pgr_msg(log.str().c_str());
164         *notice_msg = notice.str().empty()?
165             *notice_msg :
166             pgr_msg(notice.str().c_str());
167     } catch (AssertFailedException &except) {
168         (*return_tuples) = pgr_free(*return_tuples);
169         (*return_count) = 0;
170         err << except.what();
171         *err_msg = pgr_msg(err.str().c_str());
172         *log_msg = pgr_msg(log.str().c_str());
173     } catch (std::exception &except) {
174         (*return_tuples) = pgr_free(*return_tuples);
175         (*return_count) = 0;
176         err << except.what();
177         *err_msg = pgr_msg(err.str().c_str());
178         *log_msg = pgr_msg(log.str().c_str());
179     } catch(...) {
180         (*return_tuples) = pgr_free(*return_tuples);
181         (*return_count) = 0;
182         err << "Caught unknown exception!";
183         *err_msg = pgr_msg(err.str().c_str());
184         *log_msg = pgr_msg(log.str().c_str());
185     }
186 }
187 
188 
189