Link to home
Start Free TrialLog in
Avatar of DoobyWho
DoobyWho

asked on

Calculate lat/long

I have a bunch of lat/longs in my database and i'd like to perform a search to find the lat/longs within a specified distance. I found the following code, but I'm not sure how to port it to do that instead of calculate the distance between two points. any ideas?


// Function takes latitude and longitude
// of two places as input and prints the
// distance in miles and KMs.
function toMiles($lat1, $lon1, $lat2, $lon2)
{
    // Formula for calculating distances
    // from latitude and longitude.
    $dist   = acos(sin(deg2rad($lat1))
              * sin(deg2rad($lat2))
              + cos(deg2rad($lat1))
              * cos(deg2rad($lat2))
              * cos(deg2rad($lon1 - $lon2)));

    $dist   = rad2deg($dist);
    $miles  = (float) $dist * 69;

    // To get kilometers, multiply miles by 1.61
    $km     = (float) $miles * 1.61;

    // This is all displaying functionality
    $display  = sprintf("%0.2f",$miles).' miles' ;
    $display .= ' ('.sprintf("%0.2f",$km).' kilometers)' ;

    return $display ;
}
Avatar of Discomonkey
Discomonkey

given a specified distance and a beginning lattitude/longitude:


// Function takes latitude and longitude
// of two places as input and prints the
// distance in miles and KMs.
function toMiles($lat1, $lon1, $lat2, $lon2, $MAX_DISTANCE, $COMPARE_MODE = "mi")
{
      // Formula for calculating distances
    // from latitude and longitude.
    $dist   = acos(sin(deg2rad($lat1))
              * sin(deg2rad($lat2))
              + cos(deg2rad($lat1))
              * cos(deg2rad($lat2))
              * cos(deg2rad($lon1 - $lon2)));

    $dist   = rad2deg($dist);
    $miles  = (float) $dist * 69;

    // To get kilometers, multiply miles by 1.61
    $km     = (float) $miles * 1.61;


   // NEW CODE
   if($COMPARE_MODE == "mi"){
      if($miles < $MAX_DISTANCE) return TRUE;
      else                                         return FALSE;
    }
    else if($COMPARE_MODE == "km"{
       if($km < $MAX_DISTANCE) return TRUE;
      else                                         return FALSE;
   }
   else {
   // throw error
}

}

and just loop through your db and call this function once per line
$loc_array = array();
while($location = mysql_fetch_array($locations)){
     if(toMiles($location['lon1'], $location['lat1'], $location['long2'], $location['lat2'], $_POST['distance']){
          array_push($loc_array, $UR_DATA);
     }


}


where $UR_DATA is whatever info you want per set of locations you calculate.
Avatar of DoobyWho

ASKER

That seems like it might be really slow. Wouldn't it be faster if we could limit what we were grabbing from the database? I have over 15,000 records in there and growing every day. I don't want to have to pull each one and test it.
well you are now asking a database query question and not a php question.  You would have to rewrite your query so that do a test inside of it.   I'm no guru when it comes to that, I must profess, so I might lead you in the wrong direction.  

Is there a way you could narrow down your query based on say a given city or something and then do a looping test on a smaller subset of data?
What I was thinking was more on the lines of this:

* We will enter in a ZIP CODE and a search radius (ie. 50 miles).
* I will retrieve the lat/long for that zip code

We perform some calculation that can take the zipcode lat/long that I have, take the search radius, and respond back with a max lat/long and a min lat/long. Then we just check the database for the lat/longs that fit in between those. Since the lat/longs are indexed in the DB, it shouldn't be too painful.
I'm just not a math genius so I don't know how you would take a lat/long, give a search radius, and get back a min/max lat/long.
I see what you mean now.  Ya, you can use PHP to calculate a MIN lat, a MIN lon, a MAX lat, and a MAX lon, then plug those into a mysql query (select * from yourtable where lat < MAXLAT AND lat > MINLAT AND lon < MAXLON AND lon > MINLON).  

What you need is a function, that given a lon and lat, and a search radius (either KM or MILES), will return an array containing the minlon, maxlon, minlat, maxlat that you can use in your db query.  Am I correct about all this?
and another function that converts zip codes into lon / lat, so you can feed the other function
The function above is used to calculate distance between 2 points, and to derive an equation that will work for what you need from it seems too obscure for someone who isn't strong in geometric math.
Correct. I need a function that can do that. I already have the function that converts zip codes into lat/lon. It's a simple google maps api geocode. I just need to be able to pump that lat/long into a function along with a search radius (miles, not km) and have it spit back out the max/min lat/long.
ASKER CERTIFIED SOLUTION
Avatar of Discomonkey
Discomonkey

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I think we figured out another easier way. I'll post the solution once we test.
Forced accept.

Computer101
EE Admin