Geo Location – Sorting and filtering content based on coordinates
If you need to sort any content based on a physical location, you can use ElasticPress Labs’ Geo Location feature. With that, you can, for example, display the list of stores closer to your user.
The feature has two main parts: adding a pair of latitude and longitude coordinates to your content and getting your users’ coordinates to compare.
Adding coordinates to your content
By default, ElasticPress will search for latitude and longitude in the ep_latitude
and ep_longitude
meta fields. You can use the ep_geo_location_pre_geo_points
filter to bypass those meta fields and send your own array with lat
and lon
as keys.
add_filter(
'ep_geo_location_pre_geo_points',
function ( $pre_geo_points, $post_args, $post_id ) {
return ( 1 === $post_id )
? [
'lat' => 34.141407,
'lon' => -118.349747,
]
: [
'lat' => 33.993553,
'lon' => -117.928116,
];
},
10,
3
);
Alternatively, you can use the ep_geo_location_geo_points
filter to manipulate those fields’ values before sending them to Elasticsearch.
add_filter(
'ep_geo_location_geo_points',
function ( $geo_points, $post_args, $post_id ) {
$geo_points['lat'] = ( 1 === $post_id ) ? 34.141407 : 33.993553;
return $geo_points;
},
10,
3
);
If you set a Google Maps API Key, a new box will be added to your editor, where you can type an address, and Google Maps will automatically fetch its coordinates.

Using a coordinate to sort by
Once all your content has coordinates set, it is time to query them, comparing their locations with another one. In most cases, you’ll want to compare them to your users’ location, but you can also send a specific pair of coordinates to your WP_Query call as well.
Here is an example of a WP_Query call ordering by geolocation:
$query = new \WP_Query(
[
'ep_integrate' => true,
'post_type' => 'post',
'orderby' => 'geo_distance',
'geo_distance' => [
'distance' => '1km', // Only gets posts within 1km of the location
'geo_point.location' => [ // The location to get posts around
'lat' => 34.151617,
'lon' => -118.1609043,
],
],
]
);
You can also make a simpler call, like this:
$query = new \WP_Query(
[
'ep_integrate' => true,
'post_type' => 'post',
'orderby' => 'geo_distance',
]
);
In this case, as we don’t have a geo_point.location
set, ElasticPress understands it should get the user’s location. To do that, it’ll run some JavaScript code.
Requesting the user location via JavaScript
If you prefer to handle the user location request yourself, you can use the ep_geo_location_ask_user_coordinates
filter to prevent ElasticPress from adding its JS file. In your code, you’ll have to get the user coordinates and store them in a cookie called ep_coordinates
, in the <latitude>,<longitude>
format.
If you already store user coordinates in a different way, you can use the ep_geo_location_user_coordinates
filter to pass that to ElasticPress. It expects an array with lat
and lon
as keys.
If you decide to keep EP’s JS code, you can handle errors using the epLabs.GeoLocation.currentPositionError
and epLabs.GeoLocation.apiNotAvailable
JS actions. The first one will be called on any errors, like when the user refuses to share their location, and the second one will be called when the user’s browser does not support the GeoLocation API.
document.addEventListener('DOMContentLoaded', function() {
const addErrorElement = (errorMessage) => {
const errorElement = document.createElement('div');
errorElement.classList.add('ep-geo-location-error');
errorElement.textContent = errorMessage;
document.body.appendChild(errorElement);
}
const displayCurrentPositionError = () => {
addErrorElement('It was not possible to get your current position.');
}
wp.hooks.addAction('epLabs.GeoLocation.currentPositionError', 'epio-demo', displayCurrentPositionError);
const displayApiNotAvailableError = () => {
addErrorElement('Your browser does not support the Geolocation API.');
}
wp.hooks.addAction('epLabs.GeoLocation.apiNotAvailable', 'epio-demo', displayApiNotAvailableError);
});
Searching content? Be careful with date decay
If you are searching for content and also ordering it by location, results might be out of the expected order if you are using date decay.
In that case, go to your WordPress Dashboard, then ElasticPress > Features > Post Search. Under “Weighting by date”, select “Don’t weight results by date”, save and try again.