• 基于pgrouting的最短路径规划


    最近项目上有一个计算两点最短路径的需求,即就是类似于百度地图的路径规划问题,小编研究了一段时间,并参考了相关资料,基于postgresql+postgis+pgrouting实现了简单的路径规划,计算的结果是组成最短路径的所有线路的集合,话不多说,直接上主要的存储过程:

    CREATE OR REPLACE FUNCTION public.pgr_shortest_road(
    IN startx double precision,
    IN starty double precision,
    IN endx double precision,
    IN endy double precision,
    OUT road_name character varying,
    OUT v_shpath character varying,
    OUT cost double precision)
    RETURNS SETOF record AS
    $BODY$ 
    declare 
    v_startLine geometry;--离起点最近的线 
    v_endLine geometry;--离终点最近的线 
    v_startTarget integer;--距离起点最近线的终点 
    v_endSource integer;--距离终点最近线的起点 
    v_statpoint geometry;--在v_startLine上距离起点最近的点 
    v_endpoint geometry;--在v_endLine上距离终点最近的点 
    v_res geometry;--最短路径分析结果 
    v_perStart float;--v_statpoint在v_res上的百分比 
    v_perEnd float;--v_endpoint在v_res上的百分比 
    v_rec record; 
    first_name varchar;
    end_name varchar;
    first_cost double precision;
    end_cost double precision;
    begin 
    --查询离起点最近的线 
    execute 'select geom,target,name from china_road where 
    ST_DWithin(geom,ST_Geometryfromtext(''point('|| startx ||' ' || starty||')''),0.01) 
    order by ST_Distance(geom,ST_GeometryFromText(''point('|| startx ||' '|| starty ||')'')) limit 1' 
    into v_startLine ,v_startTarget,first_name; 
    --查询离终点最近的线 
    execute 'select geom,source,name from china_road
    where ST_DWithin(geom,ST_Geometryfromtext(''point('|| endx || ' ' || endy ||')''),0.01) 
    order by ST_Distance(geom,ST_GeometryFromText(''point('|| endx ||' ' || endy ||')'')) limit 1' 
    into v_endLine,v_endSource,end_name; 
    --如果没找到最近的线,就返回null 
    if (v_startLine is null) or (v_endLine is null) then 
    return; 
    end if ; 
    select ST_ClosestPoint(v_startLine, ST_Geometryfromtext('point('|| startx ||' ' || starty ||')')) into v_statpoint; 
    select ST_ClosestPoint(v_endLine, ST_GeometryFromText('point('|| endx ||' ' || endy ||')')) into v_endpoint; 
    
    --计算距离起点最近线上的点在该线中的位置
    select ST_Line_Locate_Point(st_linemerge(v_startLine), v_statpoint) into v_perStart;
    
    select ST_Line_Locate_Point(st_linemerge(v_endLine), v_endpoint) into v_perEnd;
    
    select ST_Distance_Sphere(v_statpoint,ST_PointN(ST_GeometryN(v_startLine,1), ST_NumPoints(ST_GeometryN(v_startLine,1)))) into first_cost;
    
    select ST_Distance_Sphere(ST_PointN(ST_GeometryN(v_endLine,1),1),v_endpoint) into end_cost; 
    
    if (ST_Intersects(st_geomfromtext('point('|| startx ||' '|| starty ||') '), v_startLine) and ST_Intersects(st_geomfromtext('point('|| endx ||' '|| endy ||') '), v_startLine)) then 
    select ST_Distance_Sphere(v_statpoint, v_endpoint) into first_cost;
    
    select ST_Line_Locate_Point(st_linemerge(v_startLine), v_endpoint) into v_perEnd;
    for v_rec in 
    select ST_Line_SubString(st_linemerge(v_startLine), v_perStart,v_perEnd) as point,COALESCE(end_name,'无名路') as name,end_cost as cost loop
    v_shPath:= ST_AsGeoJSON(v_rec.point);
    cost:= v_rec.cost;
    road_name:= v_rec.name;
    return next;
    end loop;
    return;
    end if;
    --最短路径 
    for v_rec in 
    (select ST_Line_SubString(st_linemerge(v_startLine),v_perStart,1) as point,COALESCE(first_name,'无名路') as name,first_cost as cost
    union all
    SELECT st_linemerge(b.geom) as point,COALESCE(b.name,'无名路') as name,b.length as cost
    FROM pgr_dijkstra(
    'SELECT gid as id, source, target, length as cost FROM china_road
    where st_intersects(geom,st_buffer(st_linefromtext(''linestring('||startx||' ' || starty ||','|| endx ||' ' || endy ||')''),0.05))', 
    v_startTarget, v_endSource , false 
    ) a, china_road b 
    WHERE a.edge = b.gid
    union all
    select ST_Line_SubString(st_linemerge(v_endLine),0,v_perEnd) as point,COALESCE(end_name,'无名路') as name,end_cost as cost)
    loop
    v_shPath:= ST_AsGeoJSON(v_rec.point);
    cost:= v_rec.cost;
    road_name:= v_rec.name;
    return next;
    end loop; 
    end; 
    $BODY$
    LANGUAGE plpgsql VOLATILE STRICT;
    
     

     如有问题,欢迎留言交流!

  • 相关阅读:
    day01-python基础
    python3.5爬虫实例:根据网站的反爬虫策略,启用代理来防止爬虫被禁用
    python3.5爬虫实例:根据城市名称来获取该城市最近七天的天气预报
    python3.5爬虫基础urllib结合beautifulsoup实例
    python3.5爬虫基础urllib实例
    面向对象相关知识及常用操作(二)
    面向对象相关知识点及常见的操作
    常用的基础模块介绍
    利用正则表达式来实现求一个数学表达式的和
    正则表达式的方法及其匹配规则
  • 原文地址:https://www.cnblogs.com/ljy-20180122/p/9378964.html
Copyright © 2020-2023  润新知