void do_pgr_maximum_cardinality_matching( pgr_basic_edge_t *data_edges, size_t total_tuples, bool directed, pgr_basic_edge_t **return_tuples, size_t *return_count, char** log_msg, char** notice_msg, char **err_msg) { std::ostringstream log; std::ostringstream notice; std::ostringstream err; try { std::vector<pgr_basic_edge_t> matched_vertices; if (directed) { pgrouting::flow::PgrCardinalityGraph< pgrouting::BasicDirectedGraph> G; G.create_max_cardinality_graph(data_edges, total_tuples); std::vector<int64_t> mate_map(boost::num_vertices(G.boost_graph)); G.maximum_cardinality_matching(mate_map); G.get_matched_vertices(matched_vertices, mate_map); } else { pgrouting::flow::PgrCardinalityGraph< pgrouting::BasicUndirectedGraph> G; G.create_max_cardinality_graph(data_edges, total_tuples); std::vector<int64_t> mate_map(boost::num_vertices(G.boost_graph)); G.maximum_cardinality_matching(mate_map); G.get_matched_vertices(matched_vertices, mate_map); } (*return_tuples) = pgr_alloc(matched_vertices.size(), (*return_tuples)); for (size_t i = 0; i < matched_vertices.size(); ++i) { (*return_tuples)[i] = matched_vertices[i]; } *return_count = matched_vertices.size(); *log_msg = log.str().empty()? *log_msg : pgr_msg(log.str().c_str()); *notice_msg = notice.str().empty()? *notice_msg : pgr_msg(notice.str().c_str()); } catch (AssertFailedException &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch (std::exception &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch(...) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } }
void do_pgr_MY_FUNCTION_NAME( MY_EDGE_TYPE *data_edges, size_t total_edges, int64_t start_vid, int64_t end_vid, bool directed, bool only_cost, MY_RETURN_VALUE_TYPE **return_tuples, size_t *return_count, char ** log_msg, char ** notice_msg, char ** err_msg) { std::ostringstream log; std::ostringstream err; std::ostringstream notice; try { pgassert(!(*log_msg)); pgassert(!(*notice_msg)); pgassert(!(*err_msg)); pgassert(!(*return_tuples)); pgassert(*return_count == 0); pgassert(total_edges != 0); graphType gType = directed? DIRECTED: UNDIRECTED; Path path; if (directed) { log << "Working with directed Graph\n"; pgrouting::DirectedGraph digraph(gType); digraph.insert_edges(data_edges, total_edges); path = pgr_MY_FUNCTION_NAME(digraph, start_vid, end_vid, only_cost); } else { log << "Working with Undirected Graph\n"; pgrouting::UndirectedGraph undigraph(gType); undigraph.insert_edges(data_edges, total_edges); path = pgr_MY_FUNCTION_NAME( undigraph, start_vid, end_vid, only_cost); } auto count = path.size(); if (count == 0) { (*return_tuples) = NULL; (*return_count) = 0; notice << "No paths found between start_vid and end_vid vertices"; return; } (*return_tuples) = pgr_alloc(count, (*return_tuples)); size_t sequence = 0; path.generate_postgres_data(return_tuples, sequence); (*return_count) = sequence; pgassert(*err_msg == NULL); *log_msg = log.str().empty()? *log_msg : pgr_msg(log.str().c_str()); *notice_msg = notice.str().empty()? *notice_msg : pgr_msg(notice.str().c_str()); } catch (AssertFailedException &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch (std::exception &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch(...) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } }
void do_pgr_max_flow( pgr_edge_t *data_edges, size_t total_tuples, int64_t *source_vertices, size_t size_source_verticesArr, int64_t *sink_vertices, size_t size_sink_verticesArr, char *algorithm, bool only_flow, pgr_flow_t **return_tuples, size_t *return_count, char** log_msg, char** notice_msg, char **err_msg) { std::ostringstream log; std::ostringstream notice; std::ostringstream err; try { pgassert(data_edges); pgassert(source_vertices); pgassert(sink_vertices); pgrouting::graph::PgrFlowGraph<pgrouting::FlowGraph> G; std::set<int64_t> set_source_vertices; std::set<int64_t> set_sink_vertices; for (size_t i = 0; i < size_source_verticesArr; ++i) { set_source_vertices.insert(source_vertices[i]); } for (size_t i = 0; i < size_sink_verticesArr; ++i) { set_sink_vertices.insert(sink_vertices[i]); } std::set<int64_t> vertices(set_source_vertices); vertices.insert(set_sink_vertices.begin(), set_sink_vertices.end()); if (vertices.size() != (set_source_vertices.size() + set_sink_vertices.size())) { *err_msg = pgr_msg("A source found as sink"); // TODO(vicky) return as hint the sources that are also sinks return; } G.create_flow_graph(data_edges, total_tuples, set_source_vertices, set_sink_vertices, algorithm); int64_t max_flow; if (strcmp(algorithm, "push_relabel") == 0) { max_flow = G.push_relabel(); } else if (strcmp(algorithm, "edmonds_karp") == 0) { max_flow = G.edmonds_karp(); } else if (strcmp(algorithm, "boykov_kolmogorov") == 0) { max_flow = G.boykov_kolmogorov(); } else { log << "Unspecified algorithm!\n"; *err_msg = pgr_msg(log.str().c_str()); (*return_tuples) = NULL; (*return_count) = 0; return; } std::vector<pgr_flow_t> flow_edges; if (only_flow) { pgr_flow_t edge; edge.edge = -1; edge.source = -1; edge.target = -1; edge.flow = max_flow; edge.residual_capacity = -1; flow_edges.push_back(edge); } else { G.get_flow_edges(flow_edges); } (*return_tuples) = pgr_alloc(flow_edges.size(), (*return_tuples)); for (size_t i = 0; i < flow_edges.size(); ++i) { (*return_tuples)[i] = flow_edges[i]; } *return_count = flow_edges.size(); *log_msg = log.str().empty()? *log_msg : pgr_msg(log.str().c_str()); *notice_msg = notice.str().empty()? *notice_msg : pgr_msg(notice.str().c_str()); } catch (AssertFailedException &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch (std::exception &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch(...) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } }
void do_pgr_connectedComponents( pgr_edge_t *data_edges, size_t total_edges, pgr_components_rt **return_tuples, size_t *return_count, char ** log_msg, char ** notice_msg, char ** err_msg) { std::ostringstream log; std::ostringstream err; std::ostringstream notice; try { pgassert(!(*log_msg)); pgassert(!(*notice_msg)); pgassert(!(*err_msg)); pgassert(!(*return_tuples)); pgassert(*return_count == 0); pgassert(total_edges != 0); graphType gType = UNDIRECTED; std::vector<pgr_components_rt> results; log << "Working with Undirected Graph\n"; pgrouting::ComponentsUndiGraph undigraph(gType); undigraph.insert_edges(data_edges, total_edges); results = pgr_connectedComponents( undigraph); auto count = results.size(); if (count == 0) { (*return_tuples) = NULL; (*return_count) = 0; notice << "No paths found between start_vid and end_vid vertices"; return; } (*return_tuples) = pgr_alloc(count, (*return_tuples)); for (size_t i = 0; i < count; i++) { *((*return_tuples) + i) = results[i]; } (*return_count) = count; pgassert(*err_msg == NULL); *log_msg = log.str().empty()? *log_msg : pgr_msg(log.str().c_str()); *notice_msg = notice.str().empty()? *notice_msg : pgr_msg(notice.str().c_str()); } catch (AssertFailedException &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch (std::exception &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch(...) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } }
// CREATE OR REPLACE FUNCTION pgr_dijkstra( // sql text, // start_vids anyarray, // end_vids anyarray, // directed boolean default true, void do_pgr_many_to_many_dijkstra( pgr_edge_t *data_edges, size_t total_edges, int64_t *start_vidsArr, size_t size_start_vidsArr, int64_t *end_vidsArr, size_t size_end_vidsArr, bool directed, bool only_cost, bool normal, General_path_element_t **return_tuples, size_t *return_count, char ** log_msg, char ** notice_msg, char ** err_msg) { std::ostringstream log; std::ostringstream err; std::ostringstream notice; try { pgassert(total_edges != 0); pgassert(!(*log_msg)); pgassert(!(*notice_msg)); pgassert(!(*err_msg)); pgassert(!(*return_tuples)); pgassert(*return_count == 0); graphType gType = directed? DIRECTED: UNDIRECTED; log << "Inserting vertices into a c++ vector structure"; std::vector<int64_t> start_vertices(start_vidsArr, start_vidsArr + size_start_vidsArr); std::vector< int64_t > end_vertices(end_vidsArr, end_vidsArr + size_end_vidsArr); std::deque< Path >paths; if (directed) { log << "\nWorking with directed Graph"; pgrouting::DirectedGraph digraph(gType); digraph.insert_edges(data_edges, total_edges); paths = pgr_dijkstra( digraph, start_vertices, end_vertices, only_cost, normal); } else { log << "\nWorking with Undirected Graph"; pgrouting::UndirectedGraph undigraph(gType); undigraph.insert_edges(data_edges, total_edges); paths = pgr_dijkstra( undigraph, start_vertices, end_vertices, only_cost, normal); } size_t count(0); count = count_tuples(paths); if (count == 0) { (*return_tuples) = NULL; (*return_count) = 0; notice << "No paths found"; *log_msg = pgr_msg(notice.str().c_str()); return; } (*return_tuples) = pgr_alloc(count, (*return_tuples)); log << "\nConverting a set of paths into the tuples"; (*return_count) = (collapse_paths(return_tuples, paths)); *log_msg = log.str().empty()? *log_msg : pgr_msg(log.str().c_str()); *notice_msg = notice.str().empty()? *notice_msg : pgr_msg(notice.str().c_str()); } catch (AssertFailedException &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch (std::exception &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch(...) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } }
void do_pgr_withPoints( 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_pidsArr, size_t size_start_pidsArr, int64_t *end_pidsArr, size_t size_end_pidsArr, char driving_side, bool details, bool directed, bool only_cost, bool normal, General_path_element_t **return_tuples, size_t *return_count, char** log_msg, char** notice_msg, char** err_msg) { std::ostringstream log; std::ostringstream notice; std::ostringstream err; try { pgassert(!(*log_msg)); pgassert(!(*notice_msg)); pgassert(!(*err_msg)); pgassert(!(*return_tuples)); pgassert((*return_count) == 0); pgassert(edges || edges_of_points); pgassert(points_p); pgassert(start_pidsArr); pgassert(end_pidsArr); std::vector< Point_on_edge_t > points(points_p, points_p + total_points); if (!normal) { for (auto &point : points) { if (point.side == 'r') { point.side = 'l'; } else if (point.side == 'l') { point.side = 'r'; } point.fraction = 1 - point.fraction; } if (driving_side == 'r') { driving_side = 'l'; } else if (driving_side == 'l') { driving_side = 'r'; } } int errcode = check_points(points, log); if (errcode) { *log_msg = strdup(log.str().c_str()); err << "Unexpected point(s) with same pid" << " but different edge/fraction/side combination found."; *err_msg = pgr_msg(err.str().c_str()); return; } std::vector< pgr_edge_t > edges_to_modify( edges_of_points, edges_of_points + total_edges_of_points); std::vector< pgr_edge_t > new_edges; create_new_edges( points, edges_to_modify, driving_side, new_edges, log); std::vector<int64_t> start_vertices(start_pidsArr, start_pidsArr + size_start_pidsArr); std::vector< int64_t > end_vertices(end_pidsArr, end_pidsArr + size_end_pidsArr); auto vertices(pgrouting::extract_vertices(edges, total_edges)); vertices = pgrouting::extract_vertices(vertices, new_edges); graphType gType = directed? DIRECTED: UNDIRECTED; std::deque< Path > paths; if (directed) { log << "Working with directed Graph\n"; pgrouting::DirectedGraph digraph(vertices, gType); digraph.insert_edges(edges, total_edges); digraph.insert_edges(new_edges); paths = pgr_dijkstra( digraph, start_vertices, end_vertices, only_cost, normal); } else { log << "Working with Undirected Graph\n"; pgrouting::UndirectedGraph undigraph(vertices, gType); undigraph.insert_edges(edges, total_edges); undigraph.insert_edges(new_edges); paths = pgr_dijkstra( undigraph, start_vertices, end_vertices, only_cost, normal); } if (!details) { for (auto &path : paths) { eliminate_details(path, edges_to_modify); } } /* * order paths based on the start_pid, end_pid */ std::sort(paths.begin(), paths.end(), [](const Path &a, const Path &b) -> bool { if (b.start_id() != a.start_id()) { return a.start_id() < b.start_id(); } return a.end_id() < b.end_id(); }); size_t count(0); count = count_tuples(paths); if (count == 0) { (*return_tuples) = NULL; (*return_count) = 0; #if 0 log << "No paths found"; *err_msg = pgr_msg(log.str().c_str()); #endif return; } (*return_tuples) = pgr_alloc(count, (*return_tuples)); log << "Converting a set of paths into the tuples\n"; (*return_count) = (collapse_paths(return_tuples, paths)); *log_msg = log.str().empty()? *log_msg : pgr_msg(log.str().c_str()); *notice_msg = notice.str().empty()? *notice_msg : pgr_msg(notice.str().c_str()); } catch (AssertFailedException &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch (std::exception &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch(...) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } }
void do_pgr_dijkstraVia( pgr_edge_t* data_edges, size_t total_edges, int64_t* via_vidsArr, size_t size_via_vidsArr, bool directed, bool strict, bool U_turn_on_edge, Routes_t** return_tuples, size_t* return_count, char** log_msg, char** notice_msg, char** err_msg) { std::ostringstream log; std::ostringstream err; std::ostringstream notice; try { pgassert(total_edges != 0); pgassert(!(*log_msg)); pgassert(!(*notice_msg)); pgassert(!(*err_msg)); pgassert(!(*return_tuples)); pgassert(*return_count == 0); graphType gType = directed? DIRECTED: UNDIRECTED; std::deque< Path >paths; log << "\nInserting vertices into a c++ vector structure"; std::vector< int64_t > via_vertices( via_vidsArr, via_vidsArr + size_via_vidsArr); if (directed) { log << "\nWorking with directed Graph"; pgrouting::DirectedGraph digraph(gType); digraph.insert_edges(data_edges, total_edges); pgr_dijkstraViaVertex( digraph, via_vertices, paths, strict, U_turn_on_edge, log); } else { log << "\nWorking with Undirected Graph"; pgrouting::UndirectedGraph undigraph(gType); undigraph.insert_edges(data_edges, total_edges); pgr_dijkstraViaVertex( undigraph, via_vertices, paths, strict, U_turn_on_edge, log); } size_t count(count_tuples(paths)); if (count == 0) { (*return_tuples) = NULL; (*return_count) = 0; notice << "No paths found"; *log_msg = pgr_msg(notice.str().c_str()); return; } // get the space required to store all the paths (*return_tuples) = pgr_alloc(count, (*return_tuples)); log << "\nConverting a set of paths into the tuples"; (*return_count) = (get_route(return_tuples, paths)); (*return_tuples)[count - 1].edge = -2; *log_msg = log.str().empty()? *log_msg : pgr_msg(log.str().c_str()); *notice_msg = notice.str().empty()? *notice_msg : pgr_msg(notice.str().c_str()); } catch (AssertFailedException &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch (std::exception &except) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << except.what(); *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } catch(...) { (*return_tuples) = pgr_free(*return_tuples); (*return_count) = 0; err << "Caught unknown exception!"; *err_msg = pgr_msg(err.str().c_str()); *log_msg = pgr_msg(log.str().c_str()); } }