This plugin adds a support for the geo_query
part of the WP_Query
and WP_User_Query
.
It uses the Haversine SQL implementation by Ollie Jones (see here).
The plugin works on PHP 5.3+.
It supports the GitHub Updater.
Activate the plugin and you can use the geo_query
parameter in all your WP_Query
and WP_User_Query
queries.
Few examples are here below, e.g. for the Rest API.
Upload the plugin to the plugin folder and activate it.
To install dependencies with Composer (not required):
composer install
or
php composer.phar install
within our folder. See here for more information on how to install Composer.
Then play with the example below, in your theme or in a plugin.
Have fun ;-)
Here's an example of the supported input parameters of the geo_query
part:
$args = [
'post_type' => 'post',
'posts_per_page' => 10,
'ignore_sticky_posts' => true,
'orderby' => [ 'title' => 'DESC' ],
'geo_query' => [
'lat' => 64, // Latitude point
'lng' => -22, // Longitude point
'lat_meta_key' => 'geo_lat', // Meta-key for the latitude data
'lng_meta_key' => 'geo_lng', // Meta-key for the longitude data
'radius' => 150, // Find locations within a given radius (km)
'order' => 'DESC', // Order by distance
'distance_unit' => 111.045, // Default distance unit (km per degree). Use 69.0 for statute miles per degree.
'context' => '\\Birgir\\Geo\\GeoQueryHaversine', // Default implementation, you can use your own here instead.
],
];
$query = new WP_Query( $args );
Here's a modified example from @florianweich:
add_filter( 'rest_query_vars', function ( $valid_vars ) {
return array_merge( $valid_vars, [ 'geo_location' ] );
} );
add_filter( 'rest_post_query', function( $args, $request ) {
$geo = json_decode( $request->get_param( 'geo_location' ) );
if ( isset( $geo->lat, $geo->lng ) ) {
$args['geo_query'] = [
'lat' => (float) $geo->lat,
'lng' => (float) $geo->lng,
'lat_meta_key' => 'geo_lat',
'lng_meta_key' => 'geo_lng',
'radius' => ($geo->radius) ? (float) $geo->radius : 50,
];
}
return $args;
}, 10, 2 );
Test it with e.g.:
https://example.com/wp-json/wp/v2/posts?geo_location={"lat":"64.128288","lng":"-21.827774","radius":"50"}
One can use rest_{custom-post-type-slug}_query
filter for a custom post type.
Here's an example from @acobster:
$args = [
'role' => 'subscriber',
'geo_query' => [
'lat' => 47.236,
'lng' => -122.435,
'lat_meta_key' => 'geo_lat',
'lng_meta_key' => 'geo_lng',
'radius' => 1,
'context' => '\\Birgir\\Geo\\GeoQueryUserHaversine',
],
];
$query = new WP_User_Query( $args );
-
The plugin assumes we store the latitudes and longitudes as custom fields ( post meta), so we need to tell the query about meta keys with the
'lat_meta_key'
and'lng_meta_key'
parameters. -
Skipping the
'radius'
parameter means that no distance filtering will take place. -
If we use the
'order'
parameter within the'geo_query'
, then it will be prepended to the native'orderby'
parameter. -
The
'distance_unit'
parameter should be69.0
for distance in statute miles, else111.045
for distance in kilometers. -
If we want to use the optimized Haversine version by Ollie Jones, we use:
'context' => '\\Birgir\\Geo\\GeoQueryHaversineOptimized'
Notice that on our current plugin setup (i.e. fetching data from the LONGTEXT post meta fields) this isn't more performant than the default
GeoQueryHaversine
class.A future work could be to use a custom table with indexes, for the optimization to work.
-
If we create our own implementation of the Haversine formula, for example the
GeoQueryCustom
class, we just have to make sure it implements theGeoQueryInterface
interface:'context' => 'GeoQueryCustom'
Any suggestions are welcomed.
0.1.1 (2019-01-23)
- Fixed #14. Fixed the user query ordering. Props @baden03
0.1.0 (2018-08-06)
- Added support for user queries. Props @acobster
- Fixed Travis issue. Travis runs successfully for PHP 7.2, 7.1,7,5.6 when installed via Composer and also 5.4 when installed without Composer. Skip the 5.4 Composer check for now.
0.0.7 (2018-06-27)
- Fixed #10. Use ^1.0.0 for composer installer. Props @wujekbogdan
0.0.6 (2017-11-16)
- Fixed #6. Support floating point radius. Props @wujekbogdan
- Added integration tests.
0.0.5 (2017-02-26)
- Added fallback for those that don't use Composer
- Removed the vendor directory
0.0.4 (2017-02-26)
- Fixed #4. Props @billzhong .
0.0.3 (2015-04-29)
- Fixed #2. Fixed a typo. Props @Ben764 and @con322.
0.0.2 (2015-03-10)
- Added: Support for the GitHub Updater.
- Updated: README.md
- Changed: Use distance_value instead of distance_in_km in SQL, since we can use miles by changing the distance_unit parameter.
0.0.1 - Init