示例#1
0
void
do_pgr_one_to_one_dijkstra(
        pgr_edge_t  *data_edges,
        size_t total_tuples,
        int64_t start_vid,
        int64_t end_vid,
        bool directed,
        bool only_cost,
        General_path_element_t **return_tuples,
        size_t *return_count,
        char ** err_msg) {
  std::ostringstream log;
  try {
      graphType gType = directed? DIRECTED: UNDIRECTED;

      Path path;

      if (directed) {
          log << "Working with directed Graph\n";
          pgrouting::DirectedGraph digraph(gType);
          digraph.graph_insert_data(data_edges, total_tuples);
          pgr_dijkstra(digraph, path, start_vid, end_vid, only_cost);
      } else {
          log << "Working with Undirected Graph\n";
          pgrouting::UndirectedGraph undigraph(gType);
          undigraph.graph_insert_data(data_edges, total_tuples);
          pgr_dijkstra(undigraph, path, start_vid, end_vid, only_cost);
      }

      size_t count(0);

      count = path.size();

      if (count == 0) {
          (*return_tuples) = NULL;
          (*return_count) = 0;
          log <<
              "No paths found between Starting and any of the Ending vertices\n";
          *err_msg = strdup(log.str().c_str());
          return;
      }

      (*return_tuples) = pgr_alloc(count, (*return_tuples));
      size_t sequence = 0;
      path.generate_postgres_data(return_tuples, sequence);
      (*return_count) = sequence;

#ifndef DEBUG
      *err_msg = strdup("OK");
#else
      *err_msg = strdup(log.str().c_str());
#endif

      return;
  } catch ( ... ) {
      log << "Caught unknown exception!\n";
      *err_msg = strdup(log.str().c_str());
      return;
  }
}
示例#2
0
void
pgr_dijkstraVia(
        G &graph,
        const std::vector< int64_t > via_vertices,
        std::deque< Path > &paths,
        bool strict,
        bool U_turn_on_edge,
        std::ostringstream &log) {
    if (via_vertices.size() == 0) {
        return;
    }

    paths.clear();
    int64_t prev_vertex = via_vertices[0];
    Path path;

    int64_t i = 0;
    for (const auto &vertex : via_vertices) {
        if (i == 0) {
            prev_vertex = vertex; ++i;
            continue;
        }

        // Delete U Turn edges only valid for paths that are not the first path
        if (!U_turn_on_edge && i > 1) {
            /*
             * Can only delete if there was a path,
             * that is at least one edge size
             */
            if (path.size() > 1) {
                /*
                 * Delete from the graph the last edge if its outgoing also
                 * edge to be removed = second to last edge path[i].edge;
                 */
                int64_t edge_to_be_removed = path[path.size() - 2].edge;
                int64_t last_vertex_of_path = prev_vertex;

                // and the current vertex is not a dead end
                if (graph.out_degree(last_vertex_of_path) > 1) {
                    log << "\ndeparting from " << last_vertex_of_path
                        << " deleting edge " << edge_to_be_removed << "\n";
                    graph.disconnect_out_going_edge(
                            last_vertex_of_path,
                            edge_to_be_removed);
                }
            }
        }

        log << "\nfrom " << prev_vertex << " to " << vertex;
        path = pgr_dijkstra(graph, prev_vertex, vertex);

        if (!U_turn_on_edge && i > 1) {
            graph.restore_graph();
            if (path.empty()) {
                /*
                 *  no path was found with the deleted edge
                 *  try with the edge back in the graph
                 */
                log << "\nEmpty so again from "
                    << prev_vertex << " to " << vertex;
                path = pgr_dijkstra(graph, prev_vertex, vertex);
            }
        }

        if (strict && path.empty()) {
            paths.clear();
            return;
        }
        paths.push_back(path);

        /*
         * got to the next
         */
        prev_vertex = vertex; ++i;
    }
}
示例#3
0
void
do_pgr_one_to_many_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_vid,
        int64_t *end_pidsArr, size_t size_end_pidsArr,
        char driving_side,
        bool details,
        bool directed,
        bool only_cost,
        General_path_element_t **return_tuples, size_t *return_count,
        char ** log_msg,
        char ** err_msg) {
    std::ostringstream log;
    std::ostringstream err;
    try {
        pgassert(!(*return_tuples));
        pgassert((*return_count) == 0);
        pgassert(!(*log_msg));
        pgassert(!(*err_msg));

        /*
         * DOCUMENT:
         *   - Points are treated as the same point when the pid is the same
         *   therefore when two points have the same pid, but different edge/fraction
         *   an error is generated.
         */
        std::vector< Point_on_edge_t >
            points(points_p, points_p + total_points);

        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 = strdup(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;

        log << "driving_side" << driving_side << "\n";
        create_new_edges(
                points,
                edges_to_modify,
                driving_side,
                new_edges);

        log << "Inserting points into a c++ vector structure\n";
        /*
         * Eliminating duplicates
         * & ordering the points
         */
        std::set< int64_t > s_end_vertices(end_pidsArr, end_pidsArr + size_end_pidsArr);

        std::vector< int64_t > end_vertices(s_end_vertices.begin(), s_end_vertices.end());

        log << "start_vid" << start_vid << "\n";
        log << "end_vertices";

        for (const auto &vid : end_vertices) {
            log << vid << "\n";
        }

        graphType gType = directed? DIRECTED: UNDIRECTED;

        std::deque< Path > paths;


        if (directed) {
            log << "Working with directed Graph\n";
            pgrouting::DirectedGraph digraph(
                    pgrouting::extract_vertices(
                        pgrouting::extract_vertices(edges, total_edges),
                        new_edges),
                    gType);
            digraph.graph_insert_data(edges, total_edges);
            digraph.graph_insert_data(new_edges);
            pgr_dijkstra(digraph, paths, start_vid, end_vertices, only_cost);
        } else {
            log << "Working with Undirected Graph\n";
            auto vertices(pgrouting::extract_vertices(edges, total_edges));
            vertices = pgrouting::extract_vertices(vertices, new_edges);
            pgrouting::UndirectedGraph undigraph(vertices, gType);
            vertices.clear();
            undigraph.graph_insert_data(edges, total_edges);
            undigraph.graph_insert_data(new_edges);
            pgr_dijkstra(undigraph, paths, start_vid, end_vertices, only_cost);
        }

        if (!details) {
            for (auto &path : paths) {
                eliminate_details(path, edges_to_modify);
            }
        }
        /*
         * order paths based on the end_pid
         */
        std::sort(paths.begin(), paths.end(), [](const Path &a, const Path &b) {
                return a.end_id() < b.end_id();
                });

        size_t count(0);
        count = count_tuples(paths);


        if (count == 0) {
            (*return_tuples) = NULL;
            (*return_count) = 0;
            log <<
                "No paths found between Starting and any of the Ending vertices\n";
            *log_msg = strdup(log.str().c_str());
            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 = strdup(log.str().c_str());
        pgassert(!(*err_msg));
        return;
    } catch (AssertFailedException &except) {
        if (*return_tuples) free(*return_tuples);
        (*return_count) = 0;
        *log_msg = strdup(log.str().c_str());
        err << except.what() << "\n";
        *err_msg = strdup(err.str().c_str());
    } catch (std::exception& except) {
        if (*return_tuples) free(*return_tuples);
        (*return_count) = 0;
        *log_msg = strdup(log.str().c_str());
        err << except.what() << "\n";
        *err_msg = strdup(err.str().c_str());
    } catch(...) {
        if (*return_tuples) free(*return_tuples);
        (*return_count) = 0;
        *log_msg = strdup(log.str().c_str());
        err << "Caught unknown exception!\n";
        *err_msg = strdup(err.str().c_str());
    }
}
示例#4
0
// 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());
    }
}
示例#5
0
/************************************************************
  MY_QUERY_LINE1
 ***********************************************************/
void
do_pgr_MY_FUNCTION_NAME(
        MY_EDGE_TYPE  *data_edges, size_t total_edges,
        int64_t start_vid,
        int64_t  *end_vidsArr, size_t size_end_vidsArr,
        bool directed,
        MY_RETURN_VALUE_TYPE **return_tuples,
        size_t *return_count,
        char ** log_msg,
        char ** err_msg){
    std::ostringstream err;
    std::ostringstream log;
    try {
        
        pgassert(!(*log_msg));
        pgassert(!(*err_msg));
        pgassert(!(*return_tuples));
        pgassert(*return_count == 0);
        pgassert(total_edges != 0);

        /* depending on the functionality some tests can be done here
         * For example */
        if (total_edges <= 1) {
            err << "Required: more than one edges\n";
            (*return_tuples) = NULL;
            (*return_count) = 0;
            *err_msg = strdup(err.str().c_str());
            return;
        }

        graphType gType = directed? DIRECTED: UNDIRECTED;

        std::deque< Path >paths;
        // samll logs
        log << "Inserting vertices into a c++ vector structure\n";
        std::vector< int64_t > end_vertices(end_vidsArr, end_vidsArr + size_end_vidsArr);
        std::sort(end_vertices.begin(),end_vertices.end());
#ifndef NDEBUG
        // big logs with cycles wrap them so on release they wont consume time
        log << "end vids: ";
        for (const auto &vid : end_vertices) log << vid << ",";
        log << "\nstart vid:" << start_vid << "\n";
#endif

        if (directed) {
            // very detailed logging
            log << "Working with directed Graph\n";
            pgRouting::DirectedGraph digraph(gType);
            log << "Working with directed Graph 1 \n";
            digraph.graph_insert_data(data_edges, total_edges);

#ifndef NDEBUG
            // a graph log is a big log
            log << digraph;
#endif
            
            log << "Working with directed Graph 2\n";
            pgr_dijkstra(digraph, paths, start_vid, end_vertices, false);
            log << "Working with directed Graph 3\n";
        } else {
            // maybe the code is working so cleaner logging
            log << "Working with Undirected Graph\n";
            pgRouting::UndirectedGraph undigraph(gType);
            undigraph.graph_insert_data(data_edges, total_edges);
            pgr_dijkstra(undigraph, paths, start_vid, end_vertices, false);
        }

        // use auto when possible
        auto count(count_tuples(paths));

        if (count == 0) {
            (*return_tuples) = NULL;
            (*return_count) = 0;
            log << 
                "No paths found between Starting and any of the Ending vertices\n";
            *log_msg = strdup(log.str().c_str());
            return;
        }

        // get the space required to store all the paths
        (*return_tuples) = pgr_alloc(count, (*return_tuples));
        log << "Converting a set of paths into the tuples\n";
        (*return_count) = (collapse_paths(return_tuples, paths));

        *err_msg = NULL;
        *log_msg = strdup(log.str().c_str());

    } catch (AssertFailedException &exept) {
        if (*return_tuples) free(*return_tuples);
        (*return_count) = 0;
        err << exept.what() << "\n";
        *err_msg = strdup(log.str().c_str());
        *log_msg = strdup(log.str().c_str());
    } catch (std::exception& exept) {
        if (*return_tuples) free(*return_tuples);
        (*return_count) = 0;
        err << exept.what() << "\n";
        *err_msg = strdup(log.str().c_str());
        *log_msg = strdup(log.str().c_str());
    } catch(...) {
        if (*return_tuples) free(*return_tuples);
        (*return_count) = 0;
        err << "Caught unknown exception!\n";
        *err_msg = strdup(log.str().c_str());
        *log_msg = strdup(log.str().c_str());
    }
}
示例#6
0
int
do_pgr_many_to_one_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_vid,
        char driving_side,
        bool details,
        bool directed,
        bool only_cost,
        General_path_element_t **return_tuples, size_t *return_count,
        char ** err_msg) {
    std::ostringstream log;
    try {
        std::vector< Point_on_edge_t >
            points(points_p, points_p + total_points);

        int errcode = check_points(points, log);
        if (errcode) {
            /* Point(s) with same pid but different edge/fraction/side combination found */
            *err_msg = strdup(log.str().c_str());
            return errcode;
        }

        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);


        std::set< int64_t > s_start_vertices(start_pidsArr, start_pidsArr + size_start_pidsArr);
        std::vector< int64_t > start_vertices(s_start_vertices.begin(), s_start_vertices.end());

        graphType gType = directed? DIRECTED: UNDIRECTED;

        std::deque< Path > paths;


        if (directed) {
            log << "Working with directed Graph\n";
            pgrouting::DirectedGraph digraph(gType);
            digraph.graph_insert_data(edges, total_edges);
            digraph.graph_insert_data(new_edges);
            pgr_dijkstra(digraph, paths, start_vertices, end_vid, only_cost);
        } else {
            log << "Working with Undirected Graph\n";
            pgrouting::UndirectedGraph undigraph(gType);
            undigraph.graph_insert_data(edges, total_edges);
            undigraph.graph_insert_data(new_edges);
            pgr_dijkstra(undigraph, paths, start_vertices, end_vid, only_cost);
        }

#if 0
        for (auto &path : paths) {
            adjust_pids(points, path);
        }
#endif
        if (!details) {
            for (auto &path : paths) {
                eliminate_details(path, edges_to_modify);
            }
        }

        /*
         * order paths based on the start_pid
         */
        std::sort(paths.begin(), paths.end(), [](const Path &a, const Path &b) {
                return a.start_id() < b.start_id();
                });

        size_t count(0);
        count = count_tuples(paths);


        if (count == 0) {
            (*return_tuples) = NULL;
            (*return_count) = 0;
            log <<
                "No paths found between Starting and any of the Ending vertices\n";
            *err_msg = strdup(log.str().c_str());
            return 0;
        }

        (*return_tuples) = pgr_alloc(count, (*return_tuples));
        log << "Converting a set of paths into the tuples\n";
        (*return_count) = (collapse_paths(return_tuples, paths));

#ifndef NDEBUG
        {
            std::ostringstream log;
            log << "OK";
            *err_msg = strdup(log.str().c_str());
        }

#else
        *err_msg = strdup(log.str().c_str());
#endif
        return 0;
    } catch ( ... ) {
        log << "Caught unknown exception!\n";
        *err_msg = strdup(log.str().c_str());
        return 1000;
    }
    return 0;
}
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());
    }
}