سلام دوستان در sql روشی برای محاسبه فاصله با استفاده از lat , long و میشناسین
میخوام نزدیکترین ها به کاربر و از دیتا بیس بکشم بیرون .
البته این کار و با فانکشن بعد select داده ها میتونم انجام بدم .
اما برای بهینه تر کردن نیاز دارم که این محاسبه داخل query انجام بشه .
از دوستانی که تجربه این کار رو داشتن ممنون میشم اگر راهنمایی کنن.
سلام
شما میتونید برای اینکار از function ها ، stored procedure و یا trigger استفاده کنید.
اگر شما بعد از هر select روی جدول نیاز دارید این فاصله محاسبه بشه توصیه میشه از trigger استفاده کنید.
ولی اگر میخواهید فقط در زمانی که نیاز دارید این محاسبه انجام بشه میتونید از فانکشن استفاده کنید.
خیلی خوب هست که تصمیم گرفتید این محاسبه رو سمت DBMS انجام بدید !
@crireal5
از لینک زیر برای درک الگوریتم محاسبه کمک بگیرید :
https://www.movable-type.co.uk/scripts/latlong.html
درمورد اینکه بخواید داخل کوئری کار رو انجام بدید، یک راه بهتر وجود داره و اونم متد chunk هستش که میتونید با استفاده از لینک زیر اون رو بررسی کنید:
https://laravel.com/docs/master/eloquent#chunking-results
سلام دوست عزیز
این تریت رو اضافه کن به مدلت
<?php
namespace App\Traits;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
trait Geographical {
/
@param Builder $query
@param float $latitude Latitude
@param float $longitude Longitude
@return Builder
/
public function scopeDistance( $query , $latitude , $longitude ) {
$latName = $this->getQualifiedLatitudeColumn();
$lonName = $this->getQualifiedLongitudeColumn();
$query->select( ""
, DB::raw("ROUND(6371 acos(cos(radians(" . $latitude . "))
cos(radians(".$latName.")) cos(radians(".$lonName.") - radians(" . $longitude . "))
+ sin(radians(" .$latitude. "))
sin(radians(".$latName."))),2) AS distance") );
return $query;
}
public function scopeGeofence( $query , $latitude , $longitude , $inner_radius , $outer_radius ) {
$query = $this->scopeDistance( $query , $latitude , $longitude );
return $query->havingRaw( 'distance BETWEEN ? AND ?' , [ $inner_radius , $outer_radius ] );
}
public function scopeWhereDistance( $query , $operation , $distance ) {
return $query->having('distance' ,$operation, $distance );
}
public function scopeWhereAround( $query , $inner_radius , $outer_radius ) {
return $query->havingRaw( 'distance BETWEEN ? AND ?' , [ $inner_radius , $outer_radius ] );
}
public function scopeOrderByDistance( $query , $dir = 'ASC' ) {
return $query->orderBy( 'distance' , $dir );
}
protected function getQualifiedLatitudeColumn() {
return $this->getTable() . '.' . $this->getLatitudeColumn();
}
protected function getQualifiedLongitudeColumn() {
return $this->getTable() . '.' . $this->getLongitudeColumn();
}
public function getLatitudeColumn() {
return defined( 'static::LATITUDE' ) ? static::LATITUDE : 'latitude';
}
public function getLongitudeColumn() {
return defined( 'static::LONGITUDE' ) ? static::LONGITUDE : 'longitude';
}
}
به این شکل استفاده کن
if ( $request->lat && $request->long ) {
$query->distance( $request->lat , $request->long );
}
if ( $request->distance ) {
$query->whereDistance( '<' , $request->distance )->orderBy( 'distance' );
}
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟