福野泰介の一日一創 - create every day

5つ星オープンデータにアクセスする便利な言語、SPARQL。オープンデータプラットフォームに格納されている日本のオープンデータ都市データを使ったアプリ「オープンデータ都市(日本)」を例に、SPARQLを使ったアプリ開発の流れを紹介します。

select * { ?s ?p ?o } limit 10

こちら、SPARQLの超基本です。4つ星と5つ星オープンデータであるRDFは、主語(s)、述語(p)、目的語(o)の3つあるのでトリプルと呼ばれるデータのセットで、世の中のあらゆるデータを表現しようという考え方です。こちらの構文は、そんなトリプルを10コ(limit 10)取得するという問い合わせ(クエリーと呼ぶ)です。odpのSPARQLコンソールを開くと、デファルトで書かれているので、「SPARQL検索」ボタンを押すだけです。

?s ?p ?o <http://odp.jig.jp/jp/fukui/localgovernment/%E7%A6%8F%E4%BA%95%E7%9C%8C> <http://schema.org/description> "福井県" <http://odp.jig.jp/jp/fukui/localgovernment/%E7%A6%8F%E4%BA%95%E7%9C%8C> <http://schema.org/url> <http://www.pref.fukui.jp/> <http://odp.jig.jp/jp/fukui/localgovernment/%E7%A6%8F%E4%BA%95%E7%9C%8C> <http://purl.org/jrrk#address> "福井市大手3丁目17-1" <http://odp.jig.jp/jp/fukui/localgovernment/%E7%A6%8F%E4%BA%95%E7%9C%8C> <http://schema.org/telephone> "0776-21-1111" <http://odp.jig.jp/jp/fukui/localgovernment/%E7%A6%8F%E4%BA%95%E7%9C%8C> <http://schema.org/postalCode> "910-8580" <http://odp.jig.jp/jp/fukui/localgovernment/%E7%A6%8F%E4%BA%95%E7%9C%8C> <http://www.w3.org/2000/01/rdf-schema#label> "福井県"@ja <http://odp.jig.jp/jp/fukui/localgovernment/%E7%A6%8F%E4%BA%95%E7%9C%8C> <http://www.w3.org/2000/01/rdf-schema#label> "ふくいけん"@ja-Hira <http://odp.jig.jp/jp/fukui/localgovernment/%E7%A6%8F%E4%BA%95%E7%9C%8C> <http://www.w3.org/2003/01/geo/wgs84_pos#long> "136.221668" <http://odp.jig.jp/jp/fukui/localgovernment/%E7%A6%8F%E4%BA%95%E7%9C%8C> <http://purl.org/jrrk#refArea> <http://statdb.nstac.go.jp/lod/sac/C18018> <http://odp.jig.jp/jp/fukui/localgovernment/%E7%A6%8F%E4%BA%95%E7%9C%8C> <http://www.w3.org/2003/01/geo/wgs84_pos#lat> "36.065631"

出力データ形式は、アプリで扱い易いJSONやXMLなど使いやすい形式を選べます。コンソールでの確認でのオススメは、タブ区切り形式「TSV」にし「ブラウザで表示する」にチェックです。

select distinct ?o { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?o. }

続いて、取得できるデータ種類の一覧を取得してみます。http://www.w3.org/ で始まるURLは、クラスの種類を表すことに語彙(ボキャブラリー)です。RDFにおいて、語彙を世界で統一して使っていくことこそ、5つ星オープンデータです。

?o <http://purl.org/jrrk#LocalGovernment> <http://purl.org/jrrk#CivicFacility> <http://purl.org/jrrk#EmergencyFacility> <http://purl.org/jrrk#Hydrant> <http://purl.org/jrrk#PublicToilet> <http://purl.org/jrrk#AED> <http://purl.org/jrrk#CivicPOI> <http://odp.jig.jp/odp/1.0#OpenDataCity> <http://www.w3.org/2000/01/rdf-schema#Property> <http://www.w3.org/2000/01/rdf-schema#Class>

現在、SPARQLを通じて取得できるデータ種類の一覧が取得できます。オープンデータ都市データを表す語彙は、http://odp.jig.jp/odp/1.0#OpenDataCity としています。

select count(*) { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://odp.jig.jp/odp/1.0#OpenDataCity>. }

こちらで何件データが入っているかわかります。データベースを扱う言語SQLに似ています。

?.1 35

35件入っていると返ってきました。

select ?s { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://odp.jig.jp/odp/1.0#OpenDataCity>. } limit 1

1都市を表すURLを取得します。

?s <http://odp.jig.jp/jp/jig/opendatacity/24>

http://odp.jig.jp/jp/jig/opendatacity/24 が1都市を表すIDとなります。

select ?p ?o { <http://odp.jig.jp/jp/jig/opendatacity/24> ?p ?o. }

このIDを主語とする、目的語と述語を取得してみます。

?p ?o <http://schema.org/description> "No.1データ" <http://schema.org/url> <http://facts.city.fukuoka.lg.jp/> <http://www.w3.org/2000/01/rdf-schema#label> "Fukuoka-city"@en <http://www.w3.org/2000/01/rdf-schema#label> "福岡県福岡市"@ja <http://www.w3.org/2003/01/geo/wgs84_pos#long> "130.401851" <http://www.w3.org/2003/01/geo/wgs84_pos#lat> "33.5903" <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://purl.org/dc/terms/created> "2014/2/14" <http://purl.org/dc/terms/identifier> "2" <http://purl.org/dc/terms/license> <http://facts.city.fukuoka.lg.jp/about/link.php>

”説明”を表す目的語の語彙、http://schema.org/description の述語として「No.1データ」という文字列が設定されている、というように読みます。

select ?url { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://odp.jig.jp/odp/1.0#OpenDataCity>. ?s <http://schema.org/url> ?url. }

これでオープンデータ都市のURLを全部取得できます。

?url <http://facts.city.fukuoka.lg.jp/> <http://www.city.chiba.jp/somu/joho/kaikaku/opendataportal_preview.html> <http://www.city.fukui-sakai.lg.jp/useful/p004787.html> <http://www.town.uchinada.lg.jp/webapps/www/service/detail.jsp?id=7789>

selectのあとにつけたもの、今回は?urlが取得できるわけです。

select ?url ?name ?lat ?lng { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://odp.jig.jp/odp/1.0#OpenDataCity>. ?s <http://schema.org/url> ?url. ?s <http://www.w3.org/2000/01/rdf-schema#label> ?name. ?s <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat. ?s <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?lng. }

都市名と、緯度経度も合わせて取得してみます。

?url ?name ?lat ?lng <http://facts.city.fukuoka.lg.jp/> "Fukuoka-city"@en "33.5903" "130.401851" <http://facts.city.fukuoka.lg.jp/> "福岡県福岡市"@ja "33.5903" "130.401851" <http://www.city.chiba.jp/somu/joho/kaikaku/opendataportal_preview.html> "Chiba-city"@en "35.607384" "140.106293" <http://www.city.chiba.jp/somu/joho/kaikaku/opendataportal_preview.html> "千葉県千葉市"@ja "35.607384" "140.106293"

日本語名と英語名、rdf-schema#label という名前を表す語彙が2つ設定されているので、このようになります。

select ?url ?name ?lat ?lng { ?s <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://odp.jig.jp/odp/1.0#OpenDataCity>. ?s <http://schema.org/url> ?url. ?s <http://www.w3.org/2000/01/rdf-schema#label> ?name. ?s <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat. ?s <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?lng. filter(lang(?name)='ja') }

言語を日本語"ja"に限定するfilterを使うと

?url ?name ?lat ?lng <http://facts.city.fukuoka.lg.jp/> "福岡県福岡市"@ja "33.5903" "130.401851" <http://www.city.chiba.jp/somu/joho/kaikaku/opendataportal_preview.html> "千葉県千葉市"@ja "35.607384" "140.106293" <http://www.city.fukui-sakai.lg.jp/useful/p004787.html> "福井県坂井市"@ja "36.16692" "136.23145" <http://www.town.uchinada.lg.jp/webapps/www/service/detail.jsp?id=7789> "石川県内灘町"@ja "36.653474" "136.645078"

このように全オープンデータ都市の一覧が取得できました。

SPARQLコンソールで表示したURL内の出力形式を表すGETパラメータ output を json にして、JavaScriptのコールバック指定用パラメータ callback を加えると、JavaScriptから扱いやすいWebAPIとして使えます。具体的なプログラムへの組み込み方は、アプリのソースをご覧ください。

いかがでしょうか?語彙のURL長めなのがちょっと面倒なところですが、主語、述語、目的語のセットがずらっと並んだデータから好きなように取得するSPARQLの感覚に慣れてしまえば簡単です。

2013年度、横浜市、鯖江市とで情報流通連携基盤の実証実験した際決まった公共トイレを表す共通語彙が http://purl.org/jrrk#PublicToilet です。腕試しに、SPARQLを使ったトイレマップアプリづくり、挑戦してみてください。

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY 福野泰介 - Taisuke Fukuno / @taisukef / アイコン画像 / プロフィール画像