• テクノロジー

Google Maps JavaScript APIのgetCenter().lng()が180を超過した経度を返す

緯度と経度というものはそもそも、以下のような仕様になっている。

  • 緯度 : -90から90まで。負の値を使わずに南緯と北緯で表す場合もある。
  • 経度 : -180から180まで。負の値を使わずに西経と東経で表す場合もある。

緯度経度とは? | 用語集とGISの使い方 | 株式会社パスコ

というわけで、Google Maps JavaScript APIの.getCenter().lng()が返す値もそれに即したものだろうと思っていたのだけど、 どうやらそういうわけではないらしい。

Google Maps JavaScript APIの経度の仕様

Google Maps JavaScript APIで緯度経度を取る場合、map.getCenter().lat()map.getCenter().lng()などのメソッドが用意されている。

が、この.lng()は180や-180に達しても0に戻らず、そのまま数値が増加し続けてしまう。

あまり地理的な知識がないので、これがバグなのかなんなのか、はたまたこうすべき理由が学術的にあったりするのかわからない。

けど、この仕様を知らないで使うと、予期せぬ動作を引き起こすことがある(あった)。

Google Maps JavaScript APIで正しい経度を取る方法

この議論は調べてもあまりメジャーではないようだけど、少なくとも同じ問題視をしている人はいる。

LatLngクラスのインスタンスを作り直す

こちらで議論されている中での結論。今のところこれが一番綺麗なように思う。

Issue 3247 - gmaps-api-issues - Longitudes returned by getCenter can be outside [-180,180] range - Google Maps API bug reports and feature requests - Google Project Hosting

var center = map.getCenter();
var wrapped = new google.maps.LatLng(center.lat(), center.lng());

Google Maps JavaScript APIの緯度経度を表すクラスのインスタンスを作り直してしまえば、適切な値に戻された上で生成される。

単純に剰余を取る

この方法だと負の値の考慮がめんどうなので、あまりよくなさそう。

map.getCenter.lng() extends beyond -180 when dragging continuously. How can I stop that? - Stack Overflow

この方法だとすべて正の数になってしまうので、

map.getCenter().lng() % 180;

こうする・・・?(Stack Overflowから引用)

var lngCenter = map.getCenter().lng();
var rem = lngCenter % 180;
if (Math.abs(parseInt(lngCenter/180)) % 2 !== 0) {
  if (rem < 0) rem += 180; else rem -= 180;
}
lngCenter = rem;