我目前正在使用Laravel 5.2中的广告系列/广告脚本。我有一张包含广告的表格,例如:广告名称,位置(纬度/经度),半径(+ 10公里)。
现在我有一个用户位置(纬度/经度)。我想知道他是否在任何广告的半径范围内并向他展示广告。
当我在Google上搜索时,我只找到基于纬度/经度+半径搜索广告的解决方案,但我想反对。因此,请查看纬度/经度是否在现有广告的半径范围内。
最好的方法是什么?建议将不胜感激
答案 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
表包含longitude
和latitude
列。它还假设您的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'时,它可以正常工作。但是,每个广告系列都有半径,但它似乎没有做到这一点。你知道为什么吗?或者有一个解决方案。