geohash学习

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 float64MaxLat float64MinLng float64MaxLng 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 // 0NorthEastEastSouthEastSouthSouthWestWestNorthWest
)

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

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.rhkb.cn/news/131742.html

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

相关文章

Spring WebFlux详解

Spring 框架中包含的原始 Web 框架 Spring Web MVC 是专门为 Servlet API 和 Servlet 容器而设计的。后来在 5.0 版本中加入了 reactive 栈的 Web 框架 Spring WebFlux。它是完全非阻塞的,支持 Reactive Streams 背压,并在 Netty、Undertow 和 Servlet 容…

lv4 嵌入式开发-1 Linux文件IO

目录 1 文件的概念和类型 2 如何理解标准IO 3 流(FILE)的含义 3.1 流 3.2 文本流和二进制流 3.3 流的缓冲类型 4 小结 5 缓存区实验 1 文件的概念和类型 概念:一组相关数据的有序集合 文件类型: 常规文件 r 目录文件 d 字符设备文件 …

一键部署k8s集群

前置动作 关闭防火墙 systemctl disable firewalld && systemctl stop firewalld 关闭SELinux sed -i s#SELINUXenforcing#SELINUXdisabled#g /etc/selinux/config && grep SELINUXdisabled /etc/selinux/config setenforce 0 getenforce 关闭swap # 关闭…

Unity3D URP 仿蜘蛛侠风格化BloomAO

Unity3D URP 仿蜘蛛侠风格化Bloom&AO BloomBloom效果流程:制作控制面板VolumeComponent.CSCustom Renderer FeatherCustom Renderer PassBloom ShaderComposite Shader 完善Custom Feather风格化AO 总结 本篇文章介绍在URP中如何进行风格化后处理,使…

做题(2)

1.command_execution 题目提示: (这道题的名字就叫命令执行漏洞) 发现ping 先rce一下 127.0.0.1 | ls 发现了东西 尝试访问一下 找到了所有的文件 访问var文件夹 发现在var/www/html目录下没找到 去别的地方找找 在home文件夹下找到flag文件 访问 得到flag cyb…

网络层--IP协议

引入: IP协议主要解决什么问题呢? IP协议提供一种将数据从主机A 发送到 主机B的能力。(有能力不一定能做到,比如小明很聪明,可以考100分,但是他也不是每次搜能考100分&#xff0…

Unity VideoPlayer 指定位置开始播放

如果 source是 videoclip(以下两种方式都可以): _videoPlayer.Play();Debug.Log("time: " _videoPlayer.clip.length);_videoPlayer.time 10; [SerializeField] VideoPlayer videoPlayer;public void SetClipWithTime(VideoClip…

23062C++QTday5

将之前定义的栈类和队列类都实现成模板类 栈&#xff1a; #include <iostream> #define MAX 128using namespace std;template<typename T,typename C> class Stack { private:T top; //栈顶元素的下标C *data; //指向堆区空间public:Sta…

【C++】常用排序算法

0.前言 1.sort #include <iostream> using namespace std;// 常用排序算法 sort #include<vector> #include<algorithm>//利用仿函数 打印输出 class myPrint { public:void operator()(int val){cout << val << " ";} };//利用普通函…

界面控件DevExpress WPF TreeMap,轻松可视化复杂的分层结构数据!

DevExpress WPF TreeMap控件允许用户使用嵌套的矩形块可视化复杂的平面或分层结构数据。 P.S&#xff1a;DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&a…

接入Websocket,自动接收CSDN短消息

最近在研究Websocket功能&#xff0c;本来想接入抖音和快手的弹幕功能&#xff0c;以及短消息功能。 在了解的过程中&#xff0c;也开发了一些测试项目。 这不是&#xff0c;就把CSDN的短消息项目给弄出来了。 直接上代码&#xff1a; # !/usr/bin python3 # -*- encodingu…

spring boot+redis整合基础入门

文章目录 前言准备依赖项配置文件redis模板类注入设置序列化方式 实施基础字符串操作、超时设置Hash操作hash的使用场景以及优缺点 列表操作列表操作的应用场景以及优缺点 Set的基础操作Set类型的业务场景以及优缺点Demo地址 总结 前言 最近项目中有用到redis进行一些数据的缓…

重构优化第三方查询接口返回大数据量的分页问题

# 问题描述 用户线上查询其上网流量详单数据加载慢&#xff0c;且有时候数据没有响应全~ 1、经排除是调用第三方数据量达10w条响应会超时&#xff0c;数据没正常返回 2、现有线上缓存分页也是加载慢数据不能正常展示 3、第三方接口返回类似报文jsonj&#…

LVS负载均衡群集——LVS-NAT模式搭建和LVS-DR模式搭建

目录 lvs工作模式 1、NAT模式&#xff08;VS-NAT&#xff09; 2、直接路由模式&#xff08;VS-DR&#xff09; 3、IP隧道模式&#xff08;VS-TUN&#xff09; LVS调度算法 LVS群集类型 1&#xff09;负载均衡群集 LB 2&#xff09;高可用群集 HA 3&#xff09;高性能运…

C#获取屏幕的分辨率、工作区分辨率

运行结果如下; 由于屏幕的任务栏在侧面所以屏幕宽度变化。 代码如下 private void Form1_Load(object sender, EventArgs e){int SH Screen.PrimaryScreen.Bounds.Height; //1080int SW Screen.PrimaryScreen.Bounds.Width; //1920System.Drawing.Rectangle rec Screen.Get…

Nginx安装与常见命令

一、Nginx简介 官方文档&#xff1a;https://www.nginx.com/ Nginx中文文档&#xff1a;https://nginx.cn/doc/index.html Nginx由俄罗斯人&#xff08;Igor Sysoev&#xff09;编写的轻量级Web服务器&#xff0c;它的发音为 [ˈendʒɪnks] 。 Nginx 不仅是一款高性能的 HTTP服…

【C语言】找单身狗问题

一.找单身狗问题初阶 1.问题描述 一个数组中只有一个数字是出现一次,其他所有数字都出现了两次.编写一个函数,找出这个只出现一次的数字. 例如: 有数组的元素是:1,2,3,4,5,1,2,3,4 只有5出现了一次,要找出5. 2.解题思路 常规思路: 在常规思路中,我们首先想到的肯定是使用两层…

@DS注解方式springboot多数据源配置及失效场景解决

1.使用教程 导入依赖 <!--多数据源--><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.0</version></dependency>配置数据源 datasource:…

stu04-快速生成HTML5文档结构

1.直接输入一个英文的感叹号“!”&#xff0c;然后按Tab键&#xff0c;自动生成 2.输入“html:5”&#xff0c;然后按Tab键自动生成 3.直接复制粘贴以下代码&#xff1a; <!doctype html> <html lang"en"> <head><meta charset"UTF-8&q…

“金钥匙”转动!安全狗成功护航第二十三届中国国际投资贸易洽谈会举办

9月8日至9月11日&#xff0c;为期4天的第二十三届中国国际投资贸易洽谈会在厦门顺利举办。 作为国内云原生安全领导厂商&#xff0c;安全狗凭借突出的安全综合实力&#xff0c;受委托并担任此次会议网络安保技术支撑单位。 厦门服云信息科技有限公司&#xff08;品牌名&#xf…