日本のOpenStreetMap行政区リレーションについて


2014年6月現在、日本の行政区のリレーションの多くは壊れています。

この事実は、OSMのデータを、レンダリングされた後の地図ではなく、データベースとして利用したい多くの人から指摘されることです。これがために、日本のOSMデータは使えない、とまで言われることもしばしばです。
また、この階層構造が正しく構成されていないこともあり、日本におけるOSMのジオコーディング(特に、行政区データをアルゴリズムに使用しているNominatim)は期待される結果が得られないことが多い、ということも以前からよく指摘されることです。

> まぁ、道路の接続や森林データの欠落など、他にも指摘される点は数多くありますが

では、そもそも "壊れている" とはどのような状態なのでしょうか。
"正しい状態"とはどのような状態なのでしょうか。

ここでは、データ構造としてあるべき姿、そしてその構成のために必要な作業を提示します。

## リレーションの階層構造
OSMにおいて、行政区(admin boundary)と、行政区のレベル(admin_level)は階層構造で表現されます。
階層構造は多くの国で10段階以内に収められており、その一覧はこのページに記載されています。(いくつかの国では11まで)

[Tag:boundary=administrative](http://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative#10_admin_level_values_for_specific_countries)

この階層構造は各国それぞれのコミュニティの中の話し合いで策定されており、日本もその例外ではありません。

日本においては長らくTalk-jaメーリングリスト、およびplaceタグのTalkページでの議論が続いていました。
しかしながら、2014年現在、ある程度その議論は収束し、前述のWikiに表記されたとおりの階層になっています。

抜粋すると、例えば以下のようになります。

|admin_level|行政レベル|例|
|:---|:---|:---|
|1|どの国でも未使用|-|
|2|国|日本国|
|3|(未使用)道州制のための確保bit|-|
|4|都道府県|神奈川県|
|5|振興局・支局|(北海道・離島で使用)|
|6|郡|-|
|7|市町村・東京23区|横浜市|
|8|区|西区|
|9|([住居表示](http://ja.wikipedia.org/wiki/%E4%BD%8F%E5%B1%85%E8%A1%A8%E7%A4%BA)の)町<br>([非住居表示・地番](http://ja.wikipedia.org/wiki/%E5%9C%B0%E7%95%AA)の)大字|中央|
|10|小字・字・丁・丁目|一丁目|

OSMでは、この階層のそれぞれが、ひとつのリレーションとして表現されます。

例えば、admin_level=4の神奈川県であれば、OSMのデータでは[id 2689487](http://www.openstreetmap.org/relation/2689487)として表現されます。

この際、リレーションは type=boundary として表現されています。
そのタグの定義は、以下のページで行われています。

[OSM wiki: relation boundary](http://wiki.openstreetmap.org/wiki/Relation:boundary)
[OSM wiki: relation boundary(ja)](http://wiki.openstreetmap.org/wiki/JA:Relation:boundary)

このリレーションでは、そのメンバーのロールに対し、いくつかの定義が行われます。

|ロール|ロールの意味|
|:---|:----|
|outer|その行政区の外周を意味する|
|inner|その行政区の中に、他自治体の飛び地がある場合に使用する|
|subarea|その行政区の下位にあたる階層を明示する|
|admin_centre|その行政区の行政施設を意味する(県庁、市役所など)|
|label|その行政区をレンダリング表示上であらわすplace nodeを指定する|

この中にある`subarea`ロールを使うことで、行政区の階層構造を明確に表現することが可能となります。
> 注: OSMにおける議論の中で、`subarea`ロールは不要だ、という意見も存在しています。
> 何故ならば、PostGISなどを使って空間クエリを発行した場合、`subarea`ロールが存在しなくとも、対象地域内に存在する下位区域を識別できるから、というものです。
> しかしながら、逆に言えばこの処理には空間クエリを使わなければできないこと、また、万が一ポリゴンが壊れた場合の処理に問題が発生することなど、不利益も多く存在します。
> そのため、`subarea`ロールは明確に指定しておいたほうがよいものであると考えます。

この階層構造を、2から10までの間できちんと繋いでおくことが、日本の行政区を表現する上で必要不可欠です。

## 行政区の元データ
行政区は、論理的な境界線です。
すなわち、surveyでは検知することができないケースが多々存在します。

> 県をまたいだ移動をする際に、`ここから先 ◯◯県`のように看板がでていることがあるのは、よく知られていると思います。
> でも、それはその道路の上の一点でしかありません。領域をあらわすためには、対象のエリアを、面の情報として保持する必要があります。

では、それぞれのレベルのデータをOSMに加えようとする際、OSMで利用が許可されている情報はなんでしょうか。その利用方法は、どのような方法が許可されているでしょうか。

それらの情報をまとめると、以下のようになります。

|admin_level|行政レベル|例|利用可能な情報:方法|
|:---|:---|:---|:---|
|1|どの国でも未使用|-|-|
|2|国|日本国|-|
|3|(未使用)道州制のための確保bit|-|-|
|4|都道府県|神奈川県|KSJ2:インポート|
|5|振興局・支局|(北海道・離島で使用)|KSJ2:インポート|
|6|郡|-|KSJ2:インポート|
|7|市町村・東京23区|横浜市|KSJ2:インポート|
|8|区|西区|KSJ2:インポート|
|9|([住居表示](http://ja.wikipedia.org/wiki/%E4%BD%8F%E5%B1%85%E8%A1%A8%E7%A4%BA)の)町<br>([非住居表示・地番](http://ja.wikipedia.org/wiki/%E5%9C%B0%E7%95%AA)の)大字|中央|ISJ:トレース/インポート (中心点のみ)<br>基盤地図情報:トレース|
|10|小字・字・丁・丁目|一丁目|ISJ:トレース/インポート (中心点のみ)<br>基盤地図情報:トレース|

* KSJ2: 国土数値情報
* ISJ:  位置参照情報

上記の表からみてとれるとおり、admin_levelの4〜8まではKSJ2のデータを利用することによって、boundaryの外周線を含めてリレーションを形成することが可能です。
そして、そのインポート作業を行うための手続きを、現在Imprts MLとTalk-ja MLを中心に行っています。

9と10の情報は、外周線を基盤地図情報のトレースから、そしてその中心点(label roleとして使うplace tag付きnodeの位置)をISJから得ることができます。

ただし、ISJに格納されている情報は、大字と小字、町名と丁目のパースが行われていません。
例えば、ISJで格納されている情報は`散田町一丁目`、という表記で入っています。

Talk-jaでの議論により、この部分はパースを行い、それぞれ別の階層にすることが決まっています。
つまり、`散田町一丁目`というデータがあった場合、以下のようなパースが必要であり、そのままトレースを行なうことはできない、ということを意味します。

* `散田町`で1つのplaceオブジェクト(`place=quarter`)
* `一丁目`で1つのplaceオブジェクト(`place=neighbourhood`)

また、この作業を行う際には、分割したこの2つのplaceそれぞれをlabelとするリレーションを作成し、明確に階層構造を作成することで紐付けを行なう必要があります。
これを行わないと、単に`一丁目`と書かれた場合に、それがどの町名の配下の一丁目なのかが判別できなくなります。

特に、基盤地図情報を元にした外周線のトレースを行わず、ISJを由来とするポイントデータのみを作成する場合は、この階層構造作成の作業を必ず行う必要があります。
何故ならば、ポイントデータのみが存在している場合、外周線となるエリアデータを使った空間クエリも行なうことができないため、階層構造を判別する手段が無くなってしまうためです。

蛇足ですが、subareaだけをmemberとしたboundaryリレーションを作成すると、妥当性検証によって`boundaryの外周線が無い`という警告が出ますが、気にしないでください。階層構造が無い事のほうが深刻です。

> リレーションの作成方法は別途ドキュメントを準備します。
> とても単純に書くと、以下のとおりです。
> * type=boundaryのリレーションを複数作成
> * それぞれにadmin_level=9、あるいは10を作成
> * admin_level=9のリレーションのsubarea memberとして、admin_level=10のリレーションを参加させる


### 丁目よりも下位の階層の表現
それでは、admin_level 10よりも下位の階層、つまり、住所用の階層である`街区番号(番)`や`住居番号(号)`のデータはどのようにして整備すればよいでしょうか。

> 念の為、あまりこの階層は一般的に意識することがないので説明しておきます。
> 例えば、住所の例として `散田町`;`一丁目`;`16`;`24` という表記があるとします。
>
> この場合、`16`が`街区番号`あるいは`番`と呼ばれる階層で、丁目の配下に割り振られた街区のナンバーにあたります。
> `24`は、その街区のなかで特定の1つの建物や住居を指定するためのナンバーになります。

OSMのタグでは以下の2つを利用します。

* 街区番号(番): `addr:block_number`
* 住居番号(号): `addr:housenumber`

#### 街区番号と住居番号に関する情報の入手 (住居表示対応地域)
先ほどまでに説明した上位階層と同様、`街区番号(番)`をリレーションであらわすためにも、その外周線となるデータと、そこに割り当てられたナンバーの情報が必要です。

この情報を得るのは簡単ではありません。
ただし、地域によっては、住居表示に対応している場所があり、その場合は、現地調査である程度調べることができます。
住居表示に対応している地域では、その街区番号を表示する義務が法律に依って発生しているため、現地のどこかに必ず看板があります。([住居表示に関する法律](http://ja.wikipedia.org/wiki/%E4%BD%8F%E5%B1%85%E8%A1%A8%E7%A4%BA%E3%81%AB%E9%96%A2%E3%81%99%E3%82%8B%E6%B3%95%E5%BE%8B#.E7.AC.AC8.E6.9D.A1.EF.BC.88.E8.A1.A8.E7.A4.BA.E6.9D.BF.E3.81.AE.E8.A8.AD.E7.BD.AE.E7.AD.89.EF.BC.89))
この表示が行われている看板 (電柱などによくついています) を探し、surveyします。

当然のことながら、より確実で正確なエリアデータとして表現するためには、より整った形式の元データがあれば便利ではあります。ただし、そうしたデータはあまり多くありません。

個人的にではありますが、[電子国土基本図（地名情報）「住居表示住所」](http://www.gsi.go.jp/kihonjohochousa/jukyo_jusho.html)のCSVを利用することで、擬似的に街区番号のエリアデータに近しいデータを得ることは可能ではないか、と思っています。
しかしながら、ライセンスの調整や利用法も含め、まだ僕の中で検討事項になっています。
基盤地図情報に記載がある場合があるので、そこからトレースで作成するのが現状で最も正確かもしれません。

また同様に、住居表示されている場所では、`住居番号(号)`、つまり住居や建物に割り振られている番号も、ある程度現地で調査を行うことができます。ただし、住居ひとつひとつが必ず表札などに住所を掲示しているわけではないので、現地での住所調査は完璧なものにはならない、という欠点があります。
この情報を埋めるためのデータは、いまのところありません。

#### 番と号に関する情報の入手 (住居表示への未対応地域)
住居表示に対応していない地域では、表示看板の設置義務がありません。
そのため、収集可能な情報に欠落が多く、現場での`番`の調査は非常に困難です。

対応する手段として、市町村によるOpenDataの公開を待つ、あるいは地元に詳しい方に輪郭を書いてもらう、などの方法が考えられます。
`号`についても同様で、掲示されている表札などを元に調査を行う必要があり、完全性の担保は現状、困難と思われます。

## 未解決の課題となっている点
Talk-ja MLにおいて、行政区境未定地域についての議論が正式な決着をみていません。

これは、例えば富士山の山頂など、行政区の境が未定である部分の処理を指します。
GISでは計算処理の関係上、エリアをあらわすためにはウェイが閉じている必要があるため、この問題は非常に厳しい課題として存在しています。
(OSMのデータ処理を行なうことが多いPostGISでも、この仕様が適用されます。PostGISでは、ウェイの進行方向に対して右側、あるいは左側のどちらを内側として扱うか、という判別を行います。ウェイが閉じていない場合、その判定ができなくなってしまいます)

この対策として、検索用のマルチポリゴンをもうひとつ用意する、その部分のデータを壊したままの状態にする、などの案がでています。
(なお、データではエリアとして閉じておいて、レンダリングで見えないようにすればよいのでは、という僕の意見はRejectされています。)