I am trying to get linked data from geonames in the following SPARQL, but obviously I'm doing someting wrong.
prefix oxprop: <http://ophileon.com/ox/property#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix wgs84_pos: <http://www.w3.org/2003/01/geo/wgs84_pos#>
select ?poi ?poiname ?geonames ?latitude
from <http://www.ophileon.com/ox/poi.rdf>
# from <http://sws.geonames.org/ >
where
{
?poi rdfs:label ?poiname.
?poi owl:sameAs ?geonames.
# ?geonames wgs84_pos:lat ?latitude.
FILTER(langMatches(lang(?poiname), "EN")).
}
which, using sparql.org 's JSON output :
{
"head": {
"vars": [ "poi" , "poiname" , "geonames" , "latitude" ]
} ,
"results": {
"bindings": [
{
"poi": { "type": "uri" , "value": "http://ophileon.com/ox/poi/2" } ,
"poiname": { "type": "literal" , "xml:lang": "en" , "value": "Wageningen" } ,
"geonames": { "type": "uri" , "value": "http://sws.geonames.org/2745088" }
} ,
{
"poi": { "type": "uri" , "value": "http://ophileon.com/ox/poi/3" } ,
"poiname": { "type": "literal" , "xml:lang": "en" , "value": "Netherlands" } ,
"geonames": { "type": "uri" , "value": "http://sws.geonames.org/2750405" }
} ,
{
"poi": { "type": "uri" , "value": "http://ophileon.com/ox/poi/1" } ,
"poiname": { "type": "literal" , "xml:lang": "en" , "value": "Amsterdam" } ,
"geonames": { "type": "uri" , "value": "http://sws.geonames.org/2759794" }
}
]
}
}
What I want to achieve is that it retrieves the latitude of each node using the geonames rdf service with addresses like "http://sws.geonames.org/2745088/about.rdf"
The lines starting with "#" are the ones I suspect to be incorrect..
Next iteration
After having added "/" behind the geonamesID , and running this:
prefix oxprop: <http://ophileon.com/ox/property#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix wgs84_pos: <http://www.w3.org/2003/01/geo/wgs84_pos#>
select *
from <http://www.ophileon.com/ox/poi.rdf>
from <http://sws.geonames.org/2745088/about.rdf>
from <http://sws.geonames.org/2750405/about.rdf>
from <http://sws.geonames.org/2759794/about.rdf>
where
{
?poi rdfs:label ?poiname.
?poi owl:sameAs ?geonames.
?geonames wgs84_pos:lat ?latitude.
FILTER(langMatches(lang(?poiname), "EN")).
}
Returns this:
-------------------------------------------------------------------------------------------------------
| poi | poiname | geonames | latitude |
=======================================================================================================
| <http://ophileon.com/ox/poi/2> | "Wageningen"@en | <http://sws.geonames.org/2745088/> | "51.97" |
| <http://ophileon.com/ox/poi/3> | "Netherlands"@en | <http://sws.geonames.org/2750405/> | "52.5" |
| <http://ophileon.com/ox/poi/1> | "Amsterdam"@en | <http://sws.geonames.org/2759794/> | "52.37403" |
-------------------------------------------------------------------------------------------------------
Next iteration : using "SERVICE" keyword
prefix oxprop: <http://ophileon.com/ox/property#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix wgs84_pos: <http://www.w3.org/2003/01/geo/wgs84_pos#>
select ?poi ?poiname ?geonameuri ?latitude
from <http://www.ophileon.com/ox/poi.rdf>
where
{
?poi rdfs:label ?poiname.
?poi owl:sameAs ?geonameuri.
SERVICE <http://factforge.net/sparql>{
?geonameuri wgs84_pos:lat ?latitude.
}
FILTER(langMatches(lang(?poiname), "EN")).
}
which results in what I wanted, except that factforge returns multiple values in various datatypes.
This resource http://wifo5-03.informatik.uni-mannheim.de/latc/www2012/Session%201.html proved to be very useful.
Typos and Inability to Retrieve Data
I think there are two issues here. The first is a minor typo. When I run your query, with the commented lines uncommented, I get a parse error because of the line
because there should not be a space in the IRI. That's easy to fix though. When fixed, the service at sparql.org replies that
which, I believe, means that Jena was able to pull down the content of that IRI, but wasn't able to figure out how to read it as RDF. While a quick Google search shows plenty of queries where that IRI is used as a namespace prefix, I don't see any where it's used as a graph from which triples can be selected. I think this matches what geonames.org says in its documentation:
I'm a bit surprised to not see a SPARQL endpoint in that list, but I expect that if there was one, it would be in this list of options.
Modifying the query to get some data
Now, the successful query (without the commented lines) returns these results:
Note: These were the results at the time that I started writing this answer. However, this is based on data in
http://www.ophileon.com/ox/poi.rdf
, which may have changed. On later runs of this query, I get values ofgeonames
that have a final/
, e.g.,http://sws.geonames.org/2745088/
.Based on the same documentation, which also says that:
This suggests that a query with those particular geonames IRIs also used as graphs names might work. That is, that a query like this might work:
Now this still doesn't return any results, but it seems like all the data should be there. Let's try a simpler query. If you use a query like this:
SPARQL results
you'll get a bunch of triples about that place. This does work with multiple
from
clauses, too. For instance, if you use that data and your data with the following query, you get the combined results.SPARQL results
In looking at the results from that dataset, we can finally see where the problem is: the IRIs for the geonames resources end with
/
in their actual form, but don't have/
in your data. You'll need to change your data accordingly.Note: it seems that the data in
http://www.ophileon.com/ox/poi.rdf
has since been corrected.It looks like you may end up needing to run your first query to determine data you want to get from geonames, retrieving that information, and then running a second query on that. Alternatively, you could download the big data dump provided by Geonames and use it locally (possibly the easiest solution).