隣接したQuadKeyを求める

googleマップ、Bingマップなどで使用するクアッドキー
大変良く出来たキー体系で、設計者の頭の良さが想像できますね。

さて、ちょっと地図情報を扱う上で、並んだQuadKeyを求める必要がありましたので
プログラムを書いてみました。

今回はjavaですが、簡単なソースなので他の言語へも適用しやすいと思います。

/**
 * 指定されたキーの隣にあたるQuadKeyを求める
 * @param srcKey 元のQuadKey
 * @param direction 0:左 1:右 2:上 3:下
 * @return
 */
private static String calcNextQuadKey(String srcKey,int direction)
{
     int lv = srcKey.length();

     long latbits = 0;
     long lonbits = 0;
     char c;
     int val;
     int bit;

     for (int i = 0; i < lv; i++) {
          c = srcKey.charAt(i);
          val = c - '0';

          // valの2ビット目を縦位置を示すlatbitsに格納
          bit = val >> 1;
          latbits += (bit << (lv - i - 1));

          // valの1ビット目を横位置を示すlonbitsに格納
          bit = val & 1;
          lonbits += (bit << (lv - i - 1));
     }

     // 隣接したQuadKeyを求めるためlat、lonを変更
     switch (direction) {
     case 0:// 左
          lonbits -= 1;
          break;
     case 1:// 右
          lonbits += 1;
          break;
     case 2:// 上
          latbits -= 1;
          break;
     case 3:// 下
          latbits += 1;
          break;
     }

     // lv以上の精度に繰り上がった場合には最上位ビットをクリアする
     long floodmask = 1 << lv;
     if ((lonbits & floodmask) != 0) lonbits ^= floodmask;
     if ((latbits & floodmask) != 0) latbits ^= floodmask;

     // latbits、lonbitsからクアッドキーを求める
     StringBuilder sb = new StringBuilder(lv);
     long mask = 1 << (lv - 1);
     boolean lonbit, latbit;
     for (int i = 0; i < lv; i++) {

          lonbit = ((lonbits & mask) != 0);
          latbit = ((latbits & mask) != 0);

          if (latbit) {
               c = lonbit ? '3' : '2';
          } else {
               c = lonbit ? '1' : '0';
          }
          sb.append(c);

          mask >>>= 1;
     }
     return sb.toString();

}

以上.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です