php - Finding the closest location based on pre-defined working radius set within the same table -
i trying find closest locations of pre-defined entries within table. far, query using works fine , provides accurate result set.
how works is: 1 table contains pre-defined estimations plumbers set estimated cost specific price range. however, each plumber has own working radius can different other plumbers. here example.
table: pre-defined quotation
id name pricerange estimated-cost working-radius lat long 1 john £500-£800 £560 20 miles 51.50 -0.118
my current query loops on full pre-defined quotations table , order results distance being closest first.
$quotes = quote::all()->where('latitude', '!=', null)->where('longitude', '!=', null)->where('estcost', '!=', null); foreach ($quotes $quote) { $tablename = "quotes"; $origlat = 52.5002721395; // customers lat $origlon = -1.98032029216; // customers long $dist = 45; // needs dynamic like: $quote->working_radius $query = db::select("select id, latitude, longitude, estcost, working_radius, 3956 * 2 * asin(sqrt( power(sin(($origlat - latitude)*pi()/180/2),2) +cos($origlat*pi()/180 )*cos(latitude*pi()/180) *power(sin(($origlon-longitude)*pi()/180/2),2))) distance $tablename longitude between ($origlon-$dist/cos(radians($origlat))*69) , ($origlon+$dist/cos(radians($origlat))*69) , latitude between ($origlat-($dist/69)) , ($origlat+($dist/69)) having distance < $dist order distance limit 25"); } $json = json_encode($query); $obj = json_decode($json, true); ($i = 0; $i < count($obj); $i++) { echo "distance " . round($obj[$i]["distance"], 1) . " est id:" . $obj[$i]["id"] . " <br />"; }
the problem have query using variable $dist
define maximum distance customers lat/long plumber should be. ok apart need defined working_radius value set within same table or plumbers_profile table.
i using laravel here , have tried several different ways find solution seem failing every time.
the basic way can explain need select pre-defined quotes no further in "miles" value set each plumber in working_radius column.
right query above return following example:
distance 4.4 quote id:1617
in ideal situation need assign $dist
variable this: $quote->working_distance
because working distance different every plumber , customer should not shown pre-defined quotation plumber not cover customer's location.
if assign $quote->working_radius $dist variable results incorrect , shown this:
distance 3.1 quote id:1508
however plumber id: 1508 has 2 mile working_radius , should not shown. if set $dist = 2;
same plumber not shown, issue lays assigning $quote->working_radius
dynamically , failing use value set in database determine result.
maybe going totally wrong way? learner have tried best far better experience can provide helping hand on this. thanks.
updated (17/11/2016)
after working on code since posting question have come solution works im not sure works or bad! maybe have gone overboard , maybe have overly complicated things assuming more complicated needs be?
$quotes = quote::orderby('working_radius')->where('latitude', '!=', null)->where('longitude', '!=', null)->where('estcost', '!=', null)->get(); $userlat = 52.5002721395; // random selected lat , long demo -- acts customers property location $userlong = -1.98032029216; $tablename = "quotes"; $dist = 250; // maximum can through app $query = db::select("select id, working_radius, ( 3959 * acos( cos( radians($userlat) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians($userlong) ) + sin( radians($userlat) ) * sin( radians( latitude ) ) ) ) distance $tablename having distance < $dist order distance limit 0 , 25"); $json = json_encode($query); $obj = json_decode($json, true); ($i = 0; $i < count($obj); $i++) { $plumbers[] = array('distance' => round($obj[$i]["distance"], 1), 'id' => $obj[$i]["id"], 'working_radius' => $obj[$i]["working_radius"]); } foreach ($plumbers $plumber) { if($plumber['distance'] <= $plumber['working_radius']){ var_dump($plumber); } }
hopefully have done things half right? learner im trying self educate @ same time progressing on app! thanks.
Comments
Post a Comment