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 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

贝壳面试:什么是回表?什么是索引下推?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题: 1.谈谈你对MySQL 索引下推 的认识? 2.在MySQL中,索引下推 是如何实现的?请简述其工作原理。 3、说说什么是 回表,什么是 索引下推 ? 最近有小伙伴在面试 贝壳、soul,又遇到了相关的

Mysql高级篇(中)——索引介绍

Mysql高级篇(中)——索引介绍 一、索引本质二、索引优缺点三、索引分类(1)按数据结构分类(2)按功能分类(3) 按存储引擎分类(4) 按存储方式分类(5) 按使用方式分类 四、 索引基本语法(1)创建索引(2)查看索引(3)删除索引(4)ALTER 关键字创建/删除索引 五、适合创建索引的情况思考题 六、不适合创建索引的情况 一、索引本质 索引本质 是 一种数据结构,它用

高斯平面直角坐标讲解,以及地理坐标转换高斯平面直角坐标

高斯平面直角坐标系(Gauss-Krüger 坐标系)是基于 高斯-克吕格投影 的一种常见的平面坐标系统,主要用于地理信息系统 (GIS)、测绘和工程等领域。该坐标系将地球表面的经纬度(地理坐标)通过一种投影方式转换为平面直角坐标,以便在二维平面中进行距离、面积和角度的计算。 一 投影原理 高斯平面直角坐标系使用的是 高斯-克吕格投影(Gauss-Krüger Projection),这是 横

ElasticSearch 6.1.1 通过Head插件,新建索引,添加文档,及其查询数据

ElasticSearch 6.1.1 通过Head插件,新建索引,添加文档,及其查询; 一、首先启动相关服务: 二、新建一个film索引: 三、建立映射: 1、通过Head插件: POST http://192.168.1.111:9200/film/_mapping/dongzuo/ {"properties": {"title": {"type":

ElasticSearch 6.1.1运用代码添加索引及其添加,修改,删除文档

1、新建一个MAVEN项目:ElasticSearchTest 2、修改pom.xml文件内容: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.or

postgres数据库中如何看查询是否走索引,以及在什么情况下走索引

在 PostgreSQL 中,可以通过 EXPLAIN 或 EXPLAIN ANALYZE 查看查询计划,以判断查询是否使用了索引。除此之外,了解索引的使用条件对于优化查询性能也很重要。 1. 如何查看查询是否使用索引 使用 EXPLAIN 查看查询计划 EXPLAIN 显示 PostgreSQL 如何执行查询,包括是否使用索引。 EXPLAIN SELECT * FROM users WH

数据库系统 第42节 数据库索引简介

数据库索引是数据库表中一个或多个列的数据结构,用于加快数据检索速度。除了基础的B-Tree索引,其他类型的索引针对特定的数据类型和查询模式提供了优化。以下是几种不同类型的索引及其使用场景的详细说明和示例代码。 1. 位图索引 (Bitmap Index) 位图索引适用于具有少量不同值的列(例如性别、国家代码等),它使用位图来表示数据,从而提高查询效率。 适用场景:当列中的值域较小,且数据分布

PostgreSQL索引介绍

梦中彩虹   博客园首页新随笔联系管理 随笔 - 131  文章 - 1  评论 - 14 PostgreSQL索引介绍 INDEX 索引是增强数据库性能的常用方法。索引使得数据库在查找和检索数据库的特定行的时候比没有索引快的多。但索引也增加了整个数据库系统的开销,所以应该合理使用。 介绍 假设我们有一个类似这样的表: CREATE TABLE test1 (id integ

openGauss 之索引回表

一. 前言 ​       在openGauss中如果表有索引信息,查询的谓词条件中又包含索引列,openGauss支持通过索引信息快速拿到需要访问元组的位置信息,然后直接到该位置上取出元组数据,称之为回表查询。如下所示,利用索引索引列id=55快速找到t111上对应元组的位置信息,然后通过位置信息拿到id为55的元组中所有列的数据。     本文通过走读openGauss的代码了解ope