Ticket #15: split_parallel_edges.sql

File split_parallel_edges.sql, 3.2 KB (added by anton, 3 years ago)
Line 
1CREATE OR REPLACE FUNCTION split_parallel_edges(
2       varchar, varchar, varchar, integer)
3       RETURNS VOID AS
4$$
5DECLARE
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       
43BEGIN
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;
126END;
127$$
128LANGUAGE 'plpgsql' VOLATILE STRICT;