dmsinc Posted December 25, 2014 Share Posted December 25, 2014 Evening everyone and Merry X-Mas (Happy Holidays) or whatever fits you best.... I have been trying over and over for about 12 hours to figure out how to get data from a specific JSON response and assign the specific values to a new array key/value pair. The various ways I have tried to figure this out are numerous so i'm going to avoid the runnig list of "I trieid this...and this...and this... etc etc." just understand I have reached a dead end point where I need help badly. Here is what our end goal is: "The company" is a "service industry" provider (plumbing, electrical etc. etc.) who wants to dispatch its technicians to new jobs based on which technician has the shortest travel time from any existing address where they already have a scheduled appointment that day and has available time in there schedule. Thus the dispatching system when a new service call is entered is going to give "recommended" technicians (up to 4) to be assigned the new service call based on the above mentioned criteria. (Efficient routing to save company gas cost) 1.) We have a "New service" street address assigned to the $to variable: $to = "4813 River Basin Dr S, Jacksonville FL 32207"; 2.) We will have "records" array which containes a series of records, each record consists of a ticket# a technician id# and a street address: $records = array(array("DV1012","30453423","9890 Hutchinson Park Dr Jacksonville, FL 32225"),array("DB3434","30404041","821 Orange Ave Crescent City, FL 32112"),array("DB3434","30605060","1972 Wells Road, Orange Park FL 32073"),array("DB4578","30605060","2 Independent Drive, Jacksonville FL 32202"),array("DB7841","30605060","5000 Norwood Avenue, Jacksonville FL 32208"),array("DB3235","30605060","9501 Arlington Expressway, Jacksonville FL 32225"),array("DB7894","30605060","Massey Avenue, Jacksonville, FL 32227"),array("DB2020","30121212","11200 Central Pkwy Jacksonville, FL 32224") ); 3.) We are going to prepare the records array for submission to Google's Distance Matrix API by URL encoding each array value into a single variable and then submit it: foreach ($records as $key => $value) {$from = $from.urlencode($value[2])."|";} $to = urlencode($to);$data = file_get_contents("//maps.googleapis.com/maps/api/distancematrix/json?origins=$from&destinations=$to&language=en-EN&units=imperial&mode=driving&sensor=false");$res=json_decode($data) or die("Error: Cannot read object"); You may look at the ACTUAL live Google response from this here: http://tiny.cc/i6eerx (We have applied <pre> and var_dump($res) to the output) We are looking to get the following information back: The distance and travel time between the "New Service" address ($to) and each of the address' in the $records array ($from), now once that information is returned from Google (JSON response) we need to parse the response and narrow it down to 4 or less (Based on the 4 lowest drive times) to form a new array which ends like this: $results = array(array("DV1012","30453423","2.3 Miles","8 mins"),array("DB3434","30404041","2.8 Miles","9 mins"),array("DB3434","30605060","4.6 Miles","13.8 mins"),array("DB4578","30605060","5.7 Miles","15.2 min") ); OUR PROBLEM: Everything up until the the Google API response is fine, but iterating over the multidimensional arrays within multidimensional arrays of the JSON response is just not coming together in my head (or 2 dozen code attempts). I am able to ECHO an individual value like ( echo $res->rows[0]->elements[0]->distance->text; ) but this has no value for the end result i need to get to. My last thoughts and efforts was that that I was going to have to embed foreach statements within foreach statements to drill down through the various arrays but that hasn't worked very well and it seems like it shouldn't be how it has to be done. I would appreciate any help in showing me how the iteration code should be written and any explanation about the code so i can wrap my head around it. Quote Link to comment Share on other sites More sharing options...
requinix Posted December 25, 2014 Share Posted December 25, 2014 (edited) echo $res->rows[0]->elements[0]->distance->text;Each of those [0]s is something you could foreach over. However only one, for rows, needs it as the other is "always" just [0]. The data is organized such that each address in origin_addresses has a corresponding key in the rows array; the Hutchinson Park Drive address (0) corresponds to rows[0], and so on. This is the same order that you passed the addresses. Instead of foreach-ing over the rows you can do it over your $records array. Worry about sorting after. foreach ($records as $key => $value) { // find $res->rows[$key]Then you piece together $results. $results[] = array($value[0], $value[1], $res->rows[$key]->elements[0]->distance->text, $res->rows[$key]->elements[0]->duration->text);Now you can deal with sorting. array_multisort can do it but you have to give it an array of values to sort by. Put the distance's "value" into a separate array at the same time - not "text" as that's not a sortable value (well, it is, but not as easily as the raw value). $results = $distances = array(); foreach ($records as $key => $value) { $results[] = array($value[0], $value[1], $res->rows[$key]->elements[0]->distance->text, $res->rows[$key]->elements[0]->duration->text); $distances[] = $res->rows[$key]->elements[0]->distance->value; }Pass both those arrays to array_multisort(): first $distances with sorting options, then $results without options. Afterwards $distances will be sorted in order and $results will be arranged to match. Edited December 25, 2014 by requinix Quote Link to comment Share on other sites More sharing options...
Barand Posted December 25, 2014 Share Posted December 25, 2014 By default, when you sort an array of arrays, the arrays are sorted on the first element. So you could put the distance at the start of each array and then just sort(). $results = [ [5, 'abc', 'defg'], [8, 'def', 'efg'], [12, 'ghj', 'fghij'], [10, 'klm', 'ghijk'], [8, 'nop', 'lmn'], ]; sort($results); echo '<pre>SORTED ',print_r($results, true),'</pre>'; gives SORTED Array ( [0] => Array ( [0] => 5 [1] => abc [2] => defg ) [1] => Array ( [0] => 8 [1] => def [2] => efg ) [2] => Array ( [0] => 8 [1] => nop [2] => lmn ) [3] => Array ( [0] => 10 [1] => klm [2] => ghijk ) [4] => Array ( [0] => 12 [1] => ghj [2] => fghij ) ) Quote Link to comment Share on other sites More sharing options...
dmsinc Posted December 26, 2014 Author Share Posted December 26, 2014 (edited) Requinix: Thank you, Although some of your answer lost me it was enough for me to try a alternate approach which eventually led to a working answer. Barand: Thank you, I have not implimented your suggestion yet, but I will as it is straight forward on sorting how i need. To both of you: Thnak you for the answers and help, below is the end code (sorting excluded for the moment) $to = "4813 River Basin Dr S, Jacksonville FL 32207"; $records = array( array("DV1012","30453423","9890 Hutchinson Park Dr Jacksonville, FL 32225"), array("DB3434","30404041","821 Orange Ave Crescent City, FL 32112"), array("DB3434","30605060","1972 Wells Road, Orange Park FL 32073"), array("DB4578","30605060","2 Independent Drive, Jacksonville FL 32202"), array("DB7841","30605060","5000 Norwood Avenue, Jacksonville FL 32208"), array("DB3235","30605060","9501 Arlington Expressway, Jacksonville FL 32225"), array("DB7894","30605060","Massey Avenue, Jacksonville, FL 32227"), array("DB2020","30121212","11200 Central Pkwy Jacksonville, FL 32224") ); foreach ($records as $key => $value) {$from = $from.urlencode($value[2])."|";} $result = array(); $to = urlencode($to); $data = file_get_contents("http://maps.googleapis.com/maps/api/distancematrix/json?origins=$from&destinations=$to&language=en-EN&units=imperial&mode=driving&sensor=false"); $res=json_decode($data) or die("Error: Cannot read object"); $time = 0; $distance = 0; $limit = count ($res->rows); for ($i = 0; $i < $limit; $i++) { foreach($res->rows[$i]->elements as $road) { $time += $road->duration->value; $distance += $road->distance->value; $distance = round(($distance * 0.00062),2); $time = ceil($time / 60); $ticket = $records[$i][0]; $from = $res->origin_addresses[$i]; $to = $res->destination_addresses[0]; $result[$ticket] = "$time"; //The end result array is a ticket# with a matching travel "time" between common point A and the other address point B...C...D...etc.etc. echo "Ticket: ".$ticket."<br>"; echo "From: ".$from; echo "<br/>"; echo "To: ".$to; echo "<br/>"; echo "Time: ".$time." minutes"; echo "<br/>"; echo "Distance: ".$distance." miles"; echo "<hr>"; } } Edited December 26, 2014 by dmsinc Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.