Benny
Benny

Reputation: 5092

Whats the most efficient way to calculate local users from a geo coord?

[edit] - as pointed out to me in the comments I should have noted that I will be using a LAMP based architecture, meaning a MySQL database. Sorry about forgetting to mention this.

I have to create a PHP backend for an iPhone app. The app sends up the users coords and requests the closes 10 local users.

I'm just wondering what is the most efficient way to determine this, I dont want to have to scan the entire table of users, calculate the distance between their geo-coords and the target & order them from lowest to farthest.

Can anyone suggest a more elegant solution instead of scanning all the users? Thanks for your time.

Upvotes: 2

Views: 157

Answers (4)

Cybercartel
Cybercartel

Reputation: 12592

The most efficient way is to use a spatial index or a space-filling-curve. A spatial index reduce the 2d complexity to a 1d complexity thus it help subdivide the surface. You want to look for Nick's spatial index quadtree hilbert curve blog.

Upvotes: 1

Bil
Bil

Reputation: 543

Due to earth curve, you must do some calculation

SELECT id, 6371 * ACos(Cos(RADIANS(users.Lat)) * Cos(RADIANS(CurrentLat)) * Cos(RADIANS(CurrentLng) - RADIANS(users.Lng)) + Sin(RADIANS(users.Lat)) * Sin(RADIANS(CurrentLat)) ) AS distance
FROM users
ORDER BY distance
LIMIT 10;

distance is in Km, if you want Miles, replace 6371 by 3959

Upvotes: 0

David Moles
David Moles

Reputation: 51143

You could bucket the users by approximate latitude and longitude (e.g. by whole degrees, or tenths of degrees, or whatever scale is appropriate to the distribution you've got) and then work outward from the querying user's bucket.

Not sure the extra complexity is worth it, though, unless the brute force approach is really a performance hog.

Upvotes: 1

ChrisChristensen
ChrisChristensen

Reputation: 21

There are multiple ways of doing this. Here is one way to do it in a sql query.

$sql = "Select id, abs($currlat - latitude) + abs($currlon - longitude) as distance from geo_loc_table order by distance asc";

The issue with this is that it is not overly efficient. I would recommend getting some form of indexing software that can do the work for you. Sphinx might be a good fit.

Upvotes: 0

Related Questions