GeoHash处理经纬度,降维,空间填充曲线

news/2024/11/13 12:25:31/文章来源:https://www.cnblogs.com/wnhyang/p/18538447

个人博客:无奈何杨(wnhyang)

个人语雀:wnhyang

共享语雀:在线知识共享

Github:wnhyang - Overview


参考

https://segmentfault.com/a/1190000042971576

GeoHash原理以及代码实现_geohash编码-CSDN博客

GeoHash代码实现--java_geohash java代码示例-CSDN博客

在线经纬度距离计算

http://geohash.co/

https://geohash.jorren.nl/

简介

Geohash是一种用于标识地理位置的编码方法。它将经纬度坐标转换为一个简短的字符串,这个字符串可以用来表示地球上的任意位置。Geohash的特点是,编码的长度越长,表示的位置就越精确;反之,编码越短,则表示的位置范围就越大。

接下来我们来一起探究一下这是个什么东西,有什么用?

参考的文章讲的也是非常不错,这里就啰嗦整理一下,并引申一下了。

经纬度

首先必须要从经纬度开始,我们都知道为了标记我们在地球上的位置,出现了经纬度,南北方向叫做纬度[-90,90],东西方向是经度[-180,180]。在使用具有定位功能的设备时,通过人造地球卫星就能确定我们在地球上的位置,其使用的都是经纬度。

GeoHash

GeoHash是一种地理编码,就是用于处理经纬度的。其原理是使用空间填充曲线—— Z 阶曲线(Z-order curve),在地球表面的经纬度球面坐标系下,划分出许许多多不规则矩形,并将每个矩形进行编码,表示某个经纬度范围的面,本质上就是一种降维打击方案。

image

如果你对hash比较敏感的话,就会联想到计算机科学中还有很多hashJava顶级父类Objecthashcode,数据结构的hashcode,散列hash算法如:md5hash负载均衡策略,等等。提到这些是为了重复强调一下相比于无序的hash算法,GeoHash是有序的,毕竟它存在的意义就是为了降维,降维是将(x,y)表示的二维坐标系的点转换为一条直线上的点,虽然信息丢失是不可避免的,但是保留信息就是降维的重要目的之一。如下图,将平面划分成矩形,并将其串联起来,最终拉成一条直线,其是有序的,信息从(x,y)变为[起点,终点],实现了降维。

image

结论出发一般会有一个很大的问题:放弃思考,不再问为什么?

提出问题往往是进步的开始!

为什么这样的曲线是可行?空间填充曲线都有什么特点?

我并不能回答所有相关问题,但至少可以知道这样的曲线一定是可微分的,也就是能通过数学表达式表示的。而且其还能一定程度上的转换二维信息,比如:二维坐标系下很重要的距离问题,在降维后通过大小就能判断。

实现原理

经纬度转GeoHash

1、经纬度,按照[-90,90][-180,180]逐渐二分,在左区间为0,在右区间为1,得到二进制编码,具体要得到多少位的二进制,看选取的精度,5位二进制对应1位GeoHash

2、合并经纬度,偶数位放经度,奇数位放纬度,注意第一位是0,放偶数,简单理解,经度纬度经度纬度…叠加

3、每5位对应以为base32编码,转译一下就得到了GeoHash编码

GeoHash转经纬度

反之即可,只是GeoHash代码的是一块区域,转换后的经纬度是区域的中心点的经纬度。

image

参考网站:

http://geohash.co/

https://geohash.jorren.nl/

局限性

GeoHash是有序的,但本质上都是从二维平面到曲线,无论如何都是会丢失信息的。

边界问题

很容易理解,所有的区域划分问题都会存在这样的问题,如下图,相比如参考点,明显红点更近一些,但是通过GeoHash编码,结论就是绿色的点更近。

通常的解决方案是除了本身区域还要使用周围的相邻区域辅助判断计算。

image

非线性问题

要知道我们讨论的是地球这个三维球体的表面,抛开地球本身就是不规则球体不讲,就算是规则,肯定不能完全套用在球面上吧,这本身就不是矩形啊。球面距离公式也不是简单平方差开根号的吧。0纬度的赤道移动一个经度和30纬度移动一个经度差别也是可想而知的。

球面的必然问题

这是不可避免的问题,还是和前面一样的原因,我们目标是球面,其是无边的!

因为我们经纬度的划分规则,体现在了经度上,-180180是一样的一条线。

GeoHash是无法理解-179179是相近的。

image

意义

尽管GeoHash具有一些局限性,但是在现实中还是有很多用处的。

顺带一讲,Redis中的Geo也有使用GeoHash哦!

1、附近,在使用某些带有地图功能的软件时,查找附近距离最近的xxx,有可能就用到了GeoHash哦,原因也很简单,GeoHash极大的加快了检索速度,相比如球面距离计算可想而知对比一串字符串要简单的多。

2、聚集,想要统计某片区域有多少用户,就可以利用GeoHash将经纬度编码,然后取不同位数,做不同精度的统计。

代码实现

下面是优化了性能的代码实现,其中使用了一些位运算,不过效果是一致的。

public class GeoHash {/*** geoHash 32位*/private static final char[] BASE32 = {'0', '1', '2', '3', '4', '5', '6', '7','8', '9', 'b', 'c', 'd', 'e', 'f', 'g','h', 'j', 'k', 'm', 'n', 'p', 'q', 'r','s', 't', 'u', 'v', 'w', 'x', 'y', 'z'};/*** 纬度范围*/private static final double MIN_LAT = -90.0, MAX_LAT = 90.0;/*** 经度范围*/private static final double MIN_LON = -180.0, MAX_LON = 180.0;/*** 将给定的纬度和经度编码为GeoHash字符串,指定精度。** @param latitude  纬度[-90,90]* @param longitude 经度[-180,180]* @param precision 精度[1,12]* @return GeoHash字符串*/public static String encode(double latitude, double longitude, int precision) {if (latitude < MIN_LAT || latitude > MAX_LAT || longitude < MIN_LON || longitude > MAX_LON) {throw new IllegalArgumentException("Latitude and longitude must be within valid ranges.");}if (precision <= 0 || precision > 12) {throw new IllegalArgumentException("precision must between 1 and 12");}long geoHashBits = 0;boolean isEven = true;double minLat = MIN_LAT, maxLat = MAX_LAT;double minLon = MIN_LON, maxLon = MAX_LON;int bitIndex = 0;// 每个字符代表5位二进制数int requiredBits = precision * 5;while (bitIndex < requiredBits) {double midValue;if (isEven) {midValue = (minLon + maxLon) / 2;if (longitude > midValue) {geoHashBits |= (1L << (requiredBits - bitIndex - 1));minLon = midValue;} else {maxLon = midValue;}} else {midValue = (minLat + maxLat) / 2;if (latitude > midValue) {geoHashBits |= (1L << (requiredBits - bitIndex - 1));minLat = midValue;} else {maxLat = midValue;}}isEven = !isEven;bitIndex++;}return bitsToBase32(geoHashBits, precision);}/*** 将给定的二进制位转换为GeoHash字符串。** @param bits      二进制位* @param precision 精度* @return GeoHash字符串*/private static String bitsToBase32(long bits, int precision) {char[] base32Chars = new char[precision];for (int i = 0; i < precision; i++) {// Extract 5 bitsint index = (int) ((bits >>> (i * 5)) & 0x1F);base32Chars[precision - i - 1] = BASE32[index];}return new String(base32Chars);}/*** 将给定的经度和纬度转换为7位GeoHash字符串。** @param latitude  纬度[-90,90]* @param longitude 经度[-180,180]* @return GeoHash字符串*/public static String geoHash7(double latitude, double longitude) {return encode(latitude, longitude, 7);}public static void main(String[] args) {long start = System.currentTimeMillis();// GeoHash 字符串长度int precision = 9;//30.2549529076, 120.1646161079System.out.println(encode(30.2549958229, 120.1647019386, precision));System.out.println(geoHash7(30.2549958229, 120.1647019386));System.out.println("耗时:" + (System.currentTimeMillis() - start));}
}

总结

说到降维,立刻就想到了前几年看的一个视频《一种降维打击的可视化方案》。

https://player.bilibili.com/player.html?bvid=BV1Sf4y147J9&autoplay=0

数学就是基础学科之王,人类进步的重要动力。

不得不说近现代文明是欧美人主导的,而至今欧美人的创造力还是领先的。很早之前我也发过一篇文章,大概有一个结论,基础学科教育无比重要,创新是发展的重要动力。

当未来越来越多的杨辉三角、王氏悖论、华氏定理、杨x材料、张x曲线、宋x射线出来就好了!

写在最后

拙作艰辛,字句心血,望诸君垂青,多予支持,不胜感激。


个人博客:无奈何杨(wnhyang)

个人语雀:wnhyang

共享语雀:在线知识共享

Github:wnhyang - Overview

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

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

相关文章

windows环境下cmd窗口打开就进入到对应目录,一般人都不知道~

前言 很久以前,我还在上一家公司的时候,有一次我看到我同事打开cmd窗口的方式,瞬间把我惊呆了。原来他打开cmd窗口的方式,不是一般的在开始里面输入cmd,然后打开cmd窗口。而是另外一种方式。 我这个同事是个技术控,喜欢研究新的技术,研究一些提高效率的小窍门。这一方面…

黑马PM- B端产品-客户管理

客户管理公海管理商机管理

C盘满了,C盘无损扩容,简单实现

C盘爆满原因很多,无外乎当年固态硬盘贵,C盘分区过小,或者装系统时无意把分区分的太小,这就造成了一个困扰,C盘满了,变成红色,造成软件无法运行,电脑无法启动。如果重新分区,电脑上的资料就没了,所以今天就来介绍一款不用重装系统,扩充C盘容量的方法,操作非常简单,…

SchedulingConfigurer 实现定时任务(动态修改cron,解决@Scheduled需重启服务问题)

通过实现Sc接口,实现定时任务,解决@Scheduled的定时任务改动cron需要服务重启的问题。@Slf4j @Component public class ATestScheduleJob implements SchedulingConfigurer {@Value("${a.c:0/5 * * * * ?}")private String cron1;@Overridepublic void configureT…

20222319 2024-2025-1 《网络与系统攻防技术》实验四实验报告

1.实验要求 1.1 实验内容 一、恶意代码文件类型标识、脱壳与字符串提取 对提供的rada恶意代码样本,进行文件类型识别,脱壳与字符串提取,以获得rada恶意代码的编写作者,具体操作如下: (1)使用文件格式和类型识别工具,给出rada恶意代码样本的文件格式、运行平台和加壳工具…

黑马PM- B端产品- CRM产品概述

CRM的定义CRM的核心要素CRM的设计思路

推荐模型梳理

Summary 目录Summary标准序列推荐模型其他推荐模型FPMCDNN(Pooling)GRU4Rec(RNN-based)GRU4Rec+(RNN-based)Caser(CNN-based)SASRec(Transformer-based)DIN(Transformer-based)BERT4Rec(Transformer-based)TiSASRec(Transformer-based)FMLP-Rec(Transformer-b…

程序是怎样跑起来的

总结自书籍:https://weread.qq.com/web/reader/94332ce0813ab7cc8g016ad1#outline?noScroll=1计算机的组成:运算器、控制器、存储器、输入设备、输出设备计算机内部都是由集成电路构成的,CPU和内存本质上都是集成电路,集成电路是由大量晶体管构成的电子部件集成电路的所有…

『模拟赛』NOIP2024(欢乐)加赛3(更新 T4 T5 T6)

『模拟赛记录』NOIP2024(欢乐)加赛3Rank 真欢乐吗, 不过 mission accomplished.A. Sakurako and Water CF2033B *900 byd 还懂难易搭配,不过这个 b 翻译甚至不着重以下主对角线差评,被硬控半个小时,直到手模样例才发觉不对。 读懂题就很简单了,最优一定是找最长的对角线…

【论文系列】之 ---- BERT

BERT(Bidirectional Encoder Representation from Transformers) 机器阅读理解领域 从名字很好理解,主要使用的方法是Transformer的方法。。进行机器翻译等操作(1)词嵌入Embedding 词嵌入又有三个部分组成:Token EmbeddingSegment EmbeddingPosiiton Embedding 文本出现的…

【神经网络组件】Transformer Encoder

【神经网络组件】Transformer Encoder 目录【神经网络组件】Transformer Encoder1. seq2seq模型2. 为什么只需要Transformer Encoder3. Transformer Encoder的结构 1. seq2seq模型什么是sequence:sequence指由多个向量组成的序列。例如,有三个向量:\(\mathbf{a} = [1,0,0]^T…