ジオコーディング(住所<->緯度経度変換)が必要な機会が訪れたのですが、Google Map APIのような外部APIを使う場合、通信エラーの対応、アカウントやキーの管理、使用料金の管理などいろいろと面倒事が多くなりがちです。
そこで、データをローカルに保持して、索引できるライブラリを調査してみたところ、自分の目的としては必要十分なライブラリがありました。
これならローカルのプログラム呼び出しに過ぎないので、どれだけ呼び出しても無料だし、通信の失敗を気にせず使えます。
demouth/DmGeocoder
GISデータをライブラリ内に持っており、このライブラリ単体でジオコーディングができるということで、目的は果たせそうですが、最終更新が8年前となっていました。
ちょっと不安だったので、他にメンテナンスが活発なライブラリはないものか、と探したんですが、他に見つけられませんでした。(探し方が悪かっただけ…かも)
自分にとっての課題
目的さえ果たせれば、と思い動作確認をしてみたところ、いくつか課題がありました。
各課題を次のように解決したフォークを公開しました。
create_function 関数を使用していたので、警告がでる・エラーになる。
create_function 関数が PHP 7.2 から廃止警告が出るように、PHP 8.0 では廃止になっており、警告や実行時エラーが発生します。
作者様は下位互換性のためにネームスペースの使用を避けているとのことでしたが、廃止になる関数までは回避できません。
PHP5.0以上で利用可能で、PHP5.3以下でも使えるようにnamespaceは使用していません。
PHP バージョンを呼び出して、バージョンごとに処理を分けることで下位互換性を確保できないこともありませんでしたが、あまり気が進みませんでした。
現時点でセキュリティサポートが継続しているのは PHP 7.3 でしたので、いっそのこと最低バージョンを引き上げることにしました。
データが2012年度で内容が古い
位置情報は平成24年度版のデータを利用しています。翌年版のデータが公開されたらcsvディレクトリに配置されているcsvファイルを差し替えれば利用可能です。
データは差し替えれば対応できるとのことだったので、現時点で公開されている最新版の2020年度版データで差し替えました。
データは国土交通省のサイトの「位置参照情報 ダウンロードサービス」からダウンロードできるデータを使用していました。
ここから「大字・町丁目レベルのみ」を選択し、年度を選んで進んでいくとダウンロードする画面が出るので、都道府県ごとにデータをダウンロードします。
URLにはルールがあるので、必要な CSV ファイルを取り出してまとめるスクリプトを書きました。
今後変更される可能性はありますが、おそらくは変数を書き換えるだけで新しい年度に対応できると思います。
アーカイブを展開すると「01_2020.csv」というファイルがでてくるのでこれを「src/Dm/Geocorder/GISCSV/csv」へ集約します。
このファイルは [都道府県番号]_[西暦].csv というルールになっていますので、47個で全部です。
これをディレクトリにいれたら「2012」でファイルを走査していたコードを「2020」に書き換えました。
ここらへんは、年度ごとのデータで切り分けたり、指定できると面白そうだと思いましたが、わざわざ古いデータを参照する理由もなく、修正の手を広げたくなかったのでやりませんでした。
データを更新して、テストコードを実行してみたところ一部のデータが更新されたようで、テストコードが落ちるようになったので、データの方に合わせて修正しました。
データの正しさをテストできていないかもしれませんが、ロジックの正しさは担保できていると思います。
テストが自動化されていない
テストコードは丁寧にかかれていたのですが、実行するにはローカルに PHPUnit を用意して、手動で実行する必要がありました。
せっかくなので、Github Action を用いて、PHP 7.3 – 8.0 でテストを動かすようにしてみました。
フォークリポジトリ
フォークして修正したものはこちらからダウンロードできます。
composer でインストールする場合は github 経由でインストールすることになります。
PHP のライブラリ公開 (packagist) のことがあまりわかってないので、ひとまずリポジトリだけで公開しておきます。
{
"repositories": [
{ "type": "git", "url": "https://github.com/44uk/DmGeocoder.git" }
],
"require": {
"44uk/dmgeocoder": "dev-master"
}
}
おまけ
調査中に見つけたので、メモとして残しておきます。
こちらは Node.js 環境向けで、フロント・サーバサイドどちらでも利用できるようになっているようです。
メンテナンスも活発ですし、JAMStack で利用するには良さそうです。
今回は使用しませんでしたが、機会があれば検討してみようと思います。