[postgis-users] Closest point problem AND How to find the nearest road (geom) for the point which is not exactly located on the road.
Stephen Woodbridge
woodbri at swoodbridge.com
Tue Aug 4 07:35:27 PDT 2009
Thurber, Fred wrote:
>
> I have a database full of point data. When our user stops at a certain
> lat/lon, how do I find the closest point in our database?
>
> We have at least 10,000 points, maybe a lot more so the search has to be
> efficient, but I have not found a way. It seems a little surprising
> considering how common this query must be.
>
>
> The obvious way is to scan the entire table and find the closest point.
> Let’s say our user stops at (40,70), I could do this:
>
> SELECT * FROM foo
> ORDER BY distance(point_geom, GeomFromText('POINT(70.0 40.1)', 4326))
> LIMIT 1
>
> When I run this through EXPLAIN ANALYZE, it shows a full-table scan. Is
> there a way I can use a GIST or is there some other way to speed it up?
Thilani also wrote:
> Hi,
> I’m developing a shortest path navigation application on GIS. I came across
> a problem when we need to find a shortest path from the location which is
> not exactly located on the road. In that case I need to find what is the
> nearest road (geom.) to that particular point 1st. Is there any available
> post GIS function to do that? If so can you kindly explain that using an
> example.
> Thanks and Best Regards,
> Thilani
Hi Fred and Thilani,
This question is asked often on the list You can check the archives for
more comments. Search for "Nearest Neighbor"
Basically, you can not currently do this efficiently with a single
query. Most people solve this problem if a plpgsql function. The key to
using an index requires a radius. Typical you should start with a small
radius and if you fail to get a result, double the radius and try again.
So something like this:
mac_search_radius := 1.0;
raduis := .0013;
loop
select into rec * from mytable
where expand(setsrid(makepoint(70.0, 40.1),4326), radius) && the_geom
order by distance(setsrid(makepoint(70.0, 40.1),4326),the_geom)
limit 1;
if found then
exit;
end if;
radius := radius * 2.0;
if radius > max_search_radius then
return null;
end if;
end loop;
-- do something with rec
return some_result;
-Steve W
More information about the postgis-users
mailing list