使用 PHP 和 MySQL 进行地理位置半径搜索
Geo Location Radius Search Using PHP and MySQL
我正在开发一个工作门户,最终用户将在其中根据他们的位置和邻近半径搜索工作。目前 REST API 由 SLIM 和 MySQL 提供支持。
在 Jobs table 中,每一行都有纬度和经度。我在这里搜索了这个并偶然发现了 Geo Distance search with MySQL .
SELECT latitude, longitude, SQRT(
POW(69.1 * (latitude - $lat), 2) +
POW(69.1 * ($long - $long) * COS(latitude / 57.3), 2)) AS distance
FROM TableName HAVING distance < 25 ORDER BY distance;
Where
$lat = User latitude
$long = User longitude
现在我还有另外两个问题。
- 如果只有 MySQL 查询就足够了,或者我必须用它设置弹性搜索?
- 是否有任何库或软件包可以帮助我解决这个特定问题?
如果您能提出任何对搜索性能有用的建议。
SELECT latitude, longitude, SQRT(
POW(69.1 * (latitude - $lat), 2) +
POW(69.1 * ($long - longitude) * COS(latitude / 57.3), 2)) AS distance
FROM TableName HAVING distance < 25 ORDER BY distance;
哪里
$lat = 用户纬度
$long = 用户经度
You have two option to find job by location
you required
1. Search users lat long
2. Job users Posted Lat long (it may be job location or job posted user location from database)
3. Query will be like -
SELECT zip,Round(((ACOS(SIN('$lat' * PI() / 180) * SIN(latitude * PI() / 180) + COS('$lat' * PI() / 180) * COS(latitude * PI() / 180) * COS(('$lon'-longitude) * PI() / 180)) * 180 / PI()) * 60 * 1.1515),(2)) AS distance FROM Jobs Having distance <= 30
Else
1. You have to call all jobs data in single query.
foreach($joblist as $job){
$milesresult = $this->calculateDistance($user_lat,$user_lon,$job['latitude'],$jobr['longitude']);
$miles = explode("-",$vendor['miles']);
$vendor_max_miles = $miles[1];
}
2. PHP function for lat long
function calculateDistance($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;
}
}
我已经完成了以下 -
SELECT id,
name,
lat,
lng,
ROUND((6371 * acos(
cos(radians($lat)) * cos(radians(lat)) * cos(radians(lng) - radians($lng)) +
sin(radians($lat)) * sin(radians(lat)))), (2)) AS distance
FROM jobs
HAVING distance < 50
ORDER BY distance;
我已经对数据进行了基准测试,发现这比 Mukesh 的答案稍快,比@jision 的答案好 2 倍。
我正在开发一个工作门户,最终用户将在其中根据他们的位置和邻近半径搜索工作。目前 REST API 由 SLIM 和 MySQL 提供支持。 在 Jobs table 中,每一行都有纬度和经度。我在这里搜索了这个并偶然发现了 Geo Distance search with MySQL .
SELECT latitude, longitude, SQRT(
POW(69.1 * (latitude - $lat), 2) +
POW(69.1 * ($long - $long) * COS(latitude / 57.3), 2)) AS distance
FROM TableName HAVING distance < 25 ORDER BY distance;
Where
$lat = User latitude
$long = User longitude
现在我还有另外两个问题。
- 如果只有 MySQL 查询就足够了,或者我必须用它设置弹性搜索?
- 是否有任何库或软件包可以帮助我解决这个特定问题?
如果您能提出任何对搜索性能有用的建议。
SELECT latitude, longitude, SQRT(
POW(69.1 * (latitude - $lat), 2) +
POW(69.1 * ($long - longitude) * COS(latitude / 57.3), 2)) AS distance
FROM TableName HAVING distance < 25 ORDER BY distance;
哪里
$lat = 用户纬度
$long = 用户经度
You have two option to find job by location
you required
1. Search users lat long
2. Job users Posted Lat long (it may be job location or job posted user location from database)
3. Query will be like -
SELECT zip,Round(((ACOS(SIN('$lat' * PI() / 180) * SIN(latitude * PI() / 180) + COS('$lat' * PI() / 180) * COS(latitude * PI() / 180) * COS(('$lon'-longitude) * PI() / 180)) * 180 / PI()) * 60 * 1.1515),(2)) AS distance FROM Jobs Having distance <= 30
Else
1. You have to call all jobs data in single query.
foreach($joblist as $job){
$milesresult = $this->calculateDistance($user_lat,$user_lon,$job['latitude'],$jobr['longitude']);
$miles = explode("-",$vendor['miles']);
$vendor_max_miles = $miles[1];
}
2. PHP function for lat long
function calculateDistance($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;
}
}
我已经完成了以下 -
SELECT id,
name,
lat,
lng,
ROUND((6371 * acos(
cos(radians($lat)) * cos(radians(lat)) * cos(radians(lng) - radians($lng)) +
sin(radians($lat)) * sin(radians(lat)))), (2)) AS distance
FROM jobs
HAVING distance < 50
ORDER BY distance;
我已经对数据进行了基准测试,发现这比 Mukesh 的答案稍快,比@jision 的答案好 2 倍。