In this session, we are going to build a simple application showing information about places in the world, through using a variety of SPARQL queries on different SPARQL endpoints, most notably the ones of DBpedia and EventMedia. You will need to use the web interfaces of these two endpoints to test your queries, so keep them arround. You will also need to rely extensively on the documentation of the SPARQL Query language, as well as (a bit less) of the SPARQL Update Language.

Basic set-up

Go to http://localhost/sssw12-ho-s2/index.html?uri=http://dbpedia.org/resource/Madrid. This should show the initial state of the application for the city of Madrid. You can try different locations by changing the DBpedia URI in the address of the application.

The application is currently rather incomplete. What we will do is to create the SPARQL queries that will make it display the right and relevant information. In order to do that, and test you ideas, you will need to work with the SPARQL endpoints of DBpedia and EventMedia, as well as generally understanding their content. To familiarise yourself with this process, go to the DBpedia SPARQL endpoint and try entering simple queries, like:
select distinct ?x where {[] a ?x} limit 10 
(gives 10 types of objects)

or
select distinct ?p ?y 
where { <http://dbpedia.org/resource/Madrid> ?p ?y} 
limit 10 
(gives 10 properties of Mardid)

Select Queries

We are now going to start putting more relevant queries into the application. All the queries the application is using that are written in the js/sssw12-s2.js file, which is the based Javascript code for this application. You will need to edit this file (and only this file) so open it in a text editor.

The top part of the page currently shows the name of the place (twice). This information is obtained from the query to the DBpedia SPARQL endpoint located in the queryLabel function in the Javascript code:
 squery = 'select distinct ?label ?desc where {'+
        '<'+uri+'> <http://www.w3.org/2000/01/rdf-schema#label> ?label. '+
        '<'+uri+'> <http://www.w3.org/2000/01/rdf-schema#label> ?desc. '+
        '}';
  1. Modify the query in the javascript code so that it obtains a short description (or abstract) of the place in the ?desc variable instead of the label (again). You might want to go to the pages of a few places in DBpedia (e.g. http://dbpedia.org/resource/Madrid) to check what property should be used.
  2. Can you change the query to make sure that this description is always English?
The second box from the top of the page should normally show images of museums located in the city, linking to the corresponding DBpedia pages. The corresponding query to DBpedia is located in the queryMuseum function, and is currently incomplete:
squery = 'select distinct ?link ?img where {'+
        '<'+uri+'>'+
        '}';
  1. Complete the query so that the ?link variable contains the URI of a museum located in the considered place (uri), and the ?img variable contains the address of an image representing the museum (thumbnail). The page should now display images of museums linking to DBpedia pages.
  2. Does it always work? What if a museum does not have an image? Is this OK for every city?

More complex things in Select queries

The third box in the page contains a list of events (supposedly recent) that were located near the place considered. This part uses the EventMedia SPARQL dataset, and you might want at this point to get familiar with the corresponding SPARQL endpoint. The query for events is located in the queryEvents function. It currently looks like this:
  squery = 'select distinct ?event ?title ?date {'+
        '?event <http://linkedevents.org/ontology/inSpace> ?space .'+
        '?space <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat. '+
        '?space <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?lon.'+
        '?event <http://purl.org/dc/elements/1.1/title> ?title .'+
        '?event <http://linkedevents.org/ontology/atTime> ?odate .'+
        '?odate <http://www.w3.org/2006/time#inXSDDateTime> ?date .'+
        'FILTER ( ( '+
        '( xsd:float(?lat) - '+lat+' ) > 0.0  && ( xsd:float(?lat) - '+lat+' ) < 0.6 '+
        ' || ( xsd:float(?lat) - '+lat+' ) < 0.0  && ( xsd:float(?lat) - '+lat+' ) > -0.6 ) '+
        ' && ( ( xsd:float(?lon) - '+lon+' ) > 0.0  && ( xsd:float(?lon) - '+lon+' ) < 0.6 '+
        ' || ( xsd:float(?lon) - '+lon+' ) < 0.0  && ( xsd:float(?lon) - '+lon+' ) > -0.6 )  '+
        ')'+
        '} limit 10';
It retrieves the URIs (?event), title (?title) and date (?date) of 10 events located in a certain radius of the place considered (based on its geograpic coordinates lat and lon). The location of the current place (lat and lon) are retrieved in another part of the programme (you might want to look at how it is done if you have time).
  1. Check that you understand the different parts of the query and what they do.
  2. Can you change it so that it shows only the most recent events (rather than 10 randomly selected ones)?
  3. Can you change it so that it excludes events of the type http://data.semanticweb.org/ns/swc/ontology#ConferenceEvent
  4. (Optional) How would you make it so that it shows events ordered by their distance to the considered place? By both the distance and the date?

Describe and Construct Queries

The box at the bottom of the page should show basic facts about the place considered. At the moment, it is based on a Describe query to DBpedia, in the function queryBasicFacts:
 squery = 'describe <'+uri+'>';
This will retrieve every triples that connects the given URI (uri) to other URIs or literals.
  1. Can you change the query into a Construct query with the same effect?
  2. Can you restrict this Construct query so that it only shows things which values are literals (strings, integers, etc.)?
  3. Can you select or exclude some properties, or values that you think are not relevant?
  4. Can you change the name of some properties so that what is displayed (the name of the property) is more readable?

SPARQL update (and Ask query)

The box in the top right corner of the page should allow you to record in a local triple store that you have visited the considered place. Currently it always shows that you have not been there.

First, you need to ensure that a local triple store is running on the machine you are using, with the right parameters. Go to directory of FUSEKI in a terminal window, and type the command:
./fuseki-server --update --mem /sssw12-ho-s2 & 
The query that should insert the information about you having visited the place (when you click on the image) is located in the declareVisited function:
squery = 'insert {<'+uri+'>} where {}'; 
The query that should delete this information (when you re-click on the image) is located in the removeVisited function:
squery = 'delete {<'+uri+'>} where {}'; 
Finally, the function that check whether you have visited the place is located in the checkIfVisited function:
squery = 'ASK {<'+uri+'>}'; 
  1. Change these queries so that they properly update and use the local triple store.
Note that you will have to decide of the representation for the information that you have visited a place, which will in particular require you to decide of (or reuse) a URI for you (or your group), and on properties to use for this representation, which you might want to reuse from somewhere else. You will also have to use this repesentation consistently in the three queries.

Note also that the following command line:
./s-get http://localhost:3030/sssw12-ho-s2 default 
downloads the whole content of the local triple-store in RDF. It is therefore useful to check whether the update queries you sent have had the effect you expected.