【问题标题】:Create a function that makes the query with all the elements of an array one by one with postgres创建一个函数,使用 postgres 对数组的所有元素一一进行查询
【发布时间】:2019-12-27 12:07:24
【问题描述】:

我正在为 PgRouting 准备一个基于我也准备好的另一个函数的函数。这样做的目的是制作一个功能,通过输入路线的起点和终点坐标作为响应。我用 pgr_dijkstra 从点到点得到了它。现在我需要做同样的事情,但使用 pgr_dijkstravia。这是基于 ARRAY,您强制路线通过您输入的特定点。一种谷歌地图,你可以把你想要的点和路线让你拉你强加的那些点。我得到了 ARRAY 的第一个函数,它会是这样的:

CREATE OR REPLACE FUNCTION wrk3_dijkstravia( 
IN edges_subset regclass, 
IN via_vertices ANYARRAY,
OUT seq INTEGER, 
OUT path_id integer,
OUT path_seq integer,
OUT start_vid BIGINT,
OUT end_vid BIGINT,
OUT node BIGINT,
OUT edge BIGINT,
OUT name TEXT, 
OUT cost FLOAT, 
OUT agg_cost FLOAT,
OUT azimuth FLOAT,
OUT route_agg_cost FLOAT,
OUT route_readable TEXT, 
OUT route_geom geometry ) 
RETURNS SETOF record 
AS 
$BODY$ 
WITH dijkstra AS 
    (SELECT * FROM pgr_dijkstravia( 'SELECT gid as id, reverse_cost, * FROM ' || $1,
    $2::BIGINT[], true ,false)), 
get_geom AS
    (SELECT dijkstra.*, ways.name,
    CASE WHEN dijkstra.node = ways.source THEN the_geom ELSE ST_Reverse(the_geom) 
    END 
    AS route_geom FROM dijkstra LEFT JOIN ways ON (edge = gid) ORDER BY seq) 
SELECT 
seq,
path_id,
path_seq,
start_vid,
end_vid,
node,
edge,
name, 
cost,
agg_cost, 
route_agg_cost, 
degrees(ST_azimuth(ST_StartPoint(route_geom), 
ST_EndPoint(route_geom))) AS azimuth, 
ST_Astext(route_geom),
route_geom
FROM get_geom ORDER BY seq; 
$BODY$ 
LANGUAGE 'sql';

查询我已经创建的视图的示例如下:

select * from wrk3_dijkstravia('vehiculo_tiempo', ARRAY [42, 64, 85])

然后他把路线还给我。但是 ARRAY 的变量是节点的 id,并且客户端使用的愿景是不可行的。于是就来了下面这个函数,就是基于这个先:

CREATE OR REPLACE FUNCTION wrk1_fromAtoB(
    IN edges_subset regclass,
    IN x ANYARRAY, IN y ANYARRAY,
    OUT seq INTEGER,
    OUT gid BIGINT,
OUT name TEXT,
OUT distancia_m NUMERIC,
OUT distancia_total NUMERIC, 
OUT cost NUMERIC, 
OUT agg_cost NUMERIC,
OUT azimuth FLOAT,
OUT route_agg_cost NUMERIC,
OUT route_readable TEXT, 
OUT route_geom geometry )

RETURNS SETOF record AS
$BODY$
DECLARE
    final_query TEXT;
BEGIN

    final_query :=
        FORMAT( $$
            WITH
            vertices AS (
                SELECT * FROM ways_vertices_pgr
                WHERE id IN (
                    SELECT source FROM %1$I
                    UNION
                    SELECT target FROM %1$I)
            ),
            dijkstra AS (
                SELECT *
                FROM wrk3_dijkstravia(
                    '%1$I',
                    ARRAY[(SELECT id FROM vertices 
                        ORDER BY the_geom <-> ST_SetSRID(ST_Point(%2$s, %3$s), 4258) LIMIT 1)]
            ))
            SELECT
                seq,
                gid,
                dijkstra.name,
                TRUNC (ways.length_m::numeric) AS distancia_m,
                TRUNC (sum(length_m::numeric) OVER (ORDER BY seq), 2) as distancia_total,
                ROUND (dijkstra.cost::numeric, 2) AS cost,
                ROUND (dijkstra.agg_cost::numeric, 2) as agg_cost,
                azimuth,
                route_agg_cost::NUMERIC,
                route_readable,
                route_geom AS geom
            FROM dijkstra LEFT JOIN ways ON dijkstra.edge = ways.gid;$$,
        edges_subset, x,y);
    RAISE notice '%', final_query;
    RETURN QUERY EXECUTE final_query;
END;
$BODY$
LANGUAGE 'plpgsql';

查询将是这样的:

select * from wrk1_fromAtoB('vehiculo_distancia',  ARRAY[-7.559516429901122,   -7.561619281768799, -7.563893795013428], ARRAY [ 43.01592861164031, 43.01329278981061, 43.00988801917453])

但他给我的错误如下:

ERROR:  syntax error at or near "{"
LINE 15: ...        ORDER BY the_geom <-> ST_SetSRID(ST_Point({-7.559516...

这是因为在 ST_Point 我得到了所有的坐标:

dijkstra AS (
                SELECT *
                FROM wrk3_dijkstravia(
                    'vehiculo_distancia',
                    ARRAY[(SELECT id FROM vertices 
                        ORDER BY the_geom <-> ST_SetSRID(ST_Point({-7.559516429901122,-7.561619281768799,-7.563893795013428}, {43.01592861164031,43.01329278981061,43.00988801917453}), 4258) LIMIT 1)]

我想要的是让 ST_Point 函数一个一个地遍历两个数组,并且与数组中存在的数据一样多次

谢谢

【问题讨论】:

    标签: arrays postgresql function postgis pgrouting


    【解决方案1】:

    我设法缩短了一点,我有这个 DO,但这只会让我加注。

    DO 
    $do$
    DECLARE 
        x numeric[];
        arr numeric[] := ARRAY [[-7.563947439193725, 43.02141169991877], [-7.56184458732605, 43.01576387609036],[-7.5599563121795645, 43.006741968861974]];
    BEGIN
    
        FOREACH x SLICE 1 IN ARRAY arr
        LOOP 
             RAISE notice  'WITH
                vertices AS (
                    SELECT * FROM ways_vertices_pgr
                    WHERE id IN (
                        SELECT source FROM ways
                        UNION
                        SELECT target FROM ways)
                ),
                dijkstra AS (
                    SELECT *
                    FROM wrk3_dijkstravia(
                        ways,
    
                       ARRAY[(SELECT id FROM vertices
                            ORDER BY the_geom <-> ST_SetSRID(ST_Point(%,%), 4258) LIMIT 1)]
                ))' ,x[1], x[2];
            END LOOP;
    END;
    $do$
    

    但我需要将它放入我的函数中。让我们看看是否有人可以帮助我。 谢谢

    【讨论】:

      猜你喜欢
      • 2021-07-22
      • 2018-02-25
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 2018-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多