2016-11-02 11 views
0

現在、Laravel 5.2のキャンペーン/広告スクリプトを作成しています。広告名、場所(緯度/経度)、半径(+ 10km)など、広告付きの表があります。GEOロケーションの逆PHPとSQL

今、私はユーザーの場所(緯度/経度)を持っています。私は彼がどんな広告の半径にいるのかを見て、彼に広告を見せたい。

私がGoogleで検索すると、私は緯度/経度+半径に基づいて広告を検索するための解決策しか見つけることができませんが、反対にしたいと思います。したがって、緯度/経度が既存の広告の半径内にあるかどうかを確認します。

これを行うにはどうすればよいですか?アドバイスをいただければ幸いです。

答えて

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(); 
} 

私はより多くの仕事で可能であろうと確信しているが、あなたは、それ熱心ロードすることができなくなりますので、それは伝統的な雄弁な関係はありません。これはあなたのusersテーブルの両方を想定し、ads表はlongitudelatitude列が含まれていることを、ユーザーの広告を見つけるために

は、あなたは単に...

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

注意を以下のような何かをするだろう。また、adsテーブルにはradiusという列があるものとします。いくつかの列の名前を変更する必要があるかもしれませんが、必要なものを与えるはずです。

また、これはあなたの半径がマイルであることを前提としています。 69の代わりにkmを使用する場合は、111.1111を使用してください。

+0

下記の返信をご覧ください。 –

0

私はあなたのバージョンuser3158900をいくつか変更しました。

ユーザーの緯度/経度が可変であるため、クエリの入力として必要になります。

私は今、この持っている:

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'に置き換えると動作します。しかし、各キャンペーンの半径は、それが仕事をしていないようです。あなたはおそらく理由を知っていますか?またはこれのための解決策があります。

+0

半径は整数列ですか?そのような文字列を比較しようとすると、何かちょっとした手間がかかるかもしれません。 – user3158900

+0

これはvarcharカラムです。 –