pgRouting
pgRouting extends the PostGIS / PostgreSQL geospatial database to provide geospatial routing functionality.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
withPoints_dd_driver.cpp
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: withPoints_driver.cpp
3 
4 Generated with Template by:
5 Copyright (c) 2015 pgRouting developers
6 Mail: project@pgrouting.org
7 
8 Function's developer:
9 Copyright (c) 2015 Celia Virginia Vergara Castillo
10 Mail:
11 
12 ------
13 
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18 
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23 
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 
28 ********************************************************************PGR-GNU*/
29 
30 
31 #if defined(__MINGW32__) || defined(_MSC_VER)
32 #include <winsock2.h>
33 #include <windows.h>
34 #ifdef open
35 #undef open
36 #endif
37 #endif
38 
39 #include <sstream>
40 #include <deque>
41 #include <vector>
42 #include <algorithm>
43 #include <set>
44 
45 #include "./../../dijkstra/src/pgr_dijkstra.hpp"
46 #include "./../../withPoints/src/pgr_withPoints.hpp"
47 #include "./withPoints_dd_driver.h"
48 
49 
50 #include "./../../common/src/pgr_types.h"
51 #include "./../../common/src/pgr_alloc.hpp"
52 
53 
54 /*******************************************************************************/
55 // CREATE OR REPLACE FUNCTION pgr_withPointsDD(
56 // edges_sql TEXT,
57 // points_sql TEXT,
58 // start_pids anyarray,
59 // distance FLOAT,
60 //
61 // driving_side CHAR -- DEFAULT 'b',
62 // details BOOLEAN -- DEFAULT false,
63 // directed BOOLEAN -- DEFAULT true,
64 // equicost BOOLEAN -- DEFAULT false,
65 
66 
67 int
69  pgr_edge_t *edges, size_t total_edges,
70  Point_on_edge_t *points_p, size_t total_points,
71  pgr_edge_t *edges_of_points, size_t total_edges_of_points,
72 
73  int64_t *start_pids_arr, size_t s_len,
74  double distance,
75 
76  bool directed,
77  char driving_side,
78  bool details,
79  bool equiCost,
80 
81  General_path_element_t **return_tuples, size_t *return_count,
82  char ** err_msg) {
83  std::ostringstream log;
84  try {
85  /*
86  * This is the original state
87  */
88  if (*err_msg) free(err_msg);
89  if (*return_tuples) free(return_tuples);
90  (*return_count) = 0;
91 
92  std::vector< Point_on_edge_t >
93  points(points_p, points_p + total_points);
94 
95  /*
96  * checking here is easier than on the C code
97  */
98  int errcode = check_points(points, log);
99  if (errcode) {
100  return errcode;
101  }
102 
103  std::vector< pgr_edge_t >
104  edges_to_modify(edges_of_points, edges_of_points + total_edges_of_points);
105 
106  std::vector< pgr_edge_t > new_edges;
108  points,
109  edges_to_modify,
110  driving_side,
111  new_edges,
112  log);
113 
114  std::set< int64_t > s_start_vids(start_pids_arr, start_pids_arr + s_len);
115  std::vector< int64_t > start_vids(s_start_vids.begin(), s_start_vids.end());
116 #if 0
117  std::set< int64_t > start_vids;
118 
119  for (const auto start_pid : start_pids) {
120  for (const auto point : points) {
121  if (point.pid == start_pid) {
122  start_vids.insert(point.vertex_id);
123  break;
124  }
125  }
126  }
127 #endif
128 
129 
130  graphType gType = directed? DIRECTED: UNDIRECTED;
131 
132  std::deque< Path >paths;
133 
134  if (directed) {
135  pgrouting::DirectedGraph digraph(gType);
136  digraph.graph_insert_data(edges, total_edges);
137  digraph.graph_insert_data(new_edges);
138  pgr_drivingDistance(digraph, paths, start_vids, distance, equiCost);
139  } else {
140  pgrouting::UndirectedGraph undigraph(gType);
141  undigraph.graph_insert_data(edges, total_edges);
142  undigraph.graph_insert_data(new_edges);
143  pgr_drivingDistance(undigraph, paths, start_vids, distance, equiCost);
144  }
145 
146  for (auto &path : paths) {
147  log << path;
148 
149  if (!details) {
150  eliminate_details_dd(path);
151  }
152  log << path;
153  std::sort(path.begin(), path.end(),
154  [](const Path_t &l, const Path_t &r)
155  {return l.node < r.node;});
156  std::stable_sort(path.begin(), path.end(),
157  [](const Path_t &l, const Path_t &r)
158  {return l.agg_cost < r.agg_cost;});
159  log << path;
160  }
161 
162  size_t count(count_tuples(paths));
163 
164 
165  if (count == 0) {
166  *err_msg = strdup("NOTICE: No return values was found");
167  return 0;
168  }
169  *return_tuples = pgr_alloc(count, (*return_tuples));
170  *return_count = collapse_paths(return_tuples, paths);
171 
172 #ifndef DEBUG
173  *err_msg = strdup("OK");
174 #else
175  *err_msg = strdup(log.str().c_str());
176 #endif
177  return 0;
178  } catch ( ... ) {
179  *err_msg = strdup("Caught unknown exception!");
180  return 1000;
181  }
182 }
183 
184 
185 // CREATE OR REPLACE FUNCTION pgr_withPointsDD(
186 // edges_sql TEXT,
187 // points_sql TEXT,
188 // start_pid BIGINT,
189 // end_pid BIGINT,
190 //
191 // driving_side CHAR -- DEFAULT 'b',
192 // details BOOLEAN -- DEFAULT false,
193 // directed BOOLEAN -- DEFAULT true,
194 // equicost BOOLEAN -- DEFAULT false,
195 
196 int
198  pgr_edge_t *edges, size_t total_edges,
199  Point_on_edge_t *points_p, size_t total_points,
200  pgr_edge_t *edges_of_points, size_t total_edges_of_points,
201 
202  int64_t start_vid,
203  double distance,
204 
205  char driving_side,
206  bool details,
207  bool directed,
208 
209  General_path_element_t **return_tuples,
210  size_t *return_count,
211  char ** err_msg) {
212  std::ostringstream log;
213  try {
214  /*
215  * This is the original state
216  */
217  if (*err_msg) free(err_msg);
218  if (*return_tuples) free(return_tuples);
219  (*return_count) = 0;
220 
221  std::vector< Point_on_edge_t >
222  points(points_p, points_p + total_points);
223 
224  /*
225  * checking here is easier than on the C code
226  */
227  int errcode = check_points(points, log);
228  if (errcode) {
229  return errcode;
230  }
231 
232 
233  std::vector< pgr_edge_t >
234  edges_to_modify(edges_of_points, edges_of_points + total_edges_of_points);
235 
236  std::vector< pgr_edge_t > new_edges;
238  points,
239  edges_to_modify,
240  driving_side,
241  new_edges,
242  log);
243 
244 #if 0
245  int64_t start_vid = 0;
246  for (const auto point : points) {
247  if (point.pid == start_pid) {
248  start_vid = point.vertex_id;
249  }
250  }
251 #endif
252 
253  graphType gType = directed? DIRECTED: UNDIRECTED;
254 
255  Path path;
256 
257  if (directed) {
258  log << "Working with directed Graph\n";
259  pgrouting::DirectedGraph digraph(gType);
260  digraph.graph_insert_data(edges, total_edges);
261  digraph.graph_insert_data(new_edges);
262  pgr_drivingDistance(digraph, path, start_vid, distance);
263  } else {
264  log << "Working with undirected Graph\n";
265  pgrouting::UndirectedGraph undigraph(gType);
266  undigraph.graph_insert_data(edges, total_edges);
267  undigraph.graph_insert_data(new_edges);
268  pgr_drivingDistance(undigraph, path, start_vid, distance);
269  }
270 
271 
272 #if 0
273  path.print_path(log);
274  adjust_pids(points, path);
275  path.print_path(log);
276 #endif
277 
278  if (!details) {
279  eliminate_details_dd(path);
280  }
281  std::sort(path.begin(), path.end(),
282  [](const Path_t &l, const Path_t &r)
283  {return l.node < r.node;});
284  std::stable_sort(path.begin(), path.end(),
285  [](const Path_t &l, const Path_t &r)
286  {return l.agg_cost < r.agg_cost;});
287 
288 
289  auto count(path.size());
290 
291  if (count == 0) {
292  return 0;
293  }
294 
295 
296  *return_tuples = NULL;
297  *return_tuples = pgr_alloc(count, (*return_tuples));
298 
299  size_t sequence = 0;
300  path.get_pg_dd_path(return_tuples, sequence);
301 
302  if (count != sequence) {
303  return 2;
304  }
305  (*return_count) = sequence;
306 
307 
308 #ifndef DEBUG
309  *err_msg = strdup("OK");
310 #else
311  *err_msg = strdup(log.str().c_str());
312 #endif
313  return 0;
314  } catch ( ... ) {
315  log << "Caught unknown exception!\n";
316  *err_msg = strdup(log.str().c_str());
317  }
318  return 1000;
319 }
int do_pgr_many_withPointsDD(pgr_edge_t *edges, size_t total_edges, Point_on_edge_t *points_p, size_t total_points, pgr_edge_t *edges_of_points, size_t total_edges_of_points, int64_t *start_pids_arr, size_t s_len, double distance, bool directed, char driving_side, bool details, bool equiCost, General_path_element_t **return_tuples, size_t *return_count, char **err_msg)
void get_pg_dd_path(General_path_element_t **ret_path, size_t &sequence) const
static void adjust_pids(const std::vector< Point_on_edge_t > &points, const int64_t &start_pid, const int64_t &end_pid, Path &path)
int do_pgr_withPointsDD(pgr_edge_t *edges, size_t total_edges, Point_on_edge_t *points_p, size_t total_points, pgr_edge_t *edges_of_points, size_t total_edges_of_points, int64_t start_vid, double distance, char driving_side, bool details, bool directed, General_path_element_t **return_tuples, size_t *return_count, char **err_msg)
int check_points(std::vector< Point_on_edge_t > &points, std::ostringstream &log)
int64_t node
Definition: pgr_types.h:83
pthIt end()
edge_astar_t * edges
Definition: BDATester.cpp:46
bool create_new_edges(std::vector< Point_on_edge_t > &points, const std::vector< pgr_edge_t > &edges, char driving_side, std::vector< pgr_edge_t > &new_edges)
graphType
Definition: pgr_types.h:192
void eliminate_details_dd(Path &path)
Definition: tsp.h:38
T * pgr_alloc(std::size_t size, T *ptr)
allocates memory
Definition: pgr_alloc.hpp:52
pthIt begin()
path_element_t * path
Definition: BDATester.cpp:49
void pgr_drivingDistance(G &graph, std::deque< Path > &paths, std::vector< int64_t > start_vids, double distance, bool equicost)
char * err_msg
Definition: BDATester.cpp:50
size_t size() const
double agg_cost
Definition: pgr_types.h:86
void graph_insert_data(const T *edges, int64_t count)
Inserts count edges of type T into the graph.