如何在此查询中获取KM中的距离

时间:2018-04-26 09:21:59

标签: php mysql sql laravel orm

$salons = Salon::select('salons.*')
    ->selectRaw('( 6371* acos( cos( radians(?) ) *
                   cos( radians( lat ) )
                   * cos( radians( lng ) - radians(?)
                   ) + sin( radians(?) ) *
                   sin( radians( lat ) ) )
                 ) AS distance', [$lat, $lng, $lat])
    ->havingRaw("distance < 25")
    ->where("category_Id" , "=" , $id)
    ->get();

这个查询给了我这个 -

"distance": 0.05205731665026305, I want distance like this 1.2KM

我尝试但没有找到解决方案

3 个答案:

答案 0 :(得分:0)

获取km每度你应该使用111.045 km(作为近似值)

   ( 111.045 * acos( cos( radians(?) ) *
                       cos( radians( lat ) )
                       * cos( radians( lng ) - radians(?)
                       ) + sin( radians(?) ) *
                       sin( radians( lat ) ) )
                     )

答案 1 :(得分:0)

尝试以下查询

$data = DB::table('salons AS S')
                ->selectRaw("
                        ( FLOOR(6371 * ACOS( COS( RADIANS( '$lat' ) ) * COS( RADIANS( S.lat ) ) * COS( RADIANS( S.lng ) - RADIANS( '$lng' ) ) + SIN( RADIANS( '$lat' ) ) * SIN( RADIANS( S.lat ) ) )) ) distance")
                ->havingRaw("distance < 25")
                ->where("category_Id" , "=" , $id)
                ->get();

$ lat,$ lng是变量。

答案 2 :(得分:0)

更好的方法是使用PHP。 SQL计算很昂贵。在某些原始计数中差异可以是30秒对0.04秒;)

public function scopeDistance($query, $from_latitude, $from_longitude, $distance)
    {
        $between_coords = \App\Services\PlaceServices::calcCoordinates($from_longitude, $from_latitude, $distance);

        return $query
            ->where(function ($q) use ($between_coords) {
                $q->whereBetween('places.longitude', [$between_coords['min']['lng'], $between_coords['max']['lng']]);
            })
            ->where(function ($q) use ($between_coords) {
                $q->whereBetween('places.latitude', [$between_coords['min']['lat'], $between_coords['max']['lat']]);
            });
    }

和calcCoodinates()

public static function calcCoordinates($longitude, $latitude, $radius = 20)
    {
        $lng_min = $longitude - $radius / abs(cos(deg2rad($latitude)) * 69);
        $lng_max = $longitude + $radius / abs(cos(deg2rad($latitude)) * 69);
        $lat_min = $latitude - ($radius / 69);
        $lat_max = $latitude + ($radius / 69);

        return [
            'min' => [
                'lat' => $lat_min,
                'lng' => $lng_min,
            ],
            'max' => [
                'lat' => $lat_max,
                'lng' => $lng_max,
            ],
        ];
    }

然后使用YourModel::distance($lat, $lon, $km)->get()