0

Here is a example i'm using to load read values from a JSON file to provide Latitude, Longitude, Address, and more. I'm using min() to return the lowest value in the array $cart and cannot figure out how to input and grab other values from the array. It shows the closest distance as needed but I would like to grab the latitude and longitude of the closest distance as well.

<?php

function distance($lat1, $lon1, $lat2, $lon2, $unit) {

    $theta = $lon1 - $lon2;
    $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta));
    $dist = acos($dist);
    $dist = rad2deg($dist);
    $miles = $dist * 60 * 1.1515;
    $unit = strtoupper($unit);

    if ($unit == "K") {
        return ($miles * 1.609344);
    } else if ($unit == "N") {
        return ($miles * 0.8684);
    } else {
        return $miles;
    }
}

$cart = array();

foreach ($json_a as $pos_name => $pos_a) {
    echo "['" . $pos_a['name'] . "',  " . $pos_a['latlng'][0] . ", " . $pos_a['latlng'][1] . ", '" . $pos_a['address'] . "', 0],";
    array_push($cart, distance($lat, $lon, $pos_a['latlng'][0], $pos_a['latlng'][1], "M") . "");
}

echo min($cart);
?>
3
  • you should first add the miles to your $pos_a array (and the $json_a resp.) Then you can find the record with the smallest "miles" Commented Jul 27, 2017 at 14:26
  • Read about PHP arrays and how to use them. Commented Jul 27, 2017 at 14:27
  • @Jeff Nice didn't even think of that. Commented Jul 27, 2017 at 14:31

2 Answers 2

1

The question is very unclear. However, I'll try to pretend I understand that you have the coordinates of a fixed point ($lat, $long) and a list ($json_a) of other points identified by their coordinates and you want to find the point from this list that is the closest to the fixed point mentioned above.

Obviously, you should keep both the distance and the coordinates of each point in the $cart array. To make the things simple, I will index the $cart array using the distance:

$cart = array();
foreach ($json_a as $pos_name => $pos_a) {
    // Compute the distance
    $distance = distance($lat, $lon, $pos_a['latlng'][0], $pos_a['latlng'][1], "M");
    // Store point info and the distance in $pos, index by distance
    $cart[$distance] = array(
        'name' => $pos_a['name'],
        'lat'  => $pos_a['latlng'][0],
        'long' => $pos_a['latlng'][1],
        'dist' => $distance,
    );
}

// Get the minimum distance
$distance = min(array_keys($cart));
// Get the position corresponding to the minimum distance
$position = $cart[$distance];

The code above contains a logic error. Put the mouse over the yellow area below to learn about it or, better, exercise your brain and discover it yourself.

If there are two or more locations at the same distance from the point, only the last one is stored in the array. This doesn't affect the processing in any way if the distance is not the smallest one.

Sign up to request clarification or add additional context in comments.

9 Comments

Worked perfectly, sorry my question was unclear. But your answer was perfect! You also have errors. Should be, $cart[$distance] = array( 'name' => $pos_a['name'], 'lat' => $pos_a['latlng'][0], 'long' => $pos_a['latlng'][1], 'dist' => $distance );
Right, fixed it.
I can't put my finger on it but there is another error keeping it from running.
On the last two lines
+1 for the exercise. When I looked at the code at first, I was like "well, it's gonna break if there are 2 equal distances", and then I saw that it was intended. :) Very nice answer.
|
0

You can find lowest value if loop as well.

$min = null;
foreach ($json_a as $pos_name => $pos_a) {
  echo "['".$pos_a['name']."',  ".$pos_a['latlng'][0].", ".$pos_a['latlng'][1].", '".$pos_a['address']."', 0],";
  $distance = distance($lat, $lon, $pos_a['latlng'][0], $pos_a['latlng'][1], "M");
  if($min === null || $distance < $min) {
      $min = $distance;
  }
  array_push($cart, $distance."");
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.