内容が古くなっている可能性がありますのでご注意下さい。
Leafletライブラリを使って開発したWeb地図に住所検索の機能を追加するために、ジオコーディングのプラグインが各種用意されています。これらのプラグインは、ユーザーが入力した住所をジオコーダと呼ばれるサーバーに渡して緯度経度を受け取ります。
プラグインによって対応するジオコーダが異なります。また、ジオコーダによって性能が異なり、高性能なジオコーダは利用登録が必要だったり費用がかかったりします。
比較的高性能でありながら無料で使えるジオコーダのひとつに、東京大学空間情報科学研究センターの「CSISシンプルジオコーディング実験」がありますが、残念なことに、対応しているLeafletプラグインがありませんでした。
そこで、 OpenStreetMap の Nominatim ジオコーダに対応した Leaflet Control Geocoder プラグインとCSISのジオコーダを橋渡しするプロキシサーバを作成しました。
動作原理を図で表すと以下のようになります。
Nominatim の形式で渡されたパラメータをCSISのジオコーダ用に変換して渡し、返された XML を JSON に変換して呼び出し元に返すというだけの簡単なものです。
ソースコードはGitHubで公開しているので、そちらを参照して下さい。ここにPHPのコードを記述すると、WAFにブロックされて投稿できなくなってしまうのです。
プログラムの前半では、パラメータが 35.658099, 139.741357 という形式の緯度経度だった場合の処理をしています。この場合はジオコーダの呼び出しをせず、この緯度経度を含む連想配列を作成します。後半ではCSISのジオコーダを呼び出し、返されたXMLを解析して連想配列を組み立てます。
// $item['address']['country'] = '日本'; $item['address']['country'] = str_replace('/', ' ', $cand->address );
となっている箇所では、本来ならば国名をセットするべき所に、〇〇県 □□市 △△町のようなデータをセットしています。Leaflet Control Geocoderプラグインでは、ジオコーダから複数の住所が返された場合に、こうした方がリストの表示が分かりやすくなるためです。別のプラグインを使用する場合は、本来の値をセットした方が良いかもしれません。
最後に、連想配列をJSONに変換して返します。
このプログラムはPHPで書かれているので、通常なら
https://server/search.php?q=住所
という形式で呼び出すことになります。しかし、Leaflet Control Geocoderプラグインでは、server の部分はオプションで指定できますが、プログラム名は拡張子の付かない search で変えることができません。そこで、.htaccessに以下の記述をし、拡張子なしでPHPプログラムを呼び出せるようにします。
RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule ^(.*)$ $1.php
Web地図のプログラムでLeaflet Control Geocoderプラグインを初期化する際は、geocoder オプションで L.Control.Geocoder.Nominatim を指定し、その serviceUrl オプションで GeocoderProxy を設置したサーバーを指定します。
L.Control.geocoder({ geocoder: new L.Control.Geocoder.Nominatim({ serviceUrl: /* URL of the service */ }),
月待ビンゴ攻略マップでは、Leaflet Control Geocoderプラグインと GeocoderProxy を実際に使用しており、動作を確認することができます。