问题
I have locations in my database. A location has the attributes latitude and longitude (taken from google maps, example: 48.809591). Is there any query that could help me retrieve the locations within a range of another location?
Example: I have the location A with latitude = 48.809591, and longitude = 2.124009 and want to retrieve all location objects in my database that are within 5 miles of location A
My first thought was to retrieve the locations in a square where location.latitude < A.latitude + 5 miles and location.latitude > A.latitude - 5 miles and location.longitude < A.longitude + 5 miles and location.longitude > A.longitude - 5 miles, and then remove the irrelevant locations from the returned array with the help of something like http://www.movable-type.co.uk/scripts/latlong.html
Any ideas?
回答1:
Just in case you're using MySQL as your DBMS1, you may be interested in checking out the following presentation:
- Geo/Spatial Search with MySQL2 by Alexander Rubin
The author describes how you can use the Haversine Formula in MySQL to order spatial data by proximity and limit the results to a defined radius. More importantly, he also describes how to avoid a full table scan for such queries, using traditional indexes on the latitude and longitude columns.
1 Even if you aren't, this is still interesting and applicable.
2 There is also a pdf version of the presentation.
回答2:
The calculation you want, i think, is called the great circle distance:
http://en.wikipedia.org/wiki/Great-circle_distance
回答3:
You would need a distance function.
For SQL Server it would look something like this (note that distance is in kilometers),
CREATE FUNCTION distance
(
@startLatitude float,
@startLongitude float,
@endLatitude float,
@endLongitude float
)
RETURNS float
AS
BEGIN
DECLARE @distance float;
set @distance =
6371 * 2 * atn2(sqrt(power(sin(pi() / 180 * (@endLatitude - @startLatitude) / 2), 2) +
power(cos(@startLatitude * pi() / 180), 2) *
power(sin(pi() / 180 * (@endLongitude - @startLongitude) / 2), 2)),
sqrt(1 - power(sin(pi() / 180 * (@endLatitude - @startLatitude) / 2), 2) +
power(cos(@startLatitude * pi() / 180), 2) *
power(sin(pi() / 180 * (@endLongitude - @startLongitude) / 2), 2)));
RETURN @distance
END
来源:https://stackoverflow.com/questions/3927258/determine-longitudes-and-latitudes-within-a-range