GEO位置反转了PHP和SQL

时间:2016-11-02 12:10:16

标签: mysql laravel laravel-5 laravel-5.2

我目前正在使用Laravel 5.2中的广告系列/广告脚本。我有一张包含广告的表格,例如:广告名称,位置(纬度/经度),半径(+ 10公里)。

现在我有一个用户位置(纬度/经度)。我想知道他是否在任何广告的半径范围内并向他展示广告。

当我在Google上搜索时,我只找到基于纬度/经度+半径搜索广告的解决方案,但我想反对。因此,请查看纬度/经度是否在现有广告的半径范围内。

最好的方法是什么?建议将不胜感激

2 个答案:

答案 0 :(得分:0)

这应该可行,您需要做的就是将此功能添加到User模型中。

public function ads()
{
    return \App\Ad::
        crossJoin('users', 'users.id', '=', \DB::raw($this->attributes['id']))
        ->where(\DB::raw('69 * DEGREES(ACOS(COS(RADIANS(users.Latitude)) * COS(RADIANS(ads.Latitude)) * COS(RADIANS(users.Longitude - ads.Longitude)) + SIN(RADIANS(users.Latitude)) * SIN(RADIANS(ads.Latitude))))'), '<=', 'ads.radius')
        ->get();
}

这不是传统的雄辩关系,所以你不能急于加载它,虽然我相信有更多的工作是可能的。

要查找用户的广告,您只需执行以下操作即可...

$ads = (new \App\User::find($user_id))->ads();

请注意,这会假设您的users表和ads表包含longitudelatitude列。它还假设您的ads表格中包含radius列。您可能需要重命名某些列,但它应该为您提供所需的内容。

此外,假设您的半径为英里。如果您使用km而不是69,请使用111.1111

答案 1 :(得分:0)

我对您的user3158900版本进行了一些更改。

从函数中创建了一个范围,用户的lat / long是可变的,所以我需要它们作为查询中的输入。

我现在有了这个:

public function scopeAdsInLocation($query, $from_latitude, $from_longitude)
{
    $query = CampaignModel::
    where(\DB::raw('111.1111 * DEGREES(ACOS(COS(RADIANS(' . $from_latitude . ')) * COS(RADIANS(campaigns.loc_lat)) * COS(RADIANS(' . $from_longitude .' -
        campaigns.loc_long)) + SIN(RADIANS(' . $from_latitude . ')) * SIN(RADIANS(campaigns.loc_lat))))'), '<=', 'campaigns.loc_radius')
        ->get();
    return $query;
}

我称之为:

$ads = CampaignModel::adsInLocation(51.191320, 5.987772);
var_dump($ads);

此代码有效,但仅限于我将半径设置为固定值。因此,当我将campaigns.loc_radius替换为'100'时,它可以正常工作。但是,每个广告系列都有半径,但它似乎没有做到这一点。你知道为什么吗?或者有一个解决方案。