ウィキデータを用いた石造物リストの作成


石造物3Dアーカイブプロジェクトでは、石造物のデータをウィキデータに入力しています。その際、石造物の大きさに関するデータ等は、市町村が発行した石造物調査報告書の類を参考にしています。
石造物調査報告書の多くはパソコンやインターネットが普及する前に作成されており、残念ながらデジタルデータとしては存在しません。そこで印刷物を見ながらの手入力となりますが仕方ありません。
しかし現在では、まず初めにデジタル的にデータベースを作成し、それを用いて印刷物を作成するというデジタルファーストな方法も可能だと思います。データベースをオープンデータとして公開すれば、印刷物と違って最新情報へと更新し続けることもできます。
そこで、Proof of Conceptのために、ウィキデータに入力されたデータを用いて横浜市の石造物のリストを作成してみました。

実行結果は以下のとおりです。石造物調査報告書風に、画像のほか各種の情報を一覧にしています。実際の画面はこちらを参照して下さい。

ソースコードはGitHubで公開しています。

はじめに、ウィキデータからデータを取得するためのSPARQLクエリについて解説します。

SELECT
  ?item
  (GROUP_CONCAT(DISTINCT ?bunruiLabel; SEPARATOR="<br/>") AS ?type)
  (GROUP_CONCAT(DISTINCT ?keijoLabel; SEPARATOR="<br/>") AS ?shape)
  (GROUP_CONCAT(DISTINCT ?pic; SEPARATOR=", ") AS ?image)
  (GROUP_CONCAT(DISTINCT ?addr; SEPARATOR="<br/>") AS ?address)
  (GROUP_CONCAT(DISTINCT ?zoLabel; SEPARATOR="<br/>") AS ?kokuzo)
  (GROUP_CONCAT(DISTINCT ?mei; SEPARATOR="<br/>") AS ?meibun)
  (GROUP_CONCAT(DISTINCT YEAR(?time); SEPARATOR=", ") AS ?year)
WHERE {
  ?item wdt:P31 ?bunrui;
        wdt:P1419 ?keijo;
        wdt:P131 ?ward;
        wdt:P6375 ?addr.
  ?keijo (wdt:P279+) wd:Q97613936.
  ?ward wdt:P131 wd:Q38283.
  OPTIONAL { ?item wdt:P1684 ?mei. }
  OPTIONAL { ?item wdt:P180 ?zo. }
  OPTIONAL { ?item wdt:P4896 ?pic. }
  OPTIONAL { ?item wdt:P18 ?pic. }
  OPTIONAL { ?item wdt:P571 ?time. }
  SERVICE wikibase:label {
    bd:serviceParam wikibase:language "ja".
    ?bunrui rdfs:label ?bunruiLabel.
    ?keijo rdfs:label ?keijoLabel.
    ?zo rdfs:label ?zoLabel.
  }
}
GROUP BY ?item
ORDER BY ?year

1つの石造物項目について1行でデータを取得するために、GROUP BY ?item でグループ化しています。そのために、SELECT で ?item 以降は得られた値を GROUP_CONCAT で連結しています。連結する際のセパレータは、HTML の TABLE にそのまま表示するものについては <br/> にしています。
石造物の抽出は

?item wdt:P1419 ?keijo.
?keijo (wdt:P279+) wd:Q97613936.

でおこなっています。形状(P1419)の値が石造物形状(Q97613936)のサブクラスであるという条件です。同様にして分類(P31)の値が石碑(Q178743)または石仏(Q11585154)のサブクラスであるという条件でも良いかと思いますが、簡単な方法を採りました。
また、横浜市の石造物に限定するため、

?item wdt:P131 ?ward.
?ward wdt:P131 wd:Q38283.

石造物の位置する行政区画(P131)の位置する行政区画(P131)が横浜市(Q38283)という条件を付けています。
ラベルを取得するための

SERVICE wikibase:label {
  bd:serviceParam wikibase:language "ja".
  ?bunrui rdfs:label ?bunruiLabel.
  ?keijo rdfs:label ?keijoLabel.
  ?zo rdfs:label ?zoLabel.
}

では、対象となる項目とバインドする変数名を明示的に指定しています。GROUP_CONCAT のような集計機能を使った際には明示的に指定する必要があります。詳しくはこちらを参照して下さい。

PHPのプログラムでは、file_get_contents の代わりに cURL を使用してウィキデータのSPARQLエンドポイントにアクセスしています。これは、

curl_setopt($curl, CURLOPT_USERAGENT, 'stone.php/0.1');

で User-Agent リクエストヘッダを付けるためです。もし付けていないと 403 Forbidden が返されてしまいます。詳しくはこちらを参照して下さい。
画像はサムネイルを取得するため、ウィキデータが返した URL の後ろに ?width=320 を追加しています。また、画像にリンクする際は、パスを

https://commons.wikimedia.org/wiki/Special:FilePath/ファイル名

という形式から

https://commons.wikimedia.org/wiki/File:ファイル名

という形式に変更しています。
画像が .stl かそれ以外かによって CSS のクラス名を変えています。それによって、サムネイルを正方形にした際にトリミングするか余白を作るかが変わるようになっています。