IMI住所変換コンポーネントを改造してリバースジオコーディングに対応してみた

先日、経産省が公開する「住所変換コンポーネント」についての性能を調べた記事を投稿しました。

IMI住所変換コンポーネントでいろんな住所を正規化してみた
https://qiita.com/uedayou/items/4c9d30fc031a9bf6762e

「IMI住所変換コンポーネント」は、表記にゆれがある住所表記を正規化してくれるとても便利なツールです。

たとえば

```
霞が関2 -> 東京都千代田区霞が関二丁目
```
のようになります。

このツールのもう一つの大きな特徴として、その住所に対する位置情報(緯度経度)も取得することができる点があります。

```
霞が関2 -> 東京都千代田区霞が関二丁目 -> {"緯度": "35.675551", "経度": "139.750413"}
```

所謂「**ジオコーディング機能**」があります。
これは、ツール内にあらかじめ住所に対する位置情報データが含まれることを意味し、作り方によってはこの逆、位置情報(緯度経度)から住所にも変換することができるのではないか？と思いました。

```
{"緯度": "35.675551", "経度": "139.750413"} -> 東京都千代田区霞が関二丁目
```

これを一般的に**リバースジオコーディング(逆ジオコーディング)**と言いますが、本家コードを改造してこの**リバースジオコーディング**機能をつけてみました。

## 使い方

ツールを使うにはまず、Node.jsとリバースジオコーディング対応住所変換コンポーネントモジュールのインストールが必要です。経産省が公開するものとは違うものをインストールします。
ファイルは

```
https://github.com/uedayou/imi-enrichment-address-plus/releases/download/v1.0.1/imi-enrichment-address-plus-1.0.1.tgz
```

にあります。このツールには3つの使い方があります。

- (1) コマンドラインインターフェイス
- (2) Web API
- (3) Node.js

(1) は、npm でグローバルにインストール

```
npm install -g https://github.com/uedayou/imi-enrichment-address-plus/releases/download/v1.0.1/imi-enrichment-address-plus-1.0.1.tgz
```

(2), (3) はローカルインストールしてください。

```
npm install https://github.com/uedayou/imi-enrichment-address-plus/releases/download/v1.0.1/imi-enrichment-address-plus-1.0.1.tgz
```

### (1) コマンドラインインターフェイス

リバースジオコーディングをコマンドラインで利用する場合は

```
$ imi-enrichment-address-plus --lat [緯度] --lng [経度]
```

```shell:例
$ imi-enrichment-address-plus --lat 35.675551 --lng 139.750413
```

```json:出力
{
  "@context": "https://imi.go.jp/ns/core/context.jsonld",
  "@type": "場所型",
  "住所": {
    "@type": "住所型",
    "表記": "東京都千代田区霞が関二丁目",
    "都道府県": "東京都",
    "都道府県コード": "http://data.e-stat.go.jp/lod/sac/C13000",
    "市区町村": "千代田区",
    "市区町村コード": "http://data.e-stat.go.jp/lod/sac/C13101",
    "町名": "霞が関",
    "丁目": "2"
  },
  "地理座標": {
    "@type": "座標型",
    "緯度": "35.675551",
    "経度": "139.750413"
  }
}
```

### (2) Web API

ツール内にWebサーバ機能があり、サーバ経由でWeb APIとして利用することができます。

```
$ node node_modules/imi-enrichment-address-plus/bin/server.js 8080
```

上記を実行して http://localhost:8080/ をブラウザで開くと以下のようなWebページが開きます。

![Webページ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62575/e1676ca6-8482-9c97-6576-4916808dea1e.jpeg)

ここの**緯度経度**の部分の**変換**ボタンを押すと、実行結果には以下のように表示されます。

![実行結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62575/340e3719-a4a9-21b0-dfa0-edb88f78c616.jpeg)

プログラム上から使う場合は、以下のJSONをPOSTしてください。

```JSON
{
  "@type": "座標型",
  "緯度": "[緯度の値]",
  "経度": "[経度の値]"
}
```

```shell:cURL
$ curl -X POST -H 'Content-Type: application/json' -d '{"@type": "座標型","緯度": "35.170915","経度": "136.881537"}' localhost:8080
```
```JSON:出力
{
  "@context": "https://imi.go.jp/ns/core/context.jsonld",
  "@type": "場所型",
  "住所": {
    "@type": "住所型",
    "表記": "愛知県名古屋市中村区名駅一丁目",
    "都道府県": "愛知県",
    "都道府県コード": "http://data.e-stat.go.jp/lod/sac/C23000",
    "市区町村": "名古屋市",
    "区": "中村区",
    "市区町村コード": "http://data.e-stat.go.jp/lod/sac/C23105",
    "町名": "名駅",
    "丁目": "1"
  },
  "地理座標": {
    "@type": "座標型",
    "緯度": "35.170778",
    "経度": "136.882494"
  }
}
```


### (3) Node.js

ツールはNode.jsのモジュールなので、Node.js のコード上からも利用可能です。
リバースジオコーディングは以下のように利用できます。

```Javascript
const convert = require('imi-enrichment-address-plus');
const point = {
  lat: 35.675551,
  lng: 139.750413
}
convert(point).then(json=>{
  console.log(json);
});
```


### 利用についての注意

本ツールのリバースジオコーディングは、半径1km内から最も近い代表点を持つ住所データを1件返します。与える緯度経度によっては必ずしもその位置の住所を表さない可能性がありますので、くれぐれも正確なデータではなくある程度あいまいなデータであることを留意して使用してください。

ただ、間違っていたとしてもかなり近い住所であることがほとんどだと思います。ざっくりとした住所でも構わない場合も結構あると思いますが、そういう場合はかなり便利だと思います。

## ソースコード

ソースコードは以下のリポジトリで公開しています。
詳しい使い方は、[README.md](https://github.com/uedayou/imi-enrichment-address-plus/blob/master/README.md)を参照してください。

<https://github.com/uedayou/imi-enrichment-address-plus>