【问题标题】:Retrieving data from geonames using SPARQL使用 SPARQL 从地名中检索数据
【发布时间】:2013-10-16 01:43:34
【问题描述】:

我正在尝试从以下 SPARQL 中的地名获取链接数据,但显然我做错了。

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")).

}

其中,使用 sparql.org 的 JSON 输出:

{
  "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" }
      }
    ]
  }
}

我想要实现的是它使用 geonames rdf 服务检索每个节点的纬度,地址如“http://sws.geonames.org/2745088/about.rdf

以“#”开头的行是我怀疑不正确的行..

下一次迭代

在 geonamesID 后面添加“/”,然后运行:

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")).
}

返回这个:

-------------------------------------------------------------------------------------------------------
| 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" |
-------------------------------------------------------------------------------------------------------

下一次迭代:使用“SERVICE”关键字

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")).
}

这导致了我想要的结果,除了 factforge 返回各种数据类型的多个值。
这个资源http://wifo5-03.informatik.uni-mannheim.de/latc/www2012/Session%201.html 被证明非常有用。

【问题讨论】:

  • 数据在哪里?您针对哪个端点运行此查询?如果您需要从不同的端点获取三元组,您可能需要考虑使用 service 关键字。
  • 我正在使用 spargl.org 的通用端点 sparql.org/sparql.html 运行它。我也用各种图表做了试验,只是重复 FROM 子句。只要它们使用 ophileon.com 域并且它们只是 rdf 文件,就没有问题。数据部分位于我服务器上的 rdf 中,部分位于 geonames 域中。
  • from &lt;http://sws.geonames.org/ &gt; 中的IRI 中实际上有空间吗?那将是一个问题。另外,请在不起作用工作时显示错误消息。当我在未注释的那些行(但在 IRI 中有空格)的情况下使用您的查询时,我收到一个解析错误。当我删除空格时,我收到一个描述性错误“无法确定三元组内容类型:(URI=sws.geonames.org:stream=null:hint=null)”,这意味着 Jena 尝试检索数据,但无法不知道如何解析它。
  • 您是否更改了此查询正在检索的服务器上的数据?在我开始研究这个时得到的结果中,我得到了geonames 的结果,比如&lt;http://sws.geonames.org/2745088&gt; URI 上有 no final /,但是现在当我运行查询时,最后有一个/。我可以看到这是问题所在,但我无法解释为什么它似乎发生了变化,除了您在服务器上的数据发生了变化。
  • 是的,我做了,我在我的编辑中声明了它;)我在 poi.rdf 中添加了斜杠

标签: rdf sparql geonames


【解决方案1】:

拼写错误和无法检索数据

我认为这里有两个问题。第一个是一个小错字。当我运行您的查询时,未注释注释行时,由于该行而出现解析错误

from  <http://sws.geonames.org/ >

因为 IRI 中不应该有空格。不过,这很容易解决。修复后,sparql.org 上的服务会回复

Error 400: Failed to load URL (parse error) http://sws.geonames.org/ : Failed to determine the triples content type: (URI=http://sws.geonames.org/ : stream=null : hint=null)

Fuseki - version 1.0.0 (Build date: 2013-09-12T10:49:49+0100)

我相信,这意味着 Jena 能够下载该 IRI 的内容,但无法弄清楚如何将其读取为 RDF。虽然快速的 Google 搜索显示了很多将 IRI 用作命名空间前缀的查询,但我看不到任何将 IRI 用作可以从中选择三元组的图表的地方。我认为这符合 geonames.org 在其documentation 中所说的:

GeoNames 语义网的入口点

您可以通过多种方式进入 GeoNames 语义网:

  • mother earth 开始,然后点击链接数据链接。
  • geonames search webservicetype=rdf 参数选项一起使用。
  • 下载数据库转储并构建功能的 url 使用模式“http://sws.geonames.org/geonameId/
  • RDF dump 与 8514201 个特征和大约 125 个 mio rdf 三元组 (2013 08 27)。垃圾场 每个地名在文件的每一行都有一个 rdf 文档。注意: 文件很大。确保您用于解压缩的工具能够 处理大小并不会在 2GB 后停止,这是一个问题 一些旧的(Windows)工具版本会发生这种情况。

我有点惊讶没有在该列表中看到 SPARQL 端点,但我希望如果有的话,它会在这个选项列表中。

修改查询以获取一些数据

现在,成功的查询(没有注释行)返回以下结果:

poi                            poiname          geonames                          latitude
<http://ophileon.com/ox/poi/2> "Wageningen"@en  <http://sws.geonames.org/2745088>   
<http://ophileon.com/ox/poi/3> "Netherlands"@en <http://sws.geonames.org/2750405>   
<http://ophileon.com/ox/poi/1> "Amsterdam"@en   <http://sws.geonames.org/2759794>

注意:这些是我开始写这个答案时的结果。但是,这是基于http://www.ophileon.com/ox/poi.rdf 中的数据,该数据可能已更改。在此查询的后续运行中,我得到了具有最终 /geonames 值,例如 http://sws.geonames.org/2745088/

基于相同的文档,其中还说:

对于法国的 Embrun 镇,我们有以下两个 URI:

  1. http://sws.geonames.org/3020251/
  2. http://sws.geonames.org/3020251/about.rdf

第一个URI[1]代表 在法国的小镇。如果要引用城镇,请使用此 URI。 第二个 URI [2] 是包含 geonames 信息的文档 关于 Embrun。

这表明使用那些特定地理名称 IRI 也用作图形名称的查询可能有效。也就是说,这样的查询可能会起作用:

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/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")).
}

现在这个 still 没有返回任何结果,但似乎所有数据都应该在那里。让我们尝试一个更简单的查询。如果您使用这样的查询:

select * 
from <http://sws.geonames.org/2759794/about.rdf>
where { ?s ?p ?o }

SPARQL results

你会得到一堆关于那个地方的三倍。这也适用于多个 from 子句。例如,如果您将该数据和您的数据用于以下查询,您将获得组合结果。

select * 
from <http://www.ophileon.com/ox/poi.rdf>
from <http://sws.geonames.org/2745088/about.rdf>  
where { ?s ?p ?o }

SPARQL results

在查看该数据集的结果时,我们终于可以看到问题出在哪里:地理名称资源的 IRI 在其实际形式中以 / 结尾,但您的数据中没有 /。您需要相应地更改数据。

注意:http://www.ophileon.com/ox/poi.rdf 中的数据似乎已经更正了。

看起来您最终可能需要运行第一个查询来确定要从地名中获取的数据,检索该信息,然后对其运行第二个查询。或者,您可以下载 Geonames 提供的大数据转储并在本地使用(可能是最简单的解决方案)。

【讨论】:

  • 约书亚,感谢您的详尽回答。通过在ophileon.com/ox/poi.rdf 中的 geonamesID 之后添加一个“/”,我已经能够更进一步了。
  • @Ophileon 是的,今天早上我意识到这是问题之一。将来(我应该早点想到这一点),您能否以不会在幕后改变的方式提供您的数据?我上面提到的一些结果现在是无效的,因为异地数据(即不在 Stack Overflow 上的数据)被修改了。
  • @Ophileon 如果只有 SPARQL 1.1 支持嵌套查询中的 from 子句,您甚至可以动态生成 from 子句所需的 URI,并在一个查询中完成所有操作。就像现在一样,看起来您要么需要下载数据并在本地使用它,要么运行一个查询来确定您需要哪些其他 URI,然后使用第二个查询将这些 URI 与 from 子句合并.
  • 这也是我的结论。对此不满意,但似乎没有更好的解决方案。
猜你喜欢
  • 2021-09-02
  • 1970-01-01
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多