地図タイル通し番号

256ピクセル地図タイルにおいてズームレベル0からタイルに通し番号をつける方法を教えていただいたのでメモ。

const t = ( 4 ** z - 1 ) / 3 + y * 2 ** z + x;
const z = Math.floor( Math.log( t * 3 + 1 ) / Math.log( 4 ) );
const w = t - ( 4 ** z - 1 ) / 3;
const x = w % 2 ** z;
const y = ( w - x ) / 2 ** z;

簡略化も可能とのこと。

const t2 = 4 ** z + y * 2 ** z + x;
const z = Math.floor( Math.log( t2 ) / Math.log( 4 ) );
const w = t2 - ( 4 ** z - 1 ) / 3;
const x = w % 2 ** z;
const y = ( w - x ) / 2 ** z;

前者の式を使ってもズームレベル16(ウェブメルカトル次数24)で32ビット(超える?)の演算になるのでTransform Feedbackは使えない点に注意が必要(後者の式では確実に32ビット超えで不可)。

JavaScriptは53ビット精度なので可。