php geolocation,PHP MySql and geolocation

问题

I am writing a site that basically looks for places within a 25 mile radius of a lat and long using php and mysql.

I am wondering how something like this would work?

I would pass a lat and long to the scrip and have it pull out only locations that are within 25 miles of the lat and long from my Database of locations.

What is the best way to do this?

EDIT:

I found this code for calculating the distance between 2 points.

function distance($lat1, $lon1, $lat2, $lon2, $unit) {

$theta = $lon1 - $lon2;

$dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));

$dist = acos($dist);

$dist = rad2deg($dist);

$miles = $dist * 60 * 1.1515;

$unit = strtoupper($unit);

if ($unit == "K") {

return ($miles * 1.609344);

} else if ($unit == "N") {

return ($miles * 0.8684);

} else {

return $miles;

}

}

Is ther a way to do this calc in the MYSQL look up so I can only return if miles =< 25?

回答1:

Calculating the distance using that function there is pretty computationally expensive, because it involves a whole bunch of transcendental functions. This is going to be problematic when you have a large number of rows to filter on.

Here's an alternative, an approximation that's way less computationally expensive:

Approximate distance in miles:

sqrt(x * x + y * y)

where x = 69.1 * (lat2 - lat1)

and y = 53.0 * (lon2 - lon1)

You can improve the accuracy of this approximate distance calculation by adding the cosine math function:

Improved approximate distance in miles:

sqrt(x * x + y * y)

where x = 69.1 * (lat2 - lat1)

and y = 69.1 * (lon2 - lon1) * cos(lat1/57.3)

Source: http://www.meridianworlddata.com/Distance-Calculation.asp

I ran a bunch of tests with randomly generated datasets.

The difference in accuracy for the 3 algorithms is minimal, especially at short distances

The slowest algorithm is, of course, the one with the trig functions (the one on your question). It is 4x slower than the other two.

Definitely not worth it. Just go with an approximation.

Code is here: http://pastebin.org/424186

To use this on MySQL, create a stored procedure that takes coordinate arguments and returns the distance, then you can do something like:

SELECT columns

FROM table

WHERE DISTANCE(col_x, col_y, target_x, target_y) < 25

回答2:

You may want to take a look at this solution - a somewhat brilliat workaround.

回答3:

You can do it easily in two steps:

Find all locations within 25 miles in each direction of the point. This will look like: WHERE lat BETWEEN $lat1 AND $lat2 AND lng BETWEEN $lng1 AND $lng2

Then loop through each result and check to see if it really is within 25 miles using your code. (i.e., Filter out those locations that are in the corners of the square.)

For the first part, here's some code I have laying around (don't remember the source):

$lat_range = $radius / ((6076 / 5280) * 60);

$lng_range = $radius / (((cos(($city['lat'] * 3.141592653589 / 180)) * 6076) / 5280) * 60);

Basically just use ($lat - $lat_range, $lat + $lat_range) and ($lng - $lng_range, $lng + $lng_range) Radius is in miles.

Obviously you can clean up the math a bit.

Edit: I forgot to mention that you would need to tweak it a bit if you need to support locations near the equator, international date line, etc. Obviously for North America, it would be fine as-is.

来源:https://stackoverflow.com/questions/3606139/php-mysql-and-geolocation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值