Jump to content

[SOLVED] Distance Estimation, closest matches using Zip Codes


Recommended Posts

I modified a script so that it calculates the distances between stores and a person, but it doesn't show closest stores first? I searched the boards and haven't found an answer for this, with so many store locators on the web I'm hoping someone knows where I am missing.

 

<?php

// our function to determine the distance

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

  $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;
}

$userzip=$_POST['userzip'];

// User posts their Zip Code
// Next we find out their latitude and longitude

$query1="SELECT b.zip AS BZIP, a.zip AS AZIP, a.long AS ALONG, a.lat As ALAT FROM latlongcodes a JOIN users b ON b.zip='$userzip'";
$result1=mysql_query($query1) or die("Failed Query 1");
$sql1=mysql_fetch_array($result1);

// Assign Variables for their lat and long

$ulat=$sql1[ALAT]
$ulong=$sql1[ALONG]

// Now we grab all the stores and check their lat and long and display the distances

$query="SELECT b.shop AS BSHOP, b.zip AS BZIP, a.zip AS AZIP, a.long AS ALONG, a.lat AS ALAT FROM latlongcodes a JOIN shops b ON b.zip=a.zip LIMIT 10";
$result=mysql_query($query) or die("Failed Query 2");
while($sql=mysql_fetch_array($result))
{
  echo distance($ulat, $ulong, $sql[ALAT], $sql[ALONG]) . " miles to $sql[bSHOP]<br/>";
  }
?>

Works great, but I can't figure out how to get the while to display closest first.

Thank you for the reply.

 

I have tried using the ORDER BY, zip, lat, long... doesn't seem to take into the distance function output, only the order in the SQL query?

 

Missing array syntax is my bad habit, thank you for the reminder!

Oh, didn't notice how you were using the distance() function.  You may want to do something like:

 

<?php
while($sql=mysql_fetch_array($result)) {
  $distances[$sql['BSHOP']] = distance($ulat, $ulong, $sql['ALAT'], $sql['ALONG']);
}
natsort($distances);
foreach ($distances as $shop=>$distance) {
   echo "$distances miles to $shop<br />";
}

So close! This is what it now displays.

 

Array miles to Store 7

Array miles to Store 8

Array miles to Store 9

Array miles to Store 6

 

Technically distance wise it's accurate, but not sure why it's saying Array instead of the actual mileage.

 

This is my latest code, I stripped out the other stuff that's not required for this test.

 

<?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;
}

$userzip=90210;

$query1="SELECT b.shop as BSHOP, b.pzcode AS BZIP, b.country as BCOUNTRY, a.zip AS AZIP, a.long AS ALONG, a.lat As ALAT FROM latlongcodes a JOIN shops b ON a.zip='$userzip'";
$result1=mysql_query($query1) or die("Failed Query 1");
$sql1=mysql_fetch_array($result1);

$ulat=$sql1['ALAT'];
$ulong=$sql1['ALONG'];

$query="SELECT b.shop AS BSHOP, b.pzcode AS BZIP, a.zip AS AZIP, a.long AS ALONG, a.lat AS ALAT FROM latlongcodes a JOIN shops b ON b.pzcode=a.zip LIMIT 10";
$result=mysql_query($query) or die("Failed Query 2");
while($sql=mysql_fetch_array($result)) {
     $distances[$sql['BSHOP']] = distance($ulat, $ulong, $sql['ALAT'], $sql['ALONG']);
   }
   natsort($distances);
   foreach ($distances as $shop=>$distance) {
      echo "$distances miles to $shop<br />";
     }
?>

My bad.  I used $distances instead of $distance:

 

<?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;
}

$userzip=90210;

$query1="SELECT b.shop as BSHOP, b.pzcode AS BZIP, b.country as BCOUNTRY, a.zip AS AZIP, a.long AS ALONG, a.lat As ALAT FROM latlongcodes a JOIN shops b ON a.zip='$userzip'";
$result1=mysql_query($query1) or die("Failed Query 1");
$sql1=mysql_fetch_array($result1);

$ulat=$sql1['ALAT'];
$ulong=$sql1['ALONG'];

$query="SELECT b.shop AS BSHOP, b.pzcode AS BZIP, a.zip AS AZIP, a.long AS ALONG, a.lat AS ALAT FROM latlongcodes a JOIN shops b ON b.pzcode=a.zip LIMIT 10";
$result=mysql_query($query) or die("Failed Query 2");
while($sql=mysql_fetch_array($result)) {
     $distances[$sql['BSHOP']] = distance($ulat, $ulong, $sql['ALAT'], $sql['ALONG']);
   }
   natsort($distances);
   foreach ($distances as $shop=>$distance) {
      echo "$distance miles to $shop<br />";
     }
?>

 

Should work perfectly.

Bah, now it's showing as blank but honestly the fact it's sorting in order, and shows me the Store Name means I can have them click on that store and have it show on that page.

 

Thank you so much!

This is the output, sorry for the delay!

 

Array ( [8] => [9] => [10] => [11] => [7] => [6] => [2] => [3] => [4] => [5] => [1] => ) miles to 8

miles to 9

miles to 10

miles to 11

miles to 7

miles to 6

miles to 2

miles to 3

miles to 4

miles to 5

miles to 1

 

Ah!  The problem is that you don't actually return $miles from the distance() function, thereby filling the array with nothing.

 

Change distance()'s code to:

<?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;
return $miles;
}

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.