1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

地図タイルにおけるピクセルの大きさをメートルに変換する

Posted at

1. 概要

地図タイルにおける**1ピクセルの大きさ(メートル)**を計算したい。

地球は平面ではないため、ピクセルの大きさは位置に依存することになる。したがって、タイル座標が与えられた時、当該タイルにおける1ピクセルの大きさを計算できるようにしたい。

2. 計算式

Understanding Scale and Resolution - Bing Maps Articles によると、以下のように緯度とズームレベルに依存した式で計算することができるらしい。

Map resolution = 156543.04 meters/pixel * cos(latitude) / (2 ^ zoomlevel)

この式をタイル座標とピクセル座標の関係、ピクセル座標と緯度経度の関係と組み合わせれば、目的を達成することができる。

3. 実装 (JavaScript)

3.1. 緯度・ズームレベルからピクセルサイズを計算

計算式通り実装する。latitudeの単位が[rad]であることに注意。

// Calculate resolution [meter/pixel]
const resolution = (latitude, zoom) => 156543.04 * Math.cos(latitude) / (1 << zoom)

3.2. タイル座標から緯度経度を計算

ここでは、タイル座標 tileZ / tileX / tileY のタイル上の (pX, pY) 要素の緯度経度を計算する関数を実装している。

// Calculate lat/lon of pixel (pX, pY) on tile tileZ/tileX/tileY
function pixelOnTileToLatLon(pX, pY, tileZ, tileX, tileY) {
  const L = 85.05112878;
  // Pixel coordinate
  const x = 256 * tileX + pX;
  const y = 256 * tileY + pY;

  const lon = 180 * (x / (1 << (tileZ + 7)) - 1);
  const lat = (180/Math.PI) * Math.asin(Math.tanh(
    - Math.PI / (1 << (tileZ + 7)) * y + Math.atanh(Math.sin(L * Math.PI/180))
  ));
  return {lat: lat, lon: lon};
}

3.3. タイル座標からピクセルサイズを計算

上記の関数を組み合わせ、タイル座標で指定されたタイルにおけるピクセルサイズを計算する関数を実装する。
同じタイル内でも緯度によって結果が異なるため、与えられたタイル座標について北西 / 南東 / 中心の緯度経度を計算し、それぞれについて計算する。

// Calculate pixel size [m] of given tile
function pixelSize(tileZ, tileX, tileY) {
  // North west / South east / Center
  const pNW =pixelOnTileToLatLon(0, 0, tileZ, tileX, tileY);
  const pSE = pixelOnTileToLatLon(255, 255, tileZ, tileX, tileY);
  const pCenter = pixelOnTileToLatLon(128, 128, tileZ, tileX, tileY);

  const deg2rad = deg => deg / 180 * Math.PI;

  return {
    min: resolution(deg2rad(pNW.lat), tileZ),
    max: resolution(deg2rad(pSE.lat), tileZ),
    center: resolution(deg2rad(pCenter.lat), tileZ)
  };
}

4. 例

例えばタイル座標 13/7262/3232 (鍋割山付近)についてpixelSize(13, 7262, 3232)を計算すると、1ピクセルあたり15.56 - 15.57 [m] であることが分かる。

{min: 15.564756939473298, max: 15.57165416877383, center: 15.568219450043276}

以上

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?