# Geo-spatial extensions¶

## What are geo-spatial extensions¶

GraphDB provides support for 2-dimensional geo-spatial data that uses the WGS84 Geo Positioning RDF vocabulary (World Geodetic System 1984). Specialised indexes can be used for this type of data, which allow efficient evaluation of query forms and extension functions for finding locations:

• within a certain distance of a point, i.e. within a specified circle on the surface of a sphere (Earth), using the nearby(...) construction;
• within rectangles and polygons, where the vertices are defined by spherical polar coordinates, using the within(...) construction.

The WGS84 ontology contains several classes and predicates:

Element Description
SpatialThing A class for representing anything with a spatial extent, i.e., size, shape or position.
Point A class for representing a point (relative to Earth) defined by latitude, longitude (and altitude). subClassOf http://www.w3.org/2003/01/geo/wgs84_pos#SpatialThing
location The relation between a thing and where it is. Range SpatialThing subPropertyOf http://xmlns.com/foaf/0.1/based_near
lat The WGS84 latitude of a SpatialThing (decimal degrees). domain http://www.w3.org/2003/01/geo/wgs84_pos#SpatialThing
long The WGS84 longitude of a SpatialThing (decimal degrees). domain http://www.w3.org/2003/01/geo/wgs84_pos#SpatialThing
lat_long A comma-separated representation of a latitude, longitude coordinate.
alt The WGS84 altitude of a SpatialThing (decimal meters above the local reference ellipsoid). domain http://www.w3.org/2003/01/geo/wgs84_pos#SpatialThing

## How to create a geo-spatial index¶

Execute the following INSERT query:

PREFIX ontogeo: <http://www.ontotext.com/owlim/geo#>
INSERT DATA { _:b1 ontogeo:createIndex _:b2. }


If all geo-spatial data is indexed successfully, the above update query will succeed. If there is an error, you will get a notification about a failed transaction and an error will be registered in the GraphDB log files.

Note

If there is no geo-spatial data in the repository, i.e., no statements describing resources with latitude and longitude properties, this update query will fail.

## Geo-spatial query syntax¶

The Geo-spatial query syntax is the SPARQL RDF Collections syntax. It uses round brackets as a shorthand for the statements, which connect a list of values using rdf:first and rdf:rest predicates with terminating rdf:nil. Statement patterns that use custom geo-spatial predicates, supported by GraphDB are treated differently by the query engine.

The following special syntax is supported when evaluating SPARQL queries. All descriptions use the namespace: omgeo: <http://www.ontotext.com/owlim/geo#>

Construct Nearby (lat long distance) ?point omgeo:nearby(?lat ?long ?distance) This statement pattern will evaluate to true, if the following constraints hold: ?point geo:lat ?plat . ?point geo:long ?plong . Shortest great circle distance from (?plat, ?plong) to (?lat, ?long) <= ?distance Such a construction uses the geo-spatial indexes to find bindings for ?point, which lie within the defined circle. Constants are allowed for any of ?lat ?long ?distance, where latitude and longitude are specified in decimal degrees and distance is specified in either kilometers (‘km’ suffix) or miles (‘mi’ suffix). If the units are not specified, then ‘km’ is assumed. Latitude is limited to the range -90 (South) to 90 (North). Longitude is limited to the range -180 (West) to +180 (East). Find the names of airports within 50 miles of Seoul: PREFIX geo-pos: PREFIX geo-ont: PREFIX omgeo: SELECT distinct ?airport WHERE { ?base geo-ont:name "Seoul" . ?base geo-pos:lat ?latBase . ?base geo-pos:long ?longBase . ?link omgeo:nearby(?latBase ?longBase "50mi") . ?link geo-ont:name ?airport . ?link geo-ont:featureCode geo-ont:S.AIRP . } 
Construct Within (rectangle) ?point omgeo:within(?lat1 ?long1 ?lat2 ?long2) This statement pattern is used to test/find points that lie within the rectangle specified by diagonally opposite corners ?lat1 ?long1 and ?lat2 ?long2. The corners of the rectangle must be either constants or bound values. It will evaluate to true, if the following constraints hold: ?point geo:lat ?plat . ?point geo:long ?plong . ?lat1 <= ?plat <= ?lat2 ?long1 <= ?plong <= ?long2 Note that the most westerly and southerly corners must be specified first and the most northerly and easterly ones - second. Constants are allowed for any of ?lat1 ?long1 ?lat2 ?long2, where latitude and longitude are specified in decimal degrees. If ?point is unbound, then bindings for all points within the rectangle will be produced. Rectangles that span across the +/-180 degree meridian might produce incorrect results. Latitude is limited to the range -90 (South) to +90 (North). Longitude is limited to the range -180 (West) to +180 (East). Rectangle vertices must be specified in the order lower-left followed by upper-right. Find tunnels lying within a rectangle enclosing Tirol, Austria: PREFIX geo-pos: PREFIX geo-ont: PREFIX omgeo: SELECT ?feature ?lat ?long WHERE { ?link omgeo:within(45.85 9.15 48.61 13.18) . ?link geo-ont:featureCode geo-ont:R.TNL . ?link geo-ont:name ?feature . ?link geo-pos:lat ?lat . ?link geo-pos:long ?long . } 
Construct Within (polygon) ?point omgeo:within(?lat1 ?long1 ... ?latN ?longN) This statement pattern is used to test/find points that lie within the polygon whose vertices are specified by three or more latitude/longitude pairs. The values of the vertices must be either constants or bound values. It will evaluate to true, if the following constraints hold: ?point geo:lat ?plat . ?point geo:long ?plong . the position ?plat ?plong is enclosed by the polygon The polygon is closed automatically if the first and last vertices do not coincide. The vertices must be constants or bound values. Coordinates are specified in decimal degrees. If ?point is unbound, then bindings for all points within the polygon will be produced. Latitude is limited to the range -90 (South) to +90 (North). Longitude is limited to the range -180 (West) to +180 (East). Find caves in the sides of cliffs lying within a polygon approximating the shape of England: PREFIX geo-pos: PREFIX geo-ont: PREFIX omgeo: SELECT ?feature ?lat ?long WHERE { ?link omgeo:within( "51.45" "-2.59" "54.99" "-3.06" "55.81" "-2.03" "52.74" "1.68" "51.17" "1.41" ) . ?link geo-ont:featureCode geo-ont:S.CAVE . ?link geo-ont:name ?feature . ?link geo-pos:lat ?lat . ?link geo-pos:long ?long . } 

## Extension query functions¶

At present, there is just one SPARQL extension function:

Function Distance function double omgeo:distance(?lat1, ?long1, ?lat2, ?long2) This SPARQL extension function computes the distance between two points in kilometers and can be used in FILTER and ORDER BY clauses. Latitude is limited to the range -90 (South) to +90 (North). Longitude is limited to the range -180 (West) to +180 (East). Find caves in the sides of cliffs lying within a polygon approximating the shape of England: PREFIX geo-pos: PREFIX geo-ont: PREFIX omgeo: SELECT distinct ?airport_name WHERE { ?a1 geo-ont:name "Bournemouth" . ?a1 geo-pos:lat ?lat1 . ?a1 geo-pos:long ?long1 . ?airport omgeo:nearby(?lat1 ?long1 "80mi" ) . ?airport geo-ont:name ?airport_name . ?airport geo-ont:featureCode geo-ont:S.AIRP . ?airport geo-pos:lat ?lat2 . ?airport geo-pos:long ?long2 . ?a2 geo-ont:name "Brize Norton" . ?a2 geo-pos:lat ?lat3 . ?a2 geo-pos:long ?long3 . FILTER( omgeo:distance(?lat2, ?long2, ?lat3, ?long3) < 80) } ORDER BY ASC( omgeo:distance(?lat2, ?long2, ?lat3, ?long3) ) 

## Implementation details¶

Knowing the implementation’s algorithms and assumptions allow you to make the best use of the GraphDB geo-spatial extensions.

The following aspects are significant and can affect the expected behaviour during query answering:

• Spherical Earth - the current implementation treats the Earth as a perfect sphere with a 6371.009km radius;
• Only 2-dimensional points are supported, i.e., there is no special handling of geo:alt (metres above the reference surface of the Earth);
• All latitude and longitude values must be specified using decimal degrees, where East and North are positive and -90 <= latitude <= +90 and -180 <= longitude <= +180;
• Distances must be in units of kilometers (suffix ‘km’) or statute miles (suffix ‘mi’). If the suffix is omitted, kilometers are assumed;
• omgeo:within( rectangle ) construct uses a ‘rectangle’ whose edges are lines of latitude and longitude, so the north-south distance is constant, and the rectangle described forms a band around the Earth, which starts and stops at the given longitudes;
• omgeo:within( polygon ) joins vertices with straight lines on a cylindrical projection of the Earth tangential to the equator. A straight line starting at the point under test and continuing East out of the polygon is examined to see how many polygon edges it intersects. If the number of intersections is even, then the point is outside the polygon. If the number of intersections is odd, the point is inside the polygon. With the current algorithm, the order of vertices is not relevant (clockwise or anticlockwise);
• omgeo:within() may not work correctly when the region (polygon or rectangle) spans the +/-180 meridian;
• omgeo:nearby() uses the great circle distance between points.