geohash学习

news2024/11/28 16:28:30

geohash编解码

import (
	"github.com/mmcloughlin/geohash"
)

func Test_Demo(t *testing.T) {
	// 编码经纬度到 geohash 字符串
	lat, lon := 40.7128, -74.0060       // 纽约市的位置
	geoHash := geohash.Encode(lat, lon) // geohash 字符串
	fmt.Println(geoHash)                // dr5regw3ppyz

	// 解码 geohash 字符串到经纬度坐标
	lat, lon = geohash.Decode("dr5regw3ppyz")
	fmt.Printf("lat: %.4f, lon: %.4f", lat, lon)
}

mmcloughlin开发的geohash

func ConvertIntToString(hash uint64, chars uint) string
将整数 geohash 转换为具有 chars 字符的等效字符串 geohash
精度:5chars
The provided integer geohash is interpreted to have 5
chars bits of precision.

func ConvertStringToInt(hash string) (uint64, uint)
将字符串 geohash 转换为等效的整数 geohash
返回整数哈希值及其精度

func Decode(hash string) (lat, lng float64)
将字符串 geohash 解码为 (lat, lng) 坐标

func DecodeCenter(hash string) (lat, lng float64)
将字符串 geohash 解码到边界框的中心点

func DecodeInt(hash uint64) (lat, lng float64)
将提供的 64 位整数 geohash 解码为 (lat, lng) 坐标

func DecodeIntWithPrecision(hash uint64, bits uint) (lat, lng float64)
将提供的整数 geohash 解码为 (lat, lng) 点的精度位。

func Encode(lat, lng float64) string
函数编码
将(lat、lng)编码为具有标准 12 个字符精度的字符串 geohash

func EncodeInt(lat, lng float64) uint64
将 (lat, lng) 编码为 64 位整数 geohash

func EncodeIntWithPrecision(lat, lng float64, bits uint) uint64
将 (lat, lng) 编码为具有指定位数的整数

func EncodeWithPrecision(lat, lng float64, chars uint) string
将 (lat, lng) 编码为具有指定精度字符数(最多 12)的字符串 geohash

func Neighbor(hash string, direction Direction) string
返回一个 geohash 字符串,该字符串对应于所提供方向上所提供的 geohash 的邻居

func NeighborInt(hash uint64, direction Direction) uint64
返回一个 uint64,它对应于所提供的散列在所提供的方向上以 64 位精度的邻居

func NeighborIntWithPrecision(hash uint64, bits uint, direction Direction) uint64
返回一个 uint64s,它对应于给定精度的指定方向上所提供的哈希的邻居

func Neighbors(hash string) []string
返回与所提供的 geohash 邻居相对应的 geohash 字符串切片

func NeighborsInt(hash uint64) []uint64
返回一个 uint64 切片,对应于所提供的哈希的 64 位精度的邻居

func NeighborsIntWithPrecision(hash uint64, bits uint) []uint64
返回 uint64 的切片,该切片对应于给定精度下提供的哈希的邻居

func Validate(hash string) error
验证字符串 geohash

type Box struct {
	MinLat float64
	MaxLat float64
	MinLng float64
	MaxLng float64
}

表示纬度/经度空间中的矩形

func BoundingBox(hash string) Box
返回由给定字符串 geohash 编码的区域

func BoundingBoxInt(hash uint64) Box
返回由给定 64 位整数 geohash 编码的区域

func BoundingBoxIntWithPrecision(hash uint64, bits uint) Box
返回由具有指定精度的整数 geohash 编码的区域

func (b Box) Center() (lat, lng float64)
返回盒子的中心

func (b Box) Contains(lat, lng float64) bool
决定 (lat, lng) 是否包含在框中

func (b Box) Round() (lat, lng float64)
返回框内的一个点,努力舍入到最小精度

type Direction int
表示纬度/经度空间中的方向

const (
	North Direction = iota // 0
	NorthEast
	East
	SouthEast
	South
	SouthWest
	West
	NorthWest
)

基本方向和基本方向,从正北开始,顺时针旋转一圈

Geohash算法

利用分层的网格系统来表示地球上的给定区域
在每个网格中,Geohash单元格将地球表面的区域划分为更小的子区域
每个 Geohash 单元格都可以映射到一个不同的 Geohash 字符串

由于 Geohash 单元格始终是正方形的,因此每个 Geohash 单元格的实际外观是类似于矩形的。
geohash.DecodeCenter 函数使用该矩形,以确定 Geohash 编码本身所代表的地理区域的标准矩形外接盒子,并返回该盒子的中心点经纬度坐标作为解码结果。

Geohash 字符串本身并不包含与其对应的矩形精确的边界坐标,因此在使用 geohash.DecodeCenter 函数时,应该了解解码结果可能与实际位置略有偏差的事实。

示例

纬度 lat:39.9257460000,经度 lng:116.5998310000
纬度二进制计算

范围负区间正区间取值
(-90, 90)(-90,0](0, 90)1
(0, 90)(0,45](45,90)0
(0, 45)(0,22.5)[22.5,45)1
(22.5,45)(22.5,33.75)[33.75,45)1
1
0
0
0
1

纬度落于区间使用1和0进行标识,最后可以组成一个二进制数字101110001100011;同理,经度二进制计算 110100101100010。

最后,奇数位放纬度,偶数位放经度:
1 1 0 1 0 0 1 0 1 1 0 0 0 1 0
1 0 1 1 1 0 0 0 1 1 0 0 0 1 1

得到30位的字节数组:
11100 11101 00100 01111 00000 01101

每五位二进制转为一个十进制:

t1 := 0b11100
t2 := 0b11101
t3 := 0b00100
t4 := 0b01111
t5 := 0b00000
t6 := 0b01101
fmt.Println(t1, t2, t3, t4, t5, t6) // 28 29 4 15 0 13

对应base32编码 wx4g0e

原理

将整个地图或者某个分割所得的区域进行进一步划分,由于采用的是base32编码方式,这样可以将整个地图区域分为32个区域,通过00000 ~ 11111来标识这32个区域。
第一次对地图划分后的情况如下图所示(每个区域中的编号对应于该区域所对应的编码)
在这里插入图片描述
在这里插入图片描述
Geohash的0、1串序列是经度0、1序列和纬度0、1序列中的数字交替进行排列,偶数位对应的序列为经度序列(从0位开始),奇数位对应的序列为纬度序列。

在这里插入图片描述

在进行第一次划分时,Geohash0、1序列中的前5个bits(11100),那么这5bits中有3bits是表示经度,2bits表示纬度。

将经度划分成8个区段(2^3 = 8)
将纬度划分为4个区段(2^2 = 4)
形成了32个区域(对应Base32)

缺点

将每一个区域画成一块块矩形块,每个矩形块使用一个字符串表示,当需要查询附近的点时,通过自己的坐标计算出一个字符串,根据这个字符串定位到所在的矩形块,然后返回这个矩形块中的点。
例如 wx4e就包含wx4e0e,也就是说wx4e0e在wx4e范围内。
在这里插入图片描述
通行做法:不仅获取当前所在的矩形区域,还获取周围8个矩形块中的点(已经知道自己的经纬度,只需要用自己的经纬度减去最小划分单位的经纬度)。
在这里插入图片描述
通过上面这张图,就能很容易的计算出周围8个点的经纬度。有了经纬度就能定位到周围8个矩形块。这样就能获取包括自己所在矩形块的9个矩形块中的所有的点。
最后分别计算这些点和自己的距离(由于范围很小,点的数量就也很少,计算量就很少)过滤掉不满足条件的点。

redis中的geohash

存储地理位置信息,并对存储的信息进行操作。

geoadd:添加地理位置的坐标。
geopos:获取地理位置的坐标。
geodist:计算两个位置之间的距离。
georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合。
georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合。
geohash:返回一个或多个位置对象的 geohash 值。

geoadd
存储指定的地理空间位置,将一个或多个经度(longitude)、纬度(latitude)、位置名称(member)添加到指定 key
GEOADD key longitude latitude member [longitude latitude member …]

geopos
从给定的 key 里返回所有指定名称(member)的位置(经度和纬度),不存在的返回 nil
GEOPOS key member [member …]

geodist
返回两个给定位置之间的距离
GEODIST key member1 member2 [m|km|ft|mi]

  • member1 member2 为两个地理位置
  • 最后一个距离单位参数说明:
    m米,默认单位 / km千米 / mi英里 / ft英尺。

georadius、georadiusbymember
以给定的经纬度为中心, 返回键包含的位置元素当中, 与中心的距离不超过给定最大距离的所有位置元素。

georadiusbymember 和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 georadiusbymember 的中心点是由给定的位置元素决定的, 而不是使用经度和纬度来决定中心点。
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。
WITHCOORD: 将位置元素的经度和纬度也一并返回。
WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。
COUNT 限定返回的记录数。
ASC: 查找结果根据距离从近到远排序。
DESC: 查找结果根据从远到近排序。

geohash
Redis GEO 使用 geohash 来保存地理位置的坐标。
geohash 用于获取一个或多个位置元素的 geohash 值。

geohash 语法格式如下:
GEOHASH key member [member …]

参考文档

https://zhuanlan.zhihu.com/p/35940647

附录

geohash编码

在这里插入图片描述
在这里插入图片描述

Base32

将数字 0~9 ,加上26个字母(去除a,i,l,o 四个)进行组合而成的32个字符编码形式
在这里插入图片描述

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

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

相关文章

浅谈Http协议、TCP协议(转载)

TCP标志位,有6种标示:SYN(synchronous建立联机) ,ACK(acknowledgement 确认) ,PSH(push传送),FIN(finish结束) ,RST(reset重置), URG(urgent紧急) Sequence number(顺序号码) ,Acknowledge num…

202330读书笔记|《中国百年文学经典桥梁书(全8册)》——故乡,匆匆,春,背影,白鹅,百草园

202330读书笔记|《中国百年文学经典桥梁书(全8册)》——故乡,匆匆,春,背影,白鹅,百草园 《中国百年文学经典桥梁书(全8册)》作者朱自清,鲁迅等。很多都是小学…

文生图模型进化简史和生成能力比较——艺术肖像篇

很久没有更新文章,最近真的太忙啦,在T2I领域,学习速度真的赶不上进化速度!每天都有无数新模型、新插件、新玩法涌现。玩得太上瘾啦。 上月初我去参加我硕士专业的夏季烧烤大趴,跟我的论文导师重逢(好多年没…

Java 中如何实现序列化?

什么是序列化?Java 中如何实现序列化? 在 Java 编程中,序列化是一种将对象转换为字节流的过程,可以将对象在网络中传输或者保存到磁盘中。序列化可以将对象的状态保存下来,以便在需要时重新创建对象。Java 中提供了一…

9.9|day 2|整数拆分|不同的二叉搜索树

整数拆分&#xff1a; class Solution {public int integerBreak(int n) {int[] dp new int[n1];dp[2] 1;for(int i 3;i<n;i){for(int j 1;j<i-j;j){dp[i] Math.max(dp[i],Math.max(j*dp[i-j],j*(i-j)));}}//这里感觉要注意的就是j是我们要拆分的数&#xff0c;所…

提升敲代码效率:SublimeLinter+iverilog实现代码语法检查

前言 SublimeLinter是sublime的语法检查框架&#xff0c;安装这个插件是实现语法检查的前提&#xff0c;在安装了这个插件后&#xff0c;我们才可以安装使用特定语言的语法检查插件&#xff0c;比如对于verilog而言&#xff0c;有如下几种语法检查插件&#xff1a; SublimeLi…

如何预防CSRF攻击

CSRF 攻击的防范措施 CSRF&#xff08;Cross-Site Request Forgery&#xff09;攻击是一种常见的 Web 攻击&#xff0c;即攻击者在用户不知情的情况下&#xff0c;利用用户已登录的身份&#xff0c;向目标网站发送恶意请求&#xff0c;从而实现攻击目的。本文将介绍 CSRF 攻击…

5. 状态

一、状态是什么 由一个任务维护&#xff0c;并且用来计算某个结果的所有数据&#xff0c;都属于这个任务的状态可以认为状态就是一个本地变量&#xff0c;可以被任务的业务逻辑访问Flink 会进行状态管理&#xff0c;包括状态一致性、故障处理以及高效存储和访问&#xff0c;以…

go通过pprof定位groutine泄漏

日常开发中除了会出现Panic、ErrorInfo等通过日志很容易捕捉到的错误&#xff0c;还会出现内存泄漏、CPU激增等日志难以捕捉的问题。今天小老虎就给大家介绍下如何使用pprof去捕捉内存、CPU这些日志难以排查到的问题。 pprof的访问 pprof是Golang的性能分析工具&#xff0c;可…

Inno Setup 打包的文件以管理员权限运行

在 Inno Setup 安装目录中找到文件 SetupLdr.e32&#xff0c;用软件 ResourceHacker 打开。如下图&#xff0c;点开清单&#xff0c;找到 <requestedExecutionLevel level"asInvoker" uiAccess"false"/></requestedPrivileges>改为 <requ…

Nomad系列-Nomad网络模式

系列文章 Nomad 系列文章 概述 Nomad 的网络和 Docker 的也有很大不同, 和 K8s 的有很大不同. 另外, Nomad 不同版本(Nomad 1.3 版本前后)或是否集成 Consul 及 CNI 等不同组件也会导致网络模式各不相同. 本文详细梳理一下 Nomad 的主要几种网络模式 在Nomad 1.3发布之前&a…

CSS_文字渐变

/* 定义渐变背景样式 */ .gradient-text {background-image: linear-gradient(to right, #ff0000, #00ff00); /* 渐变色范围 */background-clip: text; /* 应用渐变背景到文本 */-webkit-background-clip: text; /* Safari 和 Chrome 的前缀 */color: transparent; /* 将文本颜…

ADS1115 模拟IIC

ADS1115是16位ADC&#xff0c;基准源内部可选&#xff0c;PGA 可提供从 256mV 到 6.144V 的输入范围。 地址可由ADDR引脚决定&#xff0c;一般接地&#xff0c;地址为0x90 写寄存器地址为0x90&#xff0c;读寄存器地址为0x91 ADS1115有4个控制寄存器&#xff0c;0x00,0x01,0x0…

debian apt安装mysqlodbc

mysql的deb包下载地址 下载后上传到linux后&#xff0c; #安装deb包 apt install ./mysql-apt-config_0.8.26-1_all.deb #更新源 apt-get update #搜索包 apt search odbc #安装包 apt-get install mysql-connector-odbc

3. 自定义datasource

一、自定义DataSource ​ 自定义DataSource有两大类&#xff1a;单线程的DataSource和多线程的DataSource 单线程&#xff1a;继承 SourceFunction 多线程&#xff1a;继承 ParallelSourceFunction&#xff0c;继承 RichParallelSourceFunction&#xff08;可以有其他的很多操…

origin中optimal cluster安装报错解决

1.在安装之后程序运行出错&#xff0c;报错信息为缺少numpy包。解决办法&#xff1a;打开窗口-脚本窗口&#xff0c;用pip安装numpy&#xff0c;其他缺少的包可用同样方法解决。 2.有的包在外部python中才有&#xff0c;通过origin无法下载。解决办法&#xff1a;在连接-python…

WIFI版本云音响设置教程阿里云平台版本

文章目录 WIFI本云音响设置教程介绍一、申请设备三元素1.登录阿里云物联网平台2.创建产品3.设置产品参数4.添加设备5.获取三元素 二、设置设备三元素1.打开MQTTConfigTools2.计算MQTT参数3.使用windows电脑的WIFI连接到设备热点4.设置参数5.配置设备连接路由器 三、阿里云物联网…

有始有终!

作者 | 磊哥 来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09; 转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09; 开始是立秋之日&#xff08;8.8 号&#xff09;&#xff0c;结束是白露之时&#xff08;9.8 号&#xff09;。 为期一月&…

Day60|leetcode 84.柱状图中最大的矩形

leetcode 84.柱状图中最大的矩形 题目链接&#xff1a;84. 柱状图中最大的矩形 - 力扣&#xff08;LeetCode&#xff09; 视频链接&#xff1a;单调栈&#xff0c;又一次经典来袭&#xff01; LeetCode&#xff1a;84.柱状图中最大的矩形_哔哩哔哩_bilibili 题目概述 给定 n 个…

CSS3技巧36:backdrop-filter 背景滤镜

CSS3 有 filter 滤镜属性&#xff0c;能给内容&#xff0c;尤其是图片&#xff0c;添加各种滤镜效果。 filter 滤镜详见博文&#xff1a;CSS3中强大的filter(滤镜)属性_css3滤镜_stones4zd的博客-CSDN博客 后续&#xff0c;CSS3 又新增了 backdrop-filter 背景滤镜。 backdr…