.. include:: /includes.rst.txt
.. comments - headings
# with overline, for parts
* with overline, for chapters
= for sections
- for subsections
^ for subsubsections
" for paragraphs
* for H5
+ for H6
.. _edg_geo_spatial_capabilities:
Geo-spatial capabilities in TopBraid EDG
========================================
The purpose of this document is to showcase how GeoSPARQL can be used within TopBraid Enterprise Data Governance (referred to as EDG). This document will walkthrough steps that enable the usage of the Geo features in EDG, from the creation of schemas to performing actions on items on maps. Finally, the cookbook demonstrates how data governance assets can be enriched with geospatial information.
You will need the following EDG project and TriG file to walk through the cookbook.
To install this sample project in EDG, navigate to Server Administration, Upload Project.
To remove this project in the future use Delete Project.
:download:`geosparql_cookbook.trig <_downloads/geosparql_cookbook.trig>`
.. contents::
.. _1-prerequisites:
1. Prerequisites
----------------
Google Maps API key set up in EDG: *Server Administration* > *System Configuration Parameters* > *Advanced Parameters*.
.. _2-creation-of-a-geo-aware-schema-in-edg:
2. Creation of a geo-aware schema in EDG
----------------------------------------
The following section demonstrates the creation of a generic schema that
describe countries and cities. A mixture of RDF constructs and SHACL
shapes are used. Under *Asset Collections* select *Ontologies*. On page
load, click on the *Create New Ontology* button, which in turn will
display the following form. The *Label* field is mandatory, and once
filled press *Create Ontology*. By default, EDG creates a skeleton
schema, importing the *Default constraints for EDG* and *GraphQL
Vocabulary*.
.. figure:: _images/create_ontology.png
:alt: Create Ontology
:align: center
:class: edg-figure
.. _21-adding-existing-geo-vocabularies-and-shapes:
2.1 Adding existing Geo vocabularies and shapes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
EDG provides a general vocabulary defining a number of classes, SHACL
shapes and SHACL functions, which drives the various functionality
within EDG, for example the *Maps Explorer* panel. The **TopBraid
GeoSPARQL Vocabulary** (``prefix: tbgeo:``) gathers concepts from the
W3C *WGS84 Geo Positioning* RDF vocabulary [1]_ and the *Open
Geospatial Consortium GeoSPARQL - A Geographic Query Language for RDF
Data* schema [2]_, and describes these concepts as SHACL shapes. The
former vocabulary allows the representation of latitude, longitude and
altitude information. The latter vocabulary enables the representation
of geospatial data, and defines a SPARQL extension to query the said
data. By defining these as SHACL shapes, it ensures that users can query
properties in geo-aware asset collections using GraphQL. Furthermore,
the TopBraid vocabulary defines a number of shapes that can be extended
to enable interactive actions on maps in EDG and other functions
relevant for querying. Therefore, adding this vocabulary in the custom
geo-aware schema will ensure that the schema contains all the required
property and node shapes to create a geo-driven asset collection.
In order to include The **TopBraid GeoSPARQL Vocabulary** in the schema,
click on the *Settings* tab, followed by the *Includes* link. This will
display a dialog box with all possible includes. Filter by the
*Collection Name* column, typing **TopBraid GeoSPARQL Vocabulary**, tick
the first column and press *Close*.
.. figure:: _images/includes.png
:alt: Includes
:align: center
:class: edg-figure
The *Settings* page will look as follows, with **TopBraid GeoSPARQL
vocabulary** added under *Includes*:
.. figure:: _images/includes-full.png
:alt: Includes Full
:align: center
:class: edg-figure
Clicking back on the *Ontology* tab, the *Class Hierarchy* panel shows a
tree, with three concepts *Geometry*, *Map context*, and *Spatial
thing*. These concepts will be explained later on in this document.
.. figure:: _images/ontology-page-empty.png
:alt: Ontology Page Empty
:align: center
:class: edg-figure
.. _22-defining-the-schema:
2.2 Defining the Schema
^^^^^^^^^^^^^^^^^^^^^^^
This section describes the shapes and properties defined to create a
geo-aware ontology. This section is not meant to demonstrate the
ontology editing capabilities of EDG. For an introduction in this
regard, the reader is referred to [3]_.
The inclusion of the **TopBraid GeoSPARQL vocabulary** automatically
added three concepts *Geometry* (``geosparql:Geometry``), *Map context*
(``tbgeo:MapContext``), and *Spatial thing* (``geo:SpatialThing``).
Having these concepts included, public classes have to be defined for
the schema. Clicking on the form's dropdown, EDG allows user to view
content related to the ontology's metadata, and content related to the
ontology's GraphQL schema. For the latter schema, this cookbook defines
*Spatial thing* as a public class, meaning that the value and all its
subclasses are included and exposed to the GraphQL endpoint [4]_.
.. figure:: _images/setting-public-class.png
:alt: Public Class Settings
:align: center
:class: edg-figure
.. _221-the-geometry-shape:
2.2.1 The Geometry Shape
""""""""""""""""""""""""
The *Geometry* shape represents the top-level geometry type. This is
equivalent to the GM_Object defined in ISO 19107 [5]_, which allows the
definition of *geometric shapes* (or geometry objects) on maps, such as
points, lines, polygons. The TopBraid vocabulary automatically adds two
property shapes that enable the serialisation of geometric shapes (e.g
polygons) in geo-aware resources in EDG: (1) *asGML*
(``geosparql:asGML``) , and (2) *asWKT* (``geosparql:asWKT``).
The following snippet shows an polygon example serialised using GML:
.. code:: xml
13.833611 48.773605 14.70028 48.581379 15.025833 49.018883 16.946182 48.619064 17.166386 48.012497 17.053886 47.709442 16.450554 47.698051 16.713886 47.543884 16.510555 47.00666 16.111805 46.86972 14.544998 46.407494 13.718655 46.526611 12.440554 46.690826 12.127777 47.001663 10.471235 46.871353 9.598635 47.063835 9.533569 47.274544 9.566724 47.540451 10.173332 47.274719 10.478054 47.591942 11.095554 47.396111 12.735554 47.684166 13.016666 47.470276 12.758333 48.123886 13.833611 48.773605
The following snippet shows a polygon example serialised in WKT:
.. code-block:: text
MULTIPOLYGON(((7.697223 47.543327, 8.57642 47.59137, 8.566111 47.806938, 9.566724 47.540451, 9.533569 47.274544, 9.474637 47.057457, 9.598635 47.063835, 10.471235 46.871353, 10.465277 46.546387, 10.050278 46.539993, 10.129999 46.227219, 9.28194400000012 46.495827, 9.036665 45.837776, 8.43638800000014 46.463333, 7.855742 45.919052, 7.038054 45.931938, 6.79138900000015 46.434166, 5.966666 46.209442, 6.99055500000014 47.497215, 7.588268 47.58448, 7.697223 47.543327)))
In this cookbook, no concepts or property shapes will be created,
extending the *Geometry* shape.
.. _222-map-context-shape:
2.2.2 Map Context Shape
"""""""""""""""""""""""
The *Map Context* shape is a core EDG shape which enables user
interactive actions on maps in geo-aware asset collections. This shape
is an abstract superclass of objects that may serve as the context of
Context Maps. A Context Map is populated with a set of geo resources
that are either asserted or dynamically computed by a ``sh:values``
rule. Section `Creating Interactive Maps <#creating-interactive-maps>`__
details the implementation of *MapContext* subclasses.
.. _223-spatial-thing-shape:
2.2.3 Spatial Thing Shape
"""""""""""""""""""""""""
The *Spatial Thing* shape describes anything with spatial extent, that
is, size, shape and/or position. By default, the TopBraid vocabulary
makes ``geo:lat`` and ``geo:long`` visible to the user by defining them
as property shapes.
.. figure:: _images/extending-spatial-thing-properties.png
:alt: Extending Spatial Thing Properties
:align: center
:class: edg-figure
For purposes of this cookbook, two properties are added to the *Spatial
Thing*, (1) *fill color* (``tbgeo:fillColor``), and (2) *hasGeometry*
(``geosparql:hasGeometry``). ``tbgeo:fillColor`` is an existing property
shape in the core TopBraid GeoSPARQL vocabulary which used internally to
define a CSS3 color that is used to fill geometry objects (such as
polygons) attached to a *Spatial Thing* resource. The property
*hasGeometry* is defined in [6]_, and thus require a definition of a
property shape. The shape defines the property path (``sh:path``) to
look for values with the predicate ``geosparql:hasGeometry`` (*range
value: geosparql:Geometry*). This ensures that the core EDG *Map
Explorer* panel can interpret and display any geometric shapes (in GML
or WKT) on maps. This shape also defines that a *Spatial Thing* expects
at most one ``geosparql:hasGeometry`` which is defined in a blank node [7]_.
Furthermore, a *Details Viewer* is a used to show the value of the geometry as a nested form-like display.
.. figure:: _images/hasGeometry-shape.png
:alt: Has Geometry Shape
:align: center
:class: edg-figure
In this cookbook, we also extend the *Spatial Thing* shape with a number
of new shapes, having two direct subclasses *Geographical Concept* and
*Points of Interest*, each having a number of children subclasses. The
former concept describes countries, cities and roads. The latter
describes physical buildings and monuments. All concepts are defined as
*Node Shapes*.
.. figure:: _images/extended-concepts.png
:alt: Extended Concepts
:align: center
:class: edg-figure
Both concepts are extended with more refined concepts, where each
concept has its own set of properties, apart from those shared by the
super-concept. Taking a closer look to the newly defined concept
*Country*, this concept has two new declared properties: (1)
*hasCapital* that points to an existing *City* resource, and (2)
*wikidata* - a predicate that indicates the corresponding wikidata [8]_
resource URI for a defined resouce in EDG (for example the *Country*
Malta in EDG would have a wikidata URI value:
http://www.wikidata.org/entity/Q233). EDG makes use of these external
links to perform transformation operations such as dynamically computing
values (e.g. getting the population of a country from wikidata),
however, this is out of scope for this cookbook.
.. figure:: _images/country-concept.png
:alt: Country Concepts
:align: center
:class: edg-figure
The rest of the concepts are described in the EDG project file attached
with this project.
.. _224-properties-defined-in-topbraid-geosparql-vocabulary:
2.2.4 Properties defined in TopBraid GeoSPARQL Vocabulary
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
The TopBraid GeoSPARQL vocabulary provides a number of properties and
property shapes that can be used off the shelf. These properties are
used within the available map panels in order to enhance the UX:
- ``tbgeo:fillColor`` - The CSS3 color that shall be used to fill the
geometry object(s).
- ``tbgeo:fillOpacity`` - The fill opacity between 0 and 1.
- ``tbgeo:strokeColor`` - The CSS3 color that shall be used for the
(out) lines the geometry object(s). For polylines (LineStrings) this
can only be a hexadecimal HTML color of the format "#FFFFFF".
- ``tbgeo:strokeWeight`` - The stroke weight in pixels.
- ``tbgeo:symbolPath`` - For Points, this may specify the SVG Path to
render the marker on a map, e.g. "M -20 -10 L 20 -10 L 20 10 L -20 10
L -20 -10" for a rectangle.
- ``tbgeo:symbolScale`` - For Points, this may specify the symbol's
scaling factor, defaulting to 1.
- ``tbgeo:text`` - A (short) text to display on a marker.
.. _3-creating-a-geo-aware-asset-collection:
3. Creating a Geo-Aware asset collection
----------------------------------------
For the purpose of this cookbook, a *Data Graph* asset collection is
created. Under *Asset Collections* select *Data Graphs*. On page load,
click on the *Create New Data Graph* button. The *Label* field is
mandatory, and in the *Includes* field search for the schema that was
created in `the previous
section <#creation-of-a-geo-aware-schema-in-edg>`__. Once filled, press
the *Create Data Graph* button. In order to mark the newly created *Data
Graph* as geo-aware, the user needs to `enable
GeoSPARQL <#enabling-geosparql>`__ for the asset collection
A sample data graph, is provided in the cookbook's EDG project. In order
to open the project, under *Asset Collections* select *Data Graphs*. On
page load, open the GeoSPARQL Cookbook asset.
.. _31-enabling-geosparql:
3.1 Enabling GeoSPARQL
^^^^^^^^^^^^^^^^^^^^^^
Any asset collection can become a geo-aware, however, it must be noted
that this assumes that the asset collection underlying schema has shapes
describing geometry features (as described in `section
2 <#creation-of-a-geo-aware-schema-in-edg>`__). In order to enable
GeoSPARQL, the following steps are to be followed:
1. Open relevant asset collection in EDG;
2. Navigate to *Manage* tab;
3. Scroll down to **Enable GeoSPARQL and Related Features** and check
the box next to *Enable GeoSPARQL for this
{asset_collection_type}*, where *{asset_collection_type}* is the
type of the selected asset collection;
.. figure:: _images/enable_geosparql.png
:alt: Enable GeoSPARQL
:align: center
:class: edg-figure
4. Click *Rebuild Spatial Index* button.
Occasionally, the Spatial Index needs to be rebuild, due to changes in
the asset collection resources. The steps mentioned above can be
re-performed for this task, however, there is no need to un-check and
re-check the enable checkbox.
.. _32-exploring-geo-resources:
3.2 Exploring Geo Resources
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The cookbook's sample asset collection has a number of countries and
cities that pre-defined. Once the asset collection is loaded, EDG loads
the default *Data Graph* view. The left panel is used to filter and
search resources, whilst the right panel is the form panel, where
resource content is displayed.
.. figure:: _images/data-graph-intro.png
:alt: Data Graph Intro
:align: center
:class: edg-figure
The user can navigate through the different types of *Spatial Types*
(e.g. countries, cities, etc...) by selecting the required type in the
search panel dropdown.
EDG 7.0 introduces two new map panels, the **Map Explorer** and the
**Context Map**. This section will walk through the former panel, whilst
the latter is discussed in section `Creating Interactive
Maps <#creating-interactive-maps>`__.
The **Map Explorer** panel can be added to the view by clicking on the
**Panels** dropdown, and drag the panel (highlighted in yellow) anywhere
on the screen.
.. figure:: _images/map-explorer-panel.png
:alt: Map Explorer Panel
:align: center
:class: edg-figure
Once open, EDG will populate the map with all geo latitute and longitute
information, and any geometric objects defined:
.. figure:: _images/map-explorer-panel-alldata.png
:alt: Map Explorer Panel All Data
:align: center
:class: edg-figure
Another feature in EDG 7.0 is to display selected resources on the map.
In the search panel, select the desired resources (clicking on the
checkbox next to the resource label). With the resources selected, click
on the batch action dropdown button and select *Show on Map Result
Panel*.
.. figure:: _images/show-result-on-map.png
:alt: Show results on Map
:align: center
:class: edg-figure
EDG will display the geo latitute and longitude of the selected
resources as pins on the map, as well as any other geometry object (such
as polygons). The currently selected resource is highligted as a blue
pin. The user can click on any displayed pin, with EDG changing the
current context resource with the newly selected one. This will also
change the information displayed on the form panel.
.. _33-creating-a-resource:
3.3 Creating a Resource
^^^^^^^^^^^^^^^^^^^^^^^
In this example, a city will be created. Click the *new* button on the
search panel. A dialog is presented to the user. The user needs to type
in a *Label*, whilst EDG will take care of generating a new ID. Press OK
when done.
.. figure:: _images/create-city-resource.png
:alt: Create City Resource
:align: center
:class: edg-figure
This will load the new resource in the form panel, where details can be
entered. Once done, press *Save Changes*.
.. figure:: _images/create-city-form.png
:alt: Create City Form
:align: center
:class: edg-figure
.. _331-creating-geometry-objects:
3.3.1 Creating Geometry Objects
"""""""""""""""""""""""""""""""
The **TopBraid GeoSPARQL vocabulary** allows users to define geometry
objects using the *Well-known Text* representation or the *Geography
Markup Language*. EDG 7.0 currently supports the following geometric
shapes: ``POINT``, ``LINESTRING``, ``POLYGON``, ``MULTIPOLYGON``.
In order to create a geometric shape on a resource, click the *Edit*
button and then click on the *New Geometry* button. This will open a
second form panel. Click the *Edit* button on the second form panel, and
type in the geometry shape values.
.. figure:: _images/geometry-entry.png
:alt: Geometry Entry
:align: center
:class: edg-figure
Once done, press *Save Changes* in both forms. In this example, the WKT
format is used.
Creating a Point
****************
Example: ``POINT(14.518878068246499 35.90215229036674)``
Map depiction:
.. figure:: _images/point-shape.png
:alt: Point Shape
:align: center
:class: edg-figure
Creating a Line String
**********************
Example:
``LINESTRING(14.509179200448648 35.896277248610694,14.517676438607827 35.901491804470666)``
Map depiction:
.. figure:: _images/line-shape.png
:alt: Line Shape
:align: center
:class: edg-figure
Creating a Polygon
******************
Example:
``POLYGON((14.506690110482827 35.89478234591123,14.50561722687687 35.89860645934702,14.508235062875405 35.900101289830765,14.509908761300698 35.89982318397129,14.513384904183999 35.902048003486435,14.515230263986245 35.90097036434348,14.517290200509683 35.9018741917139,14.518663491525308 35.90048368379201,14.518019761361733 35.89732018726464,14.514543618478433 35.896207718878536,14.513556565560952 35.894608518183865,14.510260930329997 35.89275639869175,14.507771840364176 35.891956767523475,14.506999364167887 35.89272163228715,14.507728925019938 35.893416957478486,14.506690110482827 35.89478234591123))``
Map depiction (with fillColor yellow):
.. figure:: _images/polygon-shape.png
:alt: Polygon Shape
:align: center
:class: edg-figure
Creating a Multi-Polygon
************************
Example:
``MULTIPOLYGON (((14.506690110482827 35.89478234591123,14.50561722687687 35.89860645934702,14.508235062875405 35.900101289830765,14.509908761300698 35.89982318397129,14.513384904183999 35.902048003486435,14.515230263986245 35.90097036434348,14.517290200509683 35.9018741917139,14.518663491525308 35.90048368379201,14.518019761361733 35.89732018726464,14.514543618478433 35.896207718878536,14.513556565560952 35.894608518183865,14.510260930329997 35.89275639869175,14.507771840364176 35.891956767523475,14.506999364167887 35.89272163228715,14.507728925019938 35.893416957478486,14.506690110482827 35.89478234591123)) , ((14.512335501507883 35.897205967563785,14.51139136393464 35.89824889398179,14.512174568966989 35.89874427921673,14.51366587717927 35.899682895370105,14.514851931908979 35.89847408810674,14.51406872687663 35.89801346527679,14.514508609155072 35.897544148693264,14.513028029778852 35.8966055071787,14.512335501507883 35.897205967563785)))``
.. Note:: Particular attention is required to bracketing when creating a multipolygon, due to the visualisation engine parsing. A multipolygon has to be defined as follows: ``MULTIPOLYGON( ((lat1 lng1, lat2, lng2 ... latn, lngn)) , ((lat1 lng1, lat2, lng2 ... latn, lngn)))``. Notice that each *polygon* is encapsulated within 2 sets of brackets.
Map depiction:
.. figure:: _images/multipolygon-shape.png
:alt: Multipolygon Shape
:align: center
:class: edg-figure
.. _4-querying-using-geosparql:
4. Querying using GeoSPARQL
---------------------------
There are three possible ways to query asset collections, in EDG:
SPARQL, GraphQL, and Active Data Shapes [9]_. This looks into the
GeoSPARQL functionalities embedded into SPARQL. Support for GeoSPARQL
functions in GraphQL is planned for future EDG versions. Remember to
rebuild the GeoSPARQL index in case of changes to the asset collection.
.. _41-required-prefixes-and-functions:
4.1 Required Prefixes and Functions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In order to use GeoSPARQL functions, the following prefixes must be
added to the SPARQL query:
.. code:: sparql
PREFIX spatial:
PREFIX spatialf:
PREFIX geof:
The ``spatial`` namespace provides property functions [10]_ that carry
out the triple matching by executing some backend code. Such functions
can have a bounded or unbounded subject and/or object variables, whilst
the predicate acts as the property function, which could have
parameters. It is not uncommon that a property functions requires the
subject or the object variable. Should any of the variables be unbound,
the function finds all cases where the pattern is true. Property
functions found in this namespace are related to spatial features (e.g.
finding features within a box) and cardinal features (e.g. finding
features that are present in a specific directions)
The ``spatialf`` namespace provides mainly filter, conversion, and
distance functions. Filter functions return true or false, whilst
conversion functions converts values between two types. Distance
functions are used to calculate distance between two points or
geometries.
The ``geof`` namespace provides functions for performing topological
spatial operations, namely covering simple features, simple features,
Egenhofer relations and RCC8 relations. The provided functions are based
on the Dimensionally Extended 9-Intersection Model (DE-9IM) [11]_.
For more informations and exhaustive list of functions:
- ``spatial`` and ``spatialf`` -
https://jena.apache.org/documentation/geosparql/index.html
- ``geof`` - http://www.opengis.net/def/function/geosparql
.. _42-querying-geo-aware-collections-using-sparql:
4.2 Querying geo-aware collections using SPARQL
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Open the *SPARQL Query* panel (from the *Panels* dropdown button under
*Search and Query*). The addition of geo features in EDG, allows users
to visualise SPARQL results to be displayed on a map. The image below
shows how the results can be shown in the **Map Results** panel.
.. figure:: _images/sparql-geo-panels.png
:alt: SPRAQL Geo Panel
:align: center
:class: edg-figure
In this section, a number of examples using the various GeoSPARQL
functions are demonstrated in this cookbook.
Example 1: Find items within a geometry box
"""""""""""""""""""""""""""""""""""""""""""
Functions used:
- ``spatial:withinBox``- calculates a rectangle by specifying the
bottom-most and top-most coordinates for the edges, and return
features that intersect the provided box.
- Usage:
``?feature spatial:withinBox(?latMin ?lonMin ?latMax ?lonMax [ ?limit ]) .``
- Parameters:
- ``?latMin ?lonMin`` - the minimum latitude and longitude point
(bottom corner point of the box);
- ``?latMax ?lonMax`` - the maximum latitude and longitude point
(opposite top corner point of the box);
- ``?limit`` — an integer that limits the number of results
returned [optional].
Query:
.. code:: sparql
# Prefixes ...
SELECT * {
?item spatial:withinBox ( 36.01474535055199 14.176477635899216 36.082639559265225 14.35780428732703 ) .
}
Example 1a: (Alternative) Find items within a geometry box
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Functions used:
- ``spatialf:convertLatLonBox`` — converts a set of latitude and
longitude double coordinates into a rectangle shaped polygon as a WKT
string
- Usage:
``BIND(spatialf:convertLatLonBox(?latMin, ?lonMin, ?latMax, ?lonMax) as ?wktString).``
- Parameters:
- ``?latMin ?lonMin`` - the minimum latitude and longitude point
(bottom corner point of the box);
- ``?latMax ?lonMax`` — the maximum latitude and longitude point
(opposite top corner point of the box).
- ``spatialf:convertLatLon`` — converts latitude and longitude double
coordinates into a WKT string of a point.
- Usage: ``BIND(spatialf:convertLatLon(?lat, ?lon) as ?wktString).``
- Parameters:
- ``?lat`` - the latitude as double value;
- ``?lon`` - the longitude as a double value.
- ``geof:sfWithin`` - a function that returns true if the first
geometry argument is spatially within the second geometry argument.
- Usage: ``FILTER(geof:sfWithin(?queryWKT, ?searchAreaWKT))``
- Parameters:
- ``?queryWKT``- the geometry WKT that is to be looked for within
the *search area* polygon;
- ``?searchAreaWKT`` - the geometry WKT search pool.
Query:
.. code:: sparql
# Prefixes ...
SELECT ?item
WHERE {
BIND(spatialf:convertLatLonBox(36.01474535055199, 14.176477635899216, 36.082639559265225, 14.35780428732703) as ?wktBox) .
?item a ?type ;
geo:lat ?lat;
geo:long ?lon .
BIND(spatialf:convertLatLon(?lat, ?lon) as ?itemWKT) .
FILTER(geof:sfWithin(?itemWKT, ?wktBox)) .
}
Results:
.. figure:: _images/results-1a.png
:alt: Results 1a
:align: center
:class: edg-figure
.. Note:: DE-9IM provides equivalent functions which GeoSPARQL (``prefix geof:``) defines. The function ``geof:sfWithin(?queryWKT, ?polygonWKT)`` can be replaced with:
- ``geof:sfContains(?searchAreaWKT, ?queryWKT)``
- ``geof:ehInside(?queryWKT, ?searchAreaWKT)``
Example 1b: (Alternative) Find items within a geometry polygon
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Similar to 1a and 1b, this example shows how a WKT polygon string can be
used in queries.
.. code:: sparql
# Prefixes ...
SELECT ?item
WHERE {
BIND("POLYGON((14.169558943455778 36.092930332940085,14.341906965916715 36.09182062002719,14.341906965916715 36.01243554775603,14.16749900693234 36.0141017909665,14.169558943455778 36.092930332940085))"^^geosparql:wktLiteral as ?wktBox)
?item a ?type ;
geo:lat ?lat;
geo:long ?lon .
BIND(spatialf:convertLatLon(?lat, ?lon) as ?cityWKT) .
FILTER(geof:sfWithin(?cityWKT, ?wktBox)) .
}
Results:
.. figure:: _images/results-1a.png
:alt: Results 1a
:align: center
:class: edg-figure
Example 2: Find if two polygons intersect
"""""""""""""""""""""""""""""""""""""""""
Functions used:
- ``geof:sfIntersects`` - returns true if the input geometries
intersect
- Usage:
``BIND(geof:sfIntersects(?wktP1, ?wktP2) as ?polygonsIntersect) .``
- Parameters:
- ``?wktP1`` - first polygon input;
- ``?wktP2`` - second polygon input.
Query:
.. code:: sparql
# Prefixes ...
SELECT ?doIntersect
WHERE {
BIND("POLYGON((14.153112021709822 36.100508784240176,14.495061484600447 36.100508784240176,14.495061484600447 35.92610888887777,14.153112021709822 35.92610888887777,14.153112021709822 36.100508784240176))"^^geosparql:wktLiteral as ?wktP1)
BIND("POLYGON((14.260228720928572 35.98891507615424,14.483388510967634 35.98891507615424,14.483388510967634 35.858800895950345,14.260228720928572 35.858800895950345,14.260228720928572 35.98891507615424))"^^geosparql:wktLiteral as ?wktP2)
BIND(geof:sfIntersects(?wktP1, ?wktP2) as ?doIntersect)
}
Result:
.. figure:: _images/result-2.png
:alt: Results 2
:align: center
:class: edg-figure
Example 3: Find geometric features within an intersection
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Functions used:
- ``geof:intersection``- A query function that returns a geometry
consisting of all points that are part of both input geometries.
- Usage:
``BIND(geof:intersection(?wktP1, ?wktP2) as ?intersection) .``
- Parameters:
- ``?wktP1`` - first polygon input;
- ``?wktP2`` - second polygon input.
Query:
.. code:: sparql
# Prefixes ...
SELECT ?item
WHERE {
BIND("POLYGON((14.153112021709822 36.100508784240176,14.495061484600447 36.100508784240176,14.488881675030134 35.95501705425438,14.151738730694197 35.92888897961968,14.153112021709822 36.100508784240176))"^^geosparql:wktLiteral as ?wktP1)
BIND("POLYGON((14.260228720928572 35.98891507615424,14.483388510967634 35.98891507615424,14.483388510967634 35.858800895950345,14.260228720928572 35.858800895950345,14.260228720928572 35.98891507615424))"^^geosparql:wktLiteral as ?wktP2)
BIND(geof:intersection(?wktP1, ?wktP2) as ?intersection)
?item a ?type ;
geo:lat ?lat;
geo:long ?lon .
BIND(spatialf:convertLatLon(?lat, ?lon) as ?itemWKT) .
FILTER(geof:sfWithin(?itemWKT, ?intersection)) .
}
Result:
.. figure:: _images/result-3.png
:alt: Results 3
:align: center
:class: edg-figure
Example 4: Find cities in a 5 km radium of a selected item
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Functions used:
- ``spatial:nearby``- find features that are within radius.
- Usage:
``?feature spatial:nearby(?lat ?lon ?radius [ ?unitsURI [ ?limit]]) .``
- Parameters:
- ``?lat`` - latitude of the selected item as a double value;
- ``?lon`` - longitude of the selected item as a double value;
- ``?radius`` - the radius as a double value;
- ``?unitsURI``- specifies the units of a distance. The default value is kilometres through the string or resource ``http://www.opengis.net/def/uom/OGC/1.0/kilometre`` [optional];
- ``?limit`` - an integer that limits the number of results returned [optional].
Query:
.. code:: sparql
# Prefixes ...
SELECT ?city
WHERE {
geo:lat ?lat;
geo:long ?lon .
?city spatial:nearby(?lat ?lon 5) .
?city a geosparql_cookbook_schema:City .
FILTER (?city != ).
}
Result:
.. figure:: _images/result-4.png
:alt: Results 4
:align: center
:class: edg-figure
.. _5-advance-topics:
5. Advance Topics
-----------------
This section discusses advanced features of using geo-spatial features
in EDG.
.. _51-interactive-maps-in-edg:
5.1 Interactive maps in EDG
^^^^^^^^^^^^^^^^^^^^^^^^^^^
EDG provides the functionality for interactive maps, in which geo-aware
resources can be edited, to a *context* extent. This means that editing
is done on *what is being shown* (referred to *geo features* later on)
basis. Previously the `Map Context Shape <#map-context-shape>`__ was
introduced whereby *Context Map*\ s were described as:
*... a set of geo resources that are either asserted or dynamically
computed by a ``sh:values`` rule.*
Taking a more concrete example, users can ask EDG to display the
countries that are part of the European Union in the map panel. The
users can then perform actions on these countries, which may modify the
state of the selected country (resource). For example removing their
membership from the European Union, or changing the color of the
polygon, and so on. These actions are programmatically defined using
JavaScript, and this is demonstrated later on in this section.
.. _511-creating-context-maps:
5.1.1 Creating Context Maps
"""""""""""""""""""""""""""
In order to create *Context Maps*, the context needs to be defined in
the geo-aware schema. The **TopBraid GeoSPARQL Vocabulary** includes the
abstract ``tbgeo:MapContext`` node shape. This node shape has to be
subclassed (``ex:myContextMap rdfs:subClassOf tbgeo:MapContext``) with
the desired context maps. subclasses must declare a new property shape
for the predicate ``tbgeo:mapFeatures`` (i.e. using ``sh:path``) which
may be an inferred property based on ``sh:this``, or hold asserted
values, using the ``sh:values`` rule. More information on the Shapes
Constraint Language (SHACL) can be found in [12]_.
In order to define a context map, navigate towards the geo-aware
ontology (under *Asset Collections* select *Ontologies*, and on page
load click on the schema that was created in `section
2 <#creating-a-geo-aware-schema-in-edg>`__).
Once loaded, in the *Class Hierarchy* panel navigate to *Map context*,
right click on the tree node and select the action item *Create subclass
of Map context...*
.. figure:: _images/create-map-context-subclass.png
:alt: Create Map Context Subclass
:align: center
:class: edg-figure
This displays a dialog box where the user is required to input a *Label*
and optionally modify the *ID* and/or add a *Description*. In the sample
cookbook project, a abstract context map, *Organisation Context*, is
created, together with two "implementations" called *Intergovernmental
Organisation* and *Regional Organisation*
.. figure:: _images/context-map-subclasses.png
:alt: Context Map Subclass
:align: center
:class: edg-figure
For each context implementation, a property shape is declared for the
predicate ``tbgeo:mapFeatures``. Click on the *+* button in the
*Property Groups* panel. This displays a dropdown menu, which the user
should click on the action *Create Attribute (Datatype property shape)*
or *Create Relationship (Object property shape)*. The predicate
``tbgeo:mapFeatures`` has a flexible range which changes based on the
values being inferred.
Once the property shape is created, the user needs to change the
property path value to ``tbgeo:mapFeatures``. Furthermore, the values
field (under *Inferences*) needs to be populated. For these two context
maps, in the inferred values looks for countries that are part of the
organisation. The following rule is defined:
``path(^geosparql_cookbook_schema:inRegionalOrganisation)``. This rule
basically takes the context resource and follows the inverse path to
find the countries. The property shape form will look as follows:
.. figure:: _images/context-property-shape.png
:alt: Context Property Shape
:align: center
:class: edg-figure
The following is the property shape definition in turtle syntax (one
could see this in EDG using the **Source Code** panel)
.. code:: turtle
geosparql_cookbook_schema:RegionalOrganisation-countries
a sh:PropertyShape ;
sh:path tbgeo:mapFeatures ;
sh:class geosparql_cookbook_schema:Country ;
sh:name "countries" ;
sh:values [
sh:path [
sh:inversePath geosparql_cookbook_schema:inRegionalOrganisation ;
] ;
] ;
.
Prior to creating this property shape, in the *Country* we declared two
additional property shapes: *inRegionalOrganisation* and
*inIntergovernmentalOrganisation*. These shapes define the groups to
which a country belongs in, e.g.
``geosparql_cookbook:ireland geosparql_cookbook_schema:inRegionalOrganisation geosparql_cookbook:EU .``
.. _512-creating-a-click-handler:
5.1.2 Creating a click handler
""""""""""""""""""""""""""""""
Map actions are created as instances of ``tbgeo:MapClickHandler``.
Instances of this type must have a script declared by the
predicate\ ``dash:js``, which gets triggered when a user clicks on a
polygon or marker on a map. The script has access to two pre-bounded
variables ``focusNode`` and ``mapContext``. The former is the resource
that was clicked on. This is a JavaScript object with the label and URI
of the resource. The ``mapContext`` variable is the currently selected
``tbgeo:MapContext``.
All scripts implementing click handlers will be invoked at each click.
Therefore, it is advisable that guard clauses (e.g if statements) are
implemented. In such statements one can verify if the action can
proceed, say for example whether the selected resource (``focusNode``)
or ``mapContext`` is of a particular instance.
.. Note:: Since map actions modify the state of resources, these are only available if the graph is not in read-only mode.
In the sample project, these functions are defined in a separate turtle
file (``geosparql.topbraid.org > GeoFunctions.ttl``). Whilst these
functions, in theory, can be defined in the schema itself, it is a good
practice to differentiate between the **A-box** and **T-box** statements
Based on the two context maps defined in the previous section, a *map
click handler* is defined that removes the *focusNode* from the
organisation in context (``mapContext``). The following JavaScript code
is declared in the *map click handler* instance.
.. code:: javascript
if (mapContext.instanceOf(geosparql_cookbook_schema.RegionalOrganisation)) {
graph.remove(focusNode, geosparql_cookbook_schema.inRegionalOrganisation, mapContext)
}
if (mapContext.instanceOf(geosparql_cookbook_schema.IntergovernmentalOrganisation)) {
graph.remove(focusNode, geosparql_cookbook_schema.inIntergovernmentalOrganisation, mapContext)
}
The turtle instance is as follows:
.. code:: turtle
gfunc:RemoveFromOrg
a tbgeo:MapClickHandler ;
dash:js """if (mapContext.instanceOf(geosparql_cookbook_schema.RegionalOrganisation)) {
graph.remove(focusNode, geosparql_cookbook_schema.inRegionalOrganisation, mapContext)
}
if (mapContext.instanceOf(geosparql_cookbook_schema.IntergovernmentalOrganisation)) {
graph.remove(focusNode, geosparql_cookbook_schema.inIntergovernmentalOrganisation, mapContext)
}
""" ;
rdfs:label "Remove from Organisation" ;
.
.. _513-using-context-maps-in-geo-aware-data-assets:
5.1.3 Using context maps in geo-aware data assets
"""""""""""""""""""""""""""""""""""""""""""""""""
In the cookbook's sample project, a number of regional organisations and
intergovernmental organisations are defined and countries are linked to
these organisations with the newly defined predicates.
In the GeoSPARQL cookbook data graph, select *Regional Organisation* in
the search drop down. Filter the organisations to find "European Union".
Once the resource is found, open the **Context Map** panel. This is done
by right-clicking the resource > *Explore* > *Show Context Map*.
.. figure:: _images/show-context-map.png
:alt: Show Context Map
:align: center
:class: edg-figure
This will open the **Context Map** panel, showing points inferred by
``tbgeo:mapFeatures``.
.. figure:: _images/context-map.png
:alt: Context Map
:align: center
:class: edg-figure
When clicking on a country resource, the *map click handler* script is
invoked and the country is no longer part of the context map, and hence
removed (in this example, Ireland is removed):
.. figure:: _images/context-map-action.png
:alt: Context Map Action
:align: center
:class: edg-figure
Since the *map click handler* is driven by JavaScript, more advanced
action can be done on the resource to change the state. This cookbook
demonstrates a toy example, however, more complex coding can be handled
by EDG [13]_.
.. _52-shacl-constraints-on-geo-spatial-resources:
5.2 SHACL Constraints on Geo-spatial resources
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In EDG, schemas are driven by SHACL node and property shapes. This gives
the opportunity for *on-the-fly* validation of data entry. An example in
this regard is making sure that the city selected for ``hasCapital``
lies within a country. Assuming that all countries have polygon
boundaries, the following SPARQL constraint can be defined:
.. code:: sparql
SELECT DISTINCT $this $value WHERE {
$this $PATH $value .
$this geosparql:hasGeometry ?aGeometry .
?aGeometry a geosparql:Geometry ;
OPTIONAL { ?aGeometry geosparql:asWKT ?wktPolygon } .
OPTIONAL { ?aGeometry geosparql:asGML ?gmlPolygon } .
BIND(COALESCE(?wktPolygon, ?gmlPolygon) as ?polygon) .
$value a ?type ;
geo:lat ?lat;
geo:long ?lon
BIND(spatialf:convertLatLon(?lat, ?lon) as ?valueWKT) .
FILTER(!geof:sfWithin(?valueWKT, ?polygon)) .
}
This query is added as a SPARQL constraint in the shape
``geosparql_cookbook_schema:Country-hasCapital``, using the
``sh:sparql`` predicate:
.. code:: turtle
geosparql_cookbook_schema:Country-hasCapital
a sh:PropertyShape ;
sh:path geosparql_cookbook_schema:hasCapital ;
sh:class geosparql_cookbook_schema:City ;
sh:group metadata:DescriptionPropertyGroup ;
sh:name "hasCapital" ;
sh:nodeKind sh:IRI ;
sh:order "1"^^xsd:decimal ;
sh:severity sh:Violation ;
sh:sparql [
sh:message "{$value} is not within {$this}." ;
sh:prefixes [
sh:declare [
sh:namespace "http://jena.apache.org/function/spatial#"^^xsd:anyURI ;
sh:prefix "spatialf" ;
] ;
] ;
sh:prefixes [
sh:declare [
sh:namespace "http://www.opengis.net/def/function/geosparql/"^^xsd:anyURI ;
sh:prefix "geof" ;
] ;
] ;
sh:prefixes [
sh:declare [
sh:namespace "http://www.opengis.net/ont/geosparql#"^^xsd:anyURI ;
sh:prefix "geosparql" ;
] ;
] ;
sh:prefixes [
sh:declare [
sh:namespace "http://www.w3.org/2003/01/geo/wgs84_pos#"^^xsd:anyURI ;
sh:prefix "geo" ;
] ;
] ;
sh:select """SELECT DISTINCT $this $value WHERE {
$this $PATH $value .
$this geosparql:hasGeometry ?aGeometry .
?aGeometry a geosparql:Geometry ;
OPTIONAL { ?aGeometry geosparql:asWKT ?wktPolygon } .
OPTIONAL { ?aGeometry geosparql:asGML ?gmlPolygon } .
BIND(COALESCE(?wktPolygon, ?gmlPolygon) as ?polygon) .
$value a ?type ;
geo:lat ?lat;
geo:long ?lon
BIND(spatialf:convertLatLon(?lat, ?lon) as ?valueWKT) .
FILTER(!geof:sfWithin(?valueWKT, ?polygon)) .
}""" ;
] ;
.
Once having this constraint in place, EDG displays an error message when the constraint is validated:
.. figure:: _images/error-shacl.png
:alt: Error SHACL
:align: center
:class: edg-figure
.. _53-extending-data-governance-ontologies-with-geo-schemas:
5.3 Extending Data Governance Ontologies with Geo Schemas
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Start off by creating a new ontology in EDG, naming it for example
*Enterprise Asset Extension*. Once created include the following two
vocabularies:
- EDG Schema - Enterprise Models
- TopBraid GeoSPARQL Vocabulary
The **EDG Schema - Enterprise Models** describe terms that make up Data
Governance (DG) assets, including *Business Assets*, *Data Assets*,
*Technical Assets*, and *Governance Assets*. In EDG, a number of DG
terms are subclasses of the concept *Locatable* (``edg:Locatable``).
This concept provides a number of predicates related to location
information, however, it lacks general geospatial information such as
``geo:lat`` and ``geo:long``. Therefore, in order to make
``edg:Locatable`` geo-aware, the concept needs to be a subclass of
``geo:SpatialThing``. This can be done by editing the *superclasses*
field in the form. Furthermore, ``geo:SpatialThing`` can be enhanced
with geometric shapes by creating a property shape for
``geosparql:hasGeometry``, as described in `section
2.2.2 <#map-context-shape>`__. The following snippet shows the TURTLE
code for the property shape:
.. code:: turtle
geo:SpatialThing
sh:property geo:SpatialThing-geometry ;
.
geo:SpatialThing-geometry
a sh:PropertyShape ;
sh:path geosparql:hasGeometry ;
sh:class geosparql:Geometry ;
sh:description "Allows the definition of geometric shapes" ;
sh:group tbgeo:MapRenderingPropertyGroup ;
sh:maxCount 1 ;
sh:name "geometry" ;
sh:order "0"^^xsd:decimal ;
.
Any other concept, such as *Information Asset*
(``edg:InformationAsset``) or *Party* (``edg:Party``), that requires
geo-spatial information can be extended to be a subclass of
``geo:SpatialThing``. In order to view all different concepts and
properties that are displayable in EDG's UI forms, in the *Quick Search*
dropdown (**Class Hierarchy** panel) search for *Enterprise Viewpoints*.
In EDG, a viewpoint is an abstract class that organises UI "views" for
different asset collections.
.. figure:: _images/enterprise-viewpoint.png
:alt: Enterprise Viewpoint
:align: center
:class: edg-figure
In order to create an enterprise asset, under *Asset Collections* select
Enterprise Assets. On page load, click on the *Create New Enterprise
Asset Collection* button. Fill in the displayed form, with the *Label*
field being mandatory, and once filled press *Create Enterprise Asset
Collection*. Once created, click on the *Settings* tab, and then
*Includes*. Find and select the extension ontology created. Finally,
click on the *Manage* tab and `enable
GeoSPARQL <#enabling-geosparql>`__.
.. _6-references:
6. References
-------------
.. [1]
WGS84 Geo Positioning RDF vocabulary -
https://www.w3.org/2003/01/geo/wgs84_pos
.. [2]
Open Geospatial Consortium GeoSPARQL - A Geographic Query Language
for RDF Data schema - https://www.ogc.org/standards/geosparql
.. [3]
https://www.topquadrant.com/project/ontology_modeling_overview/
.. [4]
https://www.topquadrant.com/graphql/shacl-graphql.html#schema
.. [5]
ISO 19107:2019 Geographic information — Spatial schema
(https://www.iso.org/standard/66175.html)
.. [6]
Open Geospatial Consortium GeoSPARQL - A Geographic Query Language
for RDF Data schema - https://www.ogc.org/standards/geosparql
.. [7]
Blank nodes are usually used to define *local scoped* resources, i.e.
those resources which are not meant to be shared outside of the asset
collection defined.
.. [8]
https://www.wikidata.org.
.. [9]
Active Data Shapes Tutorial - http://datashapes.org/active/
.. [10]
Jena Extensions in ARQ -
https://jena.apache.org/documentation/query/extension.html#property-functions
.. [11]
Dimensionally Extended 9-Intersection Model (DE-9IM) -
https://en.wikipedia.org/wiki/DE-9IM
.. [12]
Shapes Constraint Language - W3C Recommendation -
https://www.w3.org/TR/shacl/
.. [13]
The Many Shapes of SHACL -
http://www.lotico.com/index.php/The_Many_Shapes_of_SHACL