pgRouting  2.2
pgRouting extends the PostGIS / PostgreSQL geospatial database to provide geospatial routing functionality.
 All Classes Functions Variables Pages
many_to_one_withPoints_driver.cpp
1 /*PGR-GNU*****************************************************************
2 File: one_to_many_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 
42 #include "./pgr_dijkstra.hpp"
43 #include "./pgr_withPoints.hpp"
44 #include "./many_to_one_withPoints_driver.h"
45 extern "C" {
46 #include "./../../common/src/pgr_types.h"
47 }
48 #include "./../../common/src/memory_func.hpp"
49 
50 // #define DEBUG
51 
52 // CREATE OR REPLACE FUNCTION pgr_withPoint(
53 // edges_sql TEXT,
54 // points_sql TEXT,
55 // start_pid ANYARRAY,
56 // end_pid BIGINT,
57 // directed BOOLEAN DEFAULT true
58 
59 
60 int
61 do_pgr_many_to_one_withPoints(
62  pgr_edge_t *edges, size_t total_edges,
63  Point_on_edge_t *points_p, size_t total_points,
64  pgr_edge_t *edges_of_points, size_t total_edges_of_points,
65  int64_t *start_pidsArr, size_t size_start_pidsArr,
66  int64_t end_vid,
67  char driving_side,
68  bool details,
69  bool directed,
70  bool only_cost,
71  General_path_element_t **return_tuples, size_t *return_count,
72  char ** err_msg){
73  std::ostringstream log;
74  try {
75  std::vector< Point_on_edge_t >
76  points(points_p, points_p + total_points);
77 
78  int errcode = check_points(points, log);
79  if (errcode) {
80  /* Point(s) with same pid but different edge/fraction/side combination found */
81  *err_msg = strdup(log.str().c_str());
82  return errcode;
83  }
84 
85  std::vector< pgr_edge_t >
86  edges_to_modify(edges_of_points, edges_of_points + total_edges_of_points);
87 
88  std::vector< pgr_edge_t > new_edges;
89 
90  create_new_edges(
91  points,
92  edges_to_modify,
93  driving_side,
94  new_edges);
95 
96 
97  std::set< int64_t > s_start_vertices(start_pidsArr, start_pidsArr + size_start_pidsArr);
98  std::vector< int64_t > start_vertices(s_start_vertices.begin(), s_start_vertices.end());
99 
100  graphType gType = directed? DIRECTED: UNDIRECTED;
101  const auto initial_size = total_edges;
102 
103  std::deque< Path > paths;
104 
105 
106  if (directed) {
107  log << "Working with directed Graph\n";
108  Pgr_base_graph< DirectedGraph > digraph(gType, initial_size);
109  digraph.graph_insert_data(edges, total_edges);
110  digraph.graph_insert_data(new_edges);
111  pgr_dijkstra(digraph, paths, start_vertices, end_vid, only_cost);
112  } else {
113  log << "Working with Undirected Graph\n";
114  Pgr_base_graph< UndirectedGraph > undigraph(gType, initial_size);
115  undigraph.graph_insert_data(edges, total_edges);
116  undigraph.graph_insert_data(new_edges);
117  pgr_dijkstra(undigraph, paths, start_vertices, end_vid, only_cost);
118  }
119 
120 #if 0
121  for (auto &path :paths) {
122  adjust_pids(points, path);
123  }
124 #endif
125  if (!details) {
126  for (auto &path :paths) {
127  eliminate_details(path, edges_to_modify);
128  }
129  }
130 
131  /*
132  * order paths based on the start_pid
133  */
134  std::sort(paths.begin(), paths.end(), [](const Path &a,const Path &b) {
135  return a.start_id() < b.start_id();
136  });
137 
138  size_t count(0);
139  count = count_tuples(paths);
140 
141 
142  if (count == 0) {
143  (*return_tuples) = NULL;
144  (*return_count) = 0;
145  log <<
146  "No paths found between Starting and any of the Ending vertices\n";
147  *err_msg = strdup(log.str().c_str());
148  return 0;
149  }
150 
151  (*return_tuples) = get_memory(count, (*return_tuples));
152  log << "Converting a set of paths into the tuples\n";
153  (*return_count) = (collapse_paths(return_tuples, paths));
154 
155 #ifndef DEBUG
156  {
157  std::ostringstream log;
158  log << "OK";
159  *err_msg = strdup(log.str().c_str());
160  }
161 
162 #else
163  *err_msg = strdup(log.str().c_str());
164 #endif
165  return 0;
166  } catch ( ... ) {
167  log << "Caught unknown expection!\n";
168  *err_msg = strdup(log.str().c_str());
169  return 1000;
170  }
171  return 0;
172 }
173