Pixel Pedals of Tomakomai

北海道苫小牧市出身の初老の日常

メルカトル図法

地図表示について、緯度と経度をx座標とy座標と見なして画像を描画するだけでしょ、くらいに甘く考えていたのだが、そんな単純な話ではなかった。そもそも地球は丸くて地図は平面なんだから、緯度経度を平面上の (x, y) 座標と見なせるわけがないのだ。

球面と平面が違うことくらい知っているつもりでいたのが、 wikipedia の以下の説明を読んで自分がいかに甘く考えていたか、思い知らされた。

ja.wikipedia.org

そもそも球面上では「3つの角がすべて90度である正三角形」もありえて、これを「正しく」地図上に描くことは不可能である。

言われてみれば確かにそうだ。やはり平面上の常識で考えるのは良くない。

そもそも、地図とはなんなのだろう。我々がよく使う google map は、メルカトル図法だそうだ。中学生で習ったはずが、恥ずかしながら全く覚えていない。残念ながら、「球面を四角にした地図」という程度のまったく正確ではない知識しか持ち合わせていなかった。

メルカトル図法は球を円筒に投影しているだけではなく、角度を正確に保つために緯度方向の縮尺を変えているそうだ。ああ、それで先日使った staticmap クレートの y 軸方向の計算式は妙だったのか。

github.com

/// Latitude to y coordinate.
pub fn lat_to_y(mut lat: f64, zoom: u8) -> f64 {
    if !(-90_f64..90_f64).contains(&lat) {
        lat = (lat + 90_f64) % 180_f64 - 90_f64;
    }

    (1_f64 - ((lat * PI / 180_f64).tan() + 1_f64 / (lat * PI / 180_f64).cos()).ln() / PI) / 2_f64
        * 2_f64.powi(zoom.into())
}

直感的にわかる lon_to_x と明らかに雰囲気が違う。

/// Longitude to x coordinate.
pub fn lon_to_x(mut lon: f64, zoom: u8) -> f64 {
    if !(-180_f64..180_f64).contains(&lon) {
        lon = (lon + 180_f64) % 360_f64 - 180_f64;
    }

    ((lon + 180_f64) / 360_f64) * 2_f64.powi(zoom.into())
}

では、この lat_to_y の計算式はどのように導出されるのだろう? 広島大学が、いい感じの文書を出している。大学初年度の解析学を実際に使う教材としてメルカトル図法を題材にしているようだ。

https://home.hiroshima-u.ac.jp/teragai/mercator.pdf

この pdf はこれからじっくり読むとして、地図のことを調べるに連れ、 geohash などの定義はどうなっているのかも気になってきた。緯度経度で定義しているとすると、それをメルカトル図法の地図上に表示するときれいな長方形になるのだろうか?

色々と調べてみる必要がある。