tags:

views:

167

answers:

1

i have 3 tables: 1 contains people with their city (comes from other table) and the range (int, 1-20) they want to be found in (in miles) 1 contains cities and the beginning of the postcode (i.e. BB2) 1 contains cities and their logitudes/latitudes

what i am trying to do is select the people according to a postcode someone enters. if this postcode is for a city within their range then the person should be selected from the DB.

i have this php code:

  // Latitude calculation
  $limit = (1 / 69.1703234283616) * $radius;
  $latitude_min = $latitude - $limit;
  $latitude_max = $latitude + $limit;

  // Longitude calculation
  $limit = (1 / (69.1703234283616 * cos($userLat * (pi/180)))) * $radius;
  $longitude_min = $longitude - $limit;
  $longitude_max = $longitude + $limit;

now heres the hard part. i dont know how i am going to select the people from the DB, depending on what postcode was entered and their range.

can someone help me out a little here?

+2  A: 

Here is a stored function for MySQL I created a while ago - it returns the (approximate) distance between two pairs of latitude and longitude in meters.

DELIMITER $$

CREATE FUNCTION LAT_LNG_DISTANCE(lat1 FLOAT, lng1 FLOAT, lat2 FLOAT, lng2 FLOAT) RETURNS int(11)
BEGIN
  DECLARE latD FLOAT;
  DECLARE lngD FLOAT;
  DECLARE latS FLOAT;
  DECLARE lngS FLOAT;
  DECLARE a FLOAT;
  DECLARE c FLOAT;

  SET lat1 = RADIANS(lat1);
  SET lng1 = RADIANS(lng1);
  SET lat2 = RADIANS(lat2);
  SET lng2 = RADIANS(lng2);

  SET latD = lat2 - lat1;
  SET lngD = lng2 - lng1;

  SET latS = SIN(latD / 2);
  SET lngS = SIN(lngD / 2);

  SET a = POW(latS, 2) + COS(lat1) * COS(lat2) * POW(lngS, 2);
  SET c = 2 * ASIN(LEAST(1, SQRT(a)));

  RETURN ROUND(c * 6378137);
END;
$$
DELIMITER ;

Now we have that defined, we need to get the origin of the search based on the postcode the user has given us. As I don't know the exact structure of your database, I will use generic joins and conditions that will hopefully be similar enough to the real thing for you to adapt easily .I'm going to use $var to imply passing the value from PHP; needless to say, it will need escaping in an appropriate manner.

SELECT l.lat, l.lng
FROM city_locations l
INNER JOIN city_postcodes c
ON l.city_id = c.city_id
WHERE c.postcode = $postcode;

Now we can pass the results of that query to the next query, which will use the LAT_LNG_DISTANCE function we defined earlier.

SELECT *
FROM people p
INNER JOIN city_locations l
ON p.city_id = l.city_id
WHERE LAT_LNG_DISTANCE(l.lat, l.lng, $search_lat, $search_lng) < p.range * 1609;

1609 is the number of meters in a mile, by the way. I hope I have understood the question correctly!

Alex Barrett
phpMyAdmin gives me this errors when trying to execute the function creation script: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER' at line 1
kevin
If you are running the query in phpMyAdmin, remove the `DELIMITER` statements from the query itself and set the delimiter field in the box below the query.
Alex Barrett