pgRouting

Ticket #15: split_parallel_edges.sql

File split_parallel_edges.sql, 3.2 kB (added by anton, 1 year ago)
Line 
1 CREATE OR REPLACE FUNCTION split_parallel_edges(
2        varchar, varchar, varchar, integer)
3        RETURNS VOID AS
4 $$
5 DECLARE
6         tbl ALIAS FOR $1;
7         gid_seq ALIAS FOR $2;
8         v_seq ALIAS FOR $3;
9         count ALIAS FOR $4;
10
11         row record;
12         r record;
13        
14         gid integer;
15        
16         source integer;
17         target integer;
18         p_source integer;
19         p_target integer;
20        
21         x1 double precision;
22         y1 double precision;
23         x2 double precision;
24         y2 double precision;
25        
26         geom geometry;
27         muid integer;
28         class_id integer;
29         length double precision;
30         reverse_cost double precision;
31        
32         l1 geometry;
33         l2 geometry;
34        
35         v_max integer;
36         gid_max integer;
37        
38         s_max integer;
39         t_max integer;
40        
41         srid integer;
42        
43 BEGIN
44        
45         FOR row IN EXECUTE
46             'select srid(the_geom) from ' ||tbl|| ' limit 1'
47         LOOP
48         END LOOP;
49         srid := row.srid;
50        
51         FOR row IN EXECUTE 'select max(gid) as max from '||tbl LOOP
52         END LOOP;
53        
54         gid_max := row.max;
55
56         FOR row IN EXECUTE 'select max(source) as max from '||tbl LOOP
57         END LOOP;
58        
59         s_max := row.max;
60
61         FOR row IN EXECUTE 'select max(target) as max from '||tbl LOOP
62         END LOOP;
63        
64         t_max := row.max;
65
66         IF s_max > t_max THEN
67             v_max := s_max;
68         ELSE
69             v_max := t_max;
70         END IF;
71        
72        
73         EXECUTE 'drop sequence '||v_seq;
74         EXECUTE 'drop sequence '||gid_seq;     
75
76         EXECUTE 'create sequence '||v_seq||' start '||v_max;
77         EXECUTE 'create sequence '||gid_seq||' start '||gid_max;       
78        
79         p_source := 0;
80         p_target := 0;
81        
82         FOR row IN EXECUTE 'select gid, the_geom, id, source, target,x1,y1,x2,y2,class_id,length,reverse_cost from '||tbl||
83                                     ' where (source, target) in (select source, target from '||tbl||
84                                     ' t2 group by source, target having count(*)>'||count||') order by source, target, length'
85         LOOP
86
87                  gid := row.gid;
88                  geom := row.the_geom;
89                  source := row.source;
90                  target := row.target;
91                  muid := row.id;
92                  x1 := row.x1;
93                  y1 := row.y1;
94                  x2 := row.x2;
95                  y2 := row.y2;
96                  length := row.length;
97                  class_id := row.class_id;
98                  reverse_cost := row.reverse_cost;
99                  
100                  IF source = p_source AND target=p_target THEN
101                     l1 := setsrid(line_substring(linemerge(geom), 0, 0.5), srid);
102                     l2 := setsrid(line_substring(linemerge(geom), 0.5, 1), srid);
103                    
104                     RAISE NOTICE 'gid=%',gid;
105                    
106                     EXECUTE 'delete from '||tbl||' where gid = '||gid;
107                    
108                     EXECUTE 'insert into '||tbl||' (gid, the_geom, x1,y1,x2,y2,source, target,id, length, reverse_cost, class_id) '||
109                                         'values ('||gid||', multi(geomfromtext('''||astext(l1)||''','||srid||')), '||x1||', '||y1||', '||
110                                         x(endpoint(l1))||', '||y(endpoint(l1))||','||
111                                         source||', (select nextval('''||v_seq||''')), '||muid||', '||length/2||
112                                         ', '||reverse_cost/2||', '||class_id||')';
113
114                     EXECUTE 'insert into '||tbl||' (gid, the_geom, x1,y1,x2,y2,source, target,id, length, reverse_cost, class_id) '||
115                                         'values ((select nextval('''||gid_seq||''')), multi(geomfromtext('''||astext(l2)||''','||srid||')), '||
116                                         x(endpoint(l2))||', '||y(endpoint(l2))||','||
117                                         x2||', '||y2||', (select currval('''||v_seq||''')), '||target||', '||muid||', '||length/2||
118                                         ', '||reverse_cost/2||', '||class_id||')';
119                  ELSE
120                     p_source = source;
121                     p_target = target;
122                  END IF;
123
124         END LOOP;
125         RETURN;
126 END;
127 $$
128 LANGUAGE 'plpgsql' VOLATILE STRICT;