LoginSignup
1
0

More than 3 years have passed since last update.

緯度経度→地理インデックスの計算コード

Posted at

背景

前回考えたZ階数曲線をベースにした地理インデックスの計算をUnityで使えるようにC#で書いてみる。
若干冗長なキャストがありそうだけど、以下コード。
bit_tableが1ビット置きに歯抜け配置に変換するためのテーブル。8ビット分をすべて用意して、4回に分けて32ビット分を処理している。
もし、簡単なビット演算だけでやる方法があったら教えてほしいです。

GeoIndexCalc.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GeoIndexCalc
{
    private static ushort[] bit_table = new ushort[]
    {
        0,1,4,5,16,17,20,21,
        64,65,68,69,80,81,84,85,
        256,257,260,261,272,273,276,277,
        320,321,324,325,336,337,340,341,
        1024,1025,1028,1029,1040,1041,1044,1045,
        1088,1089,1092,1093,1104,1105,1108,1109,
        1280,1281,1284,1285,1296,1297,1300,1301,
        1344,1345,1348,1349,1360,1361,1364,1365,
        4096,4097,4100,4101,4112,4113,4116,4117,
        4160,4161,4164,4165,4176,4177,4180,4181,
        4352,4353,4356,4357,4368,4369,4372,4373,
        4416,4417,4420,4421,4432,4433,4436,4437,
        5120,5121,5124,5125,5136,5137,5140,5141,
        5184,5185,5188,5189,5200,5201,5204,5205,
        5376,5377,5380,5381,5392,5393,5396,5397,
        5440,5441,5444,5445,5456,5457,5460,5461,
        16384,16385,16388,16389,16400,16401,16404,16405,
        16448,16449,16452,16453,16464,16465,16468,16469,
        16640,16641,16644,16645,16656,16657,16660,16661,
        16704,16705,16708,16709,16720,16721,16724,16725,
        17408,17409,17412,17413,17424,17425,17428,17429,
        17472,17473,17476,17477,17488,17489,17492,17493,
        17664,17665,17668,17669,17680,17681,17684,17685,
        17728,17729,17732,17733,17744,17745,17748,17749,
        20480,20481,20484,20485,20496,20497,20500,20501,
        20544,20545,20548,20549,20560,20561,20564,20565,
        20736,20737,20740,20741,20752,20753,20756,20757,
        20800,20801,20804,20805,20816,20817,20820,20821,
        21504,21505,21508,21509,21520,21521,21524,21525,
        21568,21569,21572,21573,21584,21585,21588,21589,
        21760,21761,21764,21765,21776,21777,21780,21781,
        21824,21825,21828,21829,21840,21841,21844,21845
    };

    public static ulong calcIndex(double lat, double lon)
    {
        uint _lat = (uint)((lat + 90.0) * (double)UInt32.MaxValue / 180.0);
        uint _lon = (uint)((lon + 180.0) * (double)UInt32.MaxValue / 360.0);

        ulong index = 0;

        byte x_byte0 = (byte)(_lon & 0xFF);
        byte x_byte1 = (byte)((_lon >> 8) & 0xFF);
        byte x_byte2 = (byte)((_lon >> 16) & 0xFF);
        byte x_byte3 = (byte)((_lon >> 24) & 0xFF);
        index |= (ulong)bit_table[x_byte3] << 49;
        index |= (ulong)bit_table[x_byte2] << 33;
        index |= (ulong)bit_table[x_byte1] << 17;
        index |= (ulong)bit_table[x_byte0] << 1;
        byte y_byte0 = (byte)(_lat & 0xFF);
        byte y_byte1 = (byte)((_lat >> 8) & 0xFF);
        byte y_byte2 = (byte)((_lat >> 16) & 0xFF);
        byte y_byte3 = (byte)((_lat >> 24) & 0xFF);
        index |= (ulong)bit_table[y_byte3] << 48;
        index |= (ulong)bit_table[y_byte2] << 32;
        index |= (ulong)bit_table[y_byte1] << 16;
        index |= (ulong)bit_table[y_byte0];
        return index;
    }
}
1
0
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
0