Skip to content

Commit

Permalink
Merge branch 'vjeranc-partial_isochrones_backport_2.6.3' into partial…
Browse files Browse the repository at this point in the history
…_isochrones_backport_2.6.3
  • Loading branch information
EPajares committed Aug 24, 2020
2 parents f550512 + 10890ad commit d5343c8
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 66 deletions.
2 changes: 1 addition & 1 deletion include/drivers/isochrones/isochrones_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ extern "C" {
void do_pgr_many_to_isochrones(pgr_edge_t *edges, size_t total_edges,
int64_t *start_vertex, size_t s_len,
double *distances, size_t d_len,
bool remove_duplicates,
bool only_minimum_cover,
Isochrones_path_element_t **return_tuples,
size_t *return_count, char **log_msg,
char **notice_msg, char **err_msg);
Expand Down
4 changes: 2 additions & 2 deletions sql/isochrones/isochrones.sql
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ CREATE OR REPLACE FUNCTION pgr_isochrones(
edges_sql text,
start_vids bigint[],
distances float[],
remove_duplicates BOOLEAN DEFAULT TRUE,
only_minimum_cover BOOLEAN DEFAULT TRUE,
OUT seq integer,
OUT from_v bigint,
OUT edge bigint,
Expand All @@ -42,7 +42,7 @@ CREATE OR REPLACE FUNCTION pgr_isochrones(
edges_sql text,
start_vid bigint,
distances float[],
remove_duplicates BOOLEAN DEFAULT TRUE,
only_minimum_cover BOOLEAN DEFAULT TRUE,
OUT seq integer,
OUT from_v bigint,
OUT edge bigint,
Expand Down
78 changes: 17 additions & 61 deletions src/isochrones/isochrones_driver.cpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
/*PGR-GNU*****************************************************************
File: isochrones_driver.cpp
Copyright (c) 2020 Vjeran Crnjak
vjeran@crnjak.xyz
------
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
********************************************************************PGR-GNU*/

#include <algorithm>
Expand Down Expand Up @@ -147,56 +141,11 @@ void append_edge_result(const double &cost_at_node, const double &edge_cost,
}
}

bool is_partial_edge(const Isochrones_path_element_t &p) {
return p.start_perc != 0. || p.end_perc != 1.;
}

size_t find_min_full_edge(size_t r_i,
const std::vector<Isochrones_path_element_t> &v) {
size_t mn_idx = -1;
double min_cost = std::numeric_limits<double>::infinity();
for (size_t i = r_i; i < v.size(); ++i) {
auto &&p = v[i];
if (is_partial_edge(p)) {
continue;
}
// larger cost is at the node where the traveller arrives.
double mx = std::max(p.start_cost, p.end_cost);
if (mx < min_cost) {
mn_idx = i;
min_cost = mx;
}
}
return mn_idx;
}

void erase_duplicates(size_t r_i, std::vector<Isochrones_path_element_t> &v) {
size_t mn_idx = find_min_full_edge(r_i, v);
if (mn_idx == -1) {
// if no full edges, then there is no need to remove anything.
return;
}
size_t i = r_i;
v.erase(
// returns an iterator
std::remove_if(
// removing elements starting from r_i
v.begin() + r_i, v.end(),
[&i, &mn_idx](const Isochrones_path_element_t &p) {
if (is_partial_edge(p)) {
// do not remove partial edges.
i++;
return false;
}
return mn_idx != i++;
}),
v.end());
}

std::vector<Isochrones_path_element_t>
do_many_dijkstras(pgr_edge_t *data_edges, size_t total_edges,
std::vector<int64_t> start_vertices,
std::vector<double> distance_limits, bool remove_duplicates) {
std::vector<double> distance_limits,
bool only_minimum_cover) {
std::sort(distance_limits.begin(), distance_limits.end());
// Using max distance limit for a single dijkstra call. After that we will
// postprocess the results and mark the visited edges.
Expand Down Expand Up @@ -245,7 +194,17 @@ do_many_dijkstras(pgr_edge_t *data_edges, size_t total_edges,
continue;
}
size_t r_i = results.size();
if (t_reached && predecessors[e.target] != e.source) {
bool skip_st = false;
bool skip_ts = false;
if (only_minimum_cover) {
double st_dist = scost + e.cost;
double ts_dist = tcost + e.reverse_cost;
bool st_fully_covered = st_dist <= max_dist_cutoff;
bool ts_fully_covered = ts_dist <= max_dist_cutoff;
skip_ts = st_fully_covered && ts_fully_covered && st_dist < ts_dist;
skip_st = st_fully_covered && ts_fully_covered && ts_dist < st_dist;
}
if (!skip_ts && t_reached && predecessors[e.target] != e.source) {
append_edge_result(tcost, e.reverse_cost, distance_limits, &results);
for (size_t rev_i = r_i; rev_i < results.size(); ++rev_i) {
// reversing the percentage
Expand All @@ -260,12 +219,9 @@ do_many_dijkstras(pgr_edge_t *data_edges, size_t total_edges,
// results[r_i].end_perc - filled in append_edge_result
}
}
if (s_reached && predecessors[e.source] != e.target) {
if (!skip_st && s_reached && predecessors[e.source] != e.target) {
append_edge_result(scost, e.cost, distance_limits, &results);
}
if (remove_duplicates) {
erase_duplicates(r_i, results);
}
for (; r_i < results.size(); ++r_i) {
results[r_i].edge = e.id;
results[r_i].start_id = start_v;
Expand All @@ -288,7 +244,7 @@ do_many_dijkstras(pgr_edge_t *data_edges, size_t total_edges,
void do_pgr_many_to_isochrones(pgr_edge_t *data_edges, size_t total_edges,
int64_t *start_vertex, size_t s_len,
double *distance_cutoffs, size_t d_len,
bool remove_duplicates,
bool only_minimum_cover,
Isochrones_path_element_t **return_tuples,
size_t *return_count, char **log_msg,
char **notice_msg, char **err_msg) {
Expand All @@ -308,7 +264,7 @@ void do_pgr_many_to_isochrones(pgr_edge_t *data_edges, size_t total_edges,
std::vector<int64_t> start_vertices(start_vertex, start_vertex + s_len);
std::vector<double> distances(distance_cutoffs, distance_cutoffs + d_len);
auto results = do_many_dijkstras(data_edges, total_edges, start_vertices,
distances, remove_duplicates);
distances, only_minimum_cover);

size_t count(results.size());
if (count == 0) {
Expand Down Expand Up @@ -346,4 +302,4 @@ void do_pgr_many_to_isochrones(pgr_edge_t *data_edges, size_t total_edges,
*err_msg = pgr_msg(err.str().c_str());
*log_msg = pgr_msg(log.str().c_str());
}
}
}
4 changes: 2 additions & 2 deletions src/isochrones/many_to_isochrones.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void process(
char* sql,
ArrayType *starts,
ArrayType *distances,
bool remove_duplicates,
bool only_minimum_cover,
Isochrones_path_element_t **result_tuples,
size_t *result_count) {
pgr_SPI_connect();
Expand Down Expand Up @@ -71,7 +71,7 @@ void process(
edges, total_tuples,
start_vidsArr, size_start_vidsArr,
distance_cutoffsArr, size_distance_cutoffsArr,
remove_duplicates,
only_minimum_cover,
result_tuples, result_count,
&log_msg,
&notice_msg,
Expand Down

0 comments on commit d5343c8

Please sign in to comment.