Introduction
The OGC GeoSPARQL standard addresses the need for standardized representation and interaction with geospatial data via SPARQL Query Language extensions. This manifests as new data types, magic predicates, and a vocabulary of terms for describing geospatial data using RDF statements that are inserted to a compliant database (or store) using INSERT
statements and/or bulk loading.
As of Virtuoso Enterprise Edition Release 8.2 and Virtuoso Open Source Edition Release 7.2.6 and above, a number of major enhancements have been made to Geospatial support, improving the Geometry data types and functions, and adding support for the OGC GeoSPARQL standard.
Virtuoso Geo Spatial Data Types
The table below outlines the common WKT (Well Known Text) representations for several types of geometric objects used in RDF:
VirtWktGeometricObjects.png 611x756 51.1 KB
Online Demonstration Queries
To complement this functionality enhancement, a new online Virtuoso GeoSpatial database server comprising common datasets from the Linked Open Data (LOD) Cloud has been commissioned.
What follows is a collection of GeoSPARQL showcase queries and live query solution links that aid understanding and exploitation of this functionality.
General Queries
-- Everything GeoSpatial
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
{
GRAPH ?g
{
my:A my:hasExactGeometry ?aGeom .
?f my:hasExactGeometry ?fGeom .
FILTER ( !geof:sfContains ( ?aGeom , ?fGeom )
&& !sameTerm ( ?aGeom , ?fGeom )
)
}
}
OGC GeoSPARQL Test Queries
A dataset and a number of test queries are provided in the OGC GeoSPARQL specification document, some of which are listed below.
OGC Query 1: Find all features that feature my:A
contains, where spatial calculations are based on my:hasExactGeometry
.
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
FROM <https://github.com/mjovanovik/GeoSPARQLBenchmark/blob/master/src/main/resources/gsb_dataset/example.rdf>
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 )
)
}
OGC Query 2: Find all features that are within a transient bounding box geometry, where spatial calculations are based on my:hasPointGeometry
.
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
FROM <https://github.com/mjovanovik/GeoSPARQLBenchmark/blob/master/src/main/resources/gsb_dataset/example.rdf>
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 )
)
}
OGC Query 3: Find all features that touch the union of feature my:A
and feature my:D
, where computations are based on my:hasExactGeometry
.
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
FROM <https://github.com/mjovanovik/GeoSPARQLBenchmark/blob/master/src/main/resources/gsb_dataset/example.rdf>
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 ) )
)
}
OGC Query 4: Find the 3 closest features to feature my:C
, where computations are based on my:hasExactGeometry
.
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX my: <http://example.org/ApplicationSchema#>
SELECT DISTINCT ?f
FROM <https://github.com/mjovanovik/GeoSPARQLBenchmark/blob/master/src/main/resources/gsb_dataset/example.rdf>
WHERE
{
?f my:hasExactGeometry ?fGeom .
?fGeom geo:asWKT ?fWKT .
FILTER ( geof:sfOverlaps ( ?fWKT , "Polygon((-83.6 34.1, -83.2 34.1, -83.2 34.5, -83.6 34.5, -83.6 34.1))"^^geo:wktLiteral )
)
}
Washington DC Landmark Queries
Landmark Query 1: Retrieve each area and its relation to the others
PREFIX unit: <http://qudt.org/vocab/unit#>
PREFIX : <http://blog.stardog.com/geons/>
PREFIX wgs: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX : <#>
# Retrieve each area and its relation to the others
SELECT DISTINCT ?feature1
?feature2
?geom1
?geom2
( geof:relate ( ?geom1+>geo:asWKT , ?geom2+>geo:asWKT ) as ?rel)
WHERE
{
?f a :Area ;
rdfs:label ?feature1 ;
geo:hasGeometry ?geom1 .
?f2 a :Area ;
rdfs:label ?feature2 ;
geo:hasGeometry ?geom2 .
}
Landmark Query 2: Retrieve the areas in our dataset where one contains the other
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX : <#>
# Retrieve the areas in our dataset where one contains the other
SELECT DISTINCT ?feature1
?feature2
FROM <urn:geosparql:dclandmarks:data>
WHERE
{
?f a :Area ;
rdfs:label ?feature1 ;
geo:hasGeometry ?geom1 .
?f2 a :Area ;
rdfs:label ?feature2 ;
geo:hasGeometry ?geom2 .
FILTER ( geof:relate ( ?geom1+>geo:asWKT , ?geom2+>geo:asWKT , "T*****FF*" )
)
}
Landmark Query 3: List monuments spatially within which parks
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX ex: <http://www.example.org/POI#>
SELECT ?m
?p
FROM <urn:geosparql:dclandmarks:washington:monuments:data>
WHERE
{
?m a ex:Monument ;
geo:hasGeometry ?mgeo .
?p a ex:Park ;
geo:hasGeometry ?pgeo .
?mgeo geo:asWKT ?point .
FILTER ( geof:sfWithin ( ?point ,
"POLYGON((-77.050125 38.892086, -77.039482 38.892036, -77.039482 38.895393, -77.033669 38.895508, -77.033585 38.892052, -77.031906 38.892086, -77.031883 38.887474, -77.050232 38.887142, -77.050125 38.892086 ))"^^geo:wktLiteral )
)
}
Landmark Query 4: List Monuments within a 3000 metre radius
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX ex: <http://www.example.org/POI#>
PREFIX units: <http://www.opengis.net/def/uom/OGC/1.0/>
SELECT ?p
FROM <urn:geosparql:dclandmarks:washington:monuments:data>
WHERE
{
?p a ex:Park ;
geo:hasGeometry ?pgeo .
?pgeo geo:asWKT ?pwkt .
ex:WashingtonMonument geo:hasGeometry ?wgeo .
?wgeo geo:asWKT ?wwkt .
FILTER ( geof:distance ( ?pwkt , ?wwkt , units:meter ) < 3000 )
}
Natural Earth Queries
Natural Earth is a public domain map dataset featuring tightly integrated vector and raster data. With Natural Earth, you can make a variety of visually pleasing, well-crafted maps with cartography or GIS software.
Natural Earth Query 1
DEFINE sql:select-option "ORDER"
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX lgv: <http://linkedgeodata.org/vocabulary#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX ogcgsf: <http://www.opengis.net/def/function/geosparql/>
WITH <file://natural_earth/10m_cultural/ne_10m_admin_0_countries.shp>
SELECT ?name1
( GROUP_CONCAT ( ?name2 , ", " ) )
WHERE
{
?s1 <NAME> ?name1 .
?s2 <NAME> ?name2 .
?s1 <http://www.opengis.net/ont/geosparql#asWKT> ?shp1 .
?s2 <http://www.opengis.net/ont/geosparql#asWKT> ?shp2 .
FILTER ( ogcgsf:sfIntersects ( ?shp1 , ?shp2 )
)
}
GROUP BY ?name1
ORDER BY DESC ( COUNT ( 1 ) )
Natural Earth Query 2
DEFINE sql:select-option "ORDER"
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX lgv: <http://linkedgeodata.org/vocabulary#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX ogcgsf: <http://www.opengis.net/def/function/geosparql/>
SELECT ?name1
( GROUP_CONCAT ( ?name2 , ", " ) AS ?group )
FROM <file://natural_earth/10m_cultural/ne_10m_admin_0_countries.shp>
WHERE
{
?s1 <NAME> ?name1 .
?s2 <NAME> ?name2 .
FILTER
( ogcgsf:sfIntersects
(
(
SELECT ?shp1
WHERE
{ ?s1 <http://www.opengis.net/ont/geosparql#asWKT> ?shp1 . }
),
(
SELECT ?shp2
WHERE
{ ?s2 <http://www.opengis.net/ont/geosparql#asWKT> ?shp2 . }
)
)
)
}
GROUP BY ?name1
ORDER BY DESC ( COUNT ( 1 ) )
Natural Earth Query 2.5
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX ogcgsf: <http://www.opengis.net/def/function/geosparql/>
PREFIX bif: <http://www.openlinksw.com/schemas/bif#>
SELECT ( ?s1 AS ?href )
?name
( ?name AS ?town )
( bif:st_xmin ( ?shp1 ) AS ?longitude )
( bif:st_ymin ( ?shp1 ) AS ?latitude )
?maxPop
WHERE
{
GRAPH <file://natural_earth/10m_cultural/ne_10m_admin_0_boundary_lines_map_units.shp>
{ ?england <NAME> "England" ;
geo:asWKT ?eng_as_region .
}
GRAPH <file://natural_earth/10m_cultural/ne_10m_populated_places_simple.shp>
{
?s1 geo:asWKT ?shp1 ;
<LS_NAME> ?name ;
<POP_MAX> ?maxPop
}
FILTER ( geof:sfIntersects ( ?eng_as_region , ?shp1 )
)
}
Natural Earth Query 3
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX ogcgsf: <http://www.opengis.net/def/function/geosparql/>
PREFIX bif: <http://www.openlinksw.com/schemas/bif#>
SELECT ( ?s1 AS ?href )
?name
( bif:st_xmin ( ?shp1 ) AS ?longitude )
( bif:st_ymin ( ?shp1 ) AS ?latitude )
WHERE
{
GRAPH <file://natural_earth/10m_cultural/ne_10m_admin_0_boundary_lines_map_units.shp>
{ ?england <NAME> "England" ;
geo:asWKT ?eng_as_region .
}
GRAPH <file://natural_earth/10m_cultural/ne_10m_populated_places_simple.shp>
{ ?s1 geo:asWKT ?shp1 ;
<LS_NAME> ?name
}
FILTER ( geof:sfIntersects ( ?eng_as_region , ?shp1 )
)
}
Natural Earth Query 4
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX ogcgsf: <http://www.opengis.net/def/function/geosparql/>
PREFIX bif: <http://www.openlinksw.com/schemas/bif#>
SELECT ( ?s1 AS ?href )
?name
( bif:st_xmin ( ?shp1 ) AS ?longitude )
( bif:st_ymin ( ?shp1 ) AS ?latitude )
WHERE
{
GRAPH <file://natural_earth/10m_cultural/ne_10m_admin_0_boundary_lines_map_units.shp>
{ ?s <NAME> "Russia" ;
geo:asWKT ?region .
}
GRAPH <file://natural_earth/10m_cultural/ne_10m_populated_places_simple.shp>
{ ?s1 geo:asWKT ?shp1 ;
<LS_NAME> ?name
}
FILTER ( geof:sfIntersects ( ?region , ?shp1 ) )
}
Natural Earth Query 5
PREFIX lgv: <http://linkedgeodata.org/ontology/>
SELECT ?href
?name
?church
?churchname
?proximity
?latitude
?longitude
WHERE
{
SERVICE <http://lod.openlinksw.com/sparql>
{
SELECT DISTINCT ( ?cafe AS ?href )
( ?cafename AS ?name )
?church
?churchname
( bif:round ( bif:st_distance ( ?churchgeo , ?cafegeo ) ) ) AS ?proximity
( ?lat AS ?latitude )
( ?long AS ?longitude )
WHERE
{
?church a lgv:PlaceOfWorship .
?church geo:geometry ?churchgeo .
?church rdfs:label ?churchname .
?cafe a lgv:Cafe .
?cafe rdfs:label ?cafename .
?cafe geo:geometry ?cafegeo .
?cafe geo:lat ?lat .
?cafe geo:long ?long .
FILTER ( bif:st_intersects ( ?churchgeo , bif:st_point ( 2.3498,48.853 ) , 5 )
&&
bif:st_intersects ( ?cafegeo , ?churchgeo
, 0.9 )
)
}
}
}
Natural Earth Query 6
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX geof: <http://www.opengis.net/def/function/geosparql/>
PREFIX ogcgsf: <http://www.opengis.net/def/function/geosparql/>
PREFIX bif: <http://www.openlinksw.com/schemas/bif#>
SELECT ?river_name
( GROUP_CONCAT ( DISTINCT ?border_name , "; " ) )
WHERE
{
GRAPH <file://natural_earth/10m_physical/ne_10m_rivers_lake_centerlines.shp>
{ ?river <NAME> ?river_name }
GRAPH <file://natural_earth/10m_cultural/ne_10m_admin_0_boundary_lines_map_units.shp>
{ ?border <NAME> ?border_name }
FILTER
( ogcgsf:sfCrosses
(
(
SELECT ?river_shp
WHERE { ?river ogcgs:asWKT ?river_shp }
) ,
(
SELECT ?border_shp
WHERE { ?border ogcgs:asWKT ?border_shp }
)
)
)
}
GROUP BY ?river_name
HAVING ( COUNT ( 1 ) > 1 )
ORDER BY ?river_name