Skip to Main Content

Search by Location with WP Query

I get a lot of client requests for “Store Locators” or “Location Finders”. There are some plugins like MapPressΒ and WP Store Locator that work well for simple Location Searches, but as soon as the client has requests for specific functionality or designs, these pre-made options start to fall short, and you end up spending more time fighting their code than writing your own.

What makes it especially frustrating is that, using the Google Maps API most of the features of a store locator or location finder are fairly easy to write. The only hard part is getting posts that are within a certain distance from a specific latitude and longitude. This requires a somewhat complicated trigonometric formula called The Haversine Formula, to calculate distance between two points on a sphere.Β  All the other filters and selections can be handled with a simple WP Query, but distance is a trickier beast.

ADVERTISEMENT:

Most of the existing plugins that I’ve seen do a great job at the distance calculation, but don’t include much of a framework for building more complicated queries that match post meta and taxonomies. So I wrote one that comes at things from the other direction. It takes the standard WP Query that offers so much flexibility, and adds a geo_query option that will calculate distance from a point.

You use it like this:

<?php
$query = new WP_Query(array(
	// ... include other query arguments as usual
	'geo_query' => array(
		'lat_field' => '_latitude',  // this is the name of the meta field storing latitude
		'lng_field' => '_longitude', // this is the name of the meta field storing longitude 
		'latitude'  => 44.485261,    // this is the latitude of the point we are getting distance from
		'longitude' => -73.218952,   // this is the longitude of the point we are getting distance from
		'distance'  => 20,           // this is the maximum distance to search
		'units'     => 'miles'       // this supports options: miles, mi, kilometers, km
	),
	'orderby' => 'distance', // this tells WP Query to sort by distance
	'order'   => 'ASC'
));

In addition, there are two included functions that can be used to retrieve distance in the resulting loop: the_distance() and get_the_distance(). Both support two optional variables: a post object, and the number of integers to round the distance to.

The full code for the plugin is included below.

11 Comments

    • gschoppe's profile image.

      I’m working on a plugin to simplify the process, but in general, you would use the google maps api (i like using gmaps.js to simplify the API calls) to geocode a search field, into latitude and longitude, then, once you have lat and lng, you send them to an ajax function that runs the query from this post.

  1. chris's profile image.

    Can this be used in combination with Toolset maps? I’m using Toolset to create custom posts, but want to sort them by distance.
    So when a user searches a city it takes the center of the city and sort by distance from that point..

    link to toolset

  2. Chris's profile image.

    This is awesome and exactly what I was looking for. I got it working but am trying to figure out how to get the get_distance() to round off? I can return the value but it has like 15 digits after the decimal point. How do I round it?

    • gschoppe's profile image.

      get_the_distance() and the_distance() each have a second argument for rounding. So, if I want to use the current global post object, and echo the distance to two decimal places, I would use the_distance(null, 2); If I wanted to make sure it was always exactly two decimal places, i would use echo number_format(get_the_distance(null, 2), 2, '.', '');.

  3. Rob's profile image.

    Hi, when I install the plugin it works fine, but wp asks me to update it, and it takes me to https://wordpress.org/plugins/geo/ which is well outdated, matter of fact, when I update it, it doesn’t work anymore. Can we avoid to assk for updates or can you create your own updatable plugin? Thanks a lot

    • gschoppe's profile image.

      Hi Rob,

      Plugin updates are identified by filename, so it sounds like you saved the plugin file as `geo.php`, which matched the filename of that outdated plugin. If you change the filename to `wp-geo-query.php` the notice about an available update should go away.

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>