[OSM-dev] PostGIS: algorithm to find the nearest way segment to a mouse click?
Nick.Whitelegg at solent.ac.uk
Fri Aug 1 13:39:34 BST 2008
As part of a walking routes feature I want to add to Freemap, I want the
user to be able to select the closest way segment to a mouse click.
By "segment" I don't mean the old-style pre-0.5 OSM segment, but rather a
series of nodes within a way (call it way A) which lie between two other
ways which intersect the way (call them B and C). The way segment would be
defined by way ID and start and end node index within the way, e.g.
Way 303, start node index 2, end node index 6
By reading the postgis reference manual I've come up with a reasonable way
of doing this, but it might not be the most efficient. So can any postgis
gurus offer a better way? The main problem, necessitating a rather
cumbersome algorithm, is that postgis does not appear to have a function
to find the index of a given node (point) within a way.
The algorithm is as follows:
1. Find the nearest way to a given position (this would be a mouse click),
and the distance (between 0 and 1) of the position along the way.
2. Store all the coordinates of all the nodes (points) making up that way.
3. Find the intersections of the selected way, and their distances (0 to
1) along the way using the query:
SELECT t2.highway,t2.osm_id as wayid,
astext(intersection(t1.way,t2.way)) as intn
from planet_osm_line t1, planet_osm_line t2
where intersects(t1.way,t2.way) and t1.osm_id != t2.osm_id
and t1.highway!='' and t2.highway!='' and
where $wayid is the ID of the way we're interested in.
4. Loop through the result set to find which intersections bracket the
selected point, and (this is where it's a bit cumbersome) find the indices
of the nodes of intersection within the way by comparing the intersection
node with each node of the way in turn (php code).
5. We now have the indices of the nodes of intersection, so extract the
relevant nodes from the way.
6. Serialise the extracted nodes as XML.
So is this the best way to do it, or are there any better ways?
More information about the dev