PGROUTING  2.6-dev
drivedist_driver.cpp
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: boost_interface_drivedist.cpp
3 
4 Copyright (c) 2015 Celia Virginia Vergara Castillo
5 vicky_vergara@hotmail.com
6 
7 ------
8 
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 
23  ********************************************************************PGR-GNU*/
24 
26 
27 #include <sstream>
28 #include <deque>
29 #include <vector>
30 
32 
33 #include "cpp_common/pgr_alloc.hpp"
34 #include "cpp_common/pgr_assert.h"
35 
36 #undef WITH_TIME
37 #ifdef WITH_TIME
38 #include <ctime>
39 #include <chrono>
40 
41 static
42 void
43 start_timing(
44  std::time_t &start_t,
45  std::chrono::steady_clock::time_point &begin_elapsed,
46  clock_t &begin) {
47  begin = clock();
48  start_t = std::time(NULL);
49  begin_elapsed = std::chrono::steady_clock::now();
50 }
51 
52 static
53 void
54 end_timing(
55  const std::time_t start_t,
56  std::chrono::steady_clock::time_point& begin_elapsed,
57  clock_t &begin,
58  std::ostringstream &log) {
59  clock_t end = clock();
60  double elapsed_secs =
61  static_cast<double>(end - begin)
62  / static_cast<double>(CLOCKS_PER_SEC);
63 
64  std::time_t end_t = std::time(NULL);
65  std::chrono::steady_clock::time_point end_elapsed =
66  std::chrono::steady_clock::now();
67 
68  typedef std::chrono::duration<int, std::milli> millisecs_t;
69  millisecs_t duration = std::chrono::duration_cast<millisecs_t>(
70  end_elapsed - begin_elapsed);
71 
72  log << "Execution started at: " << std::ctime(&start_t);
73  log << "Execution ended at: " << std::ctime(&end_t);
74  log << "Elapsed time: "
75  << static_cast<double>(duration.count())/static_cast<double>(1000)
76  << " Seconds.\n";
77  log << "User CPU time: -> " << elapsed_secs << " seconds\n";
78 }
79 #endif
80 
81 void
83  pgr_edge_t *data_edges, size_t total_edges,
84  int64_t *start_vertex, size_t s_len,
85  double distance,
86  bool directedFlag,
87  bool equiCostFlag,
88  General_path_element_t **return_tuples, size_t *return_count,
89  char **log_msg,
90  char **notice_msg,
91  char **err_msg) {
92  std::ostringstream log;
93  std::ostringstream err;
94  std::ostringstream notice;
95 
96  try {
97  pgassert(total_edges != 0);
98  pgassert(!(*log_msg));
99  pgassert(!(*notice_msg));
100  pgassert(!(*err_msg));
101  pgassert(!(*return_tuples));
102  pgassert(*return_count == 0);
103  pgassert((*return_tuples) == NULL);
104 
105  graphType gType = directedFlag? DIRECTED: UNDIRECTED;
106 
107  std::deque<Path> paths;
108  std::vector<int64_t> start_vertices(start_vertex, start_vertex + s_len);
109 
110  auto vertices(pgrouting::extract_vertices(data_edges, total_edges));
111 
112 #ifdef WITH_TIME
113  clock_t begin;
114  std::time_t start_t;
115  std::chrono::steady_clock::time_point begin_elapsed;
116 #endif
117 
118  if (directedFlag) {
119 #ifdef WITH_TIME
120  start_timing(start_t, begin_elapsed, begin);
121  log << "*********Creating graph at time: " << std::ctime(&start_t)
122  << "\n";
123 #endif
124  pgrouting::DirectedGraph digraph(vertices, gType);
125 #ifdef WITH_TIME
126  end_timing(start_t, begin_elapsed, begin, log);
127 #endif
128 
129 #ifdef WITH_TIME
130  start_timing(start_t, begin_elapsed, begin);
131  log << "********Inserting edges at time: " << std::ctime(&start_t)
132  << "\n";
133 #endif
134  digraph.insert_edges(data_edges, total_edges, true);
135 #ifdef WITH_TIME
136  end_timing(start_t, begin_elapsed, begin, log);
137 #endif
138 
139 #ifdef WITH_TIME
140  start_timing(start_t, begin_elapsed, begin);
141  log << "*******Calling the C++ call to pgr_drivingDistance: "
142  << std::ctime(&start_t) << "\n";
143 #endif
144  paths = pgr_drivingDistance(
145  digraph, start_vertices, distance, equiCostFlag, log);
146 #ifdef WITH_TIME
147  end_timing(start_t, begin_elapsed, begin, log);
148 #endif
149  } else {
150 #ifdef WITH_TIME
151  start_timing(start_t, begin_elapsed, begin);
152  log << "******Creating graph at time: " << std::ctime(&start_t)
153  << "\n";
154 #endif
155  pgrouting::UndirectedGraph undigraph(vertices, gType);
156 #ifdef WITH_TIME
157  end_timing(start_t, begin_elapsed, begin, log);
158 #endif
159 
160 #ifdef WITH_TIME
161  start_timing(start_t, begin_elapsed, begin);
162  log << "*******Inserting edges at time: " << std::ctime(&start_t)
163  << "\n";
164 #endif
165  undigraph.insert_edges(data_edges, total_edges, true);
166 #ifdef WITH_TIME
167  end_timing(start_t, begin_elapsed, begin, log);
168 #endif
169 
170 #ifdef WITH_TIME
171  start_timing(start_t, begin_elapsed, begin);
172  log << "*******Calling the C++ call to pgr_drivingDistance: "
173  << std::ctime(&start_t) << "\n";
174 #endif
175  paths = pgr_drivingDistance(
176  undigraph, start_vertices, distance, equiCostFlag, log);
177 #ifdef WITH_TIME
178  end_timing(start_t, begin_elapsed, begin, log);
179 #endif
180  }
181 
182  size_t count(count_tuples(paths));
183 
184 
185  if (count == 0) {
186  log << "\nNo return values were found";
187  *notice_msg = pgr_msg(log.str().c_str());
188  return;
189  }
190  *return_tuples = pgr_alloc(count, (*return_tuples));
191  auto trueCount(collapse_paths(return_tuples, paths));
192  *return_count = trueCount;
193 
194 
195  *log_msg = log.str().empty()?
196  *log_msg :
197  pgr_msg(log.str().c_str());
198  *notice_msg = notice.str().empty()?
199  *notice_msg :
200  pgr_msg(notice.str().c_str());
201  } catch (AssertFailedException &except) {
202  (*return_tuples) = pgr_free(*return_tuples);
203  (*return_count) = 0;
204  err << except.what();
205  *err_msg = pgr_msg(err.str().c_str());
206  *log_msg = pgr_msg(log.str().c_str());
207  } catch (std::exception &except) {
208  (*return_tuples) = pgr_free(*return_tuples);
209  (*return_count) = 0;
210  err << except.what();
211  *err_msg = pgr_msg(err.str().c_str());
212  *log_msg = pgr_msg(log.str().c_str());
213  } catch( ... ) {
214  (*return_tuples) = pgr_free(*return_tuples);
215  (*return_count) = 0;
216  err << "Caught unknown exception!";
217  *err_msg = pgr_msg(err.str().c_str());
218  *log_msg = pgr_msg(log.str().c_str());
219  }
220 }
Extends std::exception and is the exception that we throw if an assert fails.
Definition: pgr_assert.h:126
void insert_edges(const T *edges, int64_t count)
Inserts count edges of type T into the graph.
void do_pgr_driving_many_to_dist(pgr_edge_t *data_edges, size_t total_edges, int64_t *start_vertex, size_t s_len, double distance, bool directedFlag, bool equiCostFlag, General_path_element_t **return_tuples, size_t *return_count, char **log_msg, char **notice_msg, char **err_msg)
size_t collapse_paths(General_path_element_t **ret_path, const std::deque< Path > &paths)
T * pgr_free(T *ptr)
Definition: pgr_alloc.hpp:77
#define pgassert(expr)
Uses the standard assert syntax.
Definition: pgr_assert.h:81
std::deque< Path > pgr_drivingDistance(G &graph, std::vector< int64_t > start_vids, double distance, bool equicost, std::ostringstream &log)
std::vector< Basic_vertex > extract_vertices(std::vector< Basic_vertex > vertices, const std::vector< pgr_edge_t > data_edges)
char * pgr_msg(const std::string &msg)
Definition: pgr_alloc.cpp:30
size_t count_tuples(const std::deque< Path > &paths)
T * pgr_alloc(std::size_t size, T *ptr)
allocates memory
Definition: pgr_alloc.hpp:66
Assertions Handling.
virtual const char * what() const
Definition: pgr_assert.cpp:53
graphType
Definition: graph_enum.h:30