[pgrouting-dev] shortest_path using nodes instead of ways

Stephen Woodbridge woodbri at swoodbridge.com
Sun Oct 27 16:02:19 PDT 2013


On 10/27/2013 6:03 PM, cathal coffey wrote:
> Hi,
>
> I want to compute the shortest path between two points
> origin=(34.052299,-118.1812657) and destination: (34.141132,-117.853179).
>
> Here is what I tried to do.
>
> *Step 1:* Find the nearest nodes.
>
> _origin: the following returns 590279764_
> _
> _
> SELECT id
> FROM nodes
> ORDER BY st_distance(the_geom, st_setsrid(st_makepoint(-118.1812657,
> 34.052299), 4326))
> LIMIT 1
>
> _destination: the following returns 123007528_
>
> SELECT id
> FROM nodes
> ORDER BY st_distance(the_geom, st_setsrid(st_makepoint(-117.853179,
> 34.141132), 4326))
> LIMIT 1
>
> *Step 2:* Compute shortest path between origin and destination.
>
> SELECT *
> FROM pgr_dijkstra(
> 'SELECT gid as id, source, target, length AS cost FROM ways',
> 590279764, 123007528, false, false
> );
>
> However when I execute this I get the following error.
>
> ERROR:  Start vertex was not found.
>
> ********** Error **********
>
> ERROR: Start vertex was not found.
> SQL state: XX000
>
> Why is this happening?

Just because you have a node in the vertex table, does not mean that you 
will have it assigned a source ot target field in the edge table.

This is a new function that you can try out. It locates the nearest edge 
then returns the nearest source or target node id along that edge.

create or replace function pgr_pointtoedgenode(edges text, pnt geometry, 
tol float8)
     returns integer as
$body$
/*
  *  pgr_pointtoedgenode(edges text, pnt geometry, tol float8)
  *
  *  Given and table of edges with a spatial index on the_geom
  *  and a point geometry search for the closest edge within tol 
distance to the edges
  *  then compute the projection of the point onto the line segment and 
select source or target
  *  based on whether the projected point is closer to the respective 
end and return source or target.
  *  If no edge is within tol distance then return -1
*/
declare
     rr record;
     pct float;

begin
     -- find the closest edge within tol distance
     execute 'select * from ' || pgr_quote_ident(edges) ||
             ' where st_dwithin(''' || pnt::text ||
             '''::geometry, the_geom, ' || tol || ') order by 
st_distance(''' || pnt::text ||
             '''::geometry, the_geom) asc limit 1' into rr;

     if rr.the_geom is not null then
         -- deal with MULTILINESTRINGS
         if geometrytype(rr.the_geom)='MULTILINESTRING' THEN
             rr.the_geom := GeometryN(rr.the_geom, 1);
         end if;

         -- project the point onto the linestring
         pct := st_line_locate_point(rr.the_geom, pnt);

         -- return the node we are closer to
         if pct < 0.5 then
             return rr.source;
         else
             return rr.target;
         end if;
     else
         -- return a failure to find an edge within tol distance
         return -1;
     end if;
end;
$body$
   language plpgsql volatile
   cost 5;

Use it like:

select * from pgr_pointtoedgenode('ways',
     st_setsrid(st_makepoint(-117.853179, 34.141132), 4326)),
     0.0013);

This is a new function that will be added to pgRouting 2.1 in our next 
major release.

-Steve




More information about the pgrouting-dev mailing list