GeoSPARQL support¶
What’s in this document?
What is GeoSPARQL¶
GeoSPARQL is a standard for representing and querying geospatial linked data from the Open Geospatial Consortium (OGC). The standard provides:
A small topological ontology in RDFS/OWL for representation using Geography Markup Language (GML) and Well-Known Text (WKT) literals.
Simple Features, RCC8, and Egenhofer topological relationship vocabularies and ontologies for qualitative reasoning.
A SPARQL query interface using a set of topological SPARQL extension functions for quantitative reasoning.
The GraphDB GeoSPARQL plugin enables the conversion of Well-Known Text from different coordinate reference systems (CRS) into the CRS84 format, which is the default CRS according to the Open Geospatial Consortium (OGC). The plugin will properly index data of all known CRS types and can be queried in the default CRS84 format.
Note
The GraphDB GeoSPARQL plugin implements the GeoSPARQL 1.0 Standard specification. For more information on GeoSPARQL predicates and functions, see the official specification.
The following is a simplified diagram of the GeoSPARQL classes Feature and Geometry, as well as some of their properties:
Usage¶
Configuration parameters¶
The following parameters can be used when configuring the plugin:
Parameter |
enabled |
|---|---|
Predicate |
|
Description |
Enables and disables plugin. |
Default |
|
Example |
PREFIX geoSparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA { [] geoSparql:enabled "true" . }
|
Parameter |
prefixTree |
|---|---|
Predicate |
|
Description |
Implementation of the tree used while building the index; stores value before rebuilding. |
Default |
prefixTree.QUAD |
Example |
PREFIX geoSparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA { [] geoSparql:prefixTree "geohash" . }
|
Parameter |
precision |
|---|---|
Predicate |
|
Description |
Specifies the desired precision; stores value before rebuilding. |
Default |
11 min value 1; maximum value depends on used prefixTree or (24 for geohash and 50 for QUAD) |
Example |
PREFIX geoSparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA { [] geoSparql:precision "11" . }
|
Parameter |
currentPrefixTree |
|---|---|
Predicate |
|
Description |
Value of last built index. |
Default |
PrefixTree.QUAD |
Example |
PREFIX geoSparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA { [] geoSparql:currentPrefixTree "geohash" . }
|
Parameter |
currentPrecision |
|---|---|
Predicate |
|
Description |
Value of last built index. |
Default |
11 |
Example |
PREFIX geoSparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA { [] geoSparql:currentPrecision "11" . }
|
Parameter |
maxBufferedDocs |
|---|---|
Predicate |
|
Description |
Speeds up building and rebuilding of index. |
Default |
1,000 (maximum allowed 5,000) |
Example |
PREFIX geoSparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA { [] geoSparql:maxBufferedDocs "3000" . }
|
Parameter |
ramBufferSizeMB |
|---|---|
Predicate |
|
Description |
Speeds up building and rebuilding of index. |
Default |
32.0 (maximum allowed 512.0) |
Example |
PREFIX geoSparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA { [] geoSparql:ramBufferSizeMB "256.0" . }
|
Parameter |
ignoreErrors |
|---|---|
Predicate |
|
Description |
Ensures building of the index even in case of erroneous data. |
Default |
|
Example |
PREFIX geoSparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA { [] geoSparql:ignoreErrors "true" . }
|
Plugin control predicates¶
The plugin allows you to configure it through SPARQL UPDATE queries with embedded control predicates.
Enable plugin¶
When the plugin is enabled, it indexes all existing GeoSPARQL data in the repository and automatically re-indexes any updates.
PREFIX geosparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA {
[] geosparql:enabled "true" .
}
Note
All functions require WKT or GML literals as input while the predicates expect resources of type geo:Feature or geo:Geometry. The GraphDB implementation has a non-standard extension that also lets you use literals with the predicates. See Example 2 (using predicates) for an example of that usage.
Warning
All GeoSPARQL functions that use the geof: prefix (for example, geof:sfOverlaps) do not use any indexes and are always enabled. This is why it’s best to use the indexed operations such as geo:sfOverlaps whenever possible.
Disable plugin¶
When the plugin is disabled, it does not index any data or process updates. It also does not handle any of the GeoSPARQL predicates.
PREFIX geosparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA {
[] geosparql:enabled "false" .
}
Check the current configuration¶
All the plugin configuration parameters are stored in $GDB_HOME/data/repositories/<repoId>/storage/GeoSPARQL/config.properties. You can use the following query to check the current runtime configuration:
PREFIX geosparql: <http://www.ontotext.com/plugins/geosparql#>
SELECT DISTINCT * WHERE {
[] geosparql:currentPrefixTree ?tree;
geosparql:currentPrecision ?precision;
}
Update the current configuration¶
The plugin supports two indexing algorithms: quad prefix tree and geohash prefix tree. Both algorithms support approximate matching controlled with the precision parameter. The default precision value of 11 for the quad prefix is about ±2.5km on the equator. When increased to 20 the precision goes down to ±6m accuracy. Respectively, the geohash prefix tree with precision 11 results ±1m.
PREFIX geosparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA {
[] geosparql:prefixTree "quad"; #geohash
geosparql:precision "25".
}
After changing the indexing algorithm a reindex is required.
Speed up the building and rebuilding of the GeoSPARQL index¶
To speed up the building and rebuilding of your GeoSPARQL index, we recommend setting higher values for the ramBufferSizeMB and maxBufferedDocs parameters. This disables the Lucene IndexWriter autocommit and starts flushing disk changes if one of these values is reached.
Default and maximum values are as follows:
ramBufferSizeMB— default 32.0, maximum 512.0.maxBufferedDocs— default 1,000, maximum 5,000.
Depending on your dataset and machine parameters, you can experiment with the values to find the ones most suitable for your use case.
Note
Do not set these values too high or you may hit an IndexWriter over-merging issue.
Force reindex geometry data¶
This configuration option is usually used after a configuration change or when index files are either corrupted or have been mistakenly deleted.
PREFIX onto-geo: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA {
[] onto-geo:forceReindex []
}
Ignore errors on indexing¶
PREFIX geosparql: <http://www.ontotext.com/plugins/geosparql#>
INSERT DATA {
[] geosparql:ignoreErrors "true"
}
The ignoreErrors predicate determines whether the GeoSPARQL index will continue building if an error has occurred. If the value is set to false, the whole index will fail if there is a problem with a document. If the value is set to true, the index will continue building and a warning will be logged. By default, the value of ignoreErrors is false.
GeoSPARQL extensions¶
On top of the standard GeoSPARQL functions, GraphDB adds a few useful extensions based on the USeekM library. The prefix geoext: stands for the namespace <http://rdf.useekm.com/ext#>.
Types such as geo:Geometry and geo:Point refer to GeoSPARQL types in the http://www.opengis.net/ont/geosparql# namespace.
Function |
Description |
|---|---|
|
Calculates the area of the surface of the geometry. |
|
For two given geometries, computes the point on the first geometry that is closest to the second geometry. |
|
Tests if the first geometry properly contains the second geometry. Geom1 contains properly geom2 if all geom1 contains geom2 and the boundaries of the two geometries do not intersect. |
|
Tests if the first geometry is covered by the second geometry. Geom1 is covered by geom2 if every point of geom1 is a point of geom2. |
|
Tests if the first geometry covers the second geometry. Geom1 covers geom2 if every point of geom2 is a point of geom1. |
|
Measures the degree of similarity between two geometries. The measure is normalized to lie in the range [0, 1]. Higher measures indicate a greater degree of similarity. |
|
Computes the shortest line between two geometries and returns it as a LineString object. |
|
Given a maximum deviation from the curve, computes a simplified version of the given geometry using the Douglas-Peuker algorithm. |
|
Given a maximum deviation from the curve, computes a simplified version of the given geometry using the Douglas-Peuker algorithm. This will avoid the creation of derived geometries (polygons in particular) that are invalid. |
|
Checks whether the input geometry is a valid geometry. |
GeoSPARQL examples¶
This section contains examples of SELECT queries on geographic data.
Examples 1, 2, and 3 have a variant using a function (corresponding to the same example in the GeoSPARQL specification), as well as a variant where the function is substituted with a predicate. Examples 4 and 5 use a predicate and correspond to the same examples in the specification.
To run the examples, you need to:
Download and import the file
geosparql-example.rdf.Enable the GeoSPARQL plugin.
The data defines the following spatial objects:
Example 1¶
Find all features that feature my:A contains, where spatial calculations are based on my:hasExactGeometry.
Using a function¶
PREFIX my: <http://example.org/ApplicationSchema#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
SELECT ?f
WHERE {
my:A my:hasExactGeometry ?aGeom .
?aGeom geo:asWKT ?aWKT .
?f my:hasExactGeometry ?fGeom .
?fGeom geo:asWKT ?fWKT .
FILTER (geof:sfContains(?aWKT, ?fWKT) && !sameTerm(?aGeom, ?fGeom))
}
Using a predicate¶
PREFIX my: <http://example.org/ApplicationSchema#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
SELECT ?f
WHERE {
my:A my:hasExactGeometry ?aGeom .
?f my:hasExactGeometry ?fGeom .
?aGeom geo:sfContains ?fGeom .
FILTER (!sameTerm(?aGeom, ?fGeom))
}
Example 1 result¶
?f |
|---|
my:B |
my:F |
Example 2¶
Find all features that are within a transient bounding box geometry, where spatial calculations are based on my:hasPointGeometry.
Using a function¶
PREFIX my: <http://example.org/ApplicationSchema#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
SELECT ?f
WHERE {
?f my:hasPointGeometry ?fGeom .
?fGeom geo:asWKT ?fWKT .
FILTER (geof:sfWithin(?fWKT, '''
<http://www.opengis.net/def/crs/OGC/1.3/CRS84>
Polygon ((-83.4 34.0, -83.1 34.0,
-83.1 34.2, -83.4 34.2,
-83.4 34.0))
'''^^geo:wktLiteral))
}
Using a predicate¶
Note
Using geometry literals in the object position is a GraphDB extension and not part of the GeoSPARQL specification.
PREFIX my: <http://example.org/ApplicationSchema#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
SELECT ?f
WHERE {
?f my:hasPointGeometry ?fGeom .
?fGeom geo:sfWithin '''
<http://www.opengis.net/def/crs/OGC/1.3/CRS84>
Polygon ((-83.4 34.0, -83.1 34.0,
-83.1 34.2, -83.4 34.2,
-83.4 34.0))
'''^^geo:wktLiteral
}
Example 2 result¶
?f |
|---|
my:D |
Example 3¶
Find all features that touch the union of feature my:A and feature my:D, where computations are based on my:hasExactGeometry.
Using a function¶
PREFIX my: <http://example.org/ApplicationSchema#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
SELECT ?f
WHERE {
?f my:hasExactGeometry ?fGeom .
?fGeom geo:asWKT ?fWKT .
my:A my:hasExactGeometry ?aGeom .
?aGeom geo:asWKT ?aWKT .
my:D my:hasExactGeometry ?dGeom .
?dGeom geo:asWKT ?dWKT .
FILTER (geof:sfTouches(?fWKT, geof:union(?aWKT, ?dWKT)))
}
Using a predicate¶
PREFIX my: <http://example.org/ApplicationSchema#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
SELECT ?f
WHERE {
?f my:hasExactGeometry ?fGeom .
?fGeom geo:asWKT ?fWKT .
my:A my:hasExactGeometry ?aGeom .
?aGeom geo:asWKT ?aWKT .
my:D my:hasExactGeometry ?dGeom .
?dGeom geo:asWKT ?dWKT .
BIND(geof:union(?aWKT, ?dWKT) AS ?union) .
?fGeom geo:sfTouches ?union
}
Example 3 result¶
?f |
|---|
my:C |
Example 4¶
Find the 3 closest features to feature my:C, where computations are based on my:hasExactGeometry.
PREFIX uom: <http://www.opengis.net/def/uom/OGC/1.0/>
PREFIX my: <http://example.org/ApplicationSchema#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
SELECT ?f
WHERE {
my:C my:hasExactGeometry ?cGeom .
?cGeom geo:asWKT ?cWKT .
?f my:hasExactGeometry ?fGeom .
?fGeom geo:asWKT ?fWKT .
FILTER (?fGeom != ?cGeom)
}
ORDER BY ASC(geof:distance(?cWKT, ?fWKT, uom:metre))
LIMIT 3
Example 4 result¶
?f |
|---|
my:A |
my:E |
my:D |
Note
The example in the GeoSPARQL specification has a different order in the result: my:A, my:D, my:E. In fact, feature my:E is closer than feature my:D even if that does not seem obvious from the drawing of the objects. my:E’s closest point is 0.1° to the West of my:C, while my:D’s closest point is 0.1° to the South. At that latitude and longitude the difference in terms of distance is larger in latitude, hence my:E is closer.
Example 5¶
Find all features or geometries that overlap feature my:A.
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX my: <http://example.org/ApplicationSchema#>
SELECT ?f
WHERE {
?f geo:sfOverlaps my:AExactGeom
}
Example 5 result¶
?f |
|---|
my:D |
my:DExactGeom |
Note
The example in the GeoSPARQL specification has additional results my:E and my:EExactGeom. In fact, my:E and my:EExactGeom do not overlap my:AExactGeom because they are of different dimensions (my:AExactGeom is a Polygon and my:EExactGeom is a LineString) and the overlaps relation is defined only for objects of the same dimension.