ウェブメルカトルの真髄の半分は、単位球を単位平面に展開することである。
ウェブメルカトルの真髄の残り半分は、ズームの概念を導入し、有限桁数の数値によって必要な分解能を得ていくことである。
前者半分に集中して考える場合、ズームレベル z と、n = 2 ** z を捨象して考えれば良い。まずは、話が簡単な x から考えよう。
(lng + 180) / 360
lng の定義域は -180 から 180 なので、上式 は 0 から 1 の間に収まる。
y については、
(1 - log(tan(lat_rad) + (1 / cos(lat_rad))) / PI) / 2
を考えることになる。この値が 0 になる時が北の限界であり、1 になる時が南の限界である。その時の lat_lad の値は解析的には得られないそうである。
他方、 https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames によれば、その値は
±arctan(sinh(π))
であるそうだ。数値的な値は、度単位で言えば ±85.0511 である。
では、与えられた緯度が南北の限界を超えるかどうかは、lat_rad と上記の値を比較することで検査すべきであろうか。私はそうは思わない。むしろ、
y = floor(n * (1 - log(tan(lat_rad) + (1 / cos(lat_rad))) / PI) / 2)
の値が 0 よりも小さくなるか、n = 2 ** z - 1 よりも大きくなるか、を検査した方が経済的であろう。
def y(lat, z)
n = 2 ** z
lat_rad = lat * Math::PI / 180
(n * (1 - Math.log(Math.tan(lat_rad) + (1 / Math.cos(lat_rad))) / Math::PI) / 2).floor
end
p y(86, 1) # -1
p y(-86, 1) # 2