Skip to content

Instantly share code, notes, and snippets.

@jenky
Created June 28, 2018 17:02
Show Gist options
  • Save jenky/172ae015a64f580b8401e22072b0d6ce to your computer and use it in GitHub Desktop.
Save jenky/172ae015a64f580b8401e22072b0d6ce to your computer and use it in GitHub Desktop.
Eloquent trait to find nearest results based on Latitude and Longitude
<?php
namespace App\Models\Traits;
trait GeoDistance
{
/**
* Filter results by nearest latitude and longitude.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param float $lat
* @param float $lng
* @param int $distance
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeGeoDistance($query, $lat, $lng, $distance)
{
$results = static::findNearest($lat, $lng, $distance);
if ($results->isNotEmpty()) {
return $query->whereIn('id', $results->pluck('id')->all());
}
return $query;
}
/**
* Find all nearest results.
*
* @param float $lat
* @param float $lng
* @param int $distance
* @return \Illuminate\Support\Collection
*/
public static function findNearest($lat, $lng, $distance)
{
return static::selectRaw('id, ( 6371 * acos( cos( radians(?) ) * cos( radians(' . static::getLatitudeColumn() . ') ) * cos( radians(' . static::getLongitudeColumn() . ') - radians(?) ) + sin( radians(?) ) * sin( radians(' . static::getLatitudeColumn() . ') ) ) ) AS distance', [$lat, $lng, $lat])
->having('distance', '<', $distance)
->orderBy('distance')
->get();
}
/**
* Get the name of the "latitude" column.
*
* @return string
*/
public static function getLatitudeColumn()
{
return defined('static::LATITUDE') ? static::LATITUDE : 'latitude';
}
/**
* Get the name of the "longitude" column.
*
* @return string
*/
public static function getLongitudeColumn()
{
return defined('static::LONGITUDE') ? static::LONGITUDE : 'longitude';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment