geohash php_空间索引-geohash算法实现

算法简介

geohash是实现空间索引的一种算法,其他实现空间索引的算法有:R树和其变种GIST树、四叉树、网格索引等

算法基本原理

geohash算法将地球理解为一个二维平面,将平面递归分解成更小的子块,每个子块在一定经纬度范围内拥有相同的编码,这种方式简单粗暴,可以满足对小规模的数据进行经纬度的检索

通过对经纬度的分割,将地球分割成无数的小正方形,每个区域,就是个geohash编码

Geohash其实就是将整个地图或者某个分割所得的区域进行一次划分,由于采用的是base32编码方式,即Geohash中的每一个字母或者数字(如wx4g0e中的w)都是由5bits组成(2^5 = 32,base32),这5bits可以有32中不同的组合(0~31),这样我们可以将整个地图区域分为32个区域,通过00000 ~ 11111来标识这32个区域。第一次对地图划分后的情况如下图所示(每个区域中的编号对应于该区域所对应的编码):

如图:

25ca73eceee2620181da9494e7777e4c.png

算法实现(php)以经纬度值:(118.6197800000,24.88849)进行算法说明,对纬度24.88849进行逼近编码 (地球纬度区间是[-90,90])

纬度区间[-90,90]进行二分为[-90,0],[0,90],命名为左右区间,坐标属于右区间记为1,左区间为0,24.88849为右区间,记为1

对所在区间进行再次划分[0,90]二分为[0,45],[45,90],24.88849属于左区间,左区间记为0

以下是php的纬度区间算法函数:

/**

* @param float $num经度或纬度

* @param string $str递归字符串

* @param int $i 递归次数

* @param int $max_separate_num递归总次数

* @param array $data 区间值

* @return string

*/

function separate( $num = 24.999,$str='',$i=1,$max_separate_num=20,$data = array('min' => -90, 'max' => 90))

{

$count   = ($data['max'] - $data['min']) / 2;

$limit_0 = array(

'min' => $data['min'],

'max' => $data['min'] + $count

);

$limit_1 = array(

'min' => $data['min'] + $count,

'max' => $data['max']

);

//    var_dump($limit_0,$limit_1);

$str.=$num > $limit_1['min']?1:0;

if($i>=$max_separate_num){

return $str;

}else{

return separate($num,$str,$i+1,$max_separate_num,$num > $limit_1['min']?$limit_1:$limit_0);

}

}

由此,纬度24.88849可得字符串为10100011011001011001

经度118.6197800000,经度分为东经和西经,区间为[-180,180],由此可得字符串11010100010110100001

组合2个字符串,偶数放经度位,奇数放纬度位,php代码实现

/**

* @param $latitude_str 纬度

* @param $longitude_str 经度

*/

function combination($latitude_str, $longitude_str)

{

$str = '';

for ($i = 0; $i =经度

$str .= $longitude_str{$i};

if(isset($latitude_str{$i})){

$str .=  $latitude_str{$i};

}

}

return $str;

}

每隔5位取出一串,转为10进制,最后使用[0-9][b-z]去掉a, i, l, o这32个字符进行编码.php代码实现

function geohash_encode($str)

{

$arr     = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];

$str_arr = str_split($str, 5);//按5位分割字符串

$str     = '';

//    var_dump($str_arr);die;

foreach ($str_arr as $va) {

$decimal = bindec($va);

$str.=$arr[$decimal];

}

return $str;

}

这样,就得到了一串'wskme6b3'字符串了,该字符串就表示了一个区域

geohash算法使用:

根据附录精度,传入经纬度生成geohash编码,存入数据库,例如:

7a14bf37acc5a9cc794ce6a7c930432a.png

当需要查询附近某个区域块点时,只需要,就可以查出该区域块所有数据select * from dm_gps where geohash like "wskme%" (记得加索引)

用法补充:

当碰到需要渲染一整个地图,而数据量大的时候怎么办?总不可能把几千万的点全部查出来渲染吧?

可以新增一个大区域块统计表,将精度更小的数据进行分组并且统计总数,例如:

0b008f1bb53bf942fe3c59142c4243d0.png

gps_id无用字段,请忽略

查出精度为2的数据:

f745de1abfcaa3f669d0a5a6ed2b486c.png

当地图放大时:可相应的查出:level=3,level=4.....等等数据

精度bug

一:如图:

433e806dfa160e64649448b8c02e8864.png

当查询红点所在区域时,数据库只能查询到该区域块右下角的点,而找不到离他更近的上面的绿点

该bug可通过查询周围8个区域块进行再次比对,或者增加精度到厘米级别,就可忽略该bug

附录:geohash精度

b243c35b7641768c76a1cc548db8653b.png

php扩展

php已经实现了对geohash的扩展,

其他补充

等有时间,将会把geohash解码算法发出来

本文为仙士可原创文章,转载无需和我联系,但请注明来自仙士可博客www.php20.cn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/399111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ActiveReports 报表控件V12新特性 -- 新增JSON和CSV导出

ActiveReports 报表控件V12新特性 -- 新增JSON和CSV导出 ActiveReports 是一款专注于 .NET 平台的报表控件,全面满足 HTML5 / WinForms / ASP.NET / ASP.NET MVC / WPF 等平台下报表设计和开发工作需求,作为专业的报表工具为全球超过 300,000 开发人员提…

php imap配置,怎么为PHP编译imap扩展?

为PHP编译imap扩展的方法:首先安装“imap-open2007e”;然后下载源代码;接着准备好系统的“imap-open”环境;最后进入“./ext/extension/imap/”文件夹下执行“make”命令即可。怎么为PHP编译imap扩展?最近为项目增加了…

vmware安装minimal centos报错/etc/rc5.d/s99local : line

2019独角兽企业重金招聘Python工程师标准>>> 有人用vmware安装minimal centos报错/etc/rc5.d/s99local : line:25 : eject : command not found 。我们看下完整报错内容: Installing VMware Tools, please wait...mount: special device /dev/hda does n…

后缀树(Suffix Trie)子串匹配结构

Suffix Trie 又称后缀Trie或后缀树。它与Trie树的最大不同在于,后缀Trie的字符串集合是由指定字符串的后缀子串构成的。比如、完整字符串"minimize"的后缀子串组成的集合S分…

java中的线程和进程,Java | 线程和进程,创建线程

一、线程与进程线程定义进程中执行的一个代码段,来完成不同的任务组成:线程ID,当前指令指针(PC),寄存器集合(存储一部分正在执行线程的处理器状态的值)和堆栈进程定义执行的一段程序,一旦程序被载入到内存中准备执行就…

Maven的pom报错的解决方法

如果在MyEclipse里面导入项目,导入不了,如下图 接下来可以点击Import Maven Projects里的Action那一行Resolve Later. 点击Do Not Execute(add to pom)就可以正常导入了转载于:https://www.cnblogs.com/JimmySeraph/p/8068299.html

django零开始

2019独角兽企业重金招聘Python工程师标准>>> 安装。。。后查看 import django django.VERSION #输出版本号,目前自己是py2.7.9和django1.8 1,新建一个django-project django-admin.py startproject project-name 一个project一般为一个项目 …

关于Python3.6下登陆接口的尝试

编者按:README:此代码为用户登陆界面,添加了寻求帮助选项。1.学习了基本数据类型,string, int,以及while循环,continue, break, if, elif, else条件语句,“x".format(x)变量替代…

php 命令安装tp5,tp5.1框架的下载与安装方法步骤(图文)

大家可以都知道啊,tp框架5.1之前的版本都是可以在thinkphp的官网进行下载压缩包来安装框架的,那么在从tp5.1开始啊,就取消了下载压缩包安装的方法,那么我们如何进行下载呢?tp5.1的手册中开始就有提到tp5.1框架有两种安…

[连载]《C#通讯(串口和网络)框架的设计与实现》- 13.中英文版本切换设计

目 录 第十三章 中英文版本切换设计... 2 13.1 不用自带的资源文件的理由... 2 13.2 配置文件... 2 13.3 语言管理类... 3 13.4 应用管理类... 12 13.5 小结... 12 第十三章 中英文版本切换设计 13.1 不用自带的资源文件…

Mybaitis JdbcType 和javaType

2019独角兽企业重金招聘Python工程师标准>>> MyBatis 通过包含的jdbcType类型 BIT FLOAT CHAR TIMESTAMP OTHER UNDEFINEDTINYINT REAL VARCHAR BINARY BLOB NVARCHARSMALLINT DOUBLE …

php数据趋势曲线,数据曲线图怎么做

数据曲线图怎么做?1、在电脑桌面上,新建一个excel文件(操作过程即为点击右键,在选项中选择“新建”选项,然后再选择“excel文件”,即可成功新建excel文件了)2、双击将新建的excel文件打开,输入你需要统计制…

ceph 分布式存储安装

[rootlocalhost ~]# rm -rf /etc/yum.repos.d/*.repo 下载阿里云的base源 [rootlocalhost ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo [rootlocalhost ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/r…

STM32学习之路-SysTick的应用(时间延迟)

开发板:奋斗V5 好~ 菜B要来搞实验了.. 前面已经说了SysTick的工作原理什么的了,这里就不说了.. 先来做第一个实验: 盗自奋斗的样例,嘿嘿, 用SysTick产生1ms的基准时间,产生中断,每秒闪烁一次(LED1 V6) (1)外围时钟初始化&#xf…

凡事预则立(Beta)

听说——凡事预则立 吸取之前alpha冲刺的经验教训,也为了这次的beta冲刺可以更好更顺利地进行,更是为了迎接我们的新成员玮诗。我们开了一次组内会议,进行beta冲刺的规划。 上一张我们的合照: 具体会议议程如下: 1、讨…

用Vue.js开发一个电影App的前端界面

我们要构建一个什么样的App? 我们大多数人使用在线流媒体服务(如Netflix)观看我们最喜欢的电影或者节目。这篇文章将重点介绍如何通过使用vue.js 2 建立一个类似风格的电影流媒体WEB交互界面(见上图)。 最终的产品可以…

eclipse 函数折叠展开

为什么80%的码农都做不了架构师?>>> 一、eclipse 代码块折叠显示 核查是否开启折叠功能全局folding(window->preference->Gerneral->Editor-Structured Text)右侧Appearance 勾选Enable folding检测对应源编辑(java/javaScript&…

mysql 引擎 校对,MySQL 字符集和校对

字符集是指一种从二进制编码到某类字符符号的映射,校对是一组用于某个字符集的排序规则。每一类编码字符都有其对应的字符集和校对规则MySQL 如何使用字符集每种字符集都可能有多种校对规则,并且都有一个默认的校对规则。每个校对规则都是针对某个特定的…

【研究】Metasploit自动攻击模块

环境:kali-linux-2017.3-vm-amd64 一、安装postgresql数据库 apt-get install postgresql apt-get install rubygems libpq-dev apt-get install libreadline-dev apt-get install libssl-dev apt-get install libpq5 apt-get install ruby-dev apt-get install lib…

让nginx支持thinkphp rewrite模式

为什么80%的码农都做不了架构师?>>> Nginx环境在Nginx低版本中,是不支持PATHINFO的,但是可以通过在Nginx.conf中配置转发规则实现:在nginx配置文件中添加 location / { if (!-e $request_filename) { rewrite ^(…