我正在制作一个用于发布广告的项目,这个项目基于本地化,因此当用户发布他的广告时,应用程序检测到他的位置,所以当其他人对他的广告感兴趣时,他们可以在地图上找到他。问题是,我想使用广告的纬度和经度以及使用该应用的人的经度和经度,从最近的广告到最远的广告订购广告
public function get_searched(Request $request){
$annonce =DB::table('annonces')
->where('nomAnnonce','like','%'.$request->input("nomAnnonce").'%')
->orderby(((('latitude'- $request->input("lat"))*('latitude'-$request->input("lat"))) + (('longitude' - $request->input("lon"))*('longitude' - $request->input("lon")))), 'ASC')
->get();
echo $annonce;}
这就是我能做的所有事情,并且给我一个错误的结果:
SQLSTATE[42S22]: Column not found: 1054 Champ '1359.309643206' inconnu dans
order clause (SQL: select * from `annonces` where `nomAnnonce` like %P%
order by `1359`.`309643206` asc)
如果有人可以提供帮助,那将会非常愉快
答案 0 :(得分:0)
public function get_searched(Request $request){
$annonce =DB::table('annonces')
->select('*',
DB::raw(((('latitude'- $request->input("lat"))*('latitude'-$request->input("lat"))) + (('longitude' - $request->input("lon"))*('longitude' - $request->input("lon"))))
as 'distance'
)
->where('nomAnnonce','like','%'.$request->input("nomAnnonce").'%')
->orderby('distance', 'ASC')
->get();
echo $annonce;}
答案 1 :(得分:0)
碰巧的是,我曾经做过一些做类似事情的项目,并整理了几个可以提供帮助的辅助功能。有一种算法可以计算两组坐标之间的距离,因此这些帮助程序将为您执行,或生成在数据库中执行它所需的SQL。 distance_sql()
一个听起来像你正在寻找的。通过使查询执行工作而不是脚本,您可以在结果集返回之前对结果集进行排序和分页。我建议在模型中放置query-scope方法来调用它。
如果您还没有这样做,请创建一个app/helpers.php
文件并将其添加到您的composer.json
文件中,然后运行composer install
:
"autoload": {
"files": [
"app/helpers.php",
...
],
...
},
...
最后,将它们放在helpers.php
:
if (!function_exists('distance')) {
/**
* Calculate the distance between two sets of coordinates
*
* @param float $latitude1
* @param float $longitude1
* @param float $latitude2
* @param float $longitude2
* @param float $padding
* @return float
*/
function distance($latitude1, $longitude1, $latitude2, $longitude2, $padding = 0.0)
{
$earthRadiusInMiles = 3959;
$latitude1 = deg2rad($latitude1);
$latitude2 = deg2rad($latitude2);
$longitude1 = deg2rad($longitude1);
$longitude2 = deg2rad($longitude2);
$miles = $earthRadiusInMiles * acos(
cos($latitude1) * cos($latitude2)
* cos($longitude2 - $longitude1)
+ sin($latitude1) * sin($latitude2)
);
$miles += $padding * $miles;
return round($miles, 3);
}
}
if (!function_exists('distance_sql')) {
/**
* Generate the SQL needed to calculate the distance between two sets of coordinates
*
* @param float|string $latitude1
* @param float|string $longitude1
* @param float|string $latitude2
* @param float|string $longitude2
* @param float $padding
* @return string
*/
function distance_sql($latitude1, $longitude1, $latitude2, $longitude2, $padding = 0.0)
{
$earthRadiusInMiles = 3959;
$latitude1 = 'RADIANS('.DB::connection()->getPdo()->quote($latitude1).')';
$latitude2 = "RADIANS($latitude2)";
$longitude1 = 'RADIANS('.DB::connection()->getPdo()->quote($longitude1).')';
$longitude2 = "RADIANS($longitude2)";
$sql = "$earthRadiusInMiles * ACOS("
. "COS($latitude1) * COS($latitude2)"
. " * COS($longitude2 - $longitude1)"
. " + SIN($latitude1) * SIN($latitude2))";
$sql .= " + $padding * $sql";
return $sql;
}
}
答案 2 :(得分:0)
尝试使用:
public function get_searched(Request $request){
$annonces = DB::table("annonces")
->where('nomAnnonce','like','%'.$request->input("nomAnnonce").'%')
->orderBy(DB::raw("3959 * acos( cos( radians({$request->input('lat')}) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(-{$request->input('lon')}) ) + sin( radians({$request->input('lat')}) ) * sin(radians(latitude)) )"), 'ASC')
->get()
dd($annonces);
}
这种方法使用余弦球面法得到距离