pgRouting  2.2
pgRouting extends the PostGIS / PostgreSQL geospatial database to provide geospatial routing functionality.
 All Classes Functions Variables Pages
withPoints_dd_driver.cpp
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 #ifdef __MINGW32__
32 #include <winsock2.h>
33 #include <windows.h>
34 #endif
35 
36 
37 #include <sstream>
38 #include <deque>
39 #include <vector>
40 #include <cassert>
41 #include "./../../dijkstra/src/pgr_dijkstra.hpp"
42 #include "./../../withPoints/src/pgr_withPoints.hpp"
43 #include "./withPoints_dd_driver.h"
44 
45 // #define DEBUG
46 
47 extern "C" {
48 #include "./../../common/src/pgr_types.h"
49 }
50 
51 #include "./../../common/src/memory_func.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
68 do_pgr_many_withPointsDD(
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  float8 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;
107  create_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  const size_t initial_size = total_edges;
132 
133  std::deque< Path >paths;
134 
135  if (directed) {
136  Pgr_base_graph< DirectedGraph > digraph(gType, initial_size);
137  digraph.graph_insert_data(edges, total_edges);
138  digraph.graph_insert_data(new_edges);
139  pgr_drivingDistance(digraph, paths, start_vids, distance, equiCost);
140  } else {
141  Pgr_base_graph< UndirectedGraph > undigraph(gType, initial_size);
142  undigraph.graph_insert_data(edges, total_edges);
143  undigraph.graph_insert_data(new_edges);
144  pgr_drivingDistance(undigraph, paths, start_vids, distance, equiCost);
145  }
146 
147  for (auto &path : paths) {
148  log << path;
149 
150  if (!details) {
151  eliminate_details_dd(path);
152  }
153  log << path;
154  std::sort(path.begin(), path.end(),
155  [](const Path_t &l, const Path_t &r)
156  {return l.node < r.node;});
157  std::stable_sort(path.begin(), path.end(),
158  [](const Path_t &l, const Path_t &r)
159  {return l.agg_cost < r.agg_cost;});
160  log << path;
161  }
162 
163  size_t count(count_tuples(paths));
164 
165 
166  if (count == 0) {
167  *err_msg = strdup("NOTICE: No return values was found");
168  return 0;
169  }
170  *return_tuples = get_memory(count, (*return_tuples));
171  *return_count = collapse_paths(return_tuples, paths);
172 
173 #ifndef DEBUG
174  *err_msg = strdup("OK");
175 #else
176  *err_msg = strdup(log.str().c_str());
177 #endif
178  return 0;
179 
180  } catch ( ... ) {
181  *err_msg = strdup("Caught unknown expection!");
182  return 1000;
183  }
184 
185 }
186 
187 
188 // CREATE OR REPLACE FUNCTION pgr_withPointsDD(
189 // edges_sql TEXT,
190 // points_sql TEXT,
191 // start_pid BIGINT,
192 // end_pid BIGINT,
193 //
194 // driving_side CHAR -- DEFAULT 'b',
195 // details BOOLEAN -- DEFAULT false,
196 // directed BOOLEAN -- DEFAULT true,
197 // equicost BOOLEAN -- DEFAULT false,
198 
199 int
200 do_pgr_withPointsDD(
201  pgr_edge_t *edges, size_t total_edges,
202  Point_on_edge_t *points_p, size_t total_points,
203  pgr_edge_t *edges_of_points, size_t total_edges_of_points,
204 
205  int64_t start_vid,
206  float8 distance,
207 
208  char driving_side,
209  bool details,
210  bool directed,
211 
212  General_path_element_t **return_tuples,
213  size_t *return_count,
214  char ** err_msg){
215  std::ostringstream log;
216  try {
217  /*
218  * This is the original state
219  */
220  if (*err_msg) free(err_msg);
221  if (*return_tuples) free(return_tuples);
222  (*return_count) = 0;
223 
224  std::vector< Point_on_edge_t >
225  points(points_p, points_p + total_points);
226 
227  /*
228  * checking here is easier than on the C code
229  */
230  int errcode = check_points(points, log);
231  if (errcode) {
232  return errcode;
233  }
234 
235 
236  std::vector< pgr_edge_t >
237  edges_to_modify(edges_of_points, edges_of_points + total_edges_of_points);
238 
239  std::vector< pgr_edge_t > new_edges;
240  create_new_edges(
241  points,
242  edges_to_modify,
243  driving_side,
244  new_edges,
245  log);
246 
247 #if 0
248  int64_t start_vid = 0;
249  for (const auto point : points) {
250  if (point.pid == start_pid) {
251  start_vid = point.vertex_id;
252  }
253  }
254 #endif
255 
256  graphType gType = directed? DIRECTED: UNDIRECTED;
257  const size_t initial_size = total_edges;
258 
259  Path path;
260 
261  if (directed) {
262  log << "Working with directed Graph\n";
263  Pgr_base_graph< DirectedGraph > digraph(gType, initial_size);
264  digraph.graph_insert_data(edges, total_edges);
265  digraph.graph_insert_data(new_edges);
266  pgr_drivingDistance(digraph, path, start_vid, distance);
267  } else {
268  log << "Working with undirected Graph\n";
269  Pgr_base_graph< UndirectedGraph > undigraph(gType, initial_size);
270  undigraph.graph_insert_data(edges, total_edges);
271  undigraph.graph_insert_data(new_edges);
272  pgr_drivingDistance(undigraph, path, start_vid, distance);
273  }
274 
275 
276 #if 0
277  path.print_path(log);
278  adjust_pids(points, path);
279  path.print_path(log);
280 #endif
281 
282  if (!details) {
283  eliminate_details_dd(path);
284  }
285  std::sort(path.begin(), path.end(),
286  [](const Path_t &l, const Path_t &r)
287  {return l.node < r.node;});
288  std::stable_sort(path.begin(), path.end(),
289  [](const Path_t &l, const Path_t &r)
290  {return l.agg_cost < r.agg_cost;});
291 
292 
293  auto count(path.size());
294 
295  if (count == 0) {
296  return 0;
297  }
298 
299 
300  *return_tuples = NULL;
301  *return_tuples = get_memory(count, (*return_tuples));
302 
303  size_t sequence = 0;
304  path.get_pg_dd_path(return_tuples, sequence);
305 
306  if (count != sequence) {
307  return 2;
308  }
309  (*return_count) = sequence;
310 
311 
312 #ifndef DEBUG
313  *err_msg = strdup("OK");
314 #else
315  *err_msg = strdup(log.str().c_str());
316 #endif
317  return 0;
318  } catch ( ... ) {
319  log << "Caught unknown expection!\n";
320  *err_msg = strdup(log.str().c_str());
321  }
322  return 1000;
323 }
Definition: tsp.h:34