WP-GeoMeta is a spatial foundation for WordPress. Store and search spatial metadata like you do any other metadata, but using MySQL spatial indexes.
WP-GeoMeta lets you take advantage MySQL's spatial data types and spatial indexes when storing and searching spatial metadata.
WP-GeoMeta isn't just a plugin, it's also a library which other plugins can take advantage of. It's a spatial platform that other GIS and mapping plugins can build on. If you want to use WP-GeoMeta in your plugin, check out wp-geometa-lib for code and instructions.
It detects when GeoJSON metadata is being stored, and transparently stores a copy in a spatial meta table.
WP-GeoMeta also adds support for spatial search operators. When a spatial search operator is used, WP-GeoMeta will make sure that the spatial table is used, taking advantage of indexes and spatial relations. This plugin provides a dashboard where you can see your existing spatial data and spatial system status. It also includes a list of the MySQL functions your database supports and admin tools for repairing the spatial meta tables if something goes wrong.
Store GeoJSON strings as metadata like you would for any other metadata.
Add geometry to a post:
$single_feature = '{ "type": "Feature", "geometry": {"type": "Point", "coordinates": [102.0, 0.5]}, "properties": {"prop0": "value0"} }';
add_post_meta(15,'singlegeom',$single_feature,false);
Update the post geometry:
$single_feature = '{ "type": "Feature", "geometry": {"type": "Point", "coordinates": [-93.5, 45]}, "properties": {"prop0": "value0"} }';
update_post_meta(15,'singlegeom',$single_feature,false);
Read GeoJSON back from the post;
$single_feature = get_post_meta(15, 'singlegeom');
print $singlegeom;
// '{ "type": "Feature", "geometry": {"type": "Point", "coordinates": [-93.5, 45]}, "properties": {"prop0": "value0"} }';
Querying is done through the WP_Query meta_query argument. See the Your Functions tab to see which spatial functions your server supports.
There are three styles of queries supported, to cover three different classes of spatial functions
- Query comparing geometries
This style of query is for all spatial functions which accept two geometries as arguments and which return a boolean as a result. For example ST_INTERSECTS, CONTAINS or MBROverlaps.
The meta_query compare is the function to use, and the value should be a GeoJSON representation of the geometry to use for the second argument. The geometry meta field indicated by the key parameter will be used as the first argument to the compare function.
$q = new WP_Query( array(
'meta_query' => array(
array(
'key' => 'singlegeom',
'compare' => 'ST_INTERSECTS',
'value' => '{"type":"Feature","geometry":{"type":"Point","coordinates":[-93.5,45]}}',
)
)
));
while($q->have_posts() ) {
$q->the_post();
print "\t* " . get_the_title() . "\n";
}
- Query geometry properties
This style of query is for all spatial functions which accept a single geometry as an argument and which return a boolean as a result. For example ST_IsSimple, IsClosed or ST_IsEmpty.
The compare argument should be the function just like above, but no value is needed.
$q = new WP_Query(array(
'meta_query' => array(
array(
'key' => 'wpgeometa_test',
'compare' => 'ST_IsEmpty'
)
)));
- Compare the results of geometry functions
This style of query is for spatial functions which accept a single geometry as an argument but return a non-boolean response. For example, GLength, ST_Area or ST_SRID.
In these queries you may want to use a normal meta_query comparison (=, >, BETWEEN, etc.) but against the result of a spatial function. To accomodate this type of case, you will need to add an additional parameter geom_op.
The key, compare and value are used in the regular WP_Query way, but the comparison will be made against the result of applying the geometry function to the spatial metadata specified.
$q = new WP_Query(array(
'meta_query' => array(
array(
'key' => 'wpgeometa_test',
'compare' => '>',
'value' => '100',
'geom_op' => 'NumPoints'
)
)));
orderby with named meta clauses should work. It's a new feature though, so send me bug reports.
-
Single arg orderby (eg. Dimension, GLength, ST_Area)
$wpq = new WP_Query(array( 'post_type' => 'geo_test', 'orderby' => ARRAY( 'dimensions' => 'ASC', 'titlemeta' => 'ASC' ), 'meta_query' => array( 'dimensions' => array( 'key' => 'wpgeometa_test', 'geom_op' => 'Dimension' ) )));
-
Two argument function that returns a value, eg. ST_Distance. Note that I use
'type' => 'DECIMAL(10,7)'
so that sorting is done numerically, instead of alphabetically.$wpq = new WP_Query(array( 'post_type' => 'geo_test', 'orderby' => 'distance', 'order' => 'ASC', 'meta_query' => array( 'distance' => array( 'key' => 'wpgeometa_test', 'compare' => 'ST_Distance', 'value' => '{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-1.26,1.08],[-1.26,1.09],[-1.21,1.09],[-1.21,1.08],[-1.26,1.08]]]}}', 'type' => 'DECIMAL(10,7)' ) )));
Supports WordPress 6+
Supports MySQL 5.7+
Supports PHP 7.4+
This talk by Michael Moore and accompanying slides give an excellent overview of the project.
Any spatial operation that takes two geometries and returns a boolean, or which takes one geometry and returns a boolean or a value is supported, if your version of MySQL supports it.
The following function should work, if your install of MySQL supports them:
Area | Contains | Crosses | Dimension |
Disjoint | Equals | GLength | GeometryType |
Intersects | IsClosed | IsEmpty | IsRing |
IsSimple | MBRContains | MBRCoveredBy | MBRDisjoint |
MBREqual | MBREquals | MBRIntersects | MBROverlaps |
MBRTouches | MBRWithin | NumGeometries | NumInteriorRings |
NumPoints | Overlaps | SRID | ST_Area |
ST_Contains | ST_Crosses | ST_Difference | ST_Dimension |
ST_Disjoint | ST_Distance | ST_Distance_Sphere | ST_Equals |
ST_GeometryType | ST_Intersects | ST_IsClosed | ST_IsEmpty |
ST_IsRing | ST_IsSimple | ST_IsValid | ST_Length |
ST_NumPoints | ST_Overlaps | ST_SRID | ST_Touches |
ST_Within | Touches | Within |
To see what your install of MySQL supports, install WP Spatial Capabilities Check. We recommend using MySQL 5.6.1 or higher since it included many important updates to spatial operators.
- "Love how this plugin handles spatial data automatically, and integrates with Advanced Custom Fields!" -- Nick Ciske
- "This plugin deserves more kudos it is fantastic, although more beneficial if you are on mysql 5.7 or greater." -- shawfactor