住所分割API
日本の住所の文字列を、OSMのaddrタグに分けて返すHTTPのAPIです。 外部のプログラム(JOSMのプラグイン、RapidやiDのユーザスクリプト、スクリプトなど)から呼べます。 鍵や利用者の登録は要りません。
OpenAPI 3.1の形式の定義を、/api/openapi.yamlで配信しています。
呼び出し用のコードを生成したり、APIを試すツールに読み込んだりするときに使えます。
項目と値の定義は、この文書とOpenAPIの定義で同じです。
このAPIがすること。
- 住所の文字列から郵便番号を切り出し、都道府県から番地までを区切ります。
- 住居表示の住所か、地番の住所かを、アドレス・ベース・レジストリ(以下ABR)の台帳で判定します。
- 番地が住居表示か地番か判定できず推測したときは、住居表示の候補と地番の候補を2つ並べて返します。
- ABRが住居表示の実施済みとしている町字で、番地が住居表示の台帳にも地番の台帳にも無いときは、住居表示と推測した候補に
guessed: trueを付けて返します。 - 番地の後ろの文字列から、建物名、階、部屋番号の候補を
optionalTagsとして返します。
このAPIがしないこと。
- 座標は返しません。
- 地番の台帳から取った番地は、タグにして返しません。地番の住所の
tagsはaddr:neighbourhoodまでとaddr:fullです。 - 建物名や階数などの番地の後ろの文字列は、
tagsには入れません。segmentsにremainderとして、taggedを偽にして返します。候補としてはoptionalTagsに分けて返します。 nameは返しません。
要求
POST /api/v1/parse
Content-Type: application/json
{"address": "高知県高知市北本町1ー2ー6"}
POSTだけを受け付けます。
GETで住所をURLに入れるとリバースプロキシのアクセスログに住所が残るため、GETでは受け付けません。
本文は8KBまでです。
addressは200文字までの空でない文字列で、全角と半角のどちらでも指定できます。
一度に分けられる住所は1件です。
応答の例
要求の形が正しければ、分けられたかどうかにかかわらず、HTTPの状態コード200で次の形のJSONを返します。
以下は、起動したサーバにcurlで要求した出力です。
住居表示と判定された住所
curl -s -X POST http://localhost:8787/api/v1/parse \
-H 'Content-Type: application/json' \
-d '{"address":"高知県高知市北本町1ー2ー6"}' | jq .
{
"apiVersion": "1",
"result": "jukyo",
"message": "住居表示の住所です。住居表示の台帳に、北本町一丁目の2-6があります。",
"segments": [
{
"value": "高知県",
"role": "prefecture",
"tagged": true
},
{
"value": "高知市",
"role": "city",
"tagged": true
},
{
"value": "北本町一丁目",
"role": "neighbourhood",
"tagged": true
},
{
"value": "2",
"role": "block_number",
"tagged": true
},
{
"value": "6",
"role": "housenumber",
"tagged": true
}
],
"candidates": [
{
"kind": "jukyo",
"tags": {
"addr:province": "高知県",
"addr:city": "高知市",
"addr:neighbourhood": "北本町一丁目",
"addr:block_number": "2",
"addr:housenumber": "6",
"addr:full": "高知県高知市北本町一丁目2-6"
}
}
]
}
地番と判定された住所
地番の番地1513-1は、chibanの区切りとして示し、addr:block_numberなどのタグにはしません。
addr:fullには、貼られた文字列から取った番地が入ります。
curl -s -X POST http://localhost:8787/api/v1/parse \
-H 'Content-Type: application/json' \
-d '{"address":"高知県安芸郡芸西村和食甲1513-1"}' | jq .
{
"apiVersion": "1",
"result": "chiban",
"message": "地番の住所です。和食甲は住居表示を実施していない町字です。番地はタグにしません。",
"segments": [
{
"value": "高知県",
"role": "prefecture",
"tagged": true
},
{
"value": "安芸郡",
"role": "county",
"tagged": true
},
{
"value": "芸西村",
"role": "city",
"tagged": true
},
{
"value": "和食",
"role": "quarter",
"tagged": true
},
{
"value": "甲",
"role": "neighbourhood",
"tagged": true
},
{
"value": "1513-1",
"role": "chiban",
"tagged": false
}
],
"candidates": [
{
"kind": "chiban",
"tags": {
"addr:province": "高知県",
"addr:county": "安芸郡",
"addr:city": "芸西村",
"addr:quarter": "和食",
"addr:neighbourhood": "甲",
"addr:full": "高知県安芸郡芸西村和食甲1513-1"
},
"note": "地番の「1513-1」はタグにしません。"
}
]
}
決められない住所(推測)
番地が住居表示か地番かを台帳でも決められず推測したときは、jukyoとchibanの2つの候補を並べて返します。
画面では、推測した住居表示の候補を先に見せます。
2つの候補を返すのは、ABRが町字を住居表示の実施済みとしているのに、番地が住居表示の台帳にも地番の台帳にも無い住所のときです。
このときjukyoの候補にguessed: trueを付けます。
これは、台帳の欠けの可能性が高いと見て、住居表示と推測したことを示します。
呼び出し側は、推測であることを利用者に示してください。
chibanの候補は、番地を入れずに町字で止めた版です。
curl -s -X POST http://localhost:8787/api/v1/parse \
-H 'Content-Type: application/json' \
-d '{"address":"高知県四万十市中村一条通3ー2ー23"}' | jq .
{
"apiVersion": "1",
"result": "ambiguous",
"message": "住居表示の住所と推測しました。ABRは中村一条通三丁目を住居表示の実施済みとしていますが、住居表示の台帳がなく、地番の台帳にも「2-23」がありません。台帳の欠けの可能性が高いため、住居表示として番地まで入れています。",
"segments": [
{
"value": "高知県",
"role": "prefecture",
"tagged": true
},
{
"value": "四万十市",
"role": "city",
"tagged": true
},
{
"value": "中村一条通三丁目",
"role": "neighbourhood",
"tagged": true
},
{
"value": "2-23",
"role": "number_undecided",
"tagged": true
}
],
"candidates": [
{
"kind": "jukyo",
"tags": {
"addr:province": "高知県",
"addr:city": "四万十市",
"addr:neighbourhood": "中村一条通三丁目",
"addr:block_number": "2",
"addr:housenumber": "23",
"addr:full": "高知県四万十市中村一条通三丁目2-23"
},
"guessed": true
},
{
"kind": "chiban",
"tags": {
"addr:province": "高知県",
"addr:city": "四万十市",
"addr:neighbourhood": "中村一条通三丁目",
"addr:full": "高知県四万十市中村一条通三丁目2-23"
},
"note": "地番の「2-23」はタグにしません。"
}
]
}
建物名、階、部屋番号のある住所
番地の後ろに建物名などがあるとき、候補にoptionalTagsが付きます。
tagsには入りません。
addr:fullには、建物名などが残ります。
curl -s -X POST http://localhost:8787/api/v1/parse \
-H 'Content-Type: application/json' \
-d '{"address":"高知県高知市北本町1ー2ー6 中村ビル3階 301号室"}' | jq .
{
"apiVersion": "1",
"result": "jukyo",
"message": "住居表示の住所です。住居表示の台帳に、北本町一丁目の2-6があります。",
"segments": [
{
"value": "高知県",
"role": "prefecture",
"tagged": true
},
{
"value": "高知市",
"role": "city",
"tagged": true
},
{
"value": "北本町一丁目",
"role": "neighbourhood",
"tagged": true
},
{
"value": "2",
"role": "block_number",
"tagged": true
},
{
"value": "6",
"role": "housenumber",
"tagged": true
},
{
"value": "中村ビル3階 301号室",
"role": "remainder",
"tagged": false
}
],
"candidates": [
{
"kind": "jukyo",
"tags": {
"addr:province": "高知県",
"addr:city": "高知市",
"addr:neighbourhood": "北本町一丁目",
"addr:block_number": "2",
"addr:housenumber": "6",
"addr:full": "高知県高知市北本町一丁目2-6 中村ビル3階 301号室"
},
"optionalTags": {
"addr:housename": "中村ビル",
"addr:unit": "301",
"addr:floor": "3"
}
}
]
}
分けられない住所
町字を特定できなかった住所は、誤りではなく、HTTPの状態コード200でresultをunresolvedにして返します。
candidatesは空です。
curl -s -X POST http://localhost:8787/api/v1/parse \
-H 'Content-Type: application/json' \
-d '{"address":"存在しない県の何か"}' | jq .
{
"apiVersion": "1",
"result": "unresolved",
"message": "町字を特定できず、住所を分けられませんでした。この住所は改善のために記録します。",
"segments": [
{
"value": "存在しない県の何か",
"role": "remainder",
"tagged": false
}
],
"candidates": []
}
jq .は表示を整えるためのもので、APIの利用には要りません。
応答の項目
| 項目 | 内容 |
|---|---|
apiVersion |
APIの版。v1では文字列の"1"です。 |
result |
判定の種類。値は後の表のとおりです。 |
message |
判定の説明文(日本語)。人に見せるためのものです。プログラムはmessageの文面で分岐せず、resultとroleで分岐してください。 |
segments |
読み取った区切りの並び。入力の順に並びます。 |
candidates |
候補の並び。0から2つです。 |
resultの値
| 値 | 意味 | candidates |
|---|---|---|
jukyo |
住居表示の住所です。 | jukyoの1つ |
chiban |
地番の住所です。 | chibanの1つ |
ambiguous |
住居表示か地番かを決められません。または、住居表示と推測しました。 | jukyo、chibanの順に2つ。または、町字までのtownの1つ。推測のときはjukyoにguessed: trueが付きます |
unresolved |
町字を特定できず、分けられませんでした。 | 空 |
jukyoでも、番地を読み取れなかったときは町字までのタグだけを返します。
このときもresultはjukyoで、messageに番地を読み取れなかったと書きます。
segmentsの項目
| 項目 | 内容 |
|---|---|
value |
区切りの文字列。 |
role |
区切りの役割を表す英字の識別子。値は後の表のとおりです。 |
tagged |
その区切りが、どれかの候補のタグになったかどうか。 |
roleの値は次のとおりです。
OSMのタグのキーに対応するものは、キーからaddr:を除いた名前です。
role |
内容 | 対応するタグ |
|---|---|---|
postcode |
郵便番号 | addr:postcode |
prefecture |
都道府県 | addr:province |
county |
郡 | addr:county |
city |
市区町村 | addr:city |
ward |
政令指定都市の区 | addr:suburb |
quarter |
大字 | addr:quarter |
neighbourhood |
町字、字 | addr:neighbourhood |
block_number |
街区符号 | addr:block_number |
housenumber |
住居番号 | addr:housenumber |
number_undecided |
住居表示の街区符号と住居番号か、地番か、決められない番地 | 候補によって異なる |
chiban |
地番 | 無し(タグにしません) |
extra_number |
番地の3つ目以降の要素 | 無し(タグにしません) |
remainder |
建物名や階数などの残り | 無し(タグにしません) |
candidatesの項目
| 項目 | 内容 |
|---|---|
kind |
候補の種類。値は後の表のとおりです。 |
tags |
OSMのタグのキーと値の組。キーはaddr:postcode、addr:provinceからaddr:housenumberまでの順に並び、最後がaddr:fullです。 |
guessed |
住居表示と推測した候補のとき、真。推測でなければ項目ごと省きます。 |
optionalTags |
番地の後ろの文字列から推測した、addr:housename、addr:floor、addr:unitのうち推測できたもの。無いときは項目ごと省きます。 |
note |
人に見せる注記(日本語)。無いときは項目ごと省きます。 |
kindの値は次のとおりです。
| 値 | 意味 |
|---|---|
jukyo |
住居表示の候補。番地まで含みます。 |
chiban |
地番の候補。番地は含まず、町字までで止めます。 |
town |
住居表示か地番かを決める材料が無く、町字までで止めた候補。国土数値情報由来の町字で、台帳に番地の明細が無いときに返します。 |
候補の見出し(「住居表示の場合」など)は、APIでは返しません。
kindとresultから、呼び出し側で作ってください。
addr:fullは、貼った住所を正規化した文字列です。
郵便番号は除き、番地の後ろの建物名、階、部屋番号は残します。
どの候補にも同じ値が入ります。
地番の住所でも番地を含みますが、番地の値は地番の台帳のレコードからではなく、貼られた文字列から取ります。
optionalTagsは、tagsに足すかどうかを呼び出し側が決めるための候補です。
どの候補にも同じ値が入ります。
推測の精度は高くないので、利用者が選んでから使ってください。
返すタグには、addr:country、note、fixme、nameを入れません。
誤りの応答
| 状態 | HTTPの状態コード | error.code |
|---|---|---|
JSONとして読めない、addressが無い、空、文字列でない |
400 | bad_request |
addressが200文字を超える、または本文が8KBを超える |
413 | too_long |
| 回数の制限を超えた | 429 | rate_limited |
| パスが無い | 404 | not_found |
/api/v1/parseにPOSTとOPTIONS以外で要求した |
405 | method_not_allowed |
| サーバ内部の失敗 | 500 | internal |
本文は次の形です。
{"error": {"code": "bad_request", "message": "住所を文字列で指定してください。"}}
messageは人に見せるための日本語で、文面は変わることがあります。
プログラムはerror.codeで分岐してください。
429には、待つ秒数を示すRetry-Afterヘッダを付けます。
405には、使える方法を示すAllowヘッダを付けます。
版と互換
パスに版(v1)を入れています。
同じ版の中では、項目やrole、result、kindの値を足すことはあっても、消したり意味を変えたりしません。
呼び出し側のプログラムは、知らない項目と知らない値を読み飛ばしてください。
たとえば、知らないroleの区切りは無視し、知らないkindの候補は表示しないようにします。
消す変更や意味を変える変更は、/api/v2/として出します。
利用の条件
回数の制限は、送り元のIPアドレスごとに、1分あたり60回が既定です。 サーバの運用者が変えられます。 上限を超えると429を返します。
CORSを許可しています(Access-Control-Allow-Origin: *)。
ブラウザで動くツールから直接呼べます。
OPTIONSの事前確認にも答えます。
住所の扱い
分けられなかった住所(町字を特定できなかったもの、正規化が失敗したもの)は、分割の改善のために、サーバに記録します。 分けられた住所は、記録しません。
返すタグには、アドレス・ベース・レジストリ(デジタル庁)と位置参照情報(国土交通省)を加工したデータに由来する値が含まれます。 出典の書き方は、README.mdの「出力される住所データ」の節にあります。
座標は返しません。
地番の台帳から取った番地は、タグ(addr:fullを含む)にして返しません。