root/tags/release-1.0/core/sql/routing_core_wrappers.sql

Revision 58, 32.3 KB (checked in by anton, 3 years ago)

Trash removed from 1.0 tag

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