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 索引简介及常见的索引类型有哪些

《MySQL索引简介及常见的索引类型有哪些》MySQL索引是加速数据检索的特殊结构,用于存储列值与位置信息,常见的索引类型包括:主键索引、唯一索引、普通索引、复合索引、全文索引和空间索引等,本文介绍... 目录什么是 mysql 的索引?常见的索引类型有哪些?总结性回答详细解释1. MySQL 索引的概念2

Oracle查询表结构建表语句索引等方式

《Oracle查询表结构建表语句索引等方式》使用USER_TAB_COLUMNS查询表结构可避免系统隐藏字段(如LISTUSER的CLOB与VARCHAR2同名字段),这些字段可能为dbms_lob.... 目录oracle查询表结构建表语句索引1.用“USER_TAB_COLUMNS”查询表结构2.用“a

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

MySQL逻辑删除与唯一索引冲突解决方案

《MySQL逻辑删除与唯一索引冲突解决方案》本文探讨MySQL逻辑删除与唯一索引冲突问题,提出四种解决方案:复合索引+时间戳、修改唯一字段、历史表、业务层校验,推荐方案1和方案3,适用于不同场景,感兴... 目录问题背景问题复现解决方案解决方案1.复合唯一索引 + 时间戳删除字段解决方案2:删除后修改唯一字

浅谈mysql的not exists走不走索引

《浅谈mysql的notexists走不走索引》在MySQL中,​NOTEXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引,下面就来介绍一下mysql的notexists走不走索... 在mysql中,​NOT EXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引。以下

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 索引(