root/branches/anton/core/sql/routing_core_wrappers.sql

Revision 28, 31.9 KB (checked in by anton, 3 years ago)

cmake branch added

Line 
1--
2-- Copyright (c) 2005 Sylvain Pasche,
3--               2006-2007 Anton A. Patrushev, Orkney, Inc.
4--
5-- This program is free software; you can redistribute it and/or modify
6-- it under the terms of the GNU General Public License as published by
7-- the Free Software Foundation; either version 2 of the License, or
8-- (at your option) any later version.
9--
10-- This program is distributed in the hope that it will be useful,
11-- but WITHOUT ANY WARRANTY; without even the implied warranty of
12-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13-- GNU General Public License for more details.
14--
15-- You should have received a copy of the GNU General Public License
16-- along with this program; if not, write to the Free Software
17-- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19
20-- TODO: use spatial index when possible
21-- TODO: make variable names more consistent
22
23-- Geometry schema description:
24-- gid
25-- source_id
26-- target_id
27-- edge_id
28
29-- BEGIN;
30
31-----------------------------------------------------------------------
32-- For each vertex in the vertices table, set a point geometry which is
33--  the corresponding line start or line end point
34-----------------------------------------------------------------------
35CREATE OR REPLACE FUNCTION add_vertices_geometry(geom_table varchar)
36       RETURNS VOID AS
37$$
38DECLARE
39        vertices_table varchar := quote_ident(geom_table) || '_vertices';
40BEGIN
41       
42        BEGIN
43                EXECUTE 'SELECT addGeometryColumn(''' ||
44                        quote_ident(vertices_table)  ||
45                        ''', ''the_geom'', -1, ''POINT'', 2)';
46        EXCEPTION
47                WHEN DUPLICATE_COLUMN THEN
48        END;
49
50        EXECUTE 'UPDATE ' || quote_ident(vertices_table) ||
51                ' SET the_geom = NULL';
52
53        EXECUTE 'UPDATE ' || quote_ident(vertices_table) ||
54                ' SET the_geom = startPoint(geometryn(m.the_geom, 1)) FROM ' ||
55                 quote_ident(geom_table) ||
56                ' m where geom_id = m.source_id';
57
58        EXECUTE 'UPDATE ' || quote_ident(vertices_table) ||
59                ' set the_geom = endPoint(geometryn(m.the_geom, 1)) FROM ' ||
60                quote_ident(geom_table) ||
61                ' m where geom_id = m.target_id AND ' ||
62                quote_ident(vertices_table) ||
63                '.the_geom IS NULL';
64
65        RETURN;
66END;
67$$
68LANGUAGE 'plpgsql' VOLATILE STRICT;
69
70-----------------------------------------------------------------------
71-- This function should not be used directly. Use assign_vertex_id instead
72--
73-- Inserts a point into a temporary vertices table, and return an id
74--  of a new point or an existing point. Tolerance is the minimal distance
75--  between existing points and the new point to create a new point.
76-----------------------------------------------------------------------
77CREATE OR REPLACE FUNCTION point_to_id(point geometry,
78       tolerance double precision)
79       RETURNS INT AS
80$$
81DECLARE
82        row record;
83        point_id int;
84BEGIN
85        LOOP
86                -- TODO: use && and index       
87                SELECT INTO row id, the_geom FROM vertices_tmp WHERE
88                   distance(the_geom, point) < tolerance;
89
90                point_id := row.id;
91
92                IF NOT FOUND THEN
93                        INSERT INTO vertices_tmp (the_geom) VALUES (point);
94                ELSE
95                        EXIT;
96                END IF;
97        END LOOP;
98        RETURN point_id;
99END;
100$$
101LANGUAGE 'plpgsql' VOLATILE STRICT;
102
103
104-----------------------------------------------------------------------
105-- Fill the source_id and target_id column for all lines. All line ends
106--  with a distance less than tolerance, are assigned the same id
107-----------------------------------------------------------------------
108CREATE OR REPLACE FUNCTION assign_vertex_id(geom_table varchar,
109       tolerance double precision,
110       geo_cname varchar,
111       gid_cname varchar)
112       RETURNS VARCHAR AS
113$$
114DECLARE
115      points record;
116      i record;
117      source_id int;
118      target_id int;
119      pre varchar;
120      post varchar;
121     
122      srid integer;
123                                       
124      BEGIN
125                                       
126            BEGIN
127                DROP TABLE vertices_tmp;
128                EXCEPTION
129                        WHEN UNDEFINED_TABLE THEN
130                END;
131                                                                   
132                CREATE TABLE vertices_tmp ( id serial );       
133                                                                       
134               
135                FOR i IN EXECUTE 'SELECT srid FROM geometry_columns WHERE f_table_name='''|| quote_ident(geom_table)||'''' LOOP
136                END LOOP;
137               
138                srid := i.srid;
139               
140                EXECUTE 'SELECT addGeometryColumn(''vertices_tmp'', ''the_geom'', '||srid||', ''POINT'', 2)';
141                                                                                                                         
142                CREATE INDEX vertices_tmp_idx ON vertices_tmp USING GIST (the_geom);
143                                                                                                                           
144                pre = '';
145                post = '';
146               
147                FOR i in EXECUTE 'SELECT count(*) as t from ' || quote_ident(geom_table) || ' WHERE NumGeometries(' || quote_ident(geo_cname) || ') is not null'  loop
148                        IF (i.t > 0) THEN
149                            pre = 'geometryN(';
150                            post = ' , 1)';
151                        END IF;
152                END LOOP;
153                                                                                                                                                                                           
154                FOR points IN EXECUTE 'SELECT ' || quote_ident(gid_cname) || ' AS id,'
155                        || ' startPoint(' || pre || quote_ident(geo_cname) || post || ') AS source,'
156                        || ' endPoint(' || pre || quote_ident(geo_cname) || post || ') as target'
157                        || ' FROM ' || quote_ident(geom_table) loop
158
159                                source_id := point_to_id(setsrid(points.source, srid), tolerance);
160                                target_id := point_to_id(setsrid(points.target, srid), tolerance);
161                                                                                                                                                                                                                                       
162                                EXECUTE 'update ' || quote_ident(geom_table) ||
163                                    ' SET source_id = ' || source_id ||
164                                    ', target_id = ' || target_id ||
165                                    ' WHERE ' || quote_ident(gid_cname) || ' =  ' || points.id;
166                END LOOP;
167                                                                                                                                                                                                                                                                                                           
168RETURN 'OK';
169
170END;
171$$
172LANGUAGE 'plpgsql' VOLATILE STRICT;
173
174-----------------------------------------------------------------------
175-- Update the cost column from the edges table, from the length of
176--  all lines which belong to an edge.
177-----------------------------------------------------------------------
178-- FIXME: directed or not ?
179CREATE OR REPLACE FUNCTION update_cost_from_distance(geom_table varchar)
180       RETURNS VOID AS
181$$
182DECLARE
183BEGIN
184        BEGIN
185          EXECUTE 'CREATE INDEX ' || quote_ident(geom_table) ||
186                  '_edge_id_idx ON ' || quote_ident(geom_table) ||
187                  ' (edge_id)';
188        EXCEPTION
189                WHEN DUPLICATE_TABLE THEN
190                RAISE NOTICE 'Not creating index, already there';
191        END;
192
193        EXECUTE 'UPDATE ' || quote_ident(geom_table) ||
194              '_edges SET cost = (SELECT sum( length( g.the_geom ) ) FROM ' ||
195              quote_ident(geom_table) ||
196              ' g WHERE g.edge_id = id GROUP BY id)';
197
198        RETURN;
199END;
200$$
201LANGUAGE 'plpgsql' VOLATILE STRICT;
202
203
204CREATE TYPE geoms AS
205(
206  id integer,
207  gid integer,
208  the_geom geometry
209);
210
211-----------------------------------------------------------------------
212-- Compute the shortest path using edges and vertices table, and return
213--  the result as a set of (gid integer, the_geom gemoetry) records.
214-- This function uses the internal vertices identifiers.
215-----------------------------------------------------------------------
216CREATE OR REPLACE FUNCTION dijkstra_sp(
217       geom_table varchar, source int4, target int4)
218       RETURNS SETOF GEOMS AS
219$$
220DECLARE
221        r record;
222        path_result record;
223        v_id integer;
224        e_id integer;
225        geom geoms;
226        id integer;
227BEGIN
228       
229        id :=0;
230       
231        FOR path_result IN EXECUTE 'SELECT gid,the_geom FROM ' ||
232          'shortest_path(''SELECT gid as id, source::integer, target::integer, ' ||
233          'length::double precision as cost FROM ' ||
234          quote_ident(geom_table) || ''', ' || quote_literal(source) ||
235          ' , ' || quote_literal(target) || ' , false, false), ' ||
236          quote_ident(geom_table) || ' where edge_id = gid '
237        LOOP
238
239                 geom.gid      := path_result.gid;
240                 geom.the_geom := path_result.the_geom;
241                 id := id+1;
242                 geom.id       := id;
243                 
244                 RETURN NEXT geom;
245
246        END LOOP;
247        RETURN;
248END;
249$$
250LANGUAGE 'plpgsql' VOLATILE STRICT;
251
252CREATE OR REPLACE FUNCTION dijkstra_sp_directed(
253       geom_table varchar, source int4, target int4, dir boolean, rc boolean)
254       RETURNS SETOF GEOMS AS
255$$
256DECLARE
257        r record;
258        path_result record;
259        v_id integer;
260        e_id integer;
261        geom geoms;
262        query text;
263        id integer;
264BEGIN
265       
266        id :=0;
267       
268        query := 'SELECT gid,the_geom FROM ' ||
269          'shortest_path(''SELECT gid as id, source::integer, target::integer, ' ||
270          'length::double precision as cost ';
271         
272        IF rc THEN query := query || ', reverse_cost '; 
273        END IF;
274       
275        query := query || 'FROM ' ||  quote_ident(geom_table) || ''', ' || quote_literal(source) ||
276          ' , ' || quote_literal(target) || ' , '''||dir||''', '''||rc||'''), ' ||
277          quote_ident(geom_table) || ' where edge_id = gid ';
278
279        FOR path_result IN EXECUTE query
280        LOOP
281
282                 geom.gid      := path_result.gid;
283                 geom.the_geom := path_result.the_geom;
284                 id := id+1;
285                 geom.id       := id;
286                 
287                 RETURN NEXT geom;
288
289        END LOOP;
290        RETURN;
291END;
292$$
293LANGUAGE 'plpgsql' VOLATILE STRICT;
294
295-----------------------------------------------------------------------
296-- Compute the shortest path using edges and vertices table, and return
297--  the result as a set of (gid integer, the_geom gemoetry) records.
298-- This function uses the internal vertices identifiers.
299-- Also data clipping added to improve function performance.
300-----------------------------------------------------------------------
301CREATE OR REPLACE FUNCTION astar_sp_delta(
302       varchar,int4, int4, float8)
303       RETURNS SETOF GEOMS AS
304$$
305DECLARE
306        geom_table ALIAS FOR $1;
307        sourceid ALIAS FOR $2;
308        targetid ALIAS FOR $3;
309        delta ALIAS FOR $4;
310
311        rec record;
312        r record;
313        path_result record;
314        v_id integer;
315        e_id integer;
316        geom geoms;
317       
318        id integer;
319BEGIN
320       
321        id :=0;
322
323        FOR path_result IN EXECUTE 'SELECT gid,the_geom FROM ' ||
324           'astar_sp_delta_directed(''' ||
325           quote_ident(geom_table) || ''', ' || quote_literal(sourceid) || ', ' ||
326           quote_literal(targetid) || ', ' || delta || ', false, false)'
327        LOOP
328
329                 geom.gid      := path_result.gid;
330                 geom.the_geom := path_result.the_geom;
331                 id := id+1;
332                 geom.id       := id;
333                 
334                 RETURN NEXT geom;
335--
336--                v_id = path_result.vertex_id;
337--                e_id = path_result.edge_id;
338
339--                FOR r IN EXECUTE 'SELECT gid, the_geom FROM ' ||
340--                      quote_ident(geom_table) || '  WHERE gid = ' ||
341--                      quote_literal(e_id) LOOP
342--                        geom.gid := r.gid;
343--                        geom.the_geom := r.the_geom;
344--                        RETURN NEXT geom;
345--                END LOOP;
346
347        END LOOP;
348        RETURN;
349END;
350$$
351LANGUAGE 'plpgsql' VOLATILE STRICT;
352
353CREATE OR REPLACE FUNCTION astar_sp_delta_directed(
354       varchar,int4, int4, float8, boolean, boolean)
355       RETURNS SETOF GEOMS AS
356$$
357DECLARE
358        geom_table ALIAS FOR $1;
359        sourceid ALIAS FOR $2;
360        targetid ALIAS FOR $3;
361        delta ALIAS FOR $4;
362        dir ALIAS FOR $5;
363        rc ALIAS FOR $6;
364
365        rec record;
366        r record;
367        path_result record;
368        v_id integer;
369        e_id integer;
370        geom geoms;
371       
372        srid integer;
373
374        source_x float8;
375        source_y float8;
376        target_x float8;
377        target_y float8;
378       
379        ll_x float8;
380        ll_y float8;
381        ur_x float8;
382        ur_y float8;
383       
384        query text;
385
386        id integer;
387BEGIN
388       
389        id :=0;
390        FOR rec IN EXECUTE
391            'select srid(the_geom) from ' ||
392            quote_ident(geom_table) || ' limit 1'
393        LOOP
394        END LOOP;
395        srid := rec.srid;
396       
397        FOR rec IN EXECUTE
398            'select x(startpoint(the_geom)) as source_x from ' ||
399            quote_ident(geom_table) || ' where source = ' ||
400            sourceid ||  ' or target='||sourceid||' limit 1'
401        LOOP
402        END LOOP;
403        source_x := rec.source_x;
404       
405        FOR rec IN EXECUTE
406            'select y(startpoint(the_geom)) as source_y from ' ||
407            quote_ident(geom_table) || ' where source = ' ||
408            sourceid ||  ' or target='||sourceid||' limit 1'
409        LOOP
410        END LOOP;
411
412        source_y := rec.source_y;
413
414        FOR rec IN EXECUTE
415            'select x(startpoint(the_geom)) as target_x from ' ||
416            quote_ident(geom_table) || ' where source = ' ||
417            targetid ||  ' or target='||targetid||' limit 1'
418        LOOP
419        END LOOP;
420
421        target_x := rec.target_x;
422       
423        FOR rec IN EXECUTE
424            'select y(startpoint(the_geom)) as target_y from ' ||
425            quote_ident(geom_table) || ' where source = ' ||
426            targetid ||  ' or target='||targetid||' limit 1'
427        LOOP
428        END LOOP;
429        target_y := rec.target_y;
430
431        FOR rec IN EXECUTE 'SELECT CASE WHEN '||source_x||'<'||target_x||
432           ' THEN '||source_x||' ELSE '||target_x||
433           ' END as ll_x, CASE WHEN '||source_x||'>'||target_x||
434           ' THEN '||source_x||' ELSE '||target_x||' END as ur_x'
435        LOOP
436        END LOOP;
437
438        ll_x := rec.ll_x;
439        ur_x := rec.ur_x;
440
441        FOR rec IN EXECUTE 'SELECT CASE WHEN '||source_y||'<'||
442            target_y||' THEN '||source_y||' ELSE '||
443            target_y||' END as ll_y, CASE WHEN '||
444            source_y||'>'||target_y||' THEN '||
445            source_y||' ELSE '||target_y||' END as ur_y'
446        LOOP
447        END LOOP;
448
449        ll_y := rec.ll_y;
450        ur_y := rec.ur_y;
451
452        query := 'SELECT gid,the_geom FROM ' ||
453          'shortest_path_astar(''SELECT gid as id, source::integer, ' ||
454          'target::integer, length::double precision as cost, ' ||
455          'x1::double precision, y1::double precision, x2::double ' ||
456          'precision, y2::double precision ';
457         
458        IF rc THEN query := query || ' , reverse_cost '; 
459        END IF;
460         
461        query := query || 'FROM ' || quote_ident(geom_table) || ' where setSRID(''''BOX3D('||
462          ll_x-delta||' '||ll_y-delta||','||ur_x+delta||' '||
463          ur_y+delta||')''''::BOX3D, ' || srid || ') && the_geom'', ' ||
464          quote_literal(sourceid) || ' , ' ||
465          quote_literal(targetid) || ' , '''||dir||''', '''||rc||''' ),' ||
466          quote_ident(geom_table) || ' where edge_id = gid ';
467         
468        FOR path_result IN EXECUTE query
469        LOOP
470                 geom.gid      := path_result.gid;
471                 geom.the_geom := path_result.the_geom;
472                 id := id+1;
473                 geom.id       := id;
474                 
475                 RETURN NEXT geom;
476--
477--                v_id = path_result.vertex_id;
478--                e_id = path_result.edge_id;
479
480--                FOR r IN EXECUTE 'SELECT gid, the_geom FROM ' ||
481--                      quote_ident(geom_table) || '  WHERE gid = ' ||
482--                      quote_literal(e_id) LOOP
483--                        geom.gid := r.gid;
484--                        geom.the_geom := r.the_geom;
485--                        RETURN NEXT geom;
486--                END LOOP;
487
488        END LOOP;
489        RETURN;
490END;
491$$
492LANGUAGE 'plpgsql' VOLATILE STRICT;
493
494
495CREATE OR REPLACE FUNCTION astar_sp_delta_cc(
496       varchar,int4, int4, float8, varchar)
497       RETURNS SETOF GEOMS AS
498$$
499DECLARE
500        geom_table ALIAS FOR $1;
501        sourceid ALIAS FOR $2;
502        targetid ALIAS FOR $3;
503        delta ALIAS FOR $4;
504        cost_column ALIAS FOR $5;
505
506        rec record;
507        r record;
508        path_result record;
509        v_id integer;
510        e_id integer;
511        geom geoms;
512       
513        id integer;
514BEGIN
515       
516        id :=0;
517        FOR path_result IN EXECUTE 'SELECT gid,the_geom FROM ' ||
518           'astar_sp_delta_cc_directed(''' ||
519           quote_ident(geom_table) || ''', ' || quote_literal(sourceid) || ', ' ||
520           quote_literal(targetid) || ', ' || delta || ',' ||
521           quote_literal(cost_column) || ', false, false)'
522        LOOP
523
524                 geom.gid      := path_result.gid;
525                 geom.the_geom := path_result.the_geom;
526                 id := id+1;
527                 geom.id       := id;
528                 
529                 RETURN NEXT geom;
530
531        END LOOP;
532        RETURN;
533END;
534$$
535LANGUAGE 'plpgsql' VOLATILE STRICT;
536
537CREATE OR REPLACE FUNCTION astar_sp_delta_cc_directed(
538       varchar,int4, int4, float8, varchar, boolean, boolean)
539       RETURNS SETOF GEOMS AS
540$$
541DECLARE
542        geom_table ALIAS FOR $1;
543        sourceid ALIAS FOR $2;
544        targetid ALIAS FOR $3;
545        delta ALIAS FOR $4;
546        cost_column ALIAS FOR $5;
547        dir ALIAS FOR $6;
548        rc ALIAS FOR $7;
549
550        rec record;
551        r record;
552        path_result record;
553        v_id integer;
554        e_id integer;
555        geom geoms;
556       
557        srid integer;
558
559        source_x float8;
560        source_y float8;
561        target_x float8;
562        target_y float8;
563       
564        ll_x float8;
565        ll_y float8;
566        ur_x float8;
567        ur_y float8;
568       
569        query text;
570
571        id integer;
572BEGIN
573       
574        id :=0;
575        FOR rec IN EXECUTE
576            'select srid(the_geom) from ' ||
577            quote_ident(geom_table) || ' limit 1'
578        LOOP
579        END LOOP;
580        srid := rec.srid;
581       
582        FOR rec IN EXECUTE
583            'select x(startpoint(the_geom)) as source_x from ' ||
584            quote_ident(geom_table) || ' where source = ' ||
585            sourceid || ' or target='||sourceid||' limit 1'
586        LOOP
587        END LOOP;
588        source_x := rec.source_x;
589       
590        FOR rec IN EXECUTE
591            'select y(startpoint(the_geom)) as source_y from ' ||
592            quote_ident(geom_table) || ' where source = ' ||
593            sourceid ||  ' or target='||sourceid||' limit 1'
594        LOOP
595        END LOOP;
596
597        source_y := rec.source_y;
598
599        FOR rec IN EXECUTE
600            'select x(startpoint(the_geom)) as target_x from ' ||
601            quote_ident(geom_table) || ' where source = ' ||
602            targetid ||  ' or target='||targetid||' limit 1'
603        LOOP
604        END LOOP;
605
606        target_x := rec.target_x;
607       
608        FOR rec IN EXECUTE
609            'select y(startpoint(the_geom)) as target_y from ' ||
610            quote_ident(geom_table) || ' where source = ' ||
611            targetid ||  ' or target='||targetid||' limit 1'
612        LOOP
613        END LOOP;
614        target_y := rec.target_y;
615
616
617        FOR rec IN EXECUTE 'SELECT CASE WHEN '||source_x||'<'||target_x||
618           ' THEN '||source_x||' ELSE '||target_x||
619           ' END as ll_x, CASE WHEN '||source_x||'>'||target_x||
620           ' THEN '||source_x||' ELSE '||target_x||' END as ur_x'
621        LOOP
622        END LOOP;
623
624        ll_x := rec.ll_x;
625        ur_x := rec.ur_x;
626
627        FOR rec IN EXECUTE 'SELECT CASE WHEN '||source_y||'<'||
628            target_y||' THEN '||source_y||' ELSE '||
629            target_y||' END as ll_y, CASE WHEN '||
630            source_y||'>'||target_y||' THEN '||
631            source_y||' ELSE '||target_y||' END as ur_y'
632        LOOP
633        END LOOP;
634
635        ll_y := rec.ll_y;
636        ur_y := rec.ur_y;
637
638        query := 'SELECT gid,the_geom FROM ' ||
639          'shortest_path_astar(''SELECT gid as id, source::integer, ' ||
640          'target::integer, '||cost_column||'::double precision as cost, ' ||
641          'x1::double precision, y1::double precision, x2::double ' ||
642          'precision, y2::double precision ';
643       
644        IF rc THEN query := query || ' , reverse_cost ';
645        END IF;
646         
647        query := query || 'FROM ' || quote_ident(geom_table) || ' where setSRID(''''BOX3D('||
648          ll_x-delta||' '||ll_y-delta||','||ur_x+delta||' '||
649          ur_y+delta||')''''::BOX3D, ' || srid || ') && the_geom'', ' ||
650          quote_literal(sourceid) || ' , ' ||
651          quote_literal(targetid) || ' , '''||dir||''', '''||rc||''' ),' ||
652          quote_ident(geom_table) || ' where edge_id = gid ';
653       
654        FOR path_result IN EXECUTE query
655        LOOP
656
657                 geom.gid      := path_result.gid;
658                 geom.the_geom := path_result.the_geom;
659                 id := id+1;
660                 geom.id       := id;
661                 
662                 RETURN NEXT geom;
663
664        END LOOP;
665        RETURN;
666END;
667$$
668LANGUAGE 'plpgsql' VOLATILE STRICT;
669
670
671CREATE OR REPLACE FUNCTION dijkstra_sp_delta(
672       varchar,int4, int4, float8)
673       RETURNS SETOF GEOMS AS
674$$
675DECLARE
676        geom_table ALIAS FOR $1;
677        sourceid ALIAS FOR $2;
678        targetid ALIAS FOR $3;
679        delta ALIAS FOR $4;
680
681        rec record;
682        r record;
683        path_result record;
684        v_id integer;
685        e_id integer;
686        geom geoms;
687       
688        id integer;
689BEGIN
690       
691        id :=0;
692        FOR path_result IN EXECUTE 'SELECT gid,the_geom FROM ' ||
693           'dijkstra_sp_delta_directed(''' ||
694           quote_ident(geom_table) || ''', ' || quote_literal(sourceid) || ', ' ||
695           quote_literal(targetid) || ', ' || delta || ', false, false)'
696        LOOP
697                 geom.gid      := path_result.gid;
698                 geom.the_geom := path_result.the_geom;
699                 id := id+1;
700                 geom.id       := id;
701                 
702                 RETURN NEXT geom;
703
704        END LOOP;
705        RETURN;
706END;
707$$
708LANGUAGE 'plpgsql' VOLATILE STRICT;
709
710CREATE OR REPLACE FUNCTION dijkstra_sp_delta_directed(
711       varchar,int4, int4, float8, boolean, boolean)
712       RETURNS SETOF GEOMS AS
713$$
714DECLARE
715        geom_table ALIAS FOR $1;
716        sourceid ALIAS FOR $2;
717        targetid ALIAS FOR $3;
718        delta ALIAS FOR $4;
719        dir ALIAS FOR $5;
720        rc ALIAS FOR $6;
721
722        rec record;
723        r record;
724        path_result record;
725        v_id integer;
726        e_id integer;
727        geom geoms;
728       
729        srid integer;
730
731        source_x float8;
732        source_y float8;
733        target_x float8;
734        target_y float8;
735       
736        ll_x float8;
737        ll_y float8;
738        ur_x float8;
739        ur_y float8;
740       
741        query text;
742        id integer;
743BEGIN
744       
745        id :=0;
746        FOR rec IN EXECUTE
747            'select srid(the_geom) from ' ||
748            quote_ident(geom_table) || ' limit 1'
749        LOOP
750        END LOOP;
751        srid := rec.srid;
752
753        FOR rec IN EXECUTE
754            'select x(startpoint(the_geom)) as source_x from ' ||
755            quote_ident(geom_table) || ' where source = ' ||
756            sourceid ||  ' or target='||sourceid||' limit 1'
757        LOOP
758        END LOOP;
759        source_x := rec.source_x;
760       
761        FOR rec IN EXECUTE
762            'select y(startpoint(the_geom)) as source_y from ' ||
763            quote_ident(geom_table) || ' where source = ' ||
764            sourceid ||  ' or target='||sourceid||' limit 1'
765        LOOP
766        END LOOP;
767
768        source_y := rec.source_y;
769
770        FOR rec IN EXECUTE
771            'select x(startpoint(the_geom)) as target_x from ' ||
772            quote_ident(geom_table) || ' where source = ' ||
773            targetid ||  ' or target='||targetid||' limit 1'
774        LOOP
775        END LOOP;
776
777        target_x := rec.target_x;
778       
779        FOR rec IN EXECUTE
780            'select y(startpoint(the_geom)) as target_y from ' ||
781            quote_ident(geom_table) || ' where source = ' ||
782            targetid ||  ' or target='||targetid||' limit 1'
783        LOOP
784        END LOOP;
785        target_y := rec.target_y;
786
787
788        FOR rec IN EXECUTE 'SELECT CASE WHEN '||source_x||'<'||target_x||
789           ' THEN '||source_x||' ELSE '||target_x||
790           ' END as ll_x, CASE WHEN '||source_x||'>'||target_x||
791           ' THEN '||source_x||' ELSE '||target_x||' END as ur_x'
792        LOOP
793        END LOOP;
794
795        ll_x := rec.ll_x;
796        ur_x := rec.ur_x;
797
798        FOR rec IN EXECUTE 'SELECT CASE WHEN '||source_y||'<'||
799            target_y||' THEN '||source_y||' ELSE '||
800            target_y||' END as ll_y, CASE WHEN '||
801            source_y||'>'||target_y||' THEN '||
802            source_y||' ELSE '||target_y||' END as ur_y'
803        LOOP
804        END LOOP;
805
806        ll_y := rec.ll_y;
807        ur_y := rec.ur_y;
808
809        query := 'SELECT gid,the_geom FROM ' ||
810          'shortest_path(''SELECT gid as id, source::integer, target::integer, ' ||
811          'length::double precision as cost ';
812         
813        IF rc THEN query := query || ' , reverse_cost ';
814        END IF;
815
816        query := query || ' FROM ' || quote_ident(geom_table) || ' where setSRID(''''BOX3D('||
817          ll_x-delta||' '||ll_y-delta||','||ur_x+delta||' '||
818          ur_y+delta||')''''::BOX3D, ' || srid || ') && the_geom'', ' ||
819          quote_literal(sourceid) || ' , ' ||
820          quote_literal(targetid) || ' , '''||dir||''', '''||rc||''' ), ' ||
821          quote_ident(geom_table) || ' where edge_id = gid ';
822         
823        FOR path_result IN EXECUTE query
824        LOOP
825                 geom.gid      := path_result.gid;
826                 geom.the_geom := path_result.the_geom;
827                 id := id+1;
828                 geom.id       := id;
829                 
830                 RETURN NEXT geom;
831
832        END LOOP;
833        RETURN;
834END;
835$$
836LANGUAGE 'plpgsql' VOLATILE STRICT;
837
838
839CREATE OR REPLACE FUNCTION astar_sp_bbox(
840       varchar,int4, int4, float8, float8, float8, float8)
841       RETURNS SETOF GEOMS AS
842$$
843DECLARE
844        geom_table ALIAS FOR $1;
845        sourceid ALIAS FOR $2;
846        targetid ALIAS FOR $3;
847        ll_x ALIAS FOR $4;
848        ll_y ALIAS FOR $5;
849        ur_x ALIAS FOR $6;
850        ur_y ALIAS FOR $7;
851
852        rec record;
853        r record;
854        path_result record;
855        v_id integer;
856        e_id integer;
857        geom geoms;
858       
859        srid integer;
860
861        id integer;
862BEGIN
863       
864        id :=0;
865        FOR path_result IN EXECUTE 'SELECT gid,the_geom FROM ' ||
866           'astar_sp_bbox_directed(''' ||
867           quote_ident(geom_table) || ''', ' || quote_literal(sourceid) || ', ' ||
868           quote_literal(targetid) || ', ' || ll_x || ', ' || ll_y || ', ' ||
869           ur_x || ', ' || ur_y || ', false, false)'
870        LOOP
871
872               geom.gid      := path_result.gid;
873               geom.the_geom := path_result.the_geom;
874               id := id+1;
875               geom.id       := id;
876                 
877               RETURN NEXT geom;
878
879        END LOOP;
880        RETURN;
881END;
882$$
883LANGUAGE 'plpgsql' VOLATILE STRICT;
884
885CREATE OR REPLACE FUNCTION astar_sp_bbox_directed(
886       varchar,int4, int4, float8, float8, float8, float8, boolean, boolean)
887       RETURNS SETOF GEOMS AS
888$$
889DECLARE
890        geom_table ALIAS FOR $1;
891        sourceid ALIAS FOR $2;
892        targetid ALIAS FOR $3;
893        ll_x ALIAS FOR $4;
894        ll_y ALIAS FOR $5;
895        ur_x ALIAS FOR $6;
896        ur_y ALIAS FOR $7;
897        dir ALIAS FOR $8;
898        rc ALIAS FOR $9;
899
900        rec record;
901        r record;
902        path_result record;
903        v_id integer;
904        e_id integer;
905        geom geoms;
906       
907        srid integer;
908       
909        query text;
910
911        id integer;
912BEGIN
913       
914        id :=0;
915        FOR rec IN EXECUTE
916            'select srid(the_geom) from ' ||
917            quote_ident(geom_table) || ' limit 1'
918        LOOP
919        END LOOP;
920        srid := rec.srid;
921       
922        query := 'SELECT gid,the_geom FROM ' ||
923           'shortest_path_astar(''SELECT gid as id, source::integer, ' ||
924           'target::integer, length::double precision as cost, ' ||
925           'x1::double precision, y1::double precision, ' ||
926           'x2::double precision, y2::double precision ';
927           
928        IF rc THEN query := query || ' , reverse_cost ';
929        END IF;
930           
931        query := query || 'FROM ' ||
932           quote_ident(geom_table) || ' where setSRID(''''BOX3D('||ll_x||' '||
933           ll_y||','||ur_x||' '||ur_y||')''''::BOX3D, ' || srid ||
934           ') && the_geom'', ' || quote_literal(sourceid) || ' , ' ||
935           quote_literal(targetid) || ' , '''||dir||''', '''||rc||''' ),'  ||
936           quote_ident(geom_table) || ' where edge_id = gid ';
937       
938        FOR path_result IN EXECUTE query
939        LOOP
940               geom.gid      := path_result.gid;
941               geom.the_geom := path_result.the_geom;
942               id := id+1;
943               geom.id       := id;
944                 
945               RETURN NEXT geom;
946
947        END LOOP;
948        RETURN;
949END;
950$$
951LANGUAGE 'plpgsql' VOLATILE STRICT;
952
953
954CREATE OR REPLACE FUNCTION astar_sp(
955       geom_table varchar, source int4, target int4)
956       RETURNS SETOF GEOMS AS
957$$
958DECLARE
959        r record;
960        path_result record;
961        v_id integer;
962        e_id integer;
963        geom geoms;
964
965        id integer;
966BEGIN
967       
968        id :=0;
969        FOR path_result IN EXECUTE 'SELECT gid,the_geom FROM ' ||
970           'astar_sp_directed(''' ||
971           quote_ident(geom_table) || ''', ' || quote_literal(source) || ', ' ||
972           quote_literal(target) || ', false, false)'
973        LOOP
974
975              geom.gid      := path_result.gid;
976              geom.the_geom := path_result.the_geom;
977              id := id+1;
978              geom.id       := id;
979                 
980              RETURN NEXT geom;
981
982        END LOOP;
983        RETURN;
984END;
985$$
986LANGUAGE 'plpgsql' VOLATILE STRICT;
987
988CREATE OR REPLACE FUNCTION astar_sp_directed(
989       geom_table varchar, source int4, target int4, dir boolean, rc boolean)
990       RETURNS SETOF GEOMS AS
991$$
992DECLARE
993        r record;
994        path_result record;
995        v_id integer;
996        e_id integer;
997        geom geoms;
998       
999        query text;
1000
1001        id integer;
1002BEGIN
1003       
1004        id :=0;
1005        query := 'SELECT gid,the_geom FROM ' ||
1006           'shortest_path_astar(''SELECT gid as id, source::integer, ' ||
1007           'target::integer, length::double precision as cost, ' ||
1008           'x1::double precision, y1::double precision, ' ||
1009           'x2::double precision, y2::double precision ';
1010           
1011        IF rc THEN query := query || ' , reverse_cost ';
1012        END IF;
1013
1014        query := query || 'FROM ' || quote_ident(geom_table) || ' '', ' ||
1015           quote_literal(source) || ' , ' ||
1016           quote_literal(target) || ' , '''||dir||''', '''||rc||'''), ' ||
1017           quote_ident(geom_table) || ' where edge_id = gid ';
1018           
1019        FOR path_result IN EXECUTE query
1020        LOOP
1021
1022              geom.gid      := path_result.gid;
1023              geom.the_geom := path_result.the_geom;
1024              id := id+1;
1025              geom.id       := id;
1026                 
1027              RETURN NEXT geom;
1028
1029        END LOOP;
1030        RETURN;
1031END;
1032$$
1033LANGUAGE 'plpgsql' VOLATILE STRICT;
1034
1035CREATE OR REPLACE FUNCTION shootingstar_sp(
1036       varchar,int4, int4, float8, varchar, boolean, boolean)
1037       RETURNS SETOF GEOMS AS
1038$$
1039DECLARE
1040        geom_table ALIAS FOR $1;
1041        sourceid ALIAS FOR $2;
1042        targetid ALIAS FOR $3;
1043        delta ALIAS FOR $4;
1044        cost_column ALIAS FOR $5;
1045        dir ALIAS FOR $6;
1046        rc ALIAS FOR $7;
1047
1048        rec record;
1049        r record;
1050        path_result record;
1051        v_id integer;
1052        e_id integer;
1053        geom geoms;
1054       
1055        srid integer;
1056
1057        source_x float8;
1058        source_y float8;
1059        target_x float8;
1060        target_y float8;
1061       
1062        ll_x float8;
1063        ll_y float8;
1064        ur_x float8;
1065        ur_y float8;
1066       
1067        query text;
1068
1069        id integer;
1070BEGIN
1071       
1072        id :=0;
1073        FOR rec IN EXECUTE
1074            'select srid(the_geom) from ' ||
1075            quote_ident(geom_table) || ' limit 1'
1076        LOOP
1077        END LOOP;
1078        srid := rec.srid;
1079       
1080        FOR rec IN EXECUTE
1081            'select x(startpoint(the_geom)) as source_x from ' ||
1082            quote_ident(geom_table) || ' where gid = '||sourceid
1083        LOOP
1084        END LOOP;
1085        source_x := rec.source_x;
1086       
1087        FOR rec IN EXECUTE
1088            'select y(startpoint(the_geom)) as source_y from ' ||
1089            quote_ident(geom_table) || ' where gid = ' ||sourceid
1090        LOOP
1091        END LOOP;
1092
1093        source_y := rec.source_y;
1094
1095        FOR rec IN EXECUTE
1096            'select x(startpoint(the_geom)) as target_x from ' ||
1097            quote_ident(geom_table) || ' where gid = ' ||targetid
1098        LOOP
1099        END LOOP;
1100
1101        target_x := rec.target_x;
1102       
1103        FOR rec IN EXECUTE
1104            'select y(startpoint(the_geom)) as target_y from ' ||
1105            quote_ident(geom_table) || ' where gid = ' ||targetid
1106        LOOP
1107        END LOOP;
1108        target_y := rec.target_y;
1109
1110        FOR rec IN EXECUTE 'SELECT CASE WHEN '||source_x||'<'||target_x||
1111           ' THEN '||source_x||' ELSE '||target_x||
1112           ' END as ll_x, CASE WHEN '||source_x||'>'||target_x||
1113           ' THEN '||source_x||' ELSE '||target_x||' END as ur_x'
1114        LOOP
1115        END LOOP;
1116
1117        ll_x := rec.ll_x;
1118        ur_x := rec.ur_x;
1119
1120        FOR rec IN EXECUTE 'SELECT CASE WHEN '||source_y||'<'||
1121            target_y||' THEN '||source_y||' ELSE '||
1122            target_y||' END as ll_y, CASE WHEN '||
1123            source_y||'>'||target_y||' THEN '||
1124            source_y||' ELSE '||target_y||' END as ur_y'
1125        LOOP
1126        END LOOP;
1127
1128        ll_y := rec.ll_y;
1129        ur_y := rec.ur_y;
1130
1131        query := 'SELECT gid,the_geom FROM ' ||
1132          'shortest_path_shooting_star(''SELECT gid as id, source::integer, ' ||
1133          'target::integer, '||cost_column||'::double precision as cost, ' ||
1134          'x1::double precision, y1::double precision, x2::double ' ||
1135          'precision, y2::double precision, rule::varchar, ' ||
1136          'to_cost::double precision ';
1137         
1138        IF rc THEN query := query || ' , reverse_cost '; 
1139        END IF;
1140         
1141        query := query || 'FROM ' || quote_ident(geom_table) || ' where setSRID(''''BOX3D('||
1142          ll_x-delta||' '||ll_y-delta||','||ur_x+delta||' '||
1143          ur_y+delta||')''''::BOX3D, ' || srid || ') && the_geom'', ' ||
1144          quote_literal(sourceid) || ' , ' ||
1145          quote_literal(targetid) || ' , '''||dir||''', '''||rc||''' ),' ||
1146          quote_ident(geom_table) || ' where edge_id = gid ';
1147         
1148        FOR path_result IN EXECUTE query
1149        LOOP
1150                 geom.gid      := path_result.gid;
1151                 geom.the_geom := path_result.the_geom;
1152                 id := id+1;
1153                 geom.id       := id;
1154                 
1155                 RETURN NEXT geom;
1156
1157        END LOOP;
1158        RETURN;
1159END;
1160$$
1161LANGUAGE 'plpgsql' VOLATILE STRICT;
1162
1163-- COMMIT;
Note: See TracBrowser for help on using the browser.