• Geohash


        举个例子来说明下Geohash的作用。

        我们需要搜索当前200米范围内的所有餐馆啊什么的。那么我们怎么去定位所有餐馆的位置呢?

        最普通的方法就是,算出当前位置能找到的餐馆的距离,然后在筛选出 ≤ 200 的餐馆。这样也是可以的,但是问题在于

    一个城市有茫茫多的餐馆,每次定位都需要计算一次然后筛选。这个开销太大了。简直可以说是爆炸。然后就可以想想别的

    方法了。按照正常的想法,我站在某个位置,那么最好的定位方法当然是以我为中心向外辐射200米。然后在这个区域内的

    所有餐馆都是我想要的。这样的话,计算量就会小很多了。

        于是呢,出现了Geohash这个东东。下面是Geohash的原理。

        Geohash 原理:

        Geohash主要是把二维的地址坐标(经纬度)转换成一个一维的字符串标识。然后用这个标识来标注这个区域。具体的

    编解码方法如下:

        经度的范围是 [-90, 90], 那么先划分成 [-90, 0), [0, 90]。 我们将这个划分为左右区域。当得到的经度在左区域的

    时侯标注0, 在右区域的时候标注为1. 假定我们现在的坐标为 39.928167, 那么得到第一个标志位是1.

        然后在从[0, 90]进行二次划分,[0, 45), [45, 90]. 这时候 39.928167在左区域, 得到标志位是0,一次类推,我们

    可以得到一窜1011100011(具体精确到多少个01 需要根据客户需求来定。)

        纬度的编码方式和经度的编码方式是一样的,只是范围是[-180, 180]。然后对116.389550进行编码,就会得到10

    111 00011。

        然后根据偶数位放度,奇数位放度进行交替编码。

        我们得到的经度编码是: 11010 01011

        我们得到的纬度编码是: 10111 00011

        所以Geohash编码是: 11100 11101 00100 01111

            注: Geohash 编码的字符串是从0开始算起的,所以第一位是经度,然后纬度,然后经度。。。

        得到Geohash编码之后,五位五位的开始编码,所以是 28、29、4、15

       

        所以得到是Geohash 是 wx4g.

        下面是一些参考网站:

        https://en.wikipedia.org/wiki/Geohash

        http://www.cnblogs.com/LBSer/p/3310455.html

        http://www.cnblogs.com/dengxinglin/archive/2012/12/14/2817761.html

        下面是C++ 代码实现:

       

     1 string encodeGeohash(const double & theLat, const double & theLong, int thePrecision)
     2 {
     3     string aStrGeohash = "";
     4     double aLatStart = -90.000000;
     5     double aLatEnd = 90.000000;
     6     double aLongStart = -180.000000;
     7     double aLongEnd = 180.000000;
     8     double aLatMidPoint = (aLatStart + aLatEnd) / 2;
     9     double aLongMidPoint = (aLongStart + aLongEnd) / 2;
    10     int aBit = 0;
    11     int aCh = 0;
    12     char aBits[] = {16, 8, 4, 2, 1};
    13     const string BASEENCODE = "0123456789bcdefghjkmnpqrstuvwxyz";
    14 
    15     if(theLat < aLatStart || theLat > aLatEnd || theLong < aLongStart || theLong > aLongEnd)
    16     {
    17         return aStrGeohash;
    18     }
    19     //The Geohash first bit is longtitude
    20     for(int i = 0; i < thePrecision; i++)
    21     {
    22         if(0 == i % 2)
    23         {
    24             if(theLong >= aLongMidPoint)
    25             {
    26                 aCh |= aBits[aBit];
    27                 aLongStart = aLongMidPoint;
    28             }
    29             else
    30             {
    31                 aLongEnd = aLongMidPoint;
    32             }
    33             aLongMidPoint = (aLongStart + aLongEnd) / 2;
    34         }
    35         else
    36         {
    37             if(theLat >= aLatMidPoint)
    38             {
    39                 aCh |= aBits[aBit];
    40                 aLatStart = aLatMidPoint;
    41             }
    42             else
    43             {
    44                 aLatEnd = aLatMidPoint;
    45             }
    46             aLatMidPoint = (aLatStart + aLatEnd) / 2;
    47         }
    48 
    49         if(aBit < 4)
    50         {
    51             aBit++;
    52         }
    53         else
    54         {
    55             aStrGeohash += BASEENCODE[aCh];
    56             aCh = 0;
    57             aBit = 0;
    58         }
    59     }
    60 
    61     return aStrGeohash;
    62 }

       

       

  • 相关阅读:
    20182311 2019-2020-1 《数据结构与面向对象程序设计》实验一报告
    20182311 2019-2020-1 《数据结构与面向对象程序设计》第1周学习总结
    20182320 2019-2020-1 《数据结构与面向对象程序设计》第2-3周学习总结
    20182320 2019-2020-1 《数据结构与面向对象程序设计》实验1报告
    预备作业
    mysql-sysbench编译安装过程问题
    mysql报错-ERROR 2002
    oracle中的root权限问题
    linux物理内存和虚拟内存
    shell-linux普通用户自动登录root脚本
  • 原文地址:https://www.cnblogs.com/AndyStudy/p/6398747.html
Copyright © 2020-2023  润新知