【问题标题】:How to enrich places with geonames ID如何使用地名 ID 丰富地点
【发布时间】:2019-07-23 17:38:27
【问题描述】:

我有一个地点列表,我可以使用地名中的 ID 来丰富这些地点。 由于默认情况下地名嵌入到 WikiData 中,因此我选择使用 WikiData 端点直接通过 SPARQL。

我的工作流程:

  • 我已将 excel 文件导入 OpenRefine 并创建了一个新项目
  • 在 OpenRefine 中,我创建了图表,然后将其下载为 RDF/XML。这是一张快照:

      <rdf:Description rdf:about="http://localhost:3333/0">
          <rdfs:label>Aïre</rdfs:label>
          <crm:P1_is_identified_by>5A1CE163-105F-4BAF 8BF9</crm:P1_is_identified_by>
      </rdf:Description>
    
  • 我已将 RDF 文件导入本地 graphDB 并运行联合查询:

PREFIX wd: <http://www.wikidata.org/entity/> 
PREFIX wdt: <http://www.wikidata.org/prop/direct/> 
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
     SELECT  *
             WHERE {?place <http://purl.org/NET/cidoc-crm/core#P1_is_identified_by> ?value;
                         rdfs:label ?label_geo.
                     SERVICE <https://query.wikidata.org/sparql> { 
                         ?value wdt:P31/wdt:P279* wd:Q515;
                                rdfs:label ?label; 
                                wdt:P1566 ?id_value. 
                      } 
                   }  

     limit 10

没有结果。

输出应该是这样的:


|-----------------------|------------------|---------------|
|      Oggetto          |    Place         | GeonamesID    |
|-----------------------|------------------|---------------|
|5A1CE163-105F-4BAF 8BF9|      Aïre        |11048419       |
|-----------------------|------------------|---------------|

建议?

非常感谢。

【问题讨论】:

  • 我不明白您在查询中做了什么。 ?value 不是字符串文字吗?在你的例子中,我猜是5A1CE163-105F-4BAF 8BF9,对吧?那么,Wikidata 中的哪个 RDF 三元组是 "5A1CE163-105F-4BAF 8BF9" wdt:P31 wd:Q515 . ?文字永远不是 RDF 三元组的主题。如果你想加入标签,你应该使用相同的标签变量,而不是?label?label_geo。您确实应该为?value 使用不同的变量。事实上,这可能仍然会失败,因为在 Wikidata 中,文字是语言标记的。
  • 明白你的意思。在开放细化中创建一个新图怎么样?
  • 如果您只使用一个标签变量,它现在可以工作吗?是相同的?我没有任何设置来测试它。如果可能,您应该创建带有语言标签的标签,例如"Aïre"@en
  • 顺便问一下,你检查过维基数据中是否存在 Aïre 吗?

标签: sparql wikidata geonames


【解决方案1】:

我直接通过客户端解决了问题

这是我的管道:

  1. 我创建了一个包含地名列表的 Excel 工作表
  2. 我构建了一个 Python 脚本,它使用 excel 表中的值作为查询参数,并将输出保存在 .txt 文件中。例如。艾尔,https://www.geonames.org/11048419
import pandas as pd 
import requests
import json
import csv


url = 'http://api.geonames.org/searchJSON?'

#Change df parameters according to excel sheet specification.

df = pd.read_excel('grp.xlsx', sheet_name='Foglio14', usecols="A")

for item in df.place_name:

    df.place_name.head()

    #Change username params with geonames API username

    params ={   'username': "XXXXXXXX", 

                'name_equals': item,

                'maxRows': "1"}

    e = requests.get(url, params=params)

    pretty_json = json.loads(e.text)

    with open("data14.txt", "a") as myfile:

            writer = csv.writer(myfile)

            for item in pretty_json["geonames"]:

                    #print("{}, https://www.geonames.org/{}".format(item["name"], item["geonameId"]))

                    writer.writerow([item["name"], "https://www.geonames.org/{}".format(item["geonameId"])])  #Write row.

    myfile.close()
  1. 我已将 .txt 文件的输出复制到 Excel 工作表的 B 列中。
  2. 然后我将输出值分成两列。例如
    |---------------------|-----------------------------------|
    |      ColA           |     ColB                          |
    |---------------------|-----------------------------------|
    |         Aïre        | https://www.geonames.org/11048419 |
    |---------------------|-----------------------------------|

  1. 由于地名和获得的结果之间没有 1:1 的对应关系,因此我将值对齐。
    • 在 excel 表中我创建了一个新的空列 B
    • 在 B 列中,我编写了公式:=IF(ISNA(MATCH(A1;C:C;0));"";INDEX(C:C;MATCH(A1;C:C;0))),并且我已将公式迭代到列表末尾
    • 然后我新建了一个空列C
    • 在 C 列中,我编写了公式:=IFERROR(INDEX($E:$E;MATCH($B1;$D:$D;0));""),并且我将公式迭代到列表末尾

这里是最终结果:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 2011-02-11
    相关资源
    最近更新 更多