一个SQL查询,它将列出所有路径,坐标下降或最接近坐标的路径

时间:2017-04-21 14:41:54

标签: postgresql postgis

我在PostgreSQL中有一个名为“routes”的PostgreSQL表,其结构和数据如下。我想要一个查询,我将提供坐标(纬度和经度),它将返回最接近起点到路线终点的路线。 例如,(40.690503,-73.840581)沿大西洋路线下降,这意味着查询将返回第一行

注意:路由是起点和终点之间的路径或路径。

下面是表格结构和示例数据

Table Structure

#Table Structure 
CREATE TABLE public.route
(
  name text NOT NULL,
  startpoint point NOT NULL,
  endpoint point NOT NULL,
  id integer NOT NULL DEFAULT nextval('route_id_seq'::regclass),
  CONSTRAINT route_pkey PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);

#Table Data
INSERT INTO public.route (name, startpoint, endpoint, id) VALUES ('Atlantic',     (-73.848838,40.688299), (-73.824869,40.694831), 1);
INSERT INTO public.route (name, startpoint, endpoint, id) VALUES ('Guy Brewer', (-73.7991,40.708257), (-73.78543,40.688334), 2);

1 个答案:

答案 0 :(得分:0)

在postgis中,LINESTRING几何是这样的:

CREATE TABLE map.vzla_rto
(
  link_id bigint,
  geom geometry(LineString)
)

SELECT ST_ASTEXT(geom)
FROM map.vzla_rto;

"LINESTRING(-72.285868 10.291798,
            -72.285604 10.291983,
            -72.285272 10.292124,
            -72.28512 10.292168,
            -72.284727 10.292228)"

在这里,我使用<-> postgis运算符来查找到该点的最近的道路对象。然后使用ST_Distance函数知道距离最近的道路的距离是什么,并选择最近的道路。

CREATE OR REPLACE FUNCTION map.get_near_link(
    x numeric,
    y numeric)
  RETURNS map.get_near_link AS
$BODY$
DECLARE
    strPoint text;
    sRow map.get_near_link; -- custom type to return all link fields
  BEGIN
    strPoint = 'POINT('|| X || ' ' || Y || ')';

    with index_query as (
        SELECT Link_ID, 
               TRUNC(ST_Distance(ST_GeomFromText(strPoint,4326), geom  )*100000)::integer as distance,                 
               geom
        FROM map.vzla_seg S
        ORDER BY 
            geom <-> ST_GeomFromText(strPoint, 4326)
        LIMIT 101
    )
    SELECT i.Link_ID, i.Distance, i.geom into sRow 
    FROM 
        index_query i
    ORDER BY 
        distance limit 1;

    RAISE DEBUG 'GetLink distance % ', sRow.distance;
    if sRow.distance > 50 then
        sRow.link_id = -1;
    end if;

    RETURN sRow;
  END;
$BODY$
  LANGUAGE plpgsql IMMUTABLE
  COST 100;