1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
/*PGR-GNU*****************************************************************
Copyright (c) 2015 pgRouting developers
Mail: project@pgrouting.org
------
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*/
--v3.0
CREATE FUNCTION pgr_trspViaEdges(
text, -- SQL (required)
integer[], -- eids (required)
FLOAT[], -- pcts (required)
BOOLEAN, -- directed (required)
BOOLEAN, -- has_rcost (requierd)
turn_restrict_sql text DEFAULT NULL::text,
OUT seq INTEGER,
OUT id1 INTEGER,
OUT id2 INTEGER,
OUT id3 INTEGER,
OUT cost FLOAT
)
RETURNS SETOF RECORD AS
$body$
/*
* pgr_trsp(sql text, eids integer[], pcts float8[], directed boolean, has_reverse_cost boolean, turn_restrict_sql text DEFAULT NULL::text)
*
* Compute TRSP with edge_ids and pposition along edge. We compute the path between eids[i], pcts[i] and eids[i+1], pcts[i+1]
* and chain the results together.
*
* NOTE: this is a prototype function, we can gain a lot of efficiencies by implementing this in C/C++
*
*/
declare
sql TEXT := $1;
eids INTEGER[] := $2;
pcts FLOAT[] := $3;
directed BOOLEAN := $4;
has_rcost BOOLEAN := $5;
i integer;
rr RECORD;
lrr RECORD;
first boolean := true;
seq1 integer := 0;
seq2 integer :=0;
has_reverse BOOLEAN;
point_is_vertex BOOLEAN := false;
edges_sql TEXT;
f float;
begin
RAISE WARNING 'pgr_trspViaEdges(text,integer[],float[],boolean,boolean,text) deprecated on v3.4.0';
SELECT 0::INTEGER AS seq, NULL::INTEGER AS id1, NULL::INTEGER AS id2, NULL::INTEGER AS id3, NULL::FLOAT AS cost INTO lrr;
has_reverse =_pgr_parameter_check('dijkstra', sql, false);
edges_sql := sql;
IF (has_reverse != has_rcost) THEN
IF (NOT has_rcost) THEN
-- user does not want to use reverse cost column
edges_sql = 'SELECT id, source, target, cost FROM (' || sql || ') a';
ELSE
raise EXCEPTION 'has_rcost set to true but reverse_cost not found';
END IF;
END IF;
FOREACH f IN ARRAY pcts LOOP
IF f in (0,1) THEN
point_is_vertex := true;
END IF;
END LOOP;
IF (turn_restrict_sql IS NULL OR length(turn_restrict_sql) = 0) AND NOT point_is_vertex THEN
-- no restrictions then its a _pgr_withPointsVia
RETURN query SELECT a.seq::INTEGER, path_id::INTEGER AS id1, node::INTEGER AS id2, edge::INTEGER AS id3, a.cost
FROM _pgr_withPointsVia(edges_sql, eids, pcts, directed) a;
RETURN;
END IF;
if array_length(eids, 1) != array_length(pcts, 1) then
raise exception 'The length of arrays eids and pcts must be the same!';
end if;
-- loop through each pair of vids and compute the path
for i in 1 .. array_length(eids, 1)-1 loop
seq2 := seq2 + 1;
for rr in select a.seq, seq2 as id1, a.id1 as id2, a.id2 as id3, a.cost
from pgr_trsp(edges_sql,
eids[i], pcts[i],
eids[i+1], pcts[i+1],
directed,
has_rcost,
turn_restrict_sql) as a loop
-- combine intermediate via costs when cost is split across
-- two parts of a segment because it stops it and
-- restarts the next leg also on it
-- we might not want to do this so we can know where the via points are in the path result
-- but this needs more thought
--
-- there are multiple condition we have to deal with
-- between the end of one leg and start of the next
-- 1. same vertex_id. edge_id=-1; drop record with edge_id=-1
-- means: path ends on vertex
-- NOTICE: rr: (19,1,44570022,-1,0)
-- NOTICE: rr: (0,2,44570022,1768045,2.89691196717448)
-- 2. vertex_id=-1; sum cost components
-- means: path end/starts with the segment
-- NOTICE: rr: (11,2,44569628,1775909,9.32885885148532)
-- NOTICE: rr: (0,3,-1,1775909,0.771386350984395)
--raise notice 'rr: %', rr;
if first then
lrr := rr;
first := false;
else
if lrr.id3 = -1 then
lrr := rr;
elsif lrr.id3 = rr.id3 then
lrr.cost := lrr.cost + rr.cost;
if rr.id2 = -1 then
rr.id2 := lrr.id2;
end if;
else
seq1 := seq1 + 1;
lrr.seq := seq1;
seq := lrr.seq;
id1 := lrr.id1;
id2 := lrr.id2;
id3 := lrr.id3;
cost := lrr.cost;
return next;
lrr := rr;
end if;
end if;
end loop;
end loop;
seq1 := seq1 + 1;
lrr.seq := seq1;
seq := lrr.seq;
id1 := lrr.id1;
id2 := lrr.id2;
id3 := lrr.id3;
cost := lrr.cost;
return next;
return;
end;
$body$
language plpgsql stable
cost 100
rows 1000;
-- COMMENTS
COMMENT ON FUNCTION pgr_trspViaEdges(TEXT, INTEGER[], FLOAT[], BOOLEAN, BOOLEAN, TEXT)
IS 'pgr_trspViaEdges
- DEPRECATED function on v3.4.0
- Documentation:
- ${PROJECT_DOC_LINK}/pgr_trspVia_withPoints.html
';
|