PGROUTING  3.2
contractGraph_driver.cpp
Go to the documentation of this file.
1 /*PGR-GNU*****************************************************************
2 File: contractGraph_driver.cpp
3 
4 Generated with Template by:
5 Copyright (c) 2015 pgRouting developers
7 
8 Function's developer:
9 Copyright (c) 2016 Rohith Reddy
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 
31 
32 #include <string.h>
33 #include <sstream>
34 #include <deque>
35 #include <vector>
36 #include <algorithm>
37 
40 
42 #include "cpp_common/pgr_alloc.hpp"
43 
44 namespace {
45 
50 template <typename G>
53  for (auto v : boost::make_iterator_range(boost::vertices(graph.graph))) {
54  if (graph[v].has_contracted_vertices()) {
55  vids += graph[v].id;
56  }
57  }
58  return vids;
59 }
60 
65 template <typename G>
66 std::vector<typename G::E> get_shortcuts(const G& graph) {
67  using E = typename G::E;
68  Identifiers<E> eids;
69  for (auto e : boost::make_iterator_range(boost::edges(graph.graph))) {
70  if (graph[e].id < 0) {
71  eids += e;
72  pgassert(!graph[e].contracted_vertices().empty());
73  } else {
74  pgassert(graph[e].contracted_vertices().empty());
75  }
76  }
77  std::vector<E> o_eids(eids.begin(), eids.end());
78  std::sort(o_eids.begin(), o_eids.end(),
79  [&](E lhs, E rhs) {return -graph[lhs].id < -graph[rhs].id;});
80  return o_eids;
81 }
82 
83 
84 template <typename G>
86  G &graph,
87  const std::vector< pgr_edge_t > &edges,
88  const std::vector< int64_t > &forbidden_vertices,
89  const std::vector< int64_t > &contraction_order,
90  int64_t max_cycles) {
91  graph.insert_edges(edges);
92  Identifiers<typename G::V> forbid_vertices;
93  for (const auto &vertex : forbidden_vertices) {
94  if (graph.has_vertex(vertex)) {
95  forbid_vertices += graph.get_V(vertex);
96  }
97  }
98 
99  /*
100  * Function call to get the contracted graph.
101  */
103  Contract result(
104  graph,
105  forbid_vertices,
106  contraction_order,
107  max_cycles);
108 }
109 
110 template <typename G>
112  G &graph,
113  contracted_rt **return_tuples,
114  size_t *count) {
115  auto modified_vertices(get_modified_vertices(graph));
116  auto shortcut_edges(get_shortcuts(graph));
117 
118  (*count) = modified_vertices.size() + shortcut_edges.size();
119  (*return_tuples) = pgr_alloc((*count), (*return_tuples));
120  size_t sequence = 0;
121 
122  for (const auto id : modified_vertices) {
123  auto v = graph.get_V(id);
124  int64_t* contracted_vertices = NULL;
125  auto vids = graph[v].contracted_vertices();
126 
127  contracted_vertices = pgr_alloc(vids.size(), contracted_vertices);
128 
129  int count = 0;
130  for (const auto id : vids) {
131  contracted_vertices[count++] = id;
132  }
133  (*return_tuples)[sequence] = {
134  id,
135  const_cast<char*>("v"),
136  -1, -1, -1.00,
137  contracted_vertices,
138  count};
139 
140  ++sequence;
141  }
142 
143  int64_t eid = 0;
144  for (auto e : shortcut_edges) {
145  auto edge = graph[e];
146  int64_t* contracted_vertices = NULL;
147 
148  const auto vids(edge.contracted_vertices());
149  pgassert(!vids.empty());
150 
151  contracted_vertices = pgr_alloc(vids.size(), contracted_vertices);
152  int count = 0;
153  for (const auto vid : vids) {
154  contracted_vertices[count++] = vid;
155  }
156  (*return_tuples)[sequence] = {
157  --eid,
158  const_cast<char*>("e"),
160  contracted_vertices, count};
161  ++sequence;
162  }
163 }
164 
165 } // namespace
166 
167 
168 
169 /************************************************************
170  edges_sql TEXT,
171  contraction_order BIGINT[],
172  forbidden_vertices BIGINT[] DEFAULT ARRAY[]::BIGINT[],
173  max_cycles integer DEFAULT 1,
174  directed BOOLEAN DEFAULT true
175  ***********************************************************/
176 void
178  pgr_edge_t *data_edges,
179  size_t total_edges,
180  int64_t *forbidden_vertices,
181  size_t size_forbidden_vertices,
182  int64_t *contraction_order,
183  size_t size_contraction_order,
184  int64_t max_cycles,
185  bool directed,
186  contracted_rt **return_tuples,
187  size_t *return_count,
188  char **log_msg,
189  char **notice_msg,
190  char **err_msg) {
191  std::ostringstream log;
192  std::ostringstream notice;
193  std::ostringstream err;
194  try {
195  pgassert(total_edges != 0);
196  pgassert(size_contraction_order != 0);
197  pgassert(max_cycles != 0);
198  pgassert(!(*log_msg));
199  pgassert(!(*notice_msg));
200  pgassert(!(*err_msg));
201  pgassert(!(*return_tuples));
202  pgassert(*return_count == 0);
203 
204  /*
205  * Converting to C++ structures
206  */
207  std::vector<pgr_edge_t> edges(data_edges, data_edges + total_edges);
208  std::vector<int64_t> forbid(
209  forbidden_vertices,
210  forbidden_vertices + size_forbidden_vertices);
211  std::vector<int64_t> ordering(
212  contraction_order,
213  contraction_order + size_contraction_order);
214 
215  for (const auto kind : ordering) {
216  if (!pgrouting::contraction::is_valid_contraction(static_cast<int>(kind))) {
217  *err_msg = pgr_msg("Invalid contraction type found");
218  log << "Contraction type " << kind << " not valid";
219  *log_msg = pgr_msg(log.str().c_str());
220  return;
221  }
222  }
223 
224 
225  graphType gType = directed? DIRECTED: UNDIRECTED;
226  if (directed) {
228  DirectedGraph digraph(gType);
229 
230  process_contraction(digraph, edges, forbid, ordering,
231  max_cycles);
232 
234  digraph,
235  return_tuples,
236  return_count);
237  } else {
239  UndirectedGraph undigraph(gType);
240  process_contraction(undigraph, edges, forbid, ordering,
241  max_cycles);
242 
244  undigraph,
245  return_tuples,
246  return_count);
247  }
248 
249  pgassert(err.str().empty());
250  *log_msg = log.str().empty()?
251  *log_msg :
252  pgr_msg(log.str().c_str());
253  *notice_msg = notice.str().empty()?
254  *notice_msg :
255  pgr_msg(notice.str().c_str());
256  } catch (AssertFailedException &except) {
257  (*return_tuples) = pgr_free(*return_tuples);
258  (*return_count) = 0;
259  err << except.what();
260  *err_msg = pgr_msg(err.str().c_str());
261  *log_msg = pgr_msg(log.str().c_str());
262  } catch (std::exception &except) {
263  (*return_tuples) = pgr_free(*return_tuples);
264  (*return_count) = 0;
265  err << except.what();
266  *err_msg = pgr_msg(err.str().c_str());
267  *log_msg = pgr_msg(log.str().c_str());
268  } catch(...) {
269  (*return_tuples) = pgr_free(*return_tuples);
270  (*return_count) = 0;
271  err << "Caught unknown exception!";
272  *err_msg = pgr_msg(err.str().c_str());
273  *log_msg = pgr_msg(log.str().c_str());
274  }
275 }
do_pgr_contractGraph
void do_pgr_contractGraph(pgr_edge_t *data_edges, size_t total_edges, int64_t *forbidden_vertices, size_t size_forbidden_vertices, int64_t *contraction_order, size_t size_contraction_order, int64_t max_cycles, bool directed, contracted_rt **return_tuples, size_t *return_count, char **log_msg, char **notice_msg, char **err_msg)
Definition: contractGraph_driver.cpp:177
pgr_alloc
T * pgr_alloc(std::size_t size, T *ptr)
allocates memory
Definition: pgr_alloc.hpp:66
edge::cost
float8 cost
Definition: trsp.h:45
contractGraph_driver.h
edge::target
int64 target
Definition: trsp.h:44
pgrouting::UndirectedGraph
graph::Pgr_base_graph< boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, Basic_vertex, Basic_edge >, Basic_vertex, Basic_edge > UndirectedGraph
Definition: pgr_base_graph.hpp:186
pgr_edge_t
Definition: pgr_edge_t.h:37
pgr_msg
char * pgr_msg(const std::string &msg)
Definition: pgr_alloc.cpp:30
AssertFailedException::what
virtual const char * what() const
Definition: pgr_assert.cpp:67
pgrouting::graph::CHDirectedGraph
Pgr_contractionGraph< boost::adjacency_list< boost::listS, boost::vecS, boost::bidirectionalS, CH_vertex, CH_edge > > CHDirectedGraph
Definition: ch_graphs.hpp:56
pgr_contract.hpp
edge
Definition: trsp.h:41
anonymous_namespace{contractGraph_driver.cpp}::get_modified_vertices
Identifiers< int64_t > get_modified_vertices(const G &graph)
vertices with at least one contracted vertex
Definition: contractGraph_driver.cpp:51
pgassert
#define pgassert(expr)
Uses the standard assert syntax.
Definition: pgr_assert.h:94
pgrouting::graph::CHUndirectedGraph
Pgr_contractionGraph< boost::adjacency_list< boost::listS, boost::vecS, boost::undirectedS, CH_vertex, CH_edge > > CHUndirectedGraph
Definition: ch_graphs.hpp:51
UNDIRECTED
@ UNDIRECTED
Definition: graph_enum.h:30
pgr_alloc.hpp
ch_graphs.hpp
Identifiers::begin
const_iterator begin() const
Definition: identifiers.hpp:81
pgrouting::alphashape::E
boost::graph_traits< BG >::edge_descriptor E
Definition: pgr_alphaShape.h:57
anonymous_namespace{contractGraph_driver.cpp}::get_shortcuts
std::vector< typename G::E > get_shortcuts(const G &graph)
vertices with at least one contracted vertex
Definition: contractGraph_driver.cpp:66
anonymous_namespace{contractGraph_driver.cpp}::process_contraction
void process_contraction(G &graph, const std::vector< pgr_edge_t > &edges, const std::vector< int64_t > &forbidden_vertices, const std::vector< int64_t > &contraction_order, int64_t max_cycles)
Definition: contractGraph_driver.cpp:85
contracted_rt
Definition: contracted_rt.h:40
edge::source
int64 source
Definition: trsp.h:43
graphType
graphType
Definition: graph_enum.h:30
DIRECTED
@ DIRECTED
Definition: graph_enum.h:30
pgrouting::DirectedGraph
graph::Pgr_base_graph< boost::adjacency_list< boost::vecS, boost::vecS, boost::bidirectionalS, Basic_vertex, Basic_edge >, Basic_vertex, Basic_edge > DirectedGraph
Definition: pgr_base_graph.hpp:192
Identifiers::end
const_iterator end() const
Definition: identifiers.hpp:82
pgrouting::alphashape::G
graph::Pgr_base_graph< BG, XY_vertex, Basic_edge > G
Definition: pgr_alphaShape.h:56
pgrouting::contraction::Pgr_contract
Definition: pgr_contract.hpp:49
pgr_free
T * pgr_free(T *ptr)
Definition: pgr_alloc.hpp:77
get_postgres_result
void get_postgres_result(std::vector< Line_graph_rt > edge_result, Line_graph_rt **return_tuples, size_t &sequence)
Definition: lineGraph_driver.cpp:46
pgrouting::contraction::is_valid_contraction
bool is_valid_contraction(int number)
Definition: pgr_contract.cpp:35
identifiers.hpp
Identifiers< int64_t >
AssertFailedException
Extends std::exception and is the exception that we throw if an assert fails.
Definition: pgr_assert.h:139