先日、Mapbox GL JSで表示中の地図をPNGでダウンロードするためのボタンを設置するプラグインを作りました。
デモは以下にあります。
その中で、ハマった小ネタを紹介します。
地図の右下の緯度経度を取得したい
Mapbox GL JS で表示されている地図の右下の緯度経度を取得する必要があって、ささっとドキュメントを調べて、一度以下のように実装しました。
const bottomRight = map.getBounds().getSouthEast()
getBounds()
についてはドキュメントには以下のような記述があります。
Returns the map's geographical bounds. When the bearing or pitch is non-zero, the visible region is not an axis-aligned rectangle, and the result is the smallest bounds that encompasses the visible region.
後半がよくわかんないけど、まあなんとかなりそうかなとおもたのですが、結論からいうとこれではダメでした。
Mapbox GL JS はベクトルタイルなので地図が傾いていることがありえるのですよね。
上の画像のように地図が傾いている場合、getBounds()
で取得している位置は赤い矢印のところでした。
地図の右下の緯度経度を取得するための正しい方法
というわけで最終的に以下のような方法で実装しました。
const width = map.getContainer().offsetWidth
const height = map.getContainer().offsetHeight
const bottomRight = map.unproject([width, height])
unproject()
という関数は、ピクセルでの位置を緯度経度に変換してくれる関数です。逆に緯度経度からピクセルに変換したいときは project()
です。
この関数の名前ちょっとわかりにくいですよね。笑
なにがしたかったのか
今回作った画像としてエクスポートするプラグインは、<canvas />
を PNG に変換してエクスポートしています。
最初、できたできたと喜んでいたのですが、© OpenStreetMap Contributors
が入ってないとまずいなと思いまして、それを入れたいと思ったのです。
ところが、Mapbox GL JS で表示されている Attribution は、Canvas ではなく 普通の HTML テキストを上のレイヤーにのっけてるだけなので、画像にはいってこなかったのですよね。
なので、Attribution 用の文字列を Canvas に放り込むという処理を行いました。
そのために動的に GeoJSON をつくって地物として挿入するという処理をおこなっていて、それで右下の緯度経度を知りたかったのです。
やってみたらなんでもない処理でしたが、「どうせ画像としてだすだけだから、一時的に地物として放り込んでしまえ」というアイディアにたどりつくまでに半日程かかってしまいました。。。
(半日は Canvas を直に操作しようと頑張ってた。。。w)