最近研究了一下GEOHASH,的确比较好用。具体的原理,就不多说了,网上资料很多。不过大多数都是java或者PHP实现的。下面提供一个mysql的function实现。有兴趣的朋友可以用用。

使用效果:

encode

decode

function源码:

CREATE DEFINER=`root`@`%` FUNCTION `geohash_base32`(_index TINYINT UNSIGNED) RETURNS char(1) CHARSET latin1NO SQLDETERMINISTICCOMMENT 'geohash_base32(0) => "0", geohash_base32(31) => "z"'
BEGINDECLARE ch CHAR(1) DEFAULT NULL;CASE _indexWHEN 0 THEN SET ch = '0';WHEN 1 THEN SET ch = '1';WHEN 2 THEN SET ch = '2';WHEN 3 THEN SET ch = '3';WHEN 4 THEN SET ch = '4';WHEN 5 THEN SET ch = '5';WHEN 6 THEN SET ch = '6';WHEN 7 THEN SET ch = '7';WHEN 8 THEN SET ch = '8';WHEN 9 THEN SET ch = '9';WHEN 10 THEN SET ch = 'b';WHEN 11 THEN SET ch = 'c';WHEN 12 THEN SET ch = 'd';WHEN 13 THEN SET ch = 'e';WHEN 14 THEN SET ch = 'f';WHEN 15 THEN SET ch = 'g';WHEN 16 THEN SET ch = 'h';WHEN 17 THEN SET ch = 'j';WHEN 18 THEN SET ch = 'k';WHEN 19 THEN SET ch = 'm';WHEN 20 THEN SET ch = 'n';WHEN 21 THEN SET ch = 'p';WHEN 22 THEN SET ch = 'q';WHEN 23 THEN SET ch = 'r';WHEN 24 THEN SET ch = 's';WHEN 25 THEN SET ch = 't';WHEN 26 THEN SET ch = 'u';WHEN 27 THEN SET ch = 'v';WHEN 28 THEN SET ch = 'w';WHEN 29 THEN SET ch = 'x';WHEN 30 THEN SET ch = 'y';WHEN 31 THEN SET ch = 'z';END CASE;RETURN ch;ENDCREATE DEFINER=`root`@`%` FUNCTION `geohash_base32_index`(_ch CHAR(1)) RETURNS tinyint(3) unsignedNO SQLDETERMINISTICCOMMENT 'geohash_base32_index("b") => 10, geohash_base32_index("z") => 31'
BEGINDECLARE idx TINYINT UNSIGNED DEFAULT NULL;CASE _chWHEN '0' THEN SET idx = 0;WHEN '1' THEN SET idx = 1;WHEN '2' THEN SET idx = 2;WHEN '3' THEN SET idx = 3;WHEN '4' THEN SET idx = 4;WHEN '5' THEN SET idx = 5;WHEN '6' THEN SET idx = 6;WHEN '7' THEN SET idx = 7;WHEN '8' THEN SET idx = 8;WHEN '9' THEN SET idx = 9;WHEN 'b' THEN SET idx = 10;WHEN 'c' THEN SET idx = 11;WHEN 'd' THEN SET idx = 12;WHEN 'e' THEN SET idx = 13;WHEN 'f' THEN SET idx = 14;WHEN 'g' THEN SET idx = 15;WHEN 'h' THEN SET idx = 16;WHEN 'j' THEN SET idx = 17;WHEN 'k' THEN SET idx = 18;WHEN 'm' THEN SET idx = 19;WHEN 'n' THEN SET idx = 20;WHEN 'p' THEN SET idx = 21;WHEN 'q' THEN SET idx = 22;WHEN 'r' THEN SET idx = 23;WHEN 's' THEN SET idx = 24;WHEN 't' THEN SET idx = 25;WHEN 'u' THEN SET idx = 26;WHEN 'v' THEN SET idx = 27;WHEN 'w' THEN SET idx = 28;WHEN 'x' THEN SET idx = 29;WHEN 'y' THEN SET idx = 30;WHEN 'z' THEN SET idx = 31;END CASE;RETURN idx;ENDCREATE DEFINER=`root`@`%` FUNCTION `geohash_bit`(_bit TINYINT UNSIGNED) RETURNS tinyint(3) unsignedNO SQLDETERMINISTICCOMMENT 'geohash_bit(0) => 16, geohash_bit(1) => 8'
BEGINDECLARE bit TINYINT UNSIGNED DEFAULT NULL;CASE _bitWHEN 0 THEN SET bit = 16;WHEN 1 THEN SET bit = 8;WHEN 2 THEN SET bit = 4;WHEN 3 THEN SET bit = 2;WHEN 4 THEN SET bit = 1;END CASE;RETURN bit;ENDCREATE DEFINER=`root`@`%` FUNCTION `geohash_decode`(_geohash varchar(12)) RETURNS char(77) CHARSET latin1COMMENT 'geohash_decode(u4pru) => csv'
BEGINDECLARE latL DOUBLE(10, 7) DEFAULT -90.0;DECLARE latR DOUBLE(10, 7) DEFAULT 90.0;DECLARE lonT DOUBLE(10, 7) DEFAULT -180.0;DECLARE lonB DOUBLE(10, 7) DEFAULT 180.0;DECLARE lat_err DOUBLE(10, 7) DEFAULT 90.0;DECLARE lon_err DOUBLE(10, 7) DEFAULT 180.0;DECLARE ch CHAR(1) DEFAULT '';DECLARE ch_pos INT UNSIGNED DEFAULT 0;DECLARE even TINYINT UNSIGNED DEFAULT 1;DECLARE geohash_length TINYINT UNSIGNED DEFAULT 0;DECLARE geohash_pos TINYINT UNSIGNED DEFAULT 0;DECLARE pos TINYINT UNSIGNED DEFAULT 0;DECLARE mask TINYINT UNSIGNED DEFAULT 0;DECLARE masked_val TINYINT UNSIGNED DEFAULT 0;DECLARE buf VARCHAR(77) DEFAULT '';SET geohash_length = LENGTH(_geohash);WHILE geohash_pos < geohash_lengthDOSET ch=substr(_geohash,geohash_pos+1,1);SET ch_pos = geohash_base32_index(ch);SET pos = 0;WHILE pos < 5DOSET mask = geohash_bit(pos);SET masked_val = ch_pos & mask;IF even = 1 THENSET lon_err = lon_err / 2;IF masked_val != 0 THENSET lonT = (lonT + lonB) / 2;ELSESET lonB = (lonT + lonB) / 2;END IF;ELSESET lat_err = lat_err / 2;IF masked_val != 0 THENSET latL = (latL + latR) / 2;ELSESET latR = (latL + latR) / 2;END IF;END IF;SET even = !even;SET pos = pos + 1;END WHILE;SET geohash_pos = geohash_pos + 1;END WHILE;SET lat_err = (latL + latR) / 2;SET lon_err = (lonT + lonB) / 2;SET buf = CONCAT(buf, latL, ',', lonT);SET buf = CONCAT(buf, ';');SET buf = CONCAT(buf, latR, ',', lonB);SET buf = CONCAT(buf, ';');SET buf = CONCAT(buf, lat_err, ',', lon_err);RETURN buf;ENDCREATE DEFINER=`root`@`%` FUNCTION `geohash_encode`(_latitude DOUBLE(10, 7),_longitude DOUBLE(10, 7),_precision TINYINT UNSIGNED) RETURNS varchar(12) CHARSET latin1NO SQLDETERMINISTICCOMMENT 'geohash_encode(57.64911, 10.40744, 12) => u4pruydqquvx'
BEGINDECLARE latL DOUBLE(10, 7) DEFAULT -90.0;DECLARE latR DOUBLE(10, 7) DEFAULT 90.0;DECLARE lonT DOUBLE(10, 7) DEFAULT -180.0;DECLARE lonB DOUBLE(10, 7) DEFAULT 180.0;DECLARE bit TINYINT UNSIGNED DEFAULT 0;DECLARE bit_pos TINYINT UNSIGNED DEFAULT 0;DECLARE ch CHAR(1) DEFAULT '';DECLARE ch_pos INT UNSIGNED DEFAULT 0;DECLARE mid DOUBLE(10, 7) DEFAULT NULL;DECLARE even TINYINT UNSIGNED DEFAULT 1;DECLARE geohash VARCHAR(12) DEFAULT '';DECLARE geohash_length TINYINT UNSIGNED DEFAULT 0;IF _precision IS NULL THENSET _precision = 12;END IF;WHILE geohash_length < _precision DOIF even = 1 THEN---- is even--SET mid = (lonT + lonB) / 2;IF mid < _longitude THENSET bit = geohash_bit(bit_pos);SET ch_pos = ch_pos | bit;SET lonT = mid;ELSESET lonB = mid;END IF;ELSE---- not even--SET mid = (latL + latR) / 2;IF mid < _latitude THENSET bit = geohash_bit(bit_pos);SET ch_pos = ch_pos | bit;SET latL = mid;ELSESET latR = mid;END IF;END IF;-- toggle evenSET even = !even;IF bit_pos < 4 THENSET bit_pos = bit_pos + 1;ELSESET ch = geohash_base32(ch_pos);SET geohash = CONCAT(geohash, ch);SET bit_pos = 0;SET ch_pos = 0;END IF;SET geohash_length = LENGTH(geohash);END WHILE;RETURN geohash;END

该mysql存过,修改自GIthub开源项目。

Mysql GEOHASH function 实现相关推荐

  1. mysql开启function,Mysql自定義函數(function)

    語法 自定義函數也需要相應的要求,語法如下: CREATE FUNCTION(參數列表) RETURNS返回值類型 函數體 刪除: DROPFUNCTION 調用自定義函數語法: SELECT (pa ...

  2. MySQL This function has none of DETERMINISTIC, NO SQL...错误1418 的原因分析及解决方法

    原因分析: 因为CREATE PROCEDURE, CREATE FUNCTION, ALTER PROCEDURE,ALTER FUNCTION,CALL, DROP PROCEDURE, DROP ...

  3. mysql geohash函数_基于MySQL实现按距离排序、范围查找geoHash

    简介 现在几乎所有的O2O应用中都会存在"按范围搜素.离我最近.显示距离"等等类似的功能,那这样的功能是怎么实现的呢?本文提供了基于MySQL的实现方式,同样适用于其它数据库.本文 ...

  4. MySQL Window Function Descriptions

    聚合函数是将多条记录聚合为一条,而窗口函数是每条记录都会执行 win_fn()over (partition by order by frame) as new_row, partition:分区,窗 ...

  5. MySQl Window Function Concepts

    create table test(user_id int1,user_class int1,user_amount int1 );insert into test values (1,1,10); ...

  6. mysql创建function 报错误1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in

    解决方法: 执行这条sql就可以了: set global log_bin_trust_function_creators=1; 运行结果: 函数创建成功了

  7. mysql function 与 procedure

    Mysql 的 function 和 procedure 有啥区别呢 ? 网上搜索后说 function 有返回值, procedure 无返回值. 1.return  从function 的语法角度 ...

  8. MySQL自定义函数(CREATE FUNCTION)

    在使用 MySQL 的过程中,MySQL 自带的函数可能完成不了我们的业务需求,这时候就需要自定义函数. 自定义函数是一种与存储过程十分相似的过程式数据库对象.它与存储过程一样,都是由 SQL 语句和 ...

  9. 数据库系列之mysql 自定义函数function,函数和存储过程的区别

    mysql 自定义函数function,函数和存储过程的区别 https://blog.csdn.net/u010365819/article/details/80470448 https://blo ...

最新文章

  1. R语言使用ggplot2包使用geom_violin函数绘制分组小提琴图(构建自定义函数配置显示均值、标准偏差)实战
  2. 字符串-字符串的查找和替换
  3. LeetCode 1030. 距离顺序排列矩阵单元格(排序Lambda表达式BFS)
  4. 计算机网络——OSI参考模型和TCP/IP协议
  5. 数学建模之微分方程(符实现例题和MATLAB源码)
  6. laravel 向模板中添加公共变量
  7. 手绘时钟的设计与实现
  8. Linux操作系统下进程讲解(史上最强总结)
  9. python3中find函数的用法_Python3正则匹配re.split,re.finditer及re.findall函数用法详解...
  10. 机器字长 存储字长 指令字长 机器字长
  11. IAR环境配置教程(CC2530版)
  12. ABAP ALV DEMO示例源码
  13. (20)雅思屠鸭第二十天:雅思听力part1中各种场景词的总结
  14. 关于Palantir——第二部分:本体(Ontology)
  15. Win10系统电脑声卡驱动正常但没声音?驱动人生解决方案
  16. Python数据可视化之随机点图
  17. 芜湖市计算机语言,2012年芜湖市小学计算机水平等级测评试卷(logo语言版)
  18. Python学多久能接单赚钱?按照这套路线学习,30天内就可以!
  19. 怎么恢复回收站清空删除的文件
  20. SDCC教程(树莓派 Debian11 bullseye 使用官方下载源)

热门文章

  1. 前端必备工具大全------强推!!!
  2. [Jsoi2013]快乐的jyy
  3. linux ibm 多路径,IBM V7000多路径解决
  4. e-table 合并行 合并列
  5. CAD怎么在线转换图纸呢?
  6. Python 逻辑运算
  7. 豆瓣评分9分+,这6部经典趣味数学纪录片堪称神作!
  8. 产品研发过程常见问题3:跨部门协作困难
  9. linux系统我的世界开服,CentOS——Linux开服教程
  10. 惠普打印机无法联网;惠普打印机 HP web 服务打不开;惠普打印机连接Internet失败;eprint无法使用