Junaid Masood
Junaid Masood

Reputation: 748

radius search with google maps and mysql in laravel

how to write this query in laravel controller

SELECT *, ACOS( SIN( RADIANS( lat ) ) * SIN( RADIANS( $lat ) ) + 
       COS( RADIANS( lat ) ) * COS( RADIANS( $lat )) * COS( RADIANS( lon ) -
       RADIANS( $long )) ) * 6380 AS distance 
FROM places
WHERE ACOS( SIN( RADIANS( lat ) ) * SIN( RADIANS( $lat ) ) + 
  COS( RADIANS( lat ) ) * COS( RADIANS( $lat )) * COS( RADIANS( lon ) - 
  RADIANS( $long )) ) * 6380 < 10 
ORDER BY distance

10 is radius in km $lat and $long is the center or the cirlce lat and lon are attributes if your table

Upvotes: 1

Views: 4244

Answers (1)

Ohgodwhy
Ohgodwhy

Reputation: 50787

You're just implementing the haversine formula here. He's a quick scope you can attach to Models.

public function scopeCloseTo($query, $location, $radius = 25)
{

    /**
     * In order for this to work correctly, you need a $location object
     * with a ->latitude and ->longitude.
     */
    $haversine = "(6371 * acos(cos(radians($location->latitude)) * cos(radians(latitude)) * cos(radians(longitude) - radians($location->longitude)) + sin(radians($location->latitude)) * sin(radians(latitude))))";
    return $query
        ->select(['comma','separated','list','of','your','columns'])
        ->selectRaw("{$haversine} AS distance")
        ->whereRaw("{$haversine} < ?", [$radius]);
}

In the above function, you can set the $radius as the 3rd argument, so in your case 10.

The 2nd argument is a location from which you wish to find places within a radius of. Think of this as your starting point.

E.G.; if you want to get all places near your house. your house would then be passed as a location object as the 3rd argument, with a longitude and latitude property.

You can adjust the radians(longitude) to match your models table. Or you can use this to reference the current model, and make this reusable (which is what we opted for.

Then you can invoke it like this:

App\Models;

class Hairdresser extends Eloquent {
    //scopeCloseTo function in here
}

Finally, invoke it:

$hairdressers = Hairdresser::closeTo($location, 10);

Which will find all Hairdressers within 10 km of your $location.

Upvotes: 3

Related Questions