Skip to content

GeoSPARQL support in QLever

c.u. edited this page Dec 7, 2024 · 3 revisions

QLever has limited support for features from the OGC GeoSPARQL standard. Additionally, QLever supports some custom spatial querying features.

GeoSPARQL geometric relations

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:wktLiterals, 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.

Example: All buildings in the city of Freiburg

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

GeoSPARQL functions

Currently QLever implements these functions from GeoSPARQL:

geof:distance

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.

geof:latitude, geof:longitude

The functions geof:latitude(?x) and geof:longitude(?x) extract the latitude or longitude coordinate from a valid coordinate point with geo:wktLiteral datatype.

Nearest neighbors search

QLever supports a custom fast spatial search operation (currently only for POINTs 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.

Configuration parameters

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 POINTs of geo:wktLiteral datatype.
right variable The right join table: "... find the closest [right]". Must refer to a column with POINTs 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.

Example: Railway stations and supermarkets

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

Special Predicate <max-distance-in-meters:m>

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.

Example

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 .
}

Deprecated: Special Predicate <nearest-neighbors:k> or <nearest-neighbors:k:m>

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 the k 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.

Example

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 .
}