GeoHash算法小记

昨天被问到一道题目,感觉挺有意思,这里记录一下:

题目:给定一个m*m的矩形区域,已知一点的(x,y)坐标,如何找到离周围xkm的所有店家?


这里需要用到一个叫做GeoHash的算法。

这个算法是什么作用呢?

GeoHash可以将地图网格化,然后把一个位置的坐标转换成一个可以排序的,可以比较的字符串编码,说到底就是将一个二维的数据映射成一个一维的数据。

核心代码:

public static String GeohashEncode(double latitude,double longitude,int precision=12){
        boolean  even=true;
        int bit=0;
        int ch=0;
        String geohash="";
        double[] lat={-90.0,90.0};
        double[] lon={-180.0,180.0};
        if(precision<1||precision>20)  precision=12;
        while(geohash.length()<precision){
            double mid;
            if(even){
                mid=(lon[0]+lon[1])/2;
                if(longitude>mid){
                    ch|=Bits[bit];
                    lon[0]=mid;

                }
                else{
                    lon[1]=mid;
                }
            }
            else{
                mid=(lon[0]+lon[1])/2;
                if(latitude>mid){
                    ch|=Bits[bit];
                    lat[0]=mid;
                }
                else{
                    lat[1]=mid;
                }
            }
            even=!even;
            if(bit<4) bit++;
            else{
                geohash+=Base32[ch];
                bit=0;
                ch=0;

            }
        }
        return geohash;
    }


结合上边的代码以及图示我们可以知道,算法的目的就是不断对(-90,90)和(-180,180)这两个区间进行划分,然后查看给定的坐标是不是在这个区间里边,如果在这个区间中,那么设置为1,如果不在这个区间中那么设置为0,直到划分的区间满足对应的精度结束循环,并且得到一串二进制数,然后再将这个二进制数变化成10进制的数,通过base32编码得到一串字符串。

base32编码表如下:

 

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

base32

0

1

2

3

4

5

6

7

8

9

b

c

d

e

f

g

十进制

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

base32

h

j

k

m

n

p

q

r

s

t

u

v

w

x

y

z

下面回到这个题目,题目要求我们找到所有距离坐标Xkm的商店,我们可以采取以下的方法:

以给定的点向外拓xkm,分别对周围8个坐标进行GeoHash(如下图),然后提取字符串的公共部分,最后查找周围点的GeoHash值以xx开头的就是满足题意的商家。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值