Googleマップの代替サービスが国から提供されていた件

こんにちは❗フリーランス・コンサルタント&エンジニアの 九保すこひ です。

いろんなサイト開発でもそうですけど、結構地図って使うことって多いじゃないですか。例えばお客さんの住所横に地図リンクを貼ったり、住所の下辺りにでも地図を埋め込んで表示させたり。

少し前までは JavaScript 開発者は地図使うってなったら、即グーグル・マップを使うって流れがありましたよね。っていうのも地図は綺麗で見やすいし、JavaScript の API をしっかり作ってくれてるし、なにより無料だったし。

でも、これも有名な話ですけど、少し前からグーグルは「んー、今まで無料だったけど、ある一定の制限をこえるとお金とるね(キラーン)」って感じでサービスの中身を変更してしまいましたよね。。もちろんそれが「サービス」っていうものなんで有料が基本なんですけど、一日に25,000回以上表示でお金を払うってのはちょっと有名な個人サイトでも行っちゃう回数だから、結構僕のクライアントさんたちも敬遠してる部分があるみたいです。

まー、正直のとこ追加の1,000回ごとに 0.50米ドル(←50円くらい)なんでそこまで高額の出費じゃないんですけど、やっぱ経費節減が基本のこの日本経済下では少ないとはいえ青天井の支払いが存在してる時点で大きなマイナス要素のようです。

で、他のサービス探してみた

そこで、ちょうど個人的サイトの開発で地図が必要だったんで、今後のためにグーグルマップの代替になるようなサービスを探してみることにしたわけです。
できれば、ドキュメントが多くて、APIも豊富で、あと無料で。

まず、一番に思い浮かんだのがオープンソースが流行ったころに知った「OpenStreetMap(オープン・ストリート・マップ)」というサービス。副題で「自由な地図をみんなの手で」と言ってるだけあって Wikipedia のように誰でも自由に編集ができる地図です。これはいいぞ!ってその時は思ったんです。

でも、アイデアはとてもとてもいいので僕も貢献したいとも思うんですけど、正直まだ中身がスカスカでグーグルマップと比べると悲しいかな情報量、使いやすさも雲泥の差があるといわざるを得ませんでした。JavaScript の APIも用意してくれてるし、とてもいいんですけど、そこが一番大事だからなー。。なんなら近くの有名なため池がごっそり地図には描かれてなかったりしてるのをみて OpenStreetMap は今後に期待!ってことで今回はパスすることにしました。

んー、あんまり地図ってみんな自分で編集しようとはしないんでしょうかね??

だから、あきらめて他を探してみた

ってことで、また別のサービスを探すことに。で、ネットサーフィン(←死語かな ^^) してみた結果、どうやら国土地理院という国交省の機関が地図データを提供してくれてるということは初めて知りました。国土地理タイルっていう名前みたいです。「えっ、なんかの間違いじゃ!?」って最初は思いましたね。

そこで急いでリンク先を調べてみるとさすが国の機関だけあって地図の情報もグーグルマップまでとはいかないですけど、最低限のデータは入ってますし、そこまでアクセスも遅くないんで、これは使える!と思いましたね。

実際の地図サンプル

そこで、次はどんな感じで使えばいいかドキュメントを探してみました。

んー、GitHub にサンプルを用意してくれているものの、正直なとこ複雑なサンプルだけしか入ってなくて、グーグルマップみたいな丁寧なドキュメントはないようだ。。。

実際のサンプルはいいできなのになー、どうしたもんかねー。。。

別の JS ライブラリで国土地理タイルを使う

そこで、またいろいろとググってみる(←死語その2 ^^)とどうやら Leaflet という JSライブラリがあってこれのオプションで国土地理タイルを使うようにすれば簡単に地図を操作したりできるみたいでした。(後から知ったんですけど、さっきの地図サンプルでも Leaflet 使ってるみたいですね)

で、実際にコードを書いてみるとあんがいすんなり地図が表示できます。さすが Leaflet。人気のライブラリだそうです。

コードは簡単。スタイルシートとJavaScript を読み込んで、

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"></script>

あとはマップ作ってレイヤーを設定するだけ。

const map = L.map('map').setView([35.681167, 139.767052], 13);
L.tileLayer(
    'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png',
    {
        attribution: '<a href="http://www.gsi.go.jp/kikakuchousei/kikakuchousei40182.html" target="_blank" rel="noopener">国土地理院</a>'
    }
).addTo(map);

【追記:2021.09.15】コードにバグがあったので修正しました。ゴメンナサイ…😫

ちなみに ‘map’ っていうのがターゲットのID。#mapってことですね。で、setView の中の2つの数字が緯度と経度。

最後のがズーム数で大きい数字ほど地図が拡大されます。

あと、tileLayer の中のURLは国土地理タイルのURLになります。で、リンクに引用元の国土地理院を追加してます。(←実際には Leaflet のリンクも表示されます。)

※注意。<div id="map"></div>
にはスタイルシートで高さ(height)を決めておいてください。僕みたいに、ん??って五分ほど無駄にしちゃいますよ(笑)

なお、使える地図は基本のものだけでなく「淡色」や「英語バージョン」なんかもあります。詳しくは以下のページをご覧ください。

📝 参考URL: 地理院タイル一覧

見やすいように中心に十文字をつけたい

地図は地図でも問題ないんですよ。でも、やっぱり中心に何かがないとあたりをつけにくいから見にくいんです。。。じゃあどうしたもんかなーって探ってみると、どうやら Leaflet にはいろんなプラグインがたくさんあって、その中に GeoPhoto っていうものを発見。実際にためしてみることに。

ありがたいことに cdn も用意してくれてるので、まずはそこから CSS と JS と読み込みますよ。

<link rel="stylesheet" href="https://unpkg.com/leaflet-geotag-photo/dist/Leaflet.GeotagPhoto.css" />
<script src="https://unpkg.com/leaflet-geotag-photo/dist/Leaflet.GeotagPhoto.min.js"></script>

で、さっきの地図コードの次辺りに、こんな感じでコードを書きます。
ちなみに cdn から読み込むと中心に表示される crosshair.svg はきちんと読み込まれないんで自分で好きなとこに配置するなりして使ってくださいね。たぶん cdn 使わないんだったらなにもしなくても読み込まれるはずです。(でも、min.js がないんだよなー)

あと、大きさを変更したい場合はクラス「crosshair」にスタイルシートをつけて width を指定すればOK!

L.geotagPhoto.crosshair({
    crosshairHTML: '<img class="crosshair" src="/images/crosshair.svg">'
}).addTo(this.map)
.on('input', function (event) {
    var point = this.getCrosshairPoint()
});

ってな感じで中心部分に画像を表示することができたわけです!

せっかくだから地名検索もしたくなった

人間の欲望はつきることはありません(笑)どうせなら地名検索して自動でそこまで移動したくなってしまいました。

ということで、また探ってみると国土地理院がJSON で検索APIをつくってくれてるんで、これを使うことに(ラッパーの歌詞以上に感謝!)。実はプラグインには地図の中に検索ボックスを作るってのもありますけど、今回は地図の外からの仕様で行くことにしました。

国土地理院のAPI・URLはこんな感じです。

https://msearch.gsi.go.jp/address-search/AddressSearch?q=(URLエンコードされた検索ワード)

※他にも都道府県コードとかで絞り込みできるんで興味のある人は ここ からどうぞ!

で、Ajax 部分ははしょりますけど、Vue と axios を使って JSON データをとってきてサラッとした感じでリストを表示することに成功しました。で、そのリストをクリックすると自動で地図が移動するようにもしました。
ちなみに地図を移動するのはこんな感じでとてもシンプルです。

map.panTo(new L.LatLng(lat, lon));

※僕いっつもどっちかわかんなくなるんですけど、lat(latitude) が経度で、lon(longitude)が緯度です。明石の経度が135度なんで日本の場合は経度の方が大きい数字ってことでOKですね。

おわりに

国土地理院って小学校の地図帳の背表紙にのってるのを見て以来ほとんど関わることなんてなかったわけですけど、ひょんなことからこんなとこで再開するとはおもってもみませんでした。こういう国のサービスとかなんとか白書とかって結構いいデータが揃ってたりするんでちゃんとチェックしとかないとダメですねー。

ってことで仕事終わりは卓上旅行に戻りたいと思います(笑)

開発のご依頼お待ちしております 😊✨
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします!
このエントリーをはてなブックマークに追加       follow us in feedly  

開発効率を上げるための機材・まとめ