Geo Spatial

From Blazegraph
Jump to: navigation, search

Geospatial Support in Blazegraph

The 2.1.0 release contains support for the processing of geospatial data. This documentation is intended as a small getting started tutorial on how to enable, use, and configure Blazegraph’s geospatial subsystem. Note that geospatial support works for both triples and quads mode.

Approach

Geospatial data is represented in Blazegraph using dedicated, typed literals that encode geospatial coordinates. While Blazegraph comes with predefined internal datatype URIs for representing geospatial literals, it is also possible to design and query arbitrary multi-dimensional datatypes (even multi dimensional datatypes without geospatial coordinates). The two predefined literals included in the default configuration are:

  1. http://www.bigdata.com/rdf/geospatial/literals/v1#lat-lon
  2. http://www.bigdata.com/rdf/geospatial/literals/v1#lat-lon-time


The first one is designed to store latitude + longitude coordinates, the second one contains an additional timestamp as a third parameter. As an example, the literal

  "48.13743#11.57549"^^<http://www.bigdata.com/rdf/geospatial/literals/v1#lat-lon>

encodes the geo location of Munich, whereas a literal such as

  "48.13188#11.54965#1379714400"^^<http://www.bigdata.com/rdf/geospatial/literals/v1#lat-lon-time>

might be used to encode the location plus start time of the Octoberfest in Munich in 2013 (the timestamp is the unix epoch timestamp for Fri, 20 Sep 2013, 10pm, GMT). In the built-in configuration, latitude and longitude are double values with at most five digits after comma (further digits present in literals will be ignored) and the timestamp is a long value. While in principle you can store any long value, the datatype is optimized for storing linux epoch time in seconds. In both built-in datatypes, the fields are separated by character "#" and no whitespaces are allowed in-between. Please note that all these restrictions hold only for the preconfigured built-in datatypes, see the section below on how to define custom datatypes.

Geospatial datatypes can be queried using Blazegraph’s custom SERVICE extension. Currently, we support efficient rectangle and distance queries over geospatial coordinates, possibly combined with range scans over non-geospatial coordinates (such as the time component in the lat-lon-time literals). We consider adding more geospatial functions (possibly even GeoSPARQL support) in future releases. Examples and details for querying will be provided below.

Setup & Configuration

Geospatial support is disabled by default. In order to enable the geospatial submodule, you need to create a fresh namespace with the following property set:

  com.bigdata.rdf.store.AbstractTripleStore.geoSpatial=true

Note that the Blazegraph Workbench contains a checkbox labelled "Enable geospatial:" in the NAMESPACE section which you can simply enable in order to get the property set automatically.

There are a couple of other system parameters that can be used to configure the behavior of Blazegraph’s geospatial subsystem (all of which need to be added manually when creating the namespace):

Property Description
com.bigdata.rdf.store.AbstractTripleStore.geoSpatialDefaultDatatype This parameter can be used to set the default datatype, which is to be used per default when submitting a query via SERVICE keyword. If, for instance, you are always (or mostly) working with the built-in lat+lon literal type, you may want to set this parameter to http://www.bigdata.com/rdf/geospatial/literals/v1#lat-lon. If no default datatype is given (which is the default setting), the datatype for literal’s you’re interested in needs to be explicitly listed in queries.
com.bigdata.rdf.store.AbstractTripleStore.geoSpatialIncludeBuiltinDatatypes This parameter can be used to disable geospatial support for the two datatypes mentioned above. This might make sense if you just do not plan to use the built-in datatypes or if you want to override their behavior.
com.bigdata.rdf.store.AbstractTripleStore.geoSpatialDatatypeConfig This parameter allows advanced configuration for the geospatial datatypes, see the section on configuration and extension.

When configuring the geospatial search module in combination with a custom com.bigdata.rdf.store.AbstractTripleStore.vocabularyClass, you need to make sure that your vocabulary class either extends com.bigdata.rdf.vocab.core.BigdataCoreVocabulary_v20160317 (or any later version) or contains the two datatype URIs above as vocabulary items.

Getting Started Example

The following example demonstrates geospatial storage and querying by means of a small sample use case. Assume we have events and cities with geospatial coordinates encoded using our built-in format:

@prefix geoliteral: <http://www.bigdata.com/rdf/geospatial/literals/v1#> .
@prefix example: <http://www.example.com/> .

example:Oktoberfest-2013
    rdf:type example:Fair ;
    rdfs:label "Oktoberfest 2013" ;
    example:happened "48.13188#11.54965#1379714400"^^geoliteral:lat-lon-time ;
                example:city example:Munich .

example:RAR-2013
    rdf:type example:Festival ;
    rdfs:label "Rock am Ring 2013" ;
    example:happened "50.33406#6.94259#1370556000"^^geoliteral:lat-lon-time ;
                example:city example:Nuerburg .

example:Oktoberfest-2014
    rdf:type example:Fair ;
    rdfs:label "Oktoberfest 2014" ;
    example:happened "48.13188#11.54965#1411164000"^^geoliteral:lat-lon-time ;
                example:city example:Munich .

example:RAR-2014
    rdf:type example:Festival ;
    rdfs:label "Rock am Ring 2014" ;
    example:happened "50.33406#6.94259#1401919200"^^geoliteral:lat-lon-time ;
                example:city example:Nuerburg .

example:Oktoberfest-2015
    rdf:type example:Fair ;
    rdfs:label "Oktoberfest 2015" ;
    example:happened "48.13188#11.54965#1442613600"^^geoliteral:lat-lon-time ;
                example:city example:Munich .

example:RAR-2015
    rdf:type example:Festival ;
    rdfs:label "Rock am Ring 2015" ;
    example:happened "50.36780#7.31170#1464904800"^^geoliteral:lat-lon-time ;
                example:city example:Mendig .

example:Munich
    rdf:type example:City ;
    example:location "48.13743#11.57549"^^geoliteral:lat-lon .

example:Nuerburg
    rdf:type example:City ;
    example:location "50.34188#6.95203"^^geoliteral:lat-lon .

example:Mendig
    rdf:type example:City ;
    example:location "50.36667#7.28333"^^geoliteral:lat-lon .

The dataset defines six events, namely the "Rock am Ring" festivals between 2013 and 2015 as well as the Oktoberfest fairs between 2013 and 2015. For each event, there is a lat-lon-time coordinate associated using predicated "example:happened" that describes where the event took place and when it started. In addition, each event has an "example:city" associated, which again has geo coordinates (latitude and longitude only, hence using the geoliteral:lat-lon datatype rather than geoliteral:lat-lon-time).

With geospatial support enabled, you can now simply load this turtle data into your Blazegraph installation: the geospatial literals contained within will be automatically indexed.

Querying Geospatial Data

As sketched previously, querying geospatial data in Blazegraph can be done through a dedicated SERVICE call against <http://www.bigdata.com/rdf/geospatial#search>. Here’s an example query that extracts all events that happened in 100km radius distance to Munich (we’re directly passing in the coordinates for Munich, "48.13743#11.57549") in 2013.

PREFIX geoliteral: <http://www.bigdata.com/rdf/geospatial/literals/v1#>
PREFIX geo: <http://www.bigdata.com/rdf/geospatial#>
PREFIX example: <http://www.example.com/>

SELECT * WHERE {
  SERVICE geo:search {
    ?event geo:search "inCircle" .
    ?event geo:searchDatatype geoliteral:lat-lon-time .
    ?event geo:predicate example:happened .
    ?event geo:spatialCircleCenter "48.13743#11.57549" .
    ?event geo:spatialCircleRadius "100" . # default unit: Kilometers
    ?event geo:timeStart "1356994800" .
    ?event geo:timeEnd "1388530799" .   # 31.12.2013, 23:59:59
  }
}

The query parameters are configured using so-called magic vocabulary, namely:

  • The predicate geo:search described the search mode. Currently, we support the two search modes “inCircle”, extracting all coordinates that are in a within a given search radius and timeframe from a given point, and "inRectangle", which defines a search rectanngle (an example can be found below). More sophisticated functions may be added in the future.
  • The geo:searchDatatype specifies the literal type we’re interested in. Note that this parameter is mandatory, unless you have set com.bigdata.rdf.store.AbstractTripleStore.geoSpatialDefaultDatatype pointing to the literal type you’re interested in by default.
  • The geo:predicate applies a filter on the predicate position. In our example, we’re using example:happened, saying that we’re only interested in geospatial data attached via this predicate (which is the case for all our data). Note that the predicate is required (which may be subject to future changes).
  • The geo:spatialCircleCenter and geo:spatialCircleRadius specify the center point and the radius of the "inCircle" search request. Default unit for the radius is "Kilometers". You may change the unit using an additional predicate geo:spatialUnit, pointing to any of the strings "Meters", "Kilometers", "Feet", "Miles", or "NauticalMiles".
  • The geo:timeStart and geo:timeEnd variables point to the begin and end time stamp we’re interested in. They are also required.

As a result, the service call will bind the variable in subject position (here: ?event) to all subjects for which a matching geospatial predicate could be found:

event
<http://www.example.com/Oktoberfest-2013>


You may also combine geospatial SERVICE requests with other query patterns. For instance, the following variant extracts all instances typed as example:Festival that have occurred in proximity of 500km to Munich until 31.12.2016:

PREFIX geoliteral: <http://www.bigdata.com/rdf/geospatial/literals/v1#>
PREFIX geo: <http://www.bigdata.com/rdf/geospatial#>
PREFIX example: <http://www.example.com/>

SELECT * WHERE {
 
  example:Munich example:location ?locationOfMunich .

  SERVICE geo:search {
    ?event geo:search "inCircle" .
    ?event geo:predicate example:happened .
    ?event geo:searchDatatype geoliteral:lat-lon-time .
    ?event geo:spatialCircleCenter ?locationOfMunich .
    ?event geo:spatialCircleRadius "500" . # default unit: Kilometers
    ?event geo:timeStart "0" . 
    ?event geo:timeEnd "1483225199" .   # 31.12.2016, 23:59:59
    ?event geo:locationValue ?location .
  }

  ?event rdf:type example:Festival .
}

Note that, in addition to the previous query, we (i) pass in the coordinates for Munich via a lookup against the database (triple pattern “example:Munich example:location ?locationOfMunich”), use the triple pattern "?event rdf:type example:Festival" to restrict the result to those instances typed as example:Festival, and (iii) use the magic predicate geo:locationValue in order to specify a variable to which the actual location of the respective event is bound (similiarly, you may use geo:latValue, geo:lonValue, geo:timeValue and geo:locationAndTimeValue in order to bind the time and a combined location+time value, respectively):

locationOfMunich event location
48.13743#11.57549 <http://www.example.com/RAR-2013> 50.33406#6.94259
48.13743#11.57549 <http://www.example.com/RAR-2014> 50.33406#6.94259
48.13743#11.57549 <http://www.example.com/RAR-2015> 50.3678#7.3117


Starting in version Blazegraph 2.2, the "inCircle" search will also support a predicate geo:distanceValue to extract the distance to the center point. See also the table at the bottom of this page for a full list of supported magic predicates in the geospatial service.

Here’s another example that uses a rectangle query to extract all events that took place in the rectangle spanned by Basel (south west) and Passau (north east) up to the end of 2013:

PREFIX geoliteral: <http://www.bigdata.com/rdf/geospatial/literals/v1#>
PREFIX geo: <http://www.bigdata.com/rdf/geospatial#>
PREFIX example: <http://www.example.com/>

SELECT * WHERE {
  SERVICE geo:search {
    ?event geo:search "inRectangle" .
    ?event geo:predicate example:happened .
    ?event geo:searchDatatype geoliteral:lat-lon-time .    
    ?event geo:spatialRectangleSouthWest "47.55793#7.58899" . # Basel
    ?event geo:spatialRectangleNorthEast "48.56420#13.42620" . # Passau
    ?event geo:timeStart "0" .
    ?event geo:timeEnd "1388530799" .   # 31.12.2013, 23:59:59
    ?event geo:locationAndTimeValue ?locationAndTime .
  }
}

The geo:search value here is "inRectangle" -- in combination with this type, we’re using the two predicates geo:spatialRectangleSouthWest and geo:spatialRectangleNorthEast (rather than specifying the circle center point and radius, as we did for inRectangle). The result is as follows:

event locationAndTime
<http://www.example.com/Oktoberfest-2013> 48.13188#11.54965#1379714400


As a final example, let’s query cities within the rectangle spanned by Basel (south west) and Passau (north east); as modifications, we change the index that we query (using geoliteral:lat-lon) and omit the magic predicates for start and end time, which are not required here:

PREFIX geoliteral: <http://www.bigdata.com/rdf/geospatial/literals/v1#>
PREFIX geo: <http://www.bigdata.com/rdf/geospatial#>
PREFIX example: <http://www.example.com/>

SELECT * WHERE {
  SERVICE geo:search {
    ?city geo:search "inRectangle" .
    ?city geo:predicate example:location .
    ?city geo:searchDatatype geoliteral:lat-lon .    
    ?city geo:spatialRectangleSouthWest "47.55793#7.58899" . # Basel
    ?city geo:spatialRectangleNorthEast "48.56420#13.42620" . # Passau
    ?city geo:latValue ?latitude .
    ?city geo:lonValue ?longitude .    
  }
}

In this example, the latitude and longitude values will be bound to variables ?latitude and ?longitude, respectively:

city latitude longitude
<http://www.example.com/Munich> 48.13743 11.57549

Custom Geospatial Datatypes

Blazegraph’s geospatial subsystem builds upon a generic z-order index implementation. While z-order indexing was initially proposed to optimize geospatial search requests, it is not limited to the latter. In contrary, z-order indexing constitutes a generic mechanism for efficient range queries over arbitrary, multi dimensional structures. While Blazegraph comes with the easy-to-use built-in geospatial datatypes sketched in the example before, it exposes the full power of its z-index to developers, making it easy to set up and query custom z-order datatypes.

Defining and Querying Custom Geospatial Datatypes

Defining a new datatype is pretty simple. First, you need to hook in a vocabulary class that defines your new datatype (see InlineIVs for how this is done). Second, you need to declare the fields that you want to expose in your datatype using a JSON configuration string. Let us start with a simple example, defining a custom datatype with URI <http://my-lat-lon-starttime-endtime-dt>. Having hooked in a vocabulary class that defines your datatype URI as vocabulary item, all you need to do is adding a config option as follows:

com.bigdata.rdf.store.AbstractTripleStore.geoSpatialDatatypeConfig.0=
  { "config":
    { "uri": "http://my-lat-lon-starttime-endtime-dt",
      "fields": [ 
        { "valueType": "DOUBLE", "multiplier": "100000", "serviceMapping": "LATITUDE" },
        { "valueType": "DOUBLE", "multiplier": "100000", "serviceMapping": "LONGITUDE" },
        { "valueType": "LONG", "serviceMapping": "starttime" },
        { "valueType": "LONG", "serviceMapping": "endtime" }
      ]
    }
  }

The trailing ".0" in the configuration parameter is a running number -- you may define an arbitrary number of geospatial datatypes by specifying configurations ".1", ".2", etc. (the numbers *must* be in order starting from "0" up to any integer value). The "uri" parameter defines the URI of the datatype, and the fields definition defines (in this case four) fields, including their value types. For DOUBLE datatypes, the multiplier determines the number of digits after comma that are supported (DOUBLE values are internall stored as long by multiplication with this value, then cutting away remaining after comma digits). The service mapping is relevant for querying in a later step. The service mapping values LATITUDE and LONGITUDE are built-in values specifying the latitude and longitude positions of the geospatial literal (in addition, you may use the predefined values TIME and COORD_SYSTEM; each of these predefined components must be used at most once, and if you use LATITUDE or LONGITUDE you also need to specify its counterpart). If you choose a string different from those, a so-called custom field will be created, as it is the case for "starttime" and "endtime".

Note that the JSON needs to be added as a property when creating a new namespace, and it needs to be written in one line (without line breaks) -- the configuration above is split across multiple lines for readability reasons. So here’s the configuration which you can copy & paste into your RWStore.properties file:

com.bigdata.rdf.store.AbstractTripleStore.geoSpatialDatatypeConfig.0={ "config": { "uri": "http://my-lat-lon-starttime-endtime-dt", "fields": [ { "valueType": "DOUBLE", "multiplier": "100000", "serviceMapping": "LATITUDE" }, { "valueType": "DOUBLE", "multiplier": "100000", "serviceMapping": "LONGITUDE" }, { "valueType": "LONG", "serviceMapping": "starttime" }, { "valueType": "LONG", "serviceMapping": "endtime" } ] } }

Again, please note that in addition you’ll need to specify a com.bigdata.rdf.store.AbstractTripleStore.vocabularyClass that defines the datatype URI.

Here’s a small sample document that makes use of our new datatype:

@prefix example: <http://www.example.com/> .

example:Oktoberfest-2013
    rdf:type example:Fair ;
    rdfs:label "Oktoberfest 2013" ;
    example:happened "48.13188#11.54965#1379714400#1381017600"^^<http://my-lat-lon-starttime-endtime-dt> .
            
example:RAR-2013
    rdf:type example:Festival ;
    rdfs:label "Rock am Ring 2013" ;
    example:happened "50.33406#6.94259#1370556000#1370736000"^^<http://my-lat-lon-starttime-endtime-dt>  .

The example:happened predicate now points to a ternary datatype composed out of latitude, longitude, start time, and end time of the event. Here’s an example of how you can query the new datatype:

PREFIX geoliteral: <http://www.bigdata.com/rdf/geospatial/literals/v1#>
PREFIX geo: <http://www.bigdata.com/rdf/geospatial#>
PREFIX example: <http://www.example.com/>

SELECT * WHERE {
 
  SERVICE geo:search {
    ?event geo:search "inCircle" .
    ?event geo:predicate example:happened .
    ?event geo:searchDatatype <http://my-lat-lon-starttime-endtime-dt>  .
    ?event geo:spatialCircleCenter "48.13743#11.57549" . # Munich
    ?event geo:spatialCircleRadius "500" . # default unit: Kilometers
    ?event geo:customFields "starttime#endtime" .
    ?event geo:customFieldsLowerBounds "1356998400#1380585600" . # 01.01.2013 / 31.09.2013
    ?event geo:customFieldsUpperBounds "1380585600#1388448000" . # 31.09.2013 / 31.12.2013
    ?event geo:latValue ?latitude .
    ?event geo:lonValue ?longitude .
    ?event geo:customFieldsValues ?customFields .    
  }
}

The query extracts all events in 500km distance to Munich that started in the range from 01.01.2013 - 31.09.2013 (see first component of customFieldsLowerBounds and customFieldsUpperBounds, respectively) and ended in the range 31.09.2013 - 31.12.2013. Here’s the result (note that we output latitude, longitude, and the actual values for the custom fields using magic predicates geo:latValue, geo:lonValue, and geo:customFieldsValues):

event latitude longitude customFields
<http://www.example.com/Oktoberfest-2013> 48.13188 11.54965 1379714400#1381017600


Let’s look at another example, where we define a datatype without geospatial component:

com.bigdata.rdf.store.AbstractTripleStore.geoSpatialDatatypeConfig.1= { "config": { "uri": "http://width-height-length-dt", "fields": [ { "valueType": "LONG", "serviceMapping": "width" }, { "valueType": "LONG", "serviceMapping": "height" }, { "valueType": "LONG", "serviceMapping": "length" } ] } }

The datatype contains three dimensions, width, height, and length. Note that we pad a “.1”, it’s intended to be used in addition to the previous datatype (you need to add the datatype URI http://width-height-length-dt to your vocabulary class and define both the lat+lon+starttime+endtime with id “.0” in addition to this one).

Here’s some simple sample data to test the datatype (assuming we describe some articles, with width, height, and length given in centimeters):

@prefix example: <http://www.example.com/> .

example:Article1
    rdf:type example:Article ;
    example:dimension "10#20#20"^^<http://width-height-length-dt> .

example:Article2
    rdf:type example:Article ;
    example:dimension "30#20#10"^^<http://width-height-length-dt> .

example:Article3
    rdf:type example:Article ;
    example:dimension "100#20#20"^^<http://width-height-length-dt> .

The following query extracts all articles that have width 10cm-30cm, height 20cm-30cm, and length 10cm-20cm:

PREFIX geoliteral: <http://www.bigdata.com/rdf/geospatial/literals/v1#>
PREFIX geo: <http://www.bigdata.com/rdf/geospatial#>
PREFIX example: <http://www.example.com/>

SELECT * WHERE {
 
  SERVICE geo:search {
    ?article geo:predicate example:dimension .
    ?article geo:searchDatatype <http://width-height-length-dt>  .
    ?article geo:customFields "width#height#length" .
    ?article geo:customFieldsLowerBounds "10#20#10" .
    ?article geo:customFieldsUpperBounds "30#30#20" .
    ?article geo:customFieldsValues ?customFields .
  }
}

Here's the result:

article customFields
<http://www.example.com/Article1> 10#20#20
<http://www.example.com/Article2> 30#20#10


Custom Serializer and Deserializer for Geospatial Datatypes

The default format assumes that the fields are separated using “#” and contain no whitespaces. In some cases you may want to work with existing literal formats. To this end, it is possible to hook in custom literal serializers. Assume, for instance, you want to support WKT literals. This can be achieved by specifying a custom literalSerializer in your configuration:

{ "config": 
    { "uri": "http://www.opengis.net/ont/geosparql#wktLiteral",
       "literalSerializer": "com.bigdata.rdf.sparql.ast.eval.service.WKTLiteralSerializer",
       "fields": [
           { "valueType": "DOUBLE", "multiplier": "1000000", "serviceMapping": "LONGITUDE" },
           { "valueType": "DOUBLE", "multiplier": "1000000", "serviceMapping": "LATITUDE" } 
      ]
    }
  }

The WKT format is a two-component format for encoding geospatial coordinates, using literals such as “Point(10.4 12.1233)^^<http://www.opengis.net/ont/geosparql#wktLiteral>”. The field definition defines these two fields (longitude as the first component, latitude as the second). The literalSerializer property points to a class that defines how to parse the datatype. The class must implement the interface com.bigdata.service.IGeoSpatialLiteralSerializer, which defines a couple of methods, most importantly:

    /**
     * Decomposes a string[] into an array of strings identifying the
     * individual components.
     *
     * @param literalString
     * @return
     */
    public String[] toComponents(final String literalString);
    
    /**
     * Recomposes the components into a string, should typically use
     * the object's toString() method.
     *
     * @param components
     * @return
     */
    public String fromComponents(final Object[] components);

So all you need to do is providing an implementation for these methods that decompose the literal string into its components (namely, the strings representing longitude and latitude) and, the way back, how to recompose them into a literal. There are a variety of other methods (such as serializeLocation(), serializeLocationAndTime(), …) which determine how the result of a query for the respective predicates (geo:locationValue, geo:locationAndTimeValue, …) will look like. You may extend GeoSpatialDefaultLiteralSerializer if you don’t want to implement them yourself or provide a custom implementation.

Summary of Geospatial Magic Predicates

The following magic predicates are available.

Predicate Description Required Example
geo:search The search function, either "inRectangle" or "inCircle" Only if the datatype to be queries has geospatial fields "inRectangle"
geo:predicate A filter over the predicate for which we’re looking up geospatial literals Yes (*plans to make this optional in future releases) <http://ex.com/location>
geo:context A filter over the context in which we’re looking up geospatial literals, to be used in quads mode only No <http://my.named.graph>
geo:searchDatatype A filter over the datatype of literals we’re interested in Yes, unless com.bigdata.rdf.store.AbstractTripleStore.geoSpatialDefaultDatatype is set via config <http://www.bigdata.com/rdf/geospatial/literals/v1#lat-lon>
geo:spatialCircleCenter Coordinates of the center for an "inCircle" search request Yes if geo:search is set to "inCircle" "10.0#10.0"
geo:spatialCircleRadius Maximum distance to the spatial circle center for an "inCircle" search request. Default unit is "Kilometers" Yes if geo:search is set to "inCircle" "50"
geo:spatialUnit "Miles", and "NauticalMiles". No "Meters"
geo:spatialRectangleSouthWest The south-west coordinates of the bounding rectangle used for search in mode "inRectangle" Yes if geo:search is set to "inRectangle" "5.112#10.33"
geo:spatialRectangleNorthEast The north-east coordinates of the bounding rectangle used for search in mode "inRectangle" Yes if geo:search is set to "inRectangle" "5.412#11.2"
geo:coordSystem The coordinate system ID used for the query. Yes if the datatype contains a coordinate system component "405"
geo:literalValue Variable to which the (complete) value of matched geospatial literals will be bound (typed with the datatype of the respective geospatial datatype being queried) No  ?geoSpatialLiteral
geo:locationValue Variable to which the location value (in the format "latitude#longitude") of matched geospatial literals will be bound (only available if the datatype has geospatial coordinates) No  ?location
geo:locationAndTimeValue Variable to which the location and time value (in the format "latitude#longitude#time") of matched geospatial literals will be bound (only available if the datatype has geospatial coordinates and time) No  ?locationTime
geo:latValue Variable to which the latitude value of matched geospatial literals will be bound (only available if the datatype has geospatial coordinates) No  ?latitude
geo:lonValue Variable to which the longitude value of matched geospatial literals will be bound (only available if the datatype has geospatial coordinates) No  ?longitude
geo:distanceValue Variable to which the distance to the center point will be bound (only available for "inCircle" queries); will be supported starting version 2.2 No  ?distance
geo:timeValue Variable to which the time value of matched geospatial literals will be bound (only available if the datatype has a time component) No  ?time
geo:coordSystemValue Variable to which the coordinate system value of matched geospatial literals will be bound (only available if the datatype has a coordinate system component) No  ?coordSystem
geo:customFieldsValues Variable to which the location and time value (separated through character "#") of matched geospatial literals will be bound (only available if the datatype has custom fields) No  ?cstFields
geo:customFields Listing of custom fields contained in the datatype to be queried (in any order). Yes if the index has custom fields "x#y#z"
geo:customFieldsLowerBounds Lower bounds for the custom fields in the index, aligned with the order given through the geo:customFields value Yes if the index has custom fields "0#1.1#1.1"
geo:customFieldsUpperBounds Upper bounds for the custom fields in the index, aligned with the order given through the geo:customFields value Yes if the index has custom fields "1#2.2#3.3"