diff --git a/doc/driving_distance/pgr_drivingDistance.rst b/doc/driving_distance/pgr_drivingDistance.rst index c5c36f6a13e..03d80d1ec28 100644 --- a/doc/driving_distance/pgr_drivingDistance.rst +++ b/doc/driving_distance/pgr_drivingDistance.rst @@ -122,7 +122,7 @@ Driving distance optional parameters * - ``equicost`` - ``BOOLEAN`` - ``true`` - - * When ``true`` the node will only appear in the closest ``from_v`` + - * When ``true`` the node will only appear in the closest ``start_vid`` list. * When ``false`` which resembles several calls using the single starting point signatures. Tie brakes are arbitrary. diff --git a/doc/src/migration.rst b/doc/src/migration.rst index 1ba2b5ba613..4d8e4c6703b 100644 --- a/doc/src/migration.rst +++ b/doc/src/migration.rst @@ -27,6 +27,11 @@ Migrating functions: signatures. This section will show how to migrate from the old signatures to the new replacement functions. This also affects the restrictions. +:doc:`pgr_withPointsDD` signatures have changed, with the addition of new columns +in the new signatures. It works mainly for driving cases, therefore the ``driving side`` +parameter changed from optional to compulsory, and its valid values differ for +directed and undirected graphs. + .. warning:: All deprecated functions will be removed on next mayor version 4.0.0 @@ -239,6 +244,76 @@ Signatures to be migrated: the function ``my_dijkstra`` returns the new additional columns of ``pgr_dijkstra``. +Migration of ``pgr_withPointsDD`` +------------------------------------------------------------------------------- + +Starting from `v3.6.0 `__ + +Signatures to be migrated: + +* ``pgr_withPointsDD`` (`Single vertex`) +* ``pgr_withPointsDD`` (`Multiple vertices`) + +:Before Migration: + +.. literalinclude:: migration.queries + :start-after: --withpointsdd1 + :end-before: --withpointsdd2 + +* ``driving_side`` parameter is optional. +* Output columns were |result-generic-no-seq| + + * Depending on the overload used, the columns ``start_vid`` might be missing: + + * ``pgr_withPointsDD`` (`Single vertex`) does not have ``start_vid`` + +:Migration: + +* ``driving side`` parameter is compulsory, and valid values differ for directed + and undirected graphs. + + * Does not have a default value. + + * In directed graph, valid values are [``r``, ``R``, ``l``, ``L``] + + * In undirected graph, valid values are [``b``, ``B``] + + +* Be aware of the existance of the additional columns. + +* In ``pgr_withPointsDD`` (`Single vertex`) + + * ``start_vid`` contains the **start vid** parameter value. + * ``depth`` contains the **depth** parameter value. + +.. literalinclude:: migration.queries + :start-after: --withpointsdd2 + :end-before: --withpointsdd3 + +* In ``pgr_withPointsDD`` (`Multiple vertices`) + + * ``depth`` contains the **depth** parameter value. + +.. literalinclude:: migration.queries + :start-after: --withpointsdd3 + :end-before: --withpointsdd4 + +* If needed filter out the added columns, for example: + +.. literalinclude:: migration.queries + :start-after: --withpointsdd4 + :end-before: --withpointsdd5 + +* If needed add the new columns, similar to the following example where + ``pgr_dijkstra`` is used, and the function had to be modified to be able to + return the new columns: + + * In `v3.0 `__ + the function ``my_dijkstra`` uses ``pgr_dijkstra``. + * Starting from `v3.5 `__ + the function ``my_dijkstra`` returns the new additional columns of + ``pgr_dijkstra``. + Migration of functions that change inner query columns names ******************************************************************************* diff --git a/doc/src/pgRouting-introduction.rst b/doc/src/pgRouting-introduction.rst index b540cbeb837..4c5dcc5b1db 100644 --- a/doc/src/pgRouting-introduction.rst +++ b/doc/src/pgRouting-introduction.rst @@ -74,7 +74,8 @@ Rajat Shinde, Regina Obe, Shobhit Chaurasia, Swapnil Joshi, -Virginia Vergara +Virginia Vergara, +Yige Huang And all the people that give us a little of their time making comments, finding @@ -150,7 +151,8 @@ Sylvain Housseman, Sylvain Pasche, Veenit Kumar, Vidhan Jain, -Virginia Vergara +Virginia Vergara, +Yige Huang Corporate Sponsors (in alphabetical order) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docqueries/src/migration.result b/docqueries/src/migration.result index 5e4aaa15f5a..ac237aaeec6 100644 --- a/docqueries/src/migration.result +++ b/docqueries/src/migration.result @@ -785,5 +785,88 @@ SELECT seq, path_seq, node, edge, cost, agg_cost FROM pgr_bdAstar( (6 rows) /* --bdastar5 */ +/* --withpointsdd1 */ +SELECT * FROM pgr_withPointsDD( + $$SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id$$, + $$SELECT pid, edge_id, fraction, side from pointsOfInterest$$, + -5, 2.3, + driving_side => 'r'); +WARNING: pgr_withpointsdd(text,text,bigint,double precision,boolean,character,boolean) is been deprecated + seq | node | edge | cost | agg_cost +-----+------+------+------+---------- + 1 | -5 | -1 | 0 | 0 + 2 | 11 | 5 | 0.2 | 0.2 + 3 | 7 | 8 | 1 | 1.2 + 4 | 12 | 11 | 1 | 1.2 + 5 | 16 | 9 | 1 | 1.2 + 6 | 3 | 7 | 1 | 2.2 + 7 | 6 | 4 | 1 | 2.2 + 8 | 8 | 10 | 1 | 2.2 + 9 | 15 | 16 | 1 | 2.2 + 10 | 17 | 13 | 1 | 2.2 +(10 rows) + +/* --withpointsdd2 */ +SELECT * FROM pgr_withPointsDD( + $$SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id$$, + $$SELECT pid, edge_id, fraction, side from pointsOfInterest$$, + -5, 2.3, 'r'); + seq | depth | start_vid | node | edge | cost | agg_cost +-----+-------+-----------+------+------+------+---------- + 1 | 0 | -5 | -5 | -1 | 0 | 0 + 2 | 1 | -5 | 11 | 5 | 0.2 | 0.2 + 3 | 2 | -5 | 7 | 8 | 1 | 1.2 + 4 | 2 | -5 | 12 | 11 | 1 | 1.2 + 5 | 2 | -5 | 16 | 9 | 1 | 1.2 + 6 | 3 | -5 | 3 | 7 | 1 | 2.2 + 7 | 3 | -5 | 6 | 4 | 1 | 2.2 + 8 | 3 | -5 | 8 | 10 | 1 | 2.2 + 9 | 3 | -5 | 15 | 16 | 1 | 2.2 + 10 | 3 | -5 | 17 | 13 | 1 | 2.2 +(10 rows) + +/* --withpointsdd3 */ +SELECT * FROM pgr_withPointsDD( + $$SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id$$, + $$SELECT pid, edge_id, fraction, side from pointsOfInterest$$, + ARRAY[-3, 16], 3.3, 'r'); + seq | depth | start_vid | node | edge | cost | agg_cost +-----+-------+-----------+------+------+------+---------- + 1 | 0 | -3 | -3 | -1 | 0 | 0 + 2 | 1 | -3 | 12 | 12 | 0.4 | 0.4 + 3 | 2 | -3 | 17 | 13 | 1 | 1.4 + 4 | 3 | -3 | 16 | 15 | 1 | 2.4 + 5 | 0 | 16 | 16 | -1 | 0 | 0 + 6 | 1 | 16 | 11 | 9 | 1 | 1 + 7 | 1 | 16 | 15 | 16 | 1 | 1 + 8 | 1 | 16 | 17 | 15 | 1 | 1 + 9 | 2 | 16 | 7 | 8 | 1 | 2 + 10 | 2 | 16 | 10 | 3 | 1 | 2 + 11 | 2 | 16 | 12 | 11 | 1 | 2 + 12 | 3 | 16 | 3 | 7 | 1 | 3 + 13 | 3 | 16 | 6 | 2 | 1 | 3 + 14 | 3 | 16 | 8 | 10 | 1 | 3 +(14 rows) + +/* --withpointsdd4 */ +SELECT seq, node, edge, cost, agg_cost FROM pgr_withPointsDD( + $$SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id$$, + $$SELECT pid, edge_id, fraction, side from pointsOfInterest$$, + -5, 2.3, 'r'); + seq | node | edge | cost | agg_cost +-----+------+------+------+---------- + 1 | -5 | -1 | 0 | 0 + 2 | 11 | 5 | 0.2 | 0.2 + 3 | 7 | 8 | 1 | 1.2 + 4 | 12 | 11 | 1 | 1.2 + 5 | 16 | 9 | 1 | 1.2 + 6 | 3 | 7 | 1 | 2.2 + 7 | 6 | 4 | 1 | 2.2 + 8 | 8 | 10 | 1 | 2.2 + 9 | 15 | 16 | 1 | 2.2 + 10 | 17 | 13 | 1 | 2.2 +(10 rows) + +/* --withpointsdd5 */ ROLLBACK; ROLLBACK diff --git a/docqueries/src/migration.test.sql b/docqueries/src/migration.test.sql index c31675127be..6fb18f15702 100644 --- a/docqueries/src/migration.test.sql +++ b/docqueries/src/migration.test.sql @@ -261,3 +261,25 @@ SELECT seq, path_seq, node, edge, cost, agg_cost FROM pgr_bdAstar( $$SELECT id, source, target, cost, reverse_cost, x1, y1, x2, y2 FROM edges$$, 6, 10); /* --bdastar5 */ +/* --withpointsdd1 */ +SELECT * FROM pgr_withPointsDD( + $$SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id$$, + $$SELECT pid, edge_id, fraction, side from pointsOfInterest$$, + -5, 2.3, + driving_side => 'r'); +/* --withpointsdd2 */ +SELECT * FROM pgr_withPointsDD( + $$SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id$$, + $$SELECT pid, edge_id, fraction, side from pointsOfInterest$$, + -5, 2.3, 'r'); +/* --withpointsdd3 */ +SELECT * FROM pgr_withPointsDD( + $$SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id$$, + $$SELECT pid, edge_id, fraction, side from pointsOfInterest$$, + ARRAY[-3, 16], 3.3, 'r'); +/* --withpointsdd4 */ +SELECT seq, node, edge, cost, agg_cost FROM pgr_withPointsDD( + $$SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id$$, + $$SELECT pid, edge_id, fraction, side from pointsOfInterest$$, + -5, 2.3, 'r'); +/* --withpointsdd5 */ diff --git a/docqueries/withPoints/doc-pgr_withPointsDD.result b/docqueries/withPoints/doc-pgr_withPointsDD.result index 4b1c028ce68..94cc7833b0f 100644 --- a/docqueries/withPoints/doc-pgr_withPointsDD.result +++ b/docqueries/withPoints/doc-pgr_withPointsDD.result @@ -8,61 +8,62 @@ SET SELECT * FROM pgr_withPointsDD( 'SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id', 'SELECT pid, edge_id, fraction, side from pointsOfInterest', - -1, 3.3, - driving_side => 'r', + -1, 3.3, 'r', details => true); - seq | node | edge | cost | agg_cost ------+------+------+------+---------- - 1 | -1 | -1 | 0 | 0 - 2 | 5 | 1 | 0.4 | 0.4 - 3 | 6 | 1 | 1 | 1.4 - 4 | -6 | 4 | 0.7 | 2.1 - 5 | 7 | 4 | 0.3 | 2.4 + seq | depth | start_vid | node | edge | cost | agg_cost +-----+-------+-----------+------+------+------+---------- + 1 | 0 | -1 | -1 | -1 | 0 | 0 + 2 | 1 | -1 | 5 | 1 | 0.4 | 0.4 + 3 | 2 | -1 | 6 | 1 | 1 | 1.4 + 4 | 3 | -1 | -6 | 4 | 0.7 | 2.1 + 5 | 4 | -1 | 7 | 4 | 0.3 | 2.4 (5 rows) /* -- q3 */ SELECT * FROM pgr_withPointsDD( 'SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id', 'SELECT pid, edge_id, fraction, side from pointsOfInterest', - ARRAY[-1, 16], 3.3, - driving_side => 'l', + ARRAY[-1, 16], 3.3, 'l', equicost => true); - seq | start_vid | node | edge | cost | agg_cost ------+-----------+------+------+------+---------- - 1 | -1 | -1 | -1 | 0 | 0 - 2 | -1 | 6 | 1 | 0.6 | 0.6 - 3 | -1 | 7 | 4 | 1 | 1.6 - 4 | -1 | 5 | 1 | 1 | 1.6 - 5 | -1 | 3 | 7 | 1 | 2.6 - 6 | -1 | 8 | 10 | 1 | 2.6 - 7 | 16 | 16 | -1 | 0 | 0 - 8 | 16 | 11 | 9 | 1 | 1 - 9 | 16 | 15 | 16 | 1 | 1 - 10 | 16 | 17 | 15 | 1 | 1 - 11 | 16 | 10 | 3 | 1 | 2 - 12 | 16 | 12 | 11 | 1 | 2 + seq | depth | start_vid | node | edge | cost | agg_cost +-----+-------+-----------+------+------+------+---------- + 1 | 0 | -1 | -1 | -1 | 0 | 0 + 2 | 1 | -1 | 6 | 1 | 0.6 | 0.6 + 3 | 2 | -1 | 7 | 4 | 1 | 1.6 + 4 | 2 | -1 | 5 | 1 | 1 | 1.6 + 5 | 3 | -1 | 3 | 7 | 1 | 2.6 + 6 | 3 | -1 | 8 | 10 | 1 | 2.6 + 7 | 0 | 16 | 16 | -1 | 0 | 0 + 8 | 1 | 16 | 11 | 9 | 1 | 1 + 9 | 1 | 16 | 15 | 16 | 1 | 1 + 10 | 1 | 16 | 17 | 15 | 1 | 1 + 11 | 2 | 16 | 10 | 3 | 1 | 2 + 12 | 2 | 16 | 12 | 11 | 1 | 2 (12 rows) /* -- q4 */ SELECT * FROM pgr_withPointsDD( 'SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id', 'SELECT pid, edge_id, fraction, side from pointsOfInterest', - -1, 3.3, - driving_side => 'b', + -1, 3.3, 'b', + directed => false, details => true); - seq | node | edge | cost | agg_cost ------+------+------+------+---------- - 1 | -1 | -1 | 0 | 0 - 2 | 5 | 1 | 0.4 | 0.4 - 3 | 6 | 1 | 0.6 | 0.6 - 4 | -6 | 4 | 0.7 | 1.3 - 5 | 7 | 4 | 0.3 | 1.6 - 6 | 3 | 7 | 1 | 2.6 - 7 | 8 | 10 | 1 | 2.6 - 8 | 11 | 8 | 1 | 2.6 - 9 | -3 | 12 | 0.6 | 3.2 - 10 | -4 | 6 | 0.7 | 3.3 -(10 rows) + seq | depth | start_vid | node | edge | cost | agg_cost +-----+-------+-----------+------+------+------+---------- + 1 | 0 | -1 | -1 | -1 | 0 | 0 + 2 | 1 | -1 | 5 | 1 | 0.4 | 0.4 + 3 | 1 | -1 | 6 | 1 | 0.6 | 0.6 + 4 | 2 | -1 | -6 | 4 | 0.7 | 1.3 + 5 | 3 | -1 | 7 | 4 | 0.3 | 1.6 + 6 | 2 | -1 | 10 | 2 | 1 | 1.6 + 7 | 3 | -1 | -5 | 5 | 0.8 | 2.4 + 8 | 4 | -1 | 3 | 7 | 1 | 2.6 + 9 | 4 | -1 | 8 | 10 | 1 | 2.6 + 10 | 4 | -1 | 11 | 8 | 1 | 2.6 + 11 | 3 | -1 | 15 | 3 | 1 | 2.6 + 12 | 5 | -1 | -3 | 12 | 0.6 | 3.2 + 13 | 5 | -1 | -4 | 6 | 0.7 | 3.3 +(13 rows) /* -- q5 */ SELECT * FROM pgr_withPointsDD( @@ -73,32 +74,31 @@ SELECT * FROM pgr_withPointsDD( (SELECT ST_POINT(2.9, 1.8)), 0.5, cap => 2) $p$, - ARRAY[-1, -2], 2.3, - driving_side => 'r', + ARRAY[-1, -2], 2.3, 'r', details => true); - seq | start_vid | node | edge | cost | agg_cost ------+-----------+------+------+------+---------- - 1 | -1 | -1 | -1 | 0 | 0 - 2 | -1 | 11 | 5 | 0.2 | 0.2 - 3 | -1 | 7 | 8 | 1 | 1.2 - 4 | -1 | 12 | 11 | 1 | 1.2 - 5 | -1 | 16 | 9 | 1 | 1.2 - 6 | -1 | -2 | 8 | 0.9 | 2.1 - 7 | -1 | 3 | 7 | 1 | 2.2 - 8 | -1 | 6 | 4 | 1 | 2.2 - 9 | -1 | 8 | 10 | 1 | 2.2 - 10 | -1 | 15 | 16 | 1 | 2.2 - 11 | -1 | 17 | 13 | 1 | 2.2 - 12 | -2 | -2 | -1 | 0 | 0 - 13 | -2 | 11 | 8 | 0.1 | 0.1 - 14 | -2 | 7 | 8 | 1 | 1.1 - 15 | -2 | 12 | 11 | 1 | 1.1 - 16 | -2 | 16 | 9 | 1 | 1.1 - 17 | -2 | 3 | 7 | 1 | 2.1 - 18 | -2 | 6 | 4 | 1 | 2.1 - 19 | -2 | 8 | 10 | 1 | 2.1 - 20 | -2 | 15 | 16 | 1 | 2.1 - 21 | -2 | 17 | 13 | 1 | 2.1 + seq | depth | start_vid | node | edge | cost | agg_cost +-----+-------+-----------+------+------+------+---------- + 1 | 0 | -1 | -1 | -1 | 0 | 0 + 2 | 1 | -1 | 11 | 5 | 0.2 | 0.2 + 3 | 2 | -1 | 7 | 8 | 1 | 1.2 + 4 | 2 | -1 | 12 | 11 | 1 | 1.2 + 5 | 2 | -1 | 16 | 9 | 1 | 1.2 + 6 | 3 | -1 | -2 | 8 | 0.9 | 2.1 + 7 | 3 | -1 | 3 | 7 | 1 | 2.2 + 8 | 3 | -1 | 6 | 4 | 1 | 2.2 + 9 | 3 | -1 | 8 | 10 | 1 | 2.2 + 10 | 3 | -1 | 15 | 16 | 1 | 2.2 + 11 | 3 | -1 | 17 | 13 | 1 | 2.2 + 12 | 0 | -2 | -2 | -1 | 0 | 0 + 13 | 1 | -2 | 11 | 8 | 0.1 | 0.1 + 14 | 2 | -2 | 7 | 8 | 1 | 1.1 + 15 | 2 | -2 | 12 | 11 | 1 | 1.1 + 16 | 2 | -2 | 16 | 9 | 1 | 1.1 + 17 | 3 | -2 | 3 | 7 | 1 | 2.1 + 18 | 3 | -2 | 6 | 4 | 1 | 2.1 + 19 | 3 | -2 | 8 | 10 | 1 | 2.1 + 20 | 3 | -2 | 15 | 16 | 1 | 2.1 + 21 | 3 | -2 | 17 | 13 | 1 | 2.1 (21 rows) /* -- q6 */ diff --git a/docqueries/withPoints/doc-pgr_withPointsDD.test.sql b/docqueries/withPoints/doc-pgr_withPointsDD.test.sql index f0e234d9c43..8cac55e704b 100644 --- a/docqueries/withPoints/doc-pgr_withPointsDD.test.sql +++ b/docqueries/withPoints/doc-pgr_withPointsDD.test.sql @@ -5,22 +5,20 @@ SET extra_float_digits=-3; SELECT * FROM pgr_withPointsDD( 'SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id', 'SELECT pid, edge_id, fraction, side from pointsOfInterest', - -1, 3.3, - driving_side => 'r', + -1, 3.3, 'r', details => true); /* -- q3 */ SELECT * FROM pgr_withPointsDD( 'SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id', 'SELECT pid, edge_id, fraction, side from pointsOfInterest', - ARRAY[-1, 16], 3.3, - driving_side => 'l', + ARRAY[-1, 16], 3.3, 'l', equicost => true); /* -- q4 */ SELECT * FROM pgr_withPointsDD( 'SELECT id, source, target, cost, reverse_cost FROM edges ORDER BY id', 'SELECT pid, edge_id, fraction, side from pointsOfInterest', - -1, 3.3, - driving_side => 'b', + -1, 3.3, 'b', + directed => false, details => true); /* -- q5 */ SELECT * FROM pgr_withPointsDD( @@ -31,7 +29,6 @@ SELECT * FROM pgr_withPointsDD( (SELECT ST_POINT(2.9, 1.8)), 0.5, cap => 2) $p$, - ARRAY[-1, -2], 2.3, - driving_side => 'r', + ARRAY[-1, -2], 2.3, 'r', details => true); /* -- q6 */ diff --git a/include/drivers/driving_distance/withPoints_dd_driver.h b/include/drivers/driving_distance/withPoints_dd_driver.h index bbaef67b8ec..77a173ada43 100644 --- a/include/drivers/driving_distance/withPoints_dd_driver.h +++ b/include/drivers/driving_distance/withPoints_dd_driver.h @@ -2,11 +2,14 @@ File: withPoints_driver.h Copyright (c) 2015 pgRouting developers -Mail: project@pgrouting.org +Mail: project at pgrouting.org Function's developer: Copyright (c) 2015 Celia Virginia Vergara Castillo -Mail: +Mail: vicky at erosion.dev + +Copyright (c) 2023 Yige Huang +Mail: square1ge at gmail.com ------ @@ -37,37 +40,32 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. using Point_on_edge_t = struct Point_on_edge_t; using Edge_t = struct Edge_t; using Path_rt = struct Path_rt; +using MST_rt = struct MST_rt; #else # include # include typedef struct Point_on_edge_t Point_on_edge_t; typedef struct Edge_t Edge_t; typedef struct Path_rt Path_rt; +typedef struct MST_rt MST_rt; #endif #ifdef __cplusplus extern "C" { #endif + void pgr_do_withPointsDD( + Edge_t*, size_t, + Point_on_edge_t*, size_t, + Edge_t*, size_t, + int64_t*, size_t, - void do_pgr_many_withPointsDD( - Edge_t *edges, size_t total_edges, - Point_on_edge_t *points_p, size_t total_points, - Edge_t *edges_of_points, size_t total_edges_of_points, - - int64_t *start_pids_arr, size_t s_len, - double distance, - - bool directed, - char driving_side, - bool details, - bool equiCost, - - Path_rt **return_tuples, size_t *return_count, - char** log_msg, - char** notice_msg, - char ** err_msg); + double, char, bool, bool, bool, bool, + /* TODO remove the following line on v4 */ + Path_rt**, size_t*, + MST_rt**, size_t*, + char**, char**, char **); #ifdef __cplusplus } diff --git a/include/driving_distance/withPointsDD.hpp b/include/driving_distance/withPointsDD.hpp new file mode 100644 index 00000000000..00f112a942c --- /dev/null +++ b/include/driving_distance/withPointsDD.hpp @@ -0,0 +1,248 @@ +/*PGR-GNU***************************************************************** +File: withPointsDD.hpp + +Generated with Template by: +Copyright (c) 2023 pgRouting developers +Mail: project at pgrouting.org + +Function's developer: +Copyright (c) 2023 Yige Huang +Mail: square1ge at gmail.com +------ + +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*/ +#ifndef INCLUDE_DRIVING_DISTANCE_WITHPOINTSDD_HPP_ +#define INCLUDE_DRIVING_DISTANCE_WITHPOINTSDD_HPP_ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include"c_types/mst_rt.h" + + +namespace pgrouting { +namespace functions { + +template +class ShortestPath_tree{ + typedef typename G::V V; + typedef typename G::E E; + typedef typename G::B_G B_G; + + + public: + std::deque get_depths( + G&, + pgrouting::Pg_points_graph&, + std::deque, + bool); + + + private: + /* Functions */ + + template + std::deque get_results( + T, + int64_t, + const G&); + + std::deque dfs_order( + const G&, + int64_t); + + void get_edges_from_path( + const G&, + const Path); + + + private: + /* Member */ + bool m_details; + Path m_path; + + struct InSpanning { + std::set edges; + bool operator()(E e) const { return edges.count(e); } + void clear() { edges.clear(); } + } m_spanning_tree; +}; + + +template +template +std::deque +ShortestPath_tree::get_results( + T order, + int64_t p_root, + const G &graph) { + std::deque results; + + std::vector depth(graph.num_vertices(), 0); + int64_t root(p_root); + + for (const auto edge : order) { + auto u = graph.source(edge); + auto v = graph.target(edge); + if (depth[u] == 0 && depth[v] != 0) { + std::swap(u, v); + } + + if (depth[u] == 0 && depth[v] == 0) { + if (graph[u].id != root) std::swap(u, v); + if (!p_root && graph[u].id > graph[v].id) std::swap(u, v); + + root = p_root? p_root: graph[u].id; + depth[u] = -1; + results.push_back({ + root, + 0, + graph[u].id, + -1, + 0.0, + 0.0 }); + } + depth[v] = depth[u] == -1? 1 : depth[u] + 1; + + int64_t node_id = graph[v].id; + auto path_index = std::find_if(m_path.begin(), m_path.end(), + [&node_id](Path_t &path_item) + {return node_id == path_item.node;}); + + if (!m_details && graph[v].id < 0) depth[v] = depth[u]; + if (m_details || graph[v].id > 0) { + results.push_back({ + root, + depth[v], + path_index->node, + path_index->edge, + path_index->cost, + path_index->agg_cost + }); + } + } + return results; +} + + +template +std::deque +ShortestPath_tree::dfs_order(const G &graph, int64_t root) { + boost::filtered_graph + mstGraph(graph.graph, m_spanning_tree, {}); + + std::deque results; + std::vector visited_order; + + using dfs_visitor = visitors::Dfs_visitor_with_root; + if (graph.has_vertex(root)) { + /* abort in case of an interruption occurs (e.g. the query is being cancelled) */ + CHECK_FOR_INTERRUPTS(); + try { + boost::depth_first_search( + mstGraph, + visitor(dfs_visitor(graph.get_V(root), visited_order)) + .root_vertex(graph.get_V(root))); + } catch(found_goals &) { + {} + } catch (boost::exception const& ex) { + (void)ex; + throw; + } catch (std::exception &e) { + (void)e; + throw; + } catch (...) { + throw; + } + auto result = get_results(visited_order, root, graph); + results.insert(results.end(), result.begin(), result.end()); + } else { + results.push_back({root, 0, root, -1, 0.0, 0.0}); + } + + return results; + } + + +template +void +ShortestPath_tree::get_edges_from_path( + const G& graph, + const Path path) { + m_spanning_tree.clear(); + + for (size_t i = 0; i < path.size(); i++) { + auto u = graph.get_V(path[i].node); + + for (size_t j = i+1; j < path.size(); j++) { + auto v = graph.get_V(path[j].node); + double cost = path[j].cost; + auto edge = graph.get_edge(u, v, cost); + if (graph.target(edge) == v + && path[i].agg_cost+cost == path[j].agg_cost + && graph[edge].id == path[j].edge) { + this->m_spanning_tree.edges.insert(edge); + } + } + } +} + + +template +std::deque +ShortestPath_tree::get_depths( + G &graph, + pgrouting::Pg_points_graph & points_graph, + std::deque paths, + bool details) { + m_details = details; + std::deque results; + + for (const Path& path : paths) { + m_path = path; + get_edges_from_path(graph, path); + if (!m_details) points_graph.eliminate_details_dd(m_path); + + int64_t root = path.start_id(); + auto result = this->dfs_order(graph, root); + + std::sort(result.begin(), result.end(), + [](const MST_rt &l, const MST_rt &r) + {return l.node < r.node;}); + std::stable_sort(result.begin(), result.end(), + [](const MST_rt &l, const MST_rt &r) + {return l.agg_cost < r.agg_cost;}); + + results.insert(results.end(), result.begin(), result.end()); + } + return results; +} + + +} // namespace functions +} // namespace pgrouting + + +#endif // INCLUDE_DRIVING_DISTANCE_WITHPOINTSDD_HPP_ diff --git a/pgtap/withPoints/withPointsDD/edge_cases/issue_979.pg b/pgtap/withPoints/withPointsDD/edge_cases/issue_979.pg index 709d7fa7a81..807acf59b53 100644 --- a/pgtap/withPoints/withPointsDD/edge_cases/issue_979.pg +++ b/pgtap/withPoints/withPointsDD/edge_cases/issue_979.pg @@ -2,7 +2,7 @@ /*PGR-GNU***************************************************************** Copyright (c) 2018 pgRouting developers -Mail: project@pgrouting.org +Mail: project at pgrouting.org ------ This program is free software; you can redistribute it and/or modify @@ -20,14 +20,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. BEGIN; -SELECT PLAN(6); - - ---- ---- DIRECTED GRAPH ---- --------- both driving sides +SELECT CASE WHEN min_version('3.6.0') THEN plan(3) ELSE plan(6) END; +/* TODO remove test_old on v4 */ +CREATE OR REPLACE FUNCTION test_old() +RETURNS SETOF TEXT AS +$BODY$ +BEGIN PREPARE q1 AS SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM pgr_withPointsDD( 'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id', @@ -35,10 +34,10 @@ SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12 -1, 6.8, driving_side := 'b', details := false) ORDER BY seq; - +EXECUTE +'CREATE TABLE test1 AS SELECT node::BIGINT, edge::BIGINT, round(cost, 12) AS cost, round(agg_cost, 12) AS agg_cost -INTO test1 FROM (VALUES ( -1 , -1 , 0 , 0), @@ -55,27 +54,24 @@ FROM ( 4 , 16 , 1 , 4.6), ( 12 , 13 , 1 , 4.6), ( 3 , 3 , 1 , 5.6) -) AS t (node, edge, cost, agg_cost); - +) AS t (node, edge, cost, agg_cost)'; +RETURN QUERY SELECT set_eq('q1', $$SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM test1$$, 'Should be aggregating individual costs: both driving sides, DIR'); - --------- right driving side - PREPARE q2 AS SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM pgr_withPointsDD( 'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id', 'SELECT pid, edge_id, fraction, side from pointsOfInterest', -1, 6.8, driving_side := 'r', details := false); - +EXECUTE +'CREATE TABLE test2 AS SELECT node::BIGINT, edge::BIGINT, cost::FLOAT, agg_cost::FLOAT -INTO test2 FROM (VALUES ( -1 , -1 , 0 , 0), @@ -92,14 +88,13 @@ FROM ( 4 , 16 , 1 , 5.4), ( 12 , 13 , 1 , 5.4), ( 3 , 3 , 1 , 6.4) -) AS t (node, edge, cost, agg_cost); - +) AS t (node, edge, cost, agg_cost)'; +RETURN QUERY SELECT set_eq('q2', $$SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM test2$$, 'Should be aggregating individual costs: right driving side, DIR'); --------- left driving side PREPARE q3 AS SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM pgr_withPointsDD( @@ -108,10 +103,10 @@ SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12 -1, 6.8, driving_side := 'l', details := false) ORDER BY seq; - +EXECUTE +'CREATE TABLE test3 AS SELECT node::BIGINT, edge::BIGINT, cost::FLOAT, agg_cost::FLOAT -INTO test3 FROM (VALUES (-1 , -1 , 0 , 0), @@ -128,22 +123,18 @@ FROM ( 4 , 16 , 1 , 4.6), ( 12 , 15 , 1 , 4.6), ( 3 , 3 , 1 , 5.6) -) AS t (node, edge, cost, agg_cost); +) AS t (node, edge, cost, agg_cost)'; - -SELECT todo('test failing with postgres 16',1); +RETURN QUERY SELECT set_eq('q3', $$SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM test3$$, 'Should be aggregating individual costs: left driving side, DIR'); ---- ---- UNDIRECTED GRAPH ---- --- all results on udirected graph are "allegedly" equal +EXECUTE +'CREATE TABLE test4 AS SELECT node::BIGINT, cost::FLOAT, agg_cost::FLOAT -INTO test4 FROM (VALUES ( -1 , 0 , 0), @@ -160,9 +151,7 @@ FROM ( 11 , 1 , 3.6), ( 13 , 1 , 3.6), ( 12 , 1 , 4.6) -) AS t (node, cost, agg_cost); - --------- both driving sides +) AS t (node, cost, agg_cost)'; PREPARE q4 AS SELECT node, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM pgr_withPointsDD( @@ -170,37 +159,187 @@ SELECT node, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS a 'SELECT pid, edge_id, fraction, side from pointsOfInterest', -1, 6.8, driving_side := 'b', details := false, directed:=false); +RETURN QUERY SELECT set_eq('q4', $$SELECT node, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM test4$$, 'Should be aggregating individual costs: both driving sides, UNDI'); - - --------- right driving side - PREPARE q5 AS SELECT node, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM pgr_withPointsDD( 'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id', 'SELECT pid, edge_id, fraction, side from pointsOfInterest', -1, 6.8, driving_side := 'r', details := false, directed:=false); - +RETURN QUERY SELECT set_eq('q5', $$SELECT node, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM test4$$, 'Should be aggregating individual costs: right driving side, UNDI'); --------- left driving side - PREPARE q6 AS SELECT node, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM pgr_withPointsDD( 'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id', 'SELECT pid, edge_id, fraction, side from pointsOfInterest', -1, 6.8, driving_side := 'l', details := false, directed:=false); - +RETURN QUERY SELECT set_eq('q6', $$SELECT node, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM test4$$, 'Should be aggregating individual costs: left driving side, UNDI'); -SELECT * FROM finish(); +DROP TABLE IF EXISTS test1; +DROP TABLE IF EXISTS test2; +DROP TABLE IF EXISTS test3; +DROP TABLE IF EXISTS test4; + +END; +$BODY$ +language plpgsql; + + +CREATE OR REPLACE FUNCTION test_new() +RETURNS SETOF TEXT AS +$BODY$ +BEGIN + +--- +--- DIRECTED GRAPH +--- +-------- right driving side + +PREPARE q1 AS +SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM pgr_withPointsDD( + 'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id', + 'SELECT pid, edge_id, fraction, side from pointsOfInterest', + -1, 6.8, 'r', details := false); + +EXECUTE +'CREATE TABLE test1 AS +SELECT + node::BIGINT, edge::BIGINT, cost::FLOAT, agg_cost::FLOAT +FROM +(VALUES + ( -1 , -1 , 0 , 0), + ( 1 , 1 , 0.4 , 0.4), + ( 2 , 1 , 1 , 1.4), + ( 5 , 4 , 1 , 2.4), + ( 6 , 8 , 1 , 3.4), + ( 8 , 7 , 1 , 3.4), + ( 10 , 10 , 1 , 3.4), + ( 7 , 6 , 1 , 4.4), + ( 9 , 9 , 1 , 4.4), + ( 11 , 11 , 1 , 4.4), + ( 13 , 14 , 1 , 4.4), + ( 4 , 16 , 1 , 5.4), + ( 12 , 13 , 1 , 5.4), + ( 3 , 3 , 1 , 6.4) +) AS t (node, edge, cost, agg_cost)'; + +RETURN QUERY +SELECT set_eq('q1', + $$SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM test1$$, + 'Should be aggregating individual costs: right driving side, DIR'); + + +-------- left driving side + +PREPARE q2 AS +SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM pgr_withPointsDD( + 'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id', + 'SELECT pid, edge_id, fraction, side from pointsOfInterest', + -1, 6.8, 'l', details := false) +ORDER BY seq; + +EXECUTE +'CREATE TABLE test2 AS +SELECT + node::BIGINT, edge::BIGINT, cost::FLOAT, agg_cost::FLOAT +FROM +(VALUES + (-1 , -1 , 0 , 0), + ( 2 , 1 , 0.6 , 0.6), + ( 5 , 4 , 1 , 1.6), + ( 1 , 1 , 1 , 1.6), + ( 6 , 8 , 1 , 2.6), + ( 8 , 7 , 1 , 2.6), + (10 , 10 , 1 , 2.6), + ( 7 , 6 , 1 , 3.6), + ( 9 , 9 , 1 , 3.6), + ( 11 , 11 , 1 , 3.6), + ( 13 , 14 , 1 , 3.6), + ( 4 , 16 , 1 , 4.6), + ( 12 , 15 , 1 , 4.6), + ( 3 , 3 , 1 , 5.6) +) AS t (node, edge, cost, agg_cost)'; + +EXECUTE 'SELECT todo($1, $2)' USING 'test failing with postgres 16', 1; +RETURN QUERY +SELECT set_eq('q2', + $$SELECT node, edge, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM test2$$, + 'Should be aggregating individual costs: left driving side, DIR'); + +--- +--- UNDIRECTED GRAPH +--- + +-- all results on udirected graph are "allegedly" equal + +-------- both driving sides + +PREPARE q3 AS +SELECT node, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM pgr_withPointsDD( + 'SELECT id, source, target, cost, reverse_cost FROM edge_table ORDER BY id', + 'SELECT pid, edge_id, fraction, side from pointsOfInterest', + -1, 6.8, 'b', details := false, directed:=false); + +EXECUTE +'CREATE TABLE test3 AS +SELECT + node::BIGINT, cost::FLOAT, agg_cost::FLOAT +FROM +(VALUES + ( -1 , 0 , 0), + ( 1 , 0.4 , 0.4), + ( 2 , 0.6 , 0.6), + ( 5 , 1 , 1.6), + ( 3 , 1 , 1.6), + ( 6 , 1 , 2.6), + ( 8 , 1 , 2.6), + ( 10 , 1 , 2.6), + ( 4 , 1 , 2.6), + ( 7 , 1 , 3.6), + ( 9 , 1 , 3.6), + ( 11 , 1 , 3.6), + ( 13 , 1 , 3.6), + ( 12 , 1 , 4.6) +) AS t (node, cost, agg_cost)'; + +RETURN QUERY +SELECT set_eq('q3', + $$SELECT node, round(cost::numeric, 12) AS cost, round(agg_cost::numeric, 12) AS agg_cost FROM test3$$, + 'Should be aggregating individual costs: both driving sides, UNDI'); + +DROP TABLE IF EXISTS test1; +DROP TABLE IF EXISTS test2; +DROP TABLE IF EXISTS test3; + +END; +$BODY$ +language plpgsql; + + +CREATE OR REPLACE FUNCTION do_test() +RETURNS SETOF TEXT AS +$BODY$ +BEGIN + IF min_version('3.6.0') THEN + RETURN QUERY SELECT * FROM test_new(); + ELSE + RETURN QUERY SELECT * FROM test_old(); + END IF; +END; +$BODY$ +language plpgsql; + +SELECT do_test(); +SELECT finish(); ROLLBACK; diff --git a/pgtap/withPoints/withPointsDD/edge_cases/undirected_driving_side.pg b/pgtap/withPoints/withPointsDD/edge_cases/undirected_driving_side.pg index 2346bc37d90..7d2d8421d4b 100644 --- a/pgtap/withPoints/withPointsDD/edge_cases/undirected_driving_side.pg +++ b/pgtap/withPoints/withPointsDD/edge_cases/undirected_driving_side.pg @@ -2,7 +2,7 @@ /*PGR-GNU***************************************************************** Copyright (c) 2018 pgRouting developers -Mail: project@pgrouting.org +Mail: project at pgrouting.org ------ This program is free software; you can redistribute it and/or modify @@ -17,18 +17,20 @@ 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*/ - +/* TODO remove in v4 */ BEGIN; SELECT PLAN(3); - +-- TEST of deprecated signature +-- This test does not make sense on new signatures due to the fact that +-- if graph is undircted then the only valid parameter of driving side can only be 'b' +SET client_min_messages TO ERROR; -- because the graph is undirected, It will not matter the side of the point --- UNDIRECTED GRAPH --- - -------- both driving sides PREPARE q1 AS SELECT seq, node, edge, cost::TEXT, agg_cost::TEXT FROM pgr_withPointsDD( diff --git a/pgtap/withPoints/withPointsDD/inner_query.pg b/pgtap/withPoints/withPointsDD/inner_query.pg index 5b5407e8bea..454efbd7780 100644 --- a/pgtap/withPoints/withPointsDD/inner_query.pg +++ b/pgtap/withPoints/withPointsDD/inner_query.pg @@ -2,7 +2,7 @@ /*PGR-GNU***************************************************************** Copyright (c) 2018 pgRouting developers -Mail: project@pgrouting.org +Mail: project at pgrouting.org ------ This program is free software; you can redistribute it and/or modify @@ -22,12 +22,43 @@ BEGIN; UPDATE edge_table SET cost = sign(cost), reverse_cost = sign(reverse_cost); SELECT plan(168); --- SINGLE VERTEX -SELECT style_dijkstra('pgr_withPointsDD(', ', $$SELECT * from pointsOfInterest$$, 2, 3.8, true)'); -SELECT innerquery_points('pgr_withPointsDD($$SELECT * FROM edge_table$$,', ', 2, 3.8, true)'); --- MULTIPLE VERTEX -SELECT style_dijkstra('pgr_withPointsDD(', ', $$SELECT * from pointsOfInterest$$, ARRAY[2,3], 3.8, true)'); -SELECT innerquery_points('pgr_withPointsDD($$SELECT * FROM edge_table$$,', ', ARRAY[2,3], 3.8, true)'); +CREATE OR REPLACE FUNCTION test_innerquery() +RETURNS SETOF TEXT AS +$BODY$ +BEGIN +IF min_version('3.6.0') THEN + -- SINGLE VERTEX + RETURN QUERY + SELECT style_dijkstra('pgr_withPointsDD(', ', $$SELECT * from pointsOfInterest$$, 2, 3.8, $$r$$, true)'); + RETURN QUERY + SELECT innerquery_points('pgr_withPointsDD($$SELECT * FROM edge_table$$,', ', 2, 3.8, $$l$$,true)'); + -- MULTIPLE VERTEX + RETURN QUERY + SELECT style_dijkstra('pgr_withPointsDD(', ', $$SELECT * from pointsOfInterest$$, ARRAY[2,3], 3.8, $$l$$,true)'); + RETURN QUERY + SELECT innerquery_points('pgr_withPointsDD($$SELECT * FROM edge_table$$,', ', ARRAY[2,3], 3.8, $$r$$,true)'); + +ELSE + +SET client_min_messages TO ERROR; + -- SINGLE VERTEX + RETURN QUERY + SELECT style_dijkstra('pgr_withPointsDD(', ', $$SELECT * from pointsOfInterest$$, 2, 3.8, true)'); + RETURN QUERY + SELECT innerquery_points('pgr_withPointsDD($$SELECT * FROM edge_table$$,', ', 2, 3.8, true)'); + -- MULTIPLE VERTEX + RETURN QUERY + SELECT style_dijkstra('pgr_withPointsDD(', ', $$SELECT * from pointsOfInterest$$, ARRAY[2,3], 3.8, true)'); + RETURN QUERY + SELECT innerquery_points('pgr_withPointsDD($$SELECT * FROM edge_table$$,', ', ARRAY[2,3], 3.8, true)'); + +END IF; + +END; +$BODY$ +language plpgsql; + +SELECT test_innerquery(); SELECT finish(); ROLLBACK; diff --git a/pgtap/withPoints/withPointsDD/no_crash_test.pg b/pgtap/withPoints/withPointsDD/no_crash_test.pg index e551d58315c..a66059ead3b 100644 --- a/pgtap/withPoints/withPointsDD/no_crash_test.pg +++ b/pgtap/withPoints/withPointsDD/no_crash_test.pg @@ -2,7 +2,7 @@ /*PGR-GNU***************************************************************** Copyright (c) 2018 pgRouting developers -Mail: project@pgrouting.org +Mail: project at pgrouting.org ------ This program is free software; you can redistribute it and/or modify @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. BEGIN; UPDATE edge_table SET cost = sign(cost), reverse_cost = sign(reverse_cost); -SELECT plan(42); +SELECT CASE WHEN min_version('3.6.0') THEN plan(50) ELSE plan(42) END; PREPARE edges AS SELECT id, source, target, cost, reverse_cost FROM edge_table; @@ -42,6 +42,66 @@ DECLARE params TEXT[]; subs TEXT[]; BEGIN +IF min_version('3.6.0') THEN + + -- 1 to distance + params = ARRAY[ + '$$SELECT id, source, target, cost, reverse_cost FROM edge_table$$', + '$$SELECT pid, edge_id, fraction from pointsOfInterest$$', + '1', + '1.3::FLOAT', + '$$r$$' + ]::TEXT[]; + subs = ARRAY[ + 'NULL', + 'NULL', + '(SELECT id FROM edge_table_vertices_pgr WHERE id IN (-1))', + 'NULL', + 'NULL' + ]::TEXT[]; + + RETURN query SELECT * FROM no_crash_test('pgr_withPointsDD', params, subs); + + subs = ARRAY[ + 'NULL', + 'NULL', + 'NULL::BIGINT', + 'NULL', + 'NULL' + ]::TEXT[]; + RETURN query SELECT * FROM no_crash_test('pgr_withPointsDD', params, subs); + + -- many to distance + params = ARRAY[ + '$$SELECT id, source, target, cost, reverse_cost FROM edge_table$$', + '$$SELECT pid, edge_id, fraction from pointsOfInterest$$', + 'ARRAY[1]', + '1.3::FLOAT', + '$$r$$' + ]::TEXT[]; + subs = ARRAY[ + 'NULL', + 'NULL', + '(SELECT array_agg(id) FROM edge_table_vertices_pgr WHERE id IN (-1))', + 'NULL', + 'NULL' + ]::TEXT[]; + + RETURN query SELECT * FROM no_crash_test('pgr_withPointsDD', params, subs); + + subs = ARRAY[ + 'NULL', + 'NULL', + 'NULL::BIGINT[]', + 'NULL', + 'NULL' + ]::TEXT[]; + RETURN query SELECT * FROM no_crash_test('pgr_withPointsDD', params, subs); + +ELSE + +/* TODO remove tests on v4 of the old signatures */ +SET client_min_messages TO ERROR; -- 1 to distance params = ARRAY[ '$$SELECT id, source, target, cost, reverse_cost FROM edge_table$$', @@ -90,6 +150,8 @@ BEGIN ]::TEXT[]; RETURN query SELECT * FROM no_crash_test('pgr_withPointsDD', params, subs); +END IF; + END $BODY$ LANGUAGE plpgsql VOLATILE; diff --git a/pgtap/withPoints/withPointsDD/types_check.pg b/pgtap/withPoints/withPointsDD/types_check.pg index b03307d007a..2770d7cb24e 100644 --- a/pgtap/withPoints/withPointsDD/types_check.pg +++ b/pgtap/withPoints/withPointsDD/types_check.pg @@ -2,7 +2,7 @@ /*PGR-GNU***************************************************************** Copyright (c) 2018 pgRouting developers -Mail: project@pgrouting.org +Mail: project at pgrouting.org ------ This program is free software; you can redistribute it and/or modify @@ -19,29 +19,82 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ BEGIN; -SELECT plan(7); +SELECT CASE WHEN min_version('3.6.0') THEN plan(11) ELSE plan(7) END; SELECT has_function('pgr_withpointsdd'); +CREATE OR REPLACE FUNCTION test_types_check() +RETURNS SETOF TEXT AS +$BODY$ +BEGIN + +IF min_version('3.6.0') THEN + +RETURN QUERY +SELECT has_function('pgr_withpointsdd', ARRAY['text','text','bigint','double precision','character','boolean','boolean']); +RETURN QUERY +SELECT has_function('pgr_withpointsdd', ARRAY['text','text','anyarray','double precision','character','boolean','boolean','boolean']); + +RETURN QUERY +SELECT function_returns('pgr_withpointsdd', ARRAY['text','text','bigint','double precision','character','boolean','boolean'],'setof record'); +RETURN QUERY +SELECT function_returns('pgr_withpointsdd', ARRAY['text','text','anyarray','double precision','character','boolean','boolean','boolean'],'setof record'); + +END IF; + +/* TODO remove last 2 rows on v4 */ +RETURN QUERY +SELECT CASE WHEN min_version('3.6.0') +THEN collect_tap ( + set_eq( + $$SELECT proargnames from pg_proc where proname = 'pgr_withpointsdd'$$, + $$VALUES + ('{"","","","","","directed","details","seq","depth","start_vid","node","edge","cost","agg_cost"}'::TEXT[]), + ('{"","","","","","directed","details","equicost","seq","depth","start_vid","node","edge","cost","agg_cost"}'::TEXT[]), + ('{"","","","","directed","driving_side","details","seq","node","edge","cost","agg_cost"}'::TEXT[]), + ('{"","","","","directed","driving_side","details","equicost","seq","start_vid","node","edge","cost","agg_cost"}'::TEXT[]) + $$), + set_eq( + $$SELECT proallargtypes from pg_proc where proname = 'pgr_withpointsdd'$$, + $$VALUES + ('{25,25,20,701,1042,16,16,20,20,20,20,20,701,701}'::OID[]), + ('{25,25,2277,701,1042,16,16,16,20,20,20,20,20,701,701}'::OID[]), + ('{25,25,20,701,16,1042,16,23,20,20,701,701}'::OID[]), + ('{25,25,2277,701,16,1042,16,16,23,20,20,20,701,701}'::OID[]) + $$) +) +ELSE collect_tap( + set_eq( + $$SELECT proargnames from pg_proc where proname = 'pgr_withpointsdd'$$, + $$VALUES + ('{"","","","","directed","driving_side","details","seq","node","edge","cost","agg_cost"}'::TEXT[]), + ('{"","","","","directed","driving_side","details","equicost","seq","start_vid","node","edge","cost","agg_cost"}'::TEXT[]) + $$), + set_eq( + $$SELECT proallargtypes from pg_proc where proname = 'pgr_withpointsdd'$$, + $$VALUES + ('{25,25,20,701,16,1042,16,23,20,20,701,701}'::OID[]), + ('{25,25,2277,701,16,1042,16,16,23,20,20,20,701,701}'::OID[]) + $$) +) +END; + +/* TODO remove on v4 this are the old signatures */ +RETURN QUERY SELECT has_function('pgr_withpointsdd', ARRAY['text','text','bigint','double precision','boolean','character','boolean']); +RETURN QUERY SELECT has_function('pgr_withpointsdd', ARRAY['text','text','anyarray','double precision','boolean','character','boolean','boolean']); +RETURN QUERY SELECT function_returns('pgr_withpointsdd', ARRAY['text','text','bigint','double precision','boolean','character','boolean'],'setof record'); +RETURN QUERY SELECT function_returns('pgr_withpointsdd', ARRAY['text','text','anyarray','double precision','boolean','character','boolean','boolean'],'setof record'); -SELECT set_eq( - $$SELECT proargnames from pg_proc where proname = 'pgr_withpointsdd'$$, - $$VALUES - ('{"","","","","directed","driving_side","details","seq","node","edge","cost","agg_cost"}'::TEXT[]), - ('{"","","","","directed","driving_side","details","equicost","seq","start_vid","node","edge","cost","agg_cost"}'::TEXT[]) - $$); - -SELECT set_eq( - $$SELECT proallargtypes from pg_proc where proname = 'pgr_withpointsdd'$$, - $$VALUES - ('{25,25,20,701,16,1042,16,23,20,20,701,701}'::OID[]), - ('{25,25,2277,701,16,1042,16,16,23,20,20,20,701,701}'::OID[]) - $$); +END; +$BODY$ +language plpgsql; + +SELECT test_types_check(); SELECT finish(); ROLLBACK; diff --git a/sql/driving_distance/_withPointsDD.sql b/sql/driving_distance/_withPointsDD.sql index 628665fa81d..2f750d28b48 100644 --- a/sql/driving_distance/_withPointsDD.sql +++ b/sql/driving_distance/_withPointsDD.sql @@ -1,8 +1,16 @@ /*PGR-GNU***************************************************************** File: _withPointsDD.sql +Generated with Template by: +Copyright (c) 2015 pgRouting developers +Mail: project at pgrouting.org + +Function's developer: Copyright (c) 2015 Celia Virginia Vergara Castillo -Mail: vicky_vergara@hotmail.com +Mail: vicky at erosion.dev + +Copyright (c) 2023 Yige Huang +Mail: square1ge at gmail.com ------ @@ -26,6 +34,35 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- pgr_withPointsDD ------------------- +--v3.6 +CREATE FUNCTION _pgr_v4withPointsDD( + edges_sql TEXT, + points_sql TEXT, + start_pid ANYARRAY, + distance FLOAT, + driving_side CHAR, + + directed BOOLEAN DEFAULT true, + details BOOLEAN DEFAULT false, + equicost BOOLEAN DEFAULT false, + + OUT seq BIGINT, + OUT depth BIGINT, + OUT start_vid BIGINT, + OUT node BIGINT, + OUT edge BIGINT, + OUT cost FLOAT, + OUT agg_cost FLOAT) +RETURNS SETOF RECORD AS +'MODULE_PATHNAME' +LANGUAGE C VOLATILE STRICT; + +-- COMMENTS + +COMMENT ON FUNCTION _pgr_v4withPointsDD(TEXT, TEXT, ANYARRAY, FLOAT, CHAR, BOOLEAN, BOOLEAN, BOOLEAN) +IS 'pgRouting internal function'; + +/* TODO remove on v4 */ --v3.0 CREATE FUNCTION _pgr_withPointsDD( edges_sql TEXT, @@ -51,4 +88,4 @@ LANGUAGE C VOLATILE STRICT; -- COMMENTS COMMENT ON FUNCTION _pgr_withPointsDD(TEXT, TEXT, ANYARRAY, FLOAT, BOOLEAN, CHAR, BOOLEAN, BOOLEAN) -IS 'pgRouting internal function'; +IS 'pgRouting deprecated function'; diff --git a/sql/driving_distance/withPointsDD.sql b/sql/driving_distance/withPointsDD.sql index 45501b3d47f..94a5b9469c7 100644 --- a/sql/driving_distance/withPointsDD.sql +++ b/sql/driving_distance/withPointsDD.sql @@ -1,8 +1,13 @@ /*PGR-GNU***************************************************************** File: withPointsDD.sql +Generated with Template by: +Copyright (c) 2015 pgRouting developers +Mail: project at pgrouting.org + +Function's developer: Copyright (c) 2015 Celia Virginia Vergara Castillo -Mail: vicky_vergara@hotmail.com +Mail: vicky at erosion.dev ------ @@ -23,45 +28,48 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ********************************************************************PGR-GNU*/ -- SINGLE ---v2.6 +--v3.6 CREATE FUNCTION pgr_withPointsDD( TEXT, --edges_sql (required) TEXT, -- points_sql (required) BIGINT, -- from_vid (required) FLOAT, -- distance (required) + CHAR, -- driving_side (required) directed BOOLEAN DEFAULT true, - driving_side CHAR DEFAULT 'b', details BOOLEAN DEFAULT false, - OUT seq INTEGER, + OUT seq BIGINT, + OUT depth BIGINT, + OUT start_vid BIGINT, OUT node BIGINT, OUT edge BIGINT, OUT cost FLOAT, OUT agg_cost FLOAT) RETURNS SETOF RECORD AS $BODY$ - SELECT seq, node, edge, cost, agg_cost - FROM _pgr_withPointsDD(_pgr_get_statement($1), _pgr_get_statement($2), ARRAY[$3]::BIGINT[], $4, $5, $6, $7, false); + SELECT * + FROM _pgr_v4withPointsDD(_pgr_get_statement($1), _pgr_get_statement($2), ARRAY[$3]::BIGINT[], $4, $5, $6, $7, false); $BODY$ LANGUAGE SQL VOLATILE STRICT COST 100 ROWS 1000; -- MULTIPLE ---v2.6 +--v3.6 CREATE FUNCTION pgr_withPointsDD( TEXT, --edges_sql (required) TEXT, -- points_sql (required) ANYARRAY, -- from_vid (required) FLOAT, -- distance (required) + CHAR, -- driving_side (required) directed BOOLEAN DEFAULT true, - driving_side CHAR DEFAULT 'b', details BOOLEAN DEFAULT false, equicost BOOLEAN DEFAULT false, - OUT seq INTEGER, + OUT seq BIGINT, + OUT depth BIGINT, OUT start_vid BIGINT, OUT node BIGINT, OUT edge BIGINT, @@ -70,7 +78,7 @@ CREATE FUNCTION pgr_withPointsDD( RETURNS SETOF RECORD AS $BODY$ SELECT * - FROM _pgr_withPointsDD(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5, $6, $7, $8); + FROM _pgr_v4withPointsDD(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5, $6, $7, $8); $BODY$ LANGUAGE SQL VOLATILE STRICT COST 100 @@ -79,7 +87,7 @@ ROWS 1000; -- COMMENTS -COMMENT ON FUNCTION pgr_withPointsDD(TEXT, TEXT, BIGINT, FLOAT, BOOLEAN, CHAR, BOOLEAN) +COMMENT ON FUNCTION pgr_withPointsDD(TEXT, TEXT, BIGINT, FLOAT, CHAR, BOOLEAN, BOOLEAN) IS 'pgr_withPointsDD(Single Vertex) - PROPOSED - Parameters: @@ -87,16 +95,16 @@ IS 'pgr_withPointsDD(Single Vertex) - Points SQL with columns: [pid], edge_id, fraction[,side] - From vertex identifier - Distance + - Driving_side - Optional Parameters - directed := true - - driving_side := b - details := false - Documentation: - ${PROJECT_DOC_LINK}/pgr_withPointsDD.html '; -COMMENT ON FUNCTION pgr_withPointsDD(TEXT, TEXT, ANYARRAY, FLOAT, BOOLEAN, CHAR, BOOLEAN, BOOLEAN) +COMMENT ON FUNCTION pgr_withPointsDD(TEXT, TEXT, ANYARRAY, FLOAT, CHAR, BOOLEAN, BOOLEAN, BOOLEAN) IS 'pgr_withPointsDD(Multiple Vertices) - PROPOSED - Parameters: @@ -104,11 +112,84 @@ IS 'pgr_withPointsDD(Multiple Vertices) - Points SQL with columns: [pid], edge_id, fraction[,side] - From ARRAY[vertices identifiers] - Distance + - Driving_side - Optional Parameters - directed := true - - driving_side := b - details := false - equicost := false - Documentation: - ${PROJECT_DOC_LINK}/pgr_withPointsDD.html '; + +/* TODO remove on V4 */ +-- SINGLE +--v2.6 +CREATE FUNCTION pgr_withPointsDD( + TEXT, --edges_sql (required) + TEXT, -- points_sql (required) + BIGINT, -- from_vid (required) + FLOAT, -- distance (required) + + directed BOOLEAN DEFAULT true, + driving_side CHAR DEFAULT 'b', + details BOOLEAN DEFAULT false, + + OUT seq INTEGER, + OUT node BIGINT, + OUT edge BIGINT, + OUT cost FLOAT, + OUT agg_cost FLOAT) +RETURNS SETOF RECORD AS +$BODY$ +BEGIN + RAISE WARNING 'pgr_withpointsdd(text,text,bigint,double precision,boolean,character,boolean) is been deprecated'; + RETURN QUERY + SELECT a.seq, a.node, a.edge, a.cost, a.agg_cost + FROM _pgr_withPointsDD(_pgr_get_statement($1), _pgr_get_statement($2), ARRAY[$3]::BIGINT[], $4, $5, $6, $7, false) AS a; +END; +$BODY$ +LANGUAGE plpgsql VOLATILE STRICT +COST 100 +ROWS 1000; + +-- MULTIPLE +--v2.6 +CREATE FUNCTION pgr_withPointsDD( + TEXT, --edges_sql (required) + TEXT, -- points_sql (required) + ANYARRAY, -- from_vid (required) + FLOAT, -- distance (required) + + directed BOOLEAN DEFAULT true, + driving_side CHAR DEFAULT 'b', + details BOOLEAN DEFAULT false, + equicost BOOLEAN DEFAULT false, + + OUT seq INTEGER, + OUT start_vid BIGINT, + OUT node BIGINT, + OUT edge BIGINT, + OUT cost FLOAT, + OUT agg_cost FLOAT) +RETURNS SETOF RECORD AS +$BODY$ +BEGIN + RAISE WARNING 'pgr_withpointsdd(text,text,anyarray,double precision,boolean,character,boolean,boolean) is been deprecated'; + RETURN QUERY + SELECT * + FROM _pgr_withPointsDD(_pgr_get_statement($1), _pgr_get_statement($2), $3, $4, $5, $6, $7, $8); +END; +$BODY$ +LANGUAGE plpgsql VOLATILE STRICT +COST 100 +ROWS 1000; + + +-- COMMENTS + +COMMENT ON FUNCTION pgr_withPointsDD(TEXT, TEXT, BIGINT, FLOAT, BOOLEAN, CHAR, BOOLEAN) +IS 'pgRouting deprecated function'; + + +COMMENT ON FUNCTION pgr_withPointsDD(TEXT, TEXT, ANYARRAY, FLOAT, BOOLEAN, CHAR, BOOLEAN, BOOLEAN) +IS 'pgRouting deprecated function'; diff --git a/sql/scripts/build-extension-update-files.pl b/sql/scripts/build-extension-update-files.pl index 1c94d49d761..6f292b57868 100755 --- a/sql/scripts/build-extension-update-files.pl +++ b/sql/scripts/build-extension-update-files.pl @@ -239,6 +239,8 @@ sub generate_upgrade_script { push @commands, drop_special_case_function("pgr_bdastar(text,bigint,bigint,boolean,integer,numeric,numeric)"); push @commands, drop_special_case_function("pgr_bdastar(text,bigint,anyarray,boolean,integer,numeric,numeric)"); push @commands, drop_special_case_function("pgr_bdastar(text,anyarray,bigint,boolean,integer,numeric,numeric)"); + push @commands, drop_special_case_function("pgr_withpointsdd(text,text,anyarray,double precision,boolean,character,boolean,boolean)"); + push @commands, drop_special_case_function("pgr_withpointsdd(text,text,bigint,double precision,boolean,character,boolean)"); } diff --git a/sql/sigs/pgrouting--3.6.sig b/sql/sigs/pgrouting--3.6.sig index 2fbc26779df..2f83dc066f7 100644 --- a/sql/sigs/pgrouting--3.6.sig +++ b/sql/sigs/pgrouting--3.6.sig @@ -291,6 +291,7 @@ _pgr_tsp(text,bigint,bigint,double precision,integer,integer,integer,double prec pgr_tsp(text,bigint,bigint,double precision,integer,integer,integer,double precision,double precision,double precision,boolean) _pgr_turnrestrictedpath(text,text,bigint,bigint,integer,boolean,boolean,boolean,boolean) pgr_turnrestrictedpath(text,text,bigint,bigint,integer,boolean,boolean,boolean,boolean) +_pgr_v4withpointsdd(text,text,anyarray,double precision,character,boolean,boolean,boolean) pgr_version() _pgr_versionless(text,text) _pgr_vrponedepot(text,text,text,integer) @@ -303,7 +304,9 @@ pgr_withpointscost(text,text,bigint,bigint,boolean,character) pgr_withpointscost(text,text,text,boolean,character) _pgr_withpointsdd(text,text,anyarray,double precision,boolean,character,boolean,boolean) pgr_withpointsdd(text,text,anyarray,double precision,boolean,character,boolean,boolean) +pgr_withpointsdd(text,text,anyarray,double precision,character,boolean,boolean,boolean) pgr_withpointsdd(text,text,bigint,double precision,boolean,character,boolean) +pgr_withpointsdd(text,text,bigint,double precision,character,boolean,boolean) _pgr_withpointsksp(text,text,bigint,bigint,integer,boolean,boolean,character,boolean) pgr_withpointsksp(text,text,bigint,bigint,integer,boolean,boolean,character,boolean) pgr_withpoints(text,text,anyarray,anyarray,boolean,character,boolean) diff --git a/src/driving_distance/many_to_dist_withPointsDD.c b/src/driving_distance/many_to_dist_withPointsDD.c index 3460b1ce7ea..c738716eb0f 100644 --- a/src/driving_distance/many_to_dist_withPointsDD.c +++ b/src/driving_distance/many_to_dist_withPointsDD.c @@ -1,9 +1,16 @@ /*PGR-GNU***************************************************************** File: many_to_dist_driving_distance.c +Generated with Template by: +Copyright (c) 2015 pgRouting developers +Mail: project at pgrouting.org + +Function's developer: Copyright (c) 2015 Celia Virginia Vergara Castillo -Mail: vicky_Vergara@hotmail.com +Mail: vicky at erosion.dev +Copyright (c) 2023 Yige Huang +Mail: square1ge at gmail.com ------ This program is free software; you can redistribute it and/or modify @@ -29,6 +36,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "c_common/debug_macro.h" #include "c_common/e_report.h" #include "c_common/time_msg.h" +#include "c_types/mst_rt.h" #include "c_common/pgdata_getters.h" @@ -36,8 +44,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "drivers/driving_distance/withPoints_dd_driver.h" -PGDLLEXPORT Datum _pgr_withpointsdd(PG_FUNCTION_ARGS); -PG_FUNCTION_INFO_V1(_pgr_withpointsdd); +PGDLLEXPORT Datum _pgr_v4withpointsdd(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(_pgr_v4withpointsdd); static void process( @@ -50,11 +58,32 @@ void process( char *driving_side, bool details, bool equicost, + bool is_new, - Path_rt **result_tuples, + Path_rt **result_old_tuples, + size_t *result_old_count, + MST_rt **result_tuples, size_t *result_count) { - driving_side[0] = estimate_drivingSide(driving_side[0]); - PGR_DBG("estimated driving side:%c", driving_side[0]); + char d_side = ' '; + if (is_new) { + d_side = estimate_drivingSide(driving_side[0]); + if (d_side == ' ') { + throw_error("Invalid value of 'driving side'", "Valid value are 'r', 'l', 'b'"); + return; + } + if (!(d_side == 'r' || d_side == 'l') && directed) { + throw_error("Graph is directed", "Valid values are 'r', 'l'"); + return; + } + if (!(d_side == 'b') && !directed) { + throw_error("Graph is undirected", "Valid value is only 'b'"); + return; + } + } else { + /* TODO remove on v4 */ + char d_side = (char)tolower(driving_side[0]); + if (!((d_side == 'r') || (d_side == 'l'))) d_side = 'b'; + } pgr_SPI_connect(); char* log_msg = NULL; @@ -103,24 +132,25 @@ void process( PGR_DBG("Starting timer"); clock_t start_t = clock(); - do_pgr_many_withPointsDD( + pgr_do_withPointsDD( edges, total_edges, points, total_points, edges_of_points, total_edges_of_points, start_pidsArr, total_starts, distance, + d_side, directed, - driving_side[0], details, equicost, + is_new, - result_tuples, - result_count, + result_old_tuples, result_old_count, + result_tuples, result_count, &log_msg, ¬ice_msg, &err_msg); - time_msg(" processing withPointsDD many starts", start_t, clock()); + time_msg(" processing withPointsDD starts", start_t, clock()); if (err_msg && (*result_tuples)) { pfree(*result_tuples); @@ -143,36 +173,107 @@ void process( PGDLLEXPORT Datum -_pgr_withpointsdd(PG_FUNCTION_ARGS) { +_pgr_v4withpointsdd(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; - TupleDesc tuple_desc; + TupleDesc tuple_desc; - /**********************************************************************/ - Path_rt *result_tuples = 0; + Path_rt *result_old_tuples = 0; + size_t result_old_count = 0; + MST_rt *result_tuples = 0; size_t result_count = 0; - /**********************************************************************/ - if (SRF_IS_FIRSTCALL()) { MemoryContext oldcontext; funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); + process( + text_to_cstring(PG_GETARG_TEXT_P(0)), + text_to_cstring(PG_GETARG_TEXT_P(1)), + PG_GETARG_ARRAYTYPE_P(2), + PG_GETARG_FLOAT8(3), + + PG_GETARG_BOOL(5), + text_to_cstring(PG_GETARG_TEXT_P(4)), + PG_GETARG_BOOL(6), + PG_GETARG_BOOL(7), + + true, + &result_old_tuples, &result_old_count, + &result_tuples, &result_count); - /**********************************************************************/ - // CREATE OR REPLACE FUNCTION pgr_withPointsDD( - // edges_sql TEXT, - // points_sql TEXT, - // start_pids anyarray, - // distance FLOAT, - // - // directed BOOLEAN -- DEFAULT true, - // driving_side CHAR -- DEFAULT 'b', - // details BOOLEAN -- DEFAULT false, - // equicost BOOLEAN -- DEFAULT false, + funcctx->max_calls = result_count; + funcctx->user_fctx = result_tuples; + if (get_call_result_type(fcinfo, NULL, &tuple_desc) + != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); + funcctx->tuple_desc = tuple_desc; + MemoryContextSwitchTo(oldcontext); + } + funcctx = SRF_PERCALL_SETUP(); + + tuple_desc = funcctx->tuple_desc; + result_tuples = (MST_rt*) funcctx->user_fctx; + + if (funcctx->call_cntr < funcctx->max_calls) { + HeapTuple tuple; + Datum result; + Datum *values; + bool* nulls; + + size_t numb = 7; + values = palloc(numb * sizeof(Datum)); + nulls = palloc(numb * sizeof(bool)); + + size_t i; + for (i = 0; i < numb; ++i) { + nulls[i] = false; + } + + values[0] = Int64GetDatum(funcctx->call_cntr + 1); + values[1] = Int64GetDatum(result_tuples[funcctx->call_cntr].depth); + values[2] = Int64GetDatum(result_tuples[funcctx->call_cntr].from_v); + values[3] = Int64GetDatum(result_tuples[funcctx->call_cntr].node); + values[4] = Int64GetDatum(result_tuples[funcctx->call_cntr].edge); + values[5] = Float8GetDatum(result_tuples[funcctx->call_cntr].cost); + values[6] = Float8GetDatum(result_tuples[funcctx->call_cntr].agg_cost); + + tuple = heap_form_tuple(tuple_desc, values, nulls); + result = HeapTupleGetDatum(tuple); + + pfree(values); + pfree(nulls); + + SRF_RETURN_NEXT(funcctx, result); + } else { + SRF_RETURN_DONE(funcctx); + } +} + + +/* TODO remove old code in v4 */ +PGDLLEXPORT Datum _pgr_withpointsdd(PG_FUNCTION_ARGS); +PG_FUNCTION_INFO_V1(_pgr_withpointsdd); + +PGDLLEXPORT Datum +_pgr_withpointsdd(PG_FUNCTION_ARGS) { + FuncCallContext *funcctx; + TupleDesc tuple_desc; + + Path_rt *result_tuples = 0; + size_t result_count = 0; + MST_rt *result_new_tuples = 0; + size_t result_new_count = 0; + + if (SRF_IS_FIRSTCALL()) { + MemoryContext oldcontext; + funcctx = SRF_FIRSTCALL_INIT(); + oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); - PGR_DBG("Calling driving_many_to_dist_driver"); process( text_to_cstring(PG_GETARG_TEXT_P(0)), text_to_cstring(PG_GETARG_TEXT_P(1)), @@ -183,9 +284,10 @@ _pgr_withpointsdd(PG_FUNCTION_ARGS) { text_to_cstring(PG_GETARG_TEXT_P(5)), PG_GETARG_BOOL(6), PG_GETARG_BOOL(7), - &result_tuples, &result_count); - /**********************************************************************/ + false, + &result_tuples, &result_count, + &result_new_tuples, &result_new_count); funcctx->max_calls = result_count; @@ -198,10 +300,8 @@ _pgr_withpointsdd(PG_FUNCTION_ARGS) { "that cannot accept type record"))); funcctx->tuple_desc = tuple_desc; - MemoryContextSwitchTo(oldcontext); } - funcctx = SRF_PERCALL_SETUP(); tuple_desc = funcctx->tuple_desc; @@ -213,7 +313,6 @@ _pgr_withpointsdd(PG_FUNCTION_ARGS) { Datum *values; bool* nulls; - /**********************************************************************/ size_t numb = 6; values = palloc(numb * sizeof(Datum)); nulls = palloc(numb * sizeof(bool)); @@ -230,8 +329,6 @@ _pgr_withpointsdd(PG_FUNCTION_ARGS) { values[4] = Float8GetDatum(result_tuples[funcctx->call_cntr].cost); values[5] = Float8GetDatum(result_tuples[funcctx->call_cntr].agg_cost); - /**********************************************************************/ - tuple = heap_form_tuple(tuple_desc, values, nulls); result = HeapTupleGetDatum(tuple); @@ -243,4 +340,3 @@ _pgr_withpointsdd(PG_FUNCTION_ARGS) { SRF_RETURN_DONE(funcctx); } } - diff --git a/src/driving_distance/withPoints_dd_driver.cpp b/src/driving_distance/withPoints_dd_driver.cpp index e9731de3a95..d14e732c80c 100644 --- a/src/driving_distance/withPoints_dd_driver.cpp +++ b/src/driving_distance/withPoints_dd_driver.cpp @@ -3,12 +3,14 @@ File: withPoints_dd_driver.cpp Generated with Template by: Copyright (c) 2015 pgRouting developers -Mail: project@pgrouting.org +Mail: project at pgrouting.org Function's developer: Copyright (c) 2015 Celia Virginia Vergara Castillo Mail: vicky at erosion.dev +Copyright (c) 2023 Yige Huang +Mail: square1ge at gmail.com ------ This program is free software; you can redistribute it and/or modify @@ -37,39 +39,29 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. #include "dijkstra/drivingDist.hpp" #include "withPoints/pgr_withPoints.hpp" - +#include "driving_distance/withPointsDD.hpp" +#include "c_types/mst_rt.h" #include "cpp_common/pgr_alloc.hpp" -/**********************************************************************/ -// CREATE OR REPLACE FUNCTION pgr_withPointsDD( -// edges_sql TEXT, -// points_sql TEXT, -// start_pids anyarray, -// distance FLOAT, -// -// driving_side CHAR -- DEFAULT 'b', -// details BOOLEAN -- DEFAULT false, -// directed BOOLEAN -- DEFAULT true, -// equicost BOOLEAN -- DEFAULT false, - - void -do_pgr_many_withPointsDD( - Edge_t *edges, size_t total_edges, +pgr_do_withPointsDD( + Edge_t *edges, size_t total_edges, Point_on_edge_t *points_p, size_t total_points, - Edge_t *edges_of_points, size_t total_edges_of_points, + Edge_t *edges_of_points, size_t total_edges_of_points, + int64_t *start_pidsArr, size_t s_len, - int64_t *start_pidsArr, size_t s_len, double distance, + char driving_side, bool directed, - char driving_side, bool details, bool equiCost, + bool do_new, - Path_rt **return_tuples, size_t *return_count, + Path_rt **return_old_tuples, size_t *return_old_count, + MST_rt **return_tuples, size_t *return_count, char** log_msg, char** notice_msg, char** err_msg) { @@ -123,7 +115,8 @@ do_pgr_many_withPointsDD( graphType gType = directed? DIRECTED: UNDIRECTED; - std::deque< Path >paths; + std::deque paths; + std::deque results; if (directed) { pgrouting::DirectedGraph digraph(gType); @@ -131,40 +124,57 @@ do_pgr_many_withPointsDD( digraph.insert_edges(pg_graph.new_edges()); paths = pgr_drivingDistance( digraph, start_vids, distance, equiCost, log); + if (do_new) { + pgrouting::functions::ShortestPath_tree spt; + results = spt.get_depths(digraph, pg_graph, paths, details); + } } else { pgrouting::UndirectedGraph undigraph(gType); undigraph.insert_edges(edges, total_edges); undigraph.insert_edges(pg_graph.new_edges()); - paths = pgr_drivingDistance( undigraph, start_vids, distance, equiCost, log); + if (do_new) { + pgrouting::functions::ShortestPath_tree spt; + results = spt.get_depths(undigraph, pg_graph, paths, details); + } } - for (auto &path : paths) { - log << path; + if (do_new) { + size_t count(results.size()); + if (count == 0) { + *notice_msg = pgr_msg("No return values was found"); + return; + } + *return_tuples = pgr_alloc(count, (*return_tuples)); + for (size_t i = 0; i < count; i++) { + *((*return_tuples) + i) = results[i]; + } + (*return_count) = count; + + } else { + /* old code */ + for (auto &path : paths) { if (!details) { pg_graph.eliminate_details_dd(path); } - log << path; std::sort(path.begin(), path.end(), [](const Path_t &l, const Path_t &r) {return l.node < r.node;}); std::stable_sort(path.begin(), path.end(), [](const Path_t &l, const Path_t &r) {return l.agg_cost < r.agg_cost;}); - log << path; } - size_t count(count_tuples(paths)); - if (count == 0) { *notice_msg = pgr_msg("No return values was found"); return; } - *return_tuples = pgr_alloc(count, (*return_tuples)); - *return_count = collapse_paths(return_tuples, paths); + *return_old_tuples = pgr_alloc(count, (*return_old_tuples)); + *return_old_count = collapse_paths(return_old_tuples, paths); + } *log_msg = log.str().empty()? *log_msg : pgr_msg(log.str().c_str()); diff --git a/src/withPoints/get_new_queries.cpp b/src/withPoints/get_new_queries.cpp index 066c24b2490..e7d55fceba8 100644 --- a/src/withPoints/get_new_queries.cpp +++ b/src/withPoints/get_new_queries.cpp @@ -35,9 +35,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. char estimate_drivingSide(char driving_side) { char d_side = static_cast(tolower(driving_side)); - if (!((d_side == 'r') - || (d_side == 'l'))) { - d_side = 'b'; + if (!((d_side == 'r') || (d_side == 'l') || (d_side == 'b'))) { + d_side = ' '; } return d_side; }