Wikidataを用いた経路検索リンク付きMAPの作成

## 作成の経緯
最近，家族が神社の御朱印の収集，特に「一の宮」と呼ばれる神社の御朱印をもらいに行くことに力をいれており，休みの日に車で一緒に行くこともしばしば...
今朝も「どの一ノ宮に行こうか？」と，Googleマップの経路検索で，所要時間を調べることになりました．
しかし，これが少しだけ面倒な作業で，

1. 「全国の一の宮」の[一覧](http://ichinomiya-junpai.jp/alllist/)と[マップ](http://ichinomiya-junpai.jp/img/MAP.png)を見比べて，「自宅から車で行けそう」な神社を検討
2.  候補となる神社をGoogleで検索
3. 検索結果からGoogleマップを表示して，自宅を起点とした経路検索を実行

という手順を繰り返し，行き先を検討していました．

## Wikidataのクエリサービスを使ったデジタルマップの作成
まぁ，大した作業ではないのですが
**「デジタル化された地図があれば，少し楽になるのでは？」**
と思い，最初に作成したのが **[「こちらのマップ」](https://w.wiki/AtMm)** です．
![Wikidataを用いた「一の宮マップ」 2024-08-11 190130.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103276/584416bb-66eb-6747-b359-d6b185db30fe.png)
このマップは，ウィキペディアのような共同編集型のオープンな知識グラフである[Wikidata](https://www.wikidata.org/)の[クエリサービス](https://query.wikidata.org/)を使用して作成しました．
具体的には，
```SPARQL:クエリ例１
#defaultView:Map
SELECT ?item ?itemLabel ?loc
WHERE {
  ?item wdt:P31 wd:Q1656379.
  ?item wdt:P625 ?loc.
  SERVICE wikibase:label { bd:serviceParam wikibase:language "ja". }
}
```
というSPARQLクエリを使用し，Wikidataで 
- **分類（[wdt:P31](http://www.wikidata.org/prop/direct/P31)）** が **一の宮（[wd:Q1656379](http://www.wikidata.org/entity/Q1656379)）** となるデータ（ **?item** という変数で表す）の
- **位置情報（[wdt:P625](http://www.wikidata.org/prop/direct/P625)）** と **名称（?itemLabl）** 

を検索し，マップとして可視化（`#defaultView:Map`で指定）したました．
これは，Wikidataのクエリサービスの基本的な機能をそのまま利用したもので，作成に要した時間は5－10分程度です．

## 経路検索用のリンクの追加
地図のデジタル化はできたので，次にもうひと工夫して
**「このマップを使って経路検索を簡単に行いたい」**
と思い作成した改良版が **[「こちらのマップ」](https://w.wiki/AtMV)** です．

 ![経路検索連携例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103276/00bb2293-d6a5-558d-e66e-8ff6a8576589.png)
これは先ほどのマップ作成に使用したSPARQLクエリを修正し，
- **Googleマップによる検索へのリンク**
例）https://www.google.com/maps/dir/現在地/伊和神社
- **その他の主要情報**（読み仮名（wdt:P1814），画像（wdt:P18），住所（wdt:P6375），公式Webサイト（wdt:P856）） 

を取得できるようにした下記のSPARQLクエリを使用しました．
```SPARQL:クエリ例２
#defaultView:Map
SELECT ?item ?itemLabel ?kana ?img  ?web ?loc ?addr
(URI(concat("https://www.google.com/maps/dir/現在地/",?itemLabel)) AS ?map)
WHERE {
  ?item wdt:P31 wd:Q1656379.
  ?item wdt:P625 ?loc.
  OPTIONAL{
    ?item wdt:P1814 ?kana. 
  }
  OPTIONAL{
    ?item wdt:P18 ?img. 
  }
  OPTIONAL{
    ?item wdt:P6375 ?addr. 
    FILTER(lang(?addr)="ja")
  }
  OPTIONAL{
    ?item wdt:P856 ?web. 
  }
  SERVICE wikibase:label { bd:serviceParam wikibase:language "ja". }
}
```
このSPARQLクエリで使用している **concat()** は引数で指定した文字列を結合する関数， **URI()** は文字列をURIに変換する関数，**AS** は関数で処理した結果を代入する変数を指定するものです．
また，**OPTINAL{...}** で指定した部分は，検索の必須条件ではなく，他の検索条件で得られた?itemがOPTINAL{...}で **指定したデータを持っていれば** 取得されます（すべてのデータがWikidataで完備に定義されているとは限らないので，このような条件にしています）．
## まとめ
今回のマップ作成に要した時間は，正確に計測した訳ではありませんが，実質15-20分程度でした．このような短時間で必要なマップの作成が行えたのは，
- Wikidataが提供する知識グラフの内容が充実おり，必要な知識（今回の例であれば，「一の宮」に関する知識）が容易に取得できたこと
- Wikidataのクエリサービスが提供する可視化機能により，マップの生成・可視化が容易に行えたこと

によるものです．
また，今回のマップは，使用するSPARQLクエリを少し変更するだけで，さまざまな種類のマップ生成に適用できます．
　例：分類（wdt:P31）を日本の城（wd:Q92026）に変更
Wikidataの簡単な利用例のひとつとして，参考にしていただければ幸いです．
## 補足
- 今回のマップでは，一部の「一の宮」のデータが取得できませんでした．これは，Wikidata上で分類（wdt:P31）が一の宮（wd:Q1656379）として定義されているデータの漏れがあったことが原因と思われます．
    - この点はWikidataのデータ作成がコミュニティの有志により行われていることに起因するとも言えます．
    その一方で，誰でもデータの編集が行えることもWikidataの特徴ですので，データの不備を発見した場合は自分で修正することができます．（一の宮のデータについては，後日，修正したいと思います）
- 今回のクエリで「1つの神社に複数の公式Webサイトが登録されている」など，?itemとして得られたデータがOPTIONAL{...}で指定したデータを複数持つ場合，マップに表示される「点」が複数になります．これは，SPARQLクエリで取得するデータは「その組み合わせ」で得られるため，同じ?itemが複数の組み合わせに現れるためです．
    - この問題を解消するには，該当するデータに関するOPTIONAL{...}での指定を削除する必要があります．
    - あるいは，クエリを変えずに対応するには，WikidataのクエリサービスのMAP可視化を使用する代わりに，独自の可視化プログラムを作成することで解消することも可能ではあります．