Search code examples
mysqllaravellatitude-longitudelaravel-6

How to convert mysql distance query to Laravel Eloquent query? - (with Latitude, Longitude and Radius param)


I have a mysql query that get the nearest location of the organization. I want to convert it into Laravel eloquent query so that I can get Attributes function of Organization model. Is it possible? this is my code:

public function getNearesOraganization(Request $request)
    {

        $mi = 10;
        $centerLat = $request->lat;
        $centerLng = $request->lng;
        // $orgs = Organization::all();
        // foreach ($orgs as $key => $value) {
        //     $value->distance = $this->distance(floatval($centerLat), floatval($centerLng), floatval($value->lat), floatval($value->lng));
        //     dump($value->distance);
        // }

        $orgs = \DB::select(
            \DB::raw(

                "SELECT id,
                        org_name,
                        org_street,
                        org_cityprov,
                        org_state,
                        org_zipcode,
                        org_lat,
                        org_lng,
                        ( 3958.8  *
                            acos(
                                    cos( radians($centerLat) ) *
                                    cos( radians( org_lat ) ) *
                                    cos( radians( org_lng ) - radians($centerLng) ) +
                                    sin( radians($centerLat)) *
                                    sin( radians( org_lat ) )
                                )
                        )
                        AS distance
                FROM organizations
                HAVING distance < $mi
                ORDER BY distance ASC"
            )
        );

        foreach ($orgs as $key => $value) {
            $value->f_distance = number_format($value->distance, 2);
        }

        return response()->json($orgs, 200);
    }

Solution

  • I coded it using Laravel Model Scope

    public function scopeNearestInMiles($query, $mi, $centerLat, $centerLng)
        {
            return $query
                ->select(\DB::raw("*,(3958.8  *
                                    acos(
                                            cos( radians(" . $centerLat . ") ) *
                                            cos( radians( org_lat ) ) *
                                            cos( radians( org_lng ) - radians(" . $centerLng . ") ) +
                                            sin( radians(" . $centerLat . ")) *
                                            sin( radians( org_lat ) )
                                        )
                                )
                                AS distance"))
                ->having('distance', '<', $mi)
                ->orderBy('distance');
        }
    

    in the controller

    $orgs = Organization::nearestInMiles($mi,$centerLat,$centerLng)->get();