-
Notifications
You must be signed in to change notification settings - Fork 57
GeoSPARQL support in QLever
QLever has limited support for features from the OGC GeoSPARQL standard. Additionally, QLever supports some custom spatial querying features.
Ad-hoc calculation of geometric relations (e.g. geof:sfContains
, geof:sfIntersects
, ...) is not yet supported. However, for OpenStreetMap data, geometric relations can be precomputed as part of the dataset (e.g. ogc:sfContains
, ogc:sfIntersects
, ... triples) using osm2rdf
. After precomputation, geometric queries are much faster than ad-hoc methods.
Geometries from osm2rdf
are represented as geo:wktLiteral
s, which can be addressed by geo:hasGeometry/geo:asWKT
. osm2rdf
also provides centroids of objects via geo:hasCentroid/geo:asWKT
. Please note that the geometric relations are given as triples between the OpenStreetMap entities, not the geometries.
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX osmkey: <https://www.openstreetmap.org/wiki/Key:>
PREFIX ogc: <http://www.opengis.net/rdf#>
PREFIX osmrel: <https://www.openstreetmap.org/relation/>
SELECT ?osm_id ?hasgeometry WHERE {
osmrel:62768 ogc:sfContains ?osm_id .
?osm_id geo:hasGeometry/geo:asWKT ?hasgeometry .
?osm_id osmkey:building [] .
}
Try it: https://qlever.cs.uni-freiburg.de/osm-planet/7cxklb
Currently QLever implements these functions from GeoSPARQL:
The function geof:distance(?x, ?y)
currently expects two values with geo:wktLiteral
datatype, each containing points. It returns the distance in kilometers. Currently, non-point geometries and different units of measurement are unsupported.
The functions geof:latitude(?x)
and geof:longitude(?x)
extract the latitude or longitude coordinate from a valid coordinate point with geo:wktLiteral
datatype.
QLever supports a custom fast spatial search operation (currently only for POINT
s from Well-known-Text). It can be invoked using a SERVICE
operation to the IRI <https://qlever.cs.uni-freiburg.de/spatialSearch/>
. Note that this address is not contacted but only used to activate the feature locally.
A spatial query has the following form:
PREFIX spatialSearch: <https://qlever.cs.uni-freiburg.de/spatialSearch/>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
SELECT * WHERE {
# Arbitrary operations that select ?left_geometry
?some_entity geo:hasCentroid/geo:asWKT ?left_geometry .
SERVICE spatialSearch: {
_:config spatialSearch:algorithm spatialSearch:s2 ;
spatialSearch:left ?left_geometry ;
spatialSearch:right ?right_geometry ;
spatialSearch:numNearestNeighbors 2 ;
spatialSearch:maxDistance 500 ;
spatialSearch:bindDistance ?dist_left_right ;
spatialSearch:payload ?payloadA , ?payloadB .
{
# Any subquery, that selects ?right_geometry, ?payloadA and ?payloadB
?some_other_entity geo:hasCentroid/geo:asWKT ?right_geometry .
# ...
}
}
}
The SERVICE
must include the configuration triples and exactly one group graph pattern that selects the right geometry. If numNearestNeighbors
is not used, the right geometry may also be provided outside of the SERVICE
definition.
The following configuration parameters are provided in the SERVICE
as triples with arbitrary subject. The predicate must be an IRI of the form <parameter>
or spatialSearch:parameter
. The parameters left
and right
are mandatory. Additionally you must provide either numNearestNeighbors
or maxDistance
or both. The remaining parameters are optional.
Parameter | Domain | Description |
---|---|---|
algorithm |
baseline , s2 , boundingBox
|
The algorithm to use. |
left |
variable | The left join table: "for every [left] ...". Must refer to a column with POINT s of geo:wktLiteral datatype. |
right |
variable | The right join table: "... find the closest [right]". Must refer to a column with POINT s of geo:wktLiteral datatype. |
numNearestNeighbors |
integer | The maximum number of nearest neighbor points from right for every point from left
|
maxDistance |
integer | The maximum distance in meters between points from left and right to be included in the result. |
bindDistance |
variable | An otherwise unbound variable name which will be used to give the distance in kilometers between the result point pairs. |
payload |
variable or IRI <all>
|
Variable from the group graph pattern inside the SERVICE to be included in the result. right is automatically included. This parameter may be repeated to include multiple variables. For all variables use <all> . If right is given outside of the SERVICE do not use this parameter. |
This example query calculates the three closest supermarkets to every railway station. QLever can answer this hard query with approx. 300 000 results for the entire planet's OpenStreetMap data within ca. 10 seconds on a good consumer PC.
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX osmkey: <https://www.openstreetmap.org/wiki/Key:>
PREFIX spatialSearch: <https://qlever.cs.uni-freiburg.de/spatialSearch/>
SELECT * WHERE {
?station osmkey:railway "station" ;
osmkey:name ?name ;
geo:hasCentroid/geo:asWKT ?station_geometry .
SERVICE spatialSearch: {
_:config spatialSearch:left ?station_geometry ;
spatialSearch:right ?supermarket_geometry ;
spatialSearch:numNearestNeighbors 3 .
{
?supermarket osmkey:shop "supermarket" ;
geo:hasCentroid/geo:asWKT ?supermarket_geometry .
}
}
}
Try it: https://qlever.cs.uni-freiburg.de/osm-planet/OXupEH
As a shortcut, a special predicate <max-distance-in-meters:m>
is also supported. The parameter m
refers to the maximum search radius in meters. It may be used as a triple with the left join variable as subject and the right join variable as object.
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
SELECT * WHERE {
?a geo:hasCentroid/geo:asWKT ?left_geometry .
?left_geometry <max-distance-in-meters:300> ?right_geometry .
?b geo:hasCentroid/geo:asWKT ?right_geometry .
}
This feature is deprecated and will produce a warning, due to confusing semantics. Please use the SERVICE
syntax instead.
A spatial search for nearest neighbors can be realized using ?left <nearest-neighbors:k:m> ?right
. Please replace k
and m
with integers as follows:
- For each point
?left
QLever will output thek
nearest points from?right
. Of course, the sets?left
and?right
can each be limited using further statements. - Using the optional integer value
m
a maximum distance in meters can be given that restricts the search radius.
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
SELECT * WHERE {
?a geo:hasCentroid/geo:asWKT ?left_geometry .
?left_geometry <nearest-neighbors:2:1000> ?right_geometry .
?b geo:hasCentroid/geo:asWKT ?right_geometry .
}