erlang 实现geohash算法
来源:互联网 发布:淘宝充值话费待发货 编辑:程序博客网 时间:2024/05/18 19:21
需求:实现查找附近 200、 500、 1000米范围的好友
关于 geohash 介绍 http://blog.csdn.net/pi9nc/article/details/11401679
×× 这里忽略球面的误差,因为像千米之内的数据可以看作是二维平面
扩展:将经度线和纬度线切割
切割规则:按轮来解释吧
第一轮 (-180, 0) 0 (0, 180)1
第二轮 (-180, -90) 0 (-90, 0) 1 (0, 90) 0 (90, 180) 1
.......
规律:
每一轮切分得到的块数都是上一轮的两倍
上一轮的任何节点都切分到下一轮的两个节点
推论1:在某一轮,任何一个节点,从根节点到该节点的二进制编码都是唯一的
推论2:同一轮节点的编码,可以由相邻节点的二进制编码加或者减1得到
综上扩展思考得:方可把经度和纬度各自看做一颗满二叉树,每一轮进行组合,那么则可以把世界切分满二叉树的块,
假设一个玩家在一个块中,那么可以通过经度和纬度进行二进制的加减,再组合得到附近八个块的二进制编码,
所以每一个玩家附近的人所在的块都得到了独有二进制码
再度分析:如果把二进制码压缩成整数,那么由中心位置O(X, Y),由 O 中心,将X,Y 进行左右移动便可获取附近8个位置
代码:
-module(radar_misc).-author('lijunqiang@moyou.me').-define(ACCURACY_ONE, 0.00001). %% 纬度精确1米, 经度精确1.1米-define(ACCURACY_TEN, 0.0001). %% 纬度精确10米, 经度精确11米-define(ACCURACY_HUNDRED, 0.001). %% 纬度精确100米, 经度精确111米-define(ACCURACY_THOUSAND, 0.01). %% 纬度精确1000米, 经度精确1113米-define(ACCURACY_MILLION, 0.1). %% 纬度精确10000米, 经度精确11132米-define(ACCURACY_FIFTY, 0.0005). %% 纬度精确50米, 经度精确55米-define(ACCURACY_TWO_HUNDRED, 0.002). %% 纬度精确200米, 经度精确222米-define(ACCURACY_FIVE_HUNDRED, 0.005). %% 纬度精确500米, 经度精确556米%% 若添加精确度,务必由大到小顺序-define(ACCURACY_LIST, [ %?ACCURACY_MILLION, ?ACCURACY_THOUSAND, ?ACCURACY_FIVE_HUNDRED, ?ACCURACY_TWO_HUNDRED %?ACCURACY_TEN, %?ACCURACY_ONE ]).%% 距离200米范围-define(DISTANCE_TWO_HUNDRED, 200). %% 距离500米范围-define(DISTANCE_FIVE_HUNDRED, 500). %% 距离1000米范围-define(DISTANCE_THOUSAND, 1000). %% 纬度精确200米, 经度精确222米-define(TWO_HUNDRED_LAT_DIS, 200).-define(TWO_HUNDRED_LONG_DIS, 222).%% 纬度精确500米, 经度精确556米-define(FIVE_HUNDRED_LAT_DIS, 500).-define(FIVE_HUNDRED_LONG_DIS, 556).%% 纬度精确1000米, 经度精确1113米-define(THOUSAND_LAT_DIS, 1000).-define(THOUSAND_LONG_DIS, 1113).-export([ get_prep_group/1, count/4, reference_accuracy_msg/2 ]).%% 经度、 纬度longitude_coding(Longitude, AccuracyList) -> coding(Longitude, -180, 180, AccuracyList, 0, []).latitude_coding(Latitude, AccuracyList) -> coding(Latitude, -90, 90, AccuracyList, 0, []).coding(_, _, _, [], _, AccList) -> lists:reverse(AccList);coding(K, L, R, [H | T] = _AccuracyList, Data, AccList) when R - L < H -> coding(K, L, R, T, Data, [Data | AccList]);coding(K, L, R, AccuracyList, Data, AccList) -> M = (L + R) / 2, if K > M -> coding(K, M, R, AccuracyList, (Data bsl 1) + 1, AccList); true -> coding(K, L, M, AccuracyList, (Data bsl 1) + 0, AccList) end.traversal(A, [A|_], [H|_]) -> H;traversal(A, [_|S], [_|T]) -> traversal(A, S, T).%------------------------------------------------------------%% 获取 9 个坑 {经度整数, 纬度整数}get_prep_group({LongBit, LatBit}) -> tuple_to_list({{LongBit+1, LatBit+1}, {LongBit+1, LatBit}, {LongBit+1, LatBit-1}, {LongBit, LatBit+1}, {LongBit, LatBit-1}, {LongBit, LatBit}, {LongBit-1, LatBit+1}, {LongBit-1, LatBit-1}, {LongBit-1, LatBit}}).%% 计算距离:先转化单位, 全部转化为 单位 = 1米%% M是 1/精确度 1/0.001 = 1000%% Lo 经度精确度 单位100米%% La 纬度精确度 单位111米%% {OldX, OldY} = {经度, 纬度} 查询玩家地理位置%% {OldX1, OldY1} = {经度, 纬度} 被查询玩家地理位置count(M, {Lo, La}, {OldX, OldY}, {OldX1, OldY1}) -> X = OldX * M * Lo, Y = OldY * M * La, X1 = OldX1 * M * Lo, Y1 = OldY1 * M * La, (X1 - X) * (X1 - X) + (Y1 - Y) * (Y1 - Y).%% 经度、纬度、精确度 (88.0000, 88.88888)%% 返回值%% [各个精确度tuple {Long(int), Lat(int)}] 顺序和 ?ACCURACY_LIST一致reference_accuracy_msg(LongitudeNum, LatitudeNum) -> %% 将 float 数值转化为 BinaryList, 包含每个精确度的 BinaryList LongitudeList = longitude_coding(LongitudeNum, ?ACCURACY_LIST), LatitudeList = latitude_coding(LatitudeNum, ?ACCURACY_LIST), MsgList = lists:map(fun(Accuracy) -> %% %% 找出精确度为 Accuracy 的 BinaryList Longitude = traversal(Accuracy, ?ACCURACY_LIST, LongitudeList), Latitude = traversal(Accuracy, ?ACCURACY_LIST, LatitudeList), {Longitude, Latitude} end, ?ACCURACY_LIST), MsgList.
欢迎转载,尊重原创,谢谢。。
0 0
- erlang 实现geohash算法
- GeoHash算法的c实现
- geohash算法原理及实现方式 1、geohash特点
- geohash算法原理及实现方式
- geohash算法原理及实现方式
- geohash算法原理及实现方式
- geohash算法原理及实现方式
- geohash 算法原理及实现方式
- geohash算法原理及实现方式
- geohash算法原理及实现方式
- 查找附近网点geohash算法及实现
- geohash算法原理及实现方式
- geohash算法原理及实现方式
- geohash算法原理及实现方式
- geohash算法原理及实现方式
- geohash算法原理及实现方式
- geohash算法原理及实现方式
- geohash算法原理及实现方式
- Volly 框架简介
- 27. Remove Element Leetcode Python
- HttpServletRequestWrapper 用法
- Font Rendering: Gecko vs Chrome
- 冒泡排序
- erlang 实现geohash算法
- 安卓绑定本地服务和远程服务
- 关于monkey大致信息收集
- MFC 文档view视图中根据鼠标指定的某个区域控制延迟显示tip的方法(原创)
- WMS仓库管理系统---(4)分类管理模块
- 单链表的建立和增删改查代码及讲解
- 求该整数的二进制表达中有多少个1
- android编译笔记
- 贝叶斯==