Wordpress - How to query posts based on lat-lng coordinate as post meta?
For anyone looking for this answer in the future, I took woony's code the extra mile and got everything working within Wordpress' post_meta table structure. This assumes you have two separate custom fields, one for Latitude (city_latitude) and one for longitude (city_longitude). Just pass the latitude, longitude, and distance parameters into a WP function and you should be set.
Here's the WP function. Drop this in your functions.php file:
function get_nearby_cities($lat, $long, $distance){
global $wpdb;
$nearbyCities = $wpdb->get_results(
"SELECT DISTINCT
city_latitude.post_id,
city_latitude.meta_key,
city_latitude.meta_value as cityLat,
city_longitude.meta_value as cityLong,
((ACOS(SIN($lat * PI() / 180) * SIN(city_latitude.meta_value * PI() / 180) + COS($lat * PI() / 180) * COS(city_latitude.meta_value * PI() / 180) * COS(($long - city_longitude.meta_value) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance,
wp_posts.post_title
FROM
wp_postmeta AS city_latitude
LEFT JOIN wp_postmeta as city_longitude ON city_latitude.post_id = city_longitude.post_id
INNER JOIN wp_posts ON wp_posts.ID = city_latitude.post_id
WHERE city_latitude.meta_key = 'city_latitude' AND city_longitude.meta_key = 'city_longitude'
HAVING distance < $distance
ORDER BY distance ASC;"
);
if($nearbyCities){
return $nearbyCities;
}
}
Return the value in your template file:
$nearbyCities = get_nearby_cities(get_post_meta($post->ID, 'city_latitude', true), get_post_meta($post->ID, 'city_longitude', true), 25);
This is a simple mathimatical problem. You will indeed need access to both your longitude and latitude, so save it in a metafield.
than you will have to query your posts like this as a sql query. Haven't got a chance to test it. and or pour it into wordpress. Don't have access to my test env now. But I guess you could do it yourself :) if not I'll do it later on when I can.
set @latitude = xxx; — center latitude
set @longitude = xxx; — center longitude
set @distance = xx; — search distance
select p.ID, p.post_name, ((ACOS(SIN(@latitude * PI() / 180) * SIN(`latitude.meta_value` * PI() / 180) + COS(@latitude * PI() / 180) * COS(`latitude.meta_value` * PI() / 180) * COS((@longitude – `longitude.meta_value`) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance
from wp_posts p
left join wp_postmeta latitude on latitude.post_id = p.ID and latitude.meta_key = ‘_latitude’
left join wp_postmeta longitude on longitude.post_id = p.ID and longitude.meta_key = ‘_longitude’
having distance < @distance;