Geohash——地理坐标索引

2023-10-23 16:50
文章标签 索引 地理坐标 geohash

本文主要是介绍Geohash——地理坐标索引,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天看july的博客:第三十六~三十七章、搜索智能提示suggestion,附近地点搜索

(http://blog.csdn.net/v_july_v/article/details/11288807)

里面提到了geohash算法对地理坐标的索引,但是引用的文章和例子让我产生了疑问,对于坐标的经纬度不应该是直接让纬度跟随在经度之后形成一个索引值的,这样只能保证经度相同的且靠近的点排列的比较近,而纬度相同经度只差1的点确不能排列的比较近。

于是查阅了geohash的维基百科说明:http://en.wikipedia.org/wiki/Geohash#Decode_from_base_32

文中举了个例子:

This operation results in the bits 01101 11111 11000 00100 00010. Assuming that counting starts at 0 in the left side, the even bits are taken for the longitude code (0111110000000), while the odd bits are taken for the latitude code (101111001001).

原来是经度和纬度相互交错形成的geohash值。这样就能比较好的让靠近的点按照geohash值也能排列的靠近一些。

写了一段程序来看看经纬度(x坐标和y坐标)互相交错形成的有序值对应的坐标是多少。

//vs2008#include "stdafx.h"
#include <atlstr.h>
#include <conio.h>void GetEvenAndOdd(int nNum, int &nEven, int &nOdd)
{int k = 1;nEven = nOdd = 0;for (int i = 0; i < 8; i++){if (0 != i%2){nEven += k*(nNum & 1);} else{nOdd += k*(nNum & 1);}if (0 != i%2) k *= 2;nNum = nNum >> 1;}
}CString GetBinaryString(int nNum, int nLen)
{CString csRet;for (int i = nLen; i > 0; i--){if ((nNum >> (i-1)) & 1)csRet += "1";elsecsRet += "0";}return csRet;
}int _tmain(int argc, _TCHAR* argv[])
{printf("十进制	geohash值	偶    奇    坐标值\n");for (int i = 0; i < 64; i++){int nEven, nOdd;GetEvenAndOdd(i, nEven, nOdd);CString strGeohash = GetBinaryString(i, 8);CString strEven    = GetBinaryString(nEven, 4);CString strOdd     = GetBinaryString(nOdd, 4);printf("%02d\t%S\t%S\t%S\t(%d,%d)\n", i, strGeohash.GetBuffer(), strEven.GetBuffer(), strOdd.GetBuffer(), nEven, nOdd);}_getch();return 0;
}

跑出来的坐标值如下:

十进制geohash值坐标值十进制geohash 值坐标值
000000000000000000(0,0)320010000001000000(4,0)
010000000100000001(0,1)330010000101000001(4,1)
020000001000010000(1,0)340010001001010000(5,0)
030000001100010001(1,1)350010001101010001(5,1)
040000010000000010(0,2)360010010001000010(4,2)
050000010100000011(0,3)370010010101000011(4,3)
060000011000010010(1,2)380010011001010010(5,2)
070000011100010011(1,3)390010011101010011(5,3)
080000100000100000(2,0)400010100001100000(6,0)
090000100100100001(2,1)410010100101100001(6,1)
100000101000110000(3,0)420010101001110000(7,0)
110000101100110001(3,1)430010101101110001(7,1)
120000110000100010(2,2)440010110001100010(6,2)
130000110100100011(2,3)450010110101100011(6,3)
140000111000110010(3,2)460010111001110010(7,2)
150000111100110011(3,3)470010111101110011(7,3)
160001000000000100(0,4)480011000001000100(4,4)
170001000100000101(0,5)490011000101000101(4,5)
180001001000010100(1,4)500011001001010100(5,4)
190001001100010101(1,5)510011001101010101(5,5)
200001010000000110(0,6)520011010001000110(4,6)
210001010100000111(0,7)530011010101000111(4,7)
220001011000010110(1,6)540011011001010110(5,6)
230001011100010111(1,7)550011011101010111(5,7)
240001100000100100(2,4)560011100001100100(6,4)
250001100100100101(2,5)570011100101100101(6,5)
260001101000110100(3,4)580011101001110100(7,4)
270001101100110101(3,5)590011101101110101(7,5)
280001110000100110(2,6)600011110001100110(6,6)
290001110100100111(2,7)610011110101100111(6,7)
300001111000110110(3,6)620011111001110110(7,6)
310001111100110111(3,7)630011111101110111(7,7)

将坐标点依次在坐标系上连起来如下图:


可以看出来,geohash和 july文中讲述的R数方法有图形上的分区域相似之处,这种编码方式在区块内尽可能的让邻近点的索引值靠近,但在区块与区块之间还是存在跳跃的地方。所以只简单使用这一种编码技术并不能完全解决邻近点搜索的问题。

要想完美解决问题,还需要考虑的更多一些。

这些问题留待以后继续研究。先写这么多吧。

update:

早上起来搜索了下别人的文章,看到了下面的话:

geohash的最大用途就是附近地址搜索了。不过,从geohash的编码算法中可以看出它的一个缺点:位于格子边界两侧的两点, 虽然十分接近,但编码会完全不同。实际应用中,可以同时搜索当前格子周围的8个格子,即可解决这个问题。

(from: http://tech.idv2.com/2011/07/05/geohash-intro/)




这篇关于Geohash——地理坐标索引的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/269160

相关文章

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

MySQL中的索引结构和分类实战案例详解

《MySQL中的索引结构和分类实战案例详解》本文详解MySQL索引结构与分类,涵盖B树、B+树、哈希及全文索引,分析其原理与优劣势,并结合实战案例探讨创建、管理及优化技巧,助力提升查询性能,感兴趣的朋... 目录一、索引概述1.1 索引的定义与作用1.2 索引的基本原理二、索引结构详解2.1 B树索引2.2

python3如何找到字典的下标index、获取list中指定元素的位置索引

《python3如何找到字典的下标index、获取list中指定元素的位置索引》:本文主要介绍python3如何找到字典的下标index、获取list中指定元素的位置索引问题,具有很好的参考价值,... 目录enumerate()找到字典的下标 index获取list中指定元素的位置索引总结enumerat

从入门到精通MySQL 数据库索引(实战案例)

《从入门到精通MySQL数据库索引(实战案例)》索引是数据库的目录,提升查询速度,主要类型包括BTree、Hash、全文、空间索引,需根据场景选择,建议用于高频查询、关联字段、排序等,避免重复率高或... 目录一、索引是什么?能干嘛?核心作用:二、索引的 4 种主要类型(附通俗例子)1. BTree 索引(

MySQL 添加索引5种方式示例详解(实用sql代码)

《MySQL添加索引5种方式示例详解(实用sql代码)》在MySQL数据库中添加索引可以帮助提高查询性能,尤其是在数据量大的表中,下面给大家分享MySQL添加索引5种方式示例详解(实用sql代码),... 在mysql数据库中添加索引可以帮助提高查询性能,尤其是在数据量大的表中。索引可以在创建表时定义,也可

MySQL索引失效问题及解决方案

《MySQL索引失效问题及解决方案》:本文主要介绍MySQL索引失效问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql索引失效一、概要二、常见的导致MpythonySQL索引失效的原因三、如何诊断MySQL索引失效四、如何解决MySQL索引失

C# foreach 循环中获取索引的实现方式

《C#foreach循环中获取索引的实现方式》:本文主要介绍C#foreach循环中获取索引的实现方式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、手动维护索引变量二、LINQ Select + 元组解构三、扩展方法封装索引四、使用 for 循环替代

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

Mysql中InnoDB与MyISAM索引差异详解(最新整理)

《Mysql中InnoDB与MyISAM索引差异详解(最新整理)》InnoDB和MyISAM在索引实现和特性上有差异,包括聚集索引、非聚集索引、事务支持、并发控制、覆盖索引、主键约束、外键支持和物理存... 目录1. 索引类型与数据存储方式InnoDBMyISAM2. 事务与并发控制InnoDBMyISAM