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

个人博客:无奈何杨(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.xdnf.cn/news/11148.html

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

相关文章

游戏引擎学习第三天

视频参考:https://www.bilibili.com/video/BV1XTmqYSEtm/ 之前的程序不能退出&#xff0c;下面写关闭窗体的操作 PostQuitMessage 是 Windows API 中的一个函数&#xff0c;用于向当前线程的消息队列发送一个退出消息。其作用是请求应用程序退出消息循环&#xff0c;通常用于处…

CSS中常见文本居中技巧详解

在网页设计中&#xff0c;文本居中是非常常见且重要的布局需求之一。无论是为了美观还是为了更好地传达信息&#xff0c;掌握文本居中的方法对于前端开发者来说都是必不可少的技能。本文将详细介绍几种常用的CSS文本居中方法&#xff0c;帮助读者解决实际开发中的问题。 默认情…

Java基础教程(001):Java基础概念:注释、关键字、字面量

文章目录 1、Java基础概念1.1 注释1.2 关键字1.3 字面量1.4 制表符 1、Java基础概念 1.1 注释 【1】注释概念 注释是在程序指定位置添加的说明性信息。 简单理解&#xff0c;就是对代码的一种解释。 【2】注释分类 单行注释&#xff1a;// 注释信息多行注释&#xff1a;/…

SIwave:释放 SIwizard 求解器的强大功能

SIwave 是一种电源完整性和信号完整性工具。SIwizard 是 SIwave 中 SI 分析的主要工具&#xff0c;也是本博客的主题。 SIwizard 用于研究 RF、clock 和 control traces 的信号完整性。该工具允许用户进行瞬态分析、眼图分析和 BER 计算。用户可以将 IBIS 和 IBIS-AMI 模型添加…

Windows10 下通过 Visual Studio2022 编译 openssl 3.4

Windows10 下通过 Visual Studio2022 编译 openssl 3.4 1 准备环境1.2 perl1.2.1 ActiveState Perl 和 Strawberry Perl 的区别1.2.2 perl 下载1.2.3 验证安装1.2 NASM1.2.1 Windows 安装 NASM1.2.2 解压1.2.3 配置 NASM 的环境变量1.3 VS 配置1.3.1 配置 VS nmake 的环境变量1…

了解Hadoop:大数据处理的核心框架

在当今数据爆炸的时代&#xff0c;海量数据的存储和处理已成为一个巨大的挑战。传统数据库和计算模型难以应对如此庞大的数据规模。为了解决这一问题&#xff0c;Apache Hadoop应运而生&#xff0c;它是一种分布式存储和处理框架&#xff0c;能够高效地处理海量数据。本文将详细…

本溪与深圳市新零售产业互联协会共商世界酒中国菜湾区农业发展

本溪满族自治县与深圳市新零售产业互联协会汇聚鹏城共商世界酒中国菜大湾区农业发展大计 2024年11月9日下午2点&#xff0c;深圳市新零售产业互联协会内气氛热烈&#xff0c;一场关乎农业产业发展未来的重要讨论正在这里举行。此次会议汇聚了来自本溪满族自治县和大湾区的众多精…

互联网广告的变现逻辑|计费模式|CPC、CPM、OCPC、OCPM

写在前面 最近的工作和广告相关&#xff0c;就整理一下自己学到的关于互联网广告变现的一些知识。 广告是互联网主要变现手段之一&#xff0c;一般的互联网公司都会有个商业化部门专门做广告的变现。那广告究竟是怎么变现的呢&#xff1f;怎么广告的好坏和什么有关呢&#xff1…

从0开始深度学习(29)——文本预处理

序列数据中&#xff0c;最常见的例子就是文本数据&#xff0c;例如&#xff0c;一篇文章可以被简单地看作一串单词序列&#xff0c;甚至是一串字符序列。 本节中&#xff0c;我们将解析文本的常见预处理步骤。 0 文本预处理步骤 将文本作为字符串加载到内存中。将字符串拆分为…

JDBC学习笔记--JdbcUtil工具类

目录 &#xff08;一&#xff09;为什么要使用JdbcUtil工具类 &#xff08;二&#xff09;创建一个prorperties文件 1.在文件目录或src目录下&#xff0c;选择新建FIle 2.创建properties文件 3.编写配置文件 Java基础&#xff1a;反射 4.获取资源的方式 第一种 第二种…

DNS域名解析

1、DNS简介 DNS&#xff08;Domain Name System&#xff09;是互联网上的一项服务&#xff0c;它作为将域名和IP地址相互映射的一个分布式 数据库&#xff0c;能够使人更方便的访问互联网。 DNS系统使用的是网络的查询&#xff0c;那么自然需要有监听的port。DNS使用的是53端…

点云从入门到精通技术详解100篇-基于结构光测量的三维人脸重建及识别(下)

目录 4.4 实验结果与分析 5 基于多特征组合阈值技术的三维人脸识别 5.1 引言 5.2 基于多特征组合阈值技术的部分遮挡三维人脸识别 5.2.1 三维人脸预处理 5.2.2 三维人脸表征 5.2.3 混合平均脸生成 5.2.4 基于多特征组合式遮挡去除法 5.2.5 神经网络架构 5.2…

A025-基于SpringBoot的售楼管理系统的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600…

私域流量圈层在新消费时代的机遇与挑战:兼论开源 AI 智能名片、2 + 1 链动模式、S2B2C 商城小程序的应用

摘要&#xff1a;本文剖析了私域流量圈层在新消费时代呈现出的独特温度与信任优势&#xff0c;阐述了从传统销售到新消费转型中用户心理的变化。同时&#xff0c;强调了内容对于私域流量的关键作用&#xff0c;并分析开源 AI 智能名片、2 1 链动模式、S2B2C 商城小程序在私域流…

LeetCode 540.有序数组中的单一元素

思路一&#xff1a;hash&#xff0c;键存入元素&#xff0c;值存入次数&#xff0c;然后遍历&#xff0c;不是最优解 思路二&#xff1a;二分查找 假设数组为 [1, 1, 2, 2, 3, 4, 4]&#xff0c;其中唯一出现一次的元素是 3。在一个有序数组中&#xff0c;如果没有唯一的元素&…

ssm082基于java斗车交易系统设计与实现+vue(论文+源码)_kaic

摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…

linux命令curl

curl 是一个用于从命令行传输数据的强大工具&#xff0c;支持多种协议&#xff08;如 HTTP、HTTPS、FTP 等&#xff09;。它常用于测试 API、下载文件、提交表单、模拟浏览器请求等操作。 基本语法 curl [选项] [URL]常用选项 以下是一些常用的 curl 命令选项及其功能&#…

【GoWeb示例】通过示例学习 Go 的 Web 编程

文章目录 你好世界HTTP 服务器路由&#xff08;使用 gorilla/mux&#xff09;连接到 MySQL 数据库MySQL 数据库简单操作模板静态资源和文件操作表单处理中间件&#xff08;基础&#xff09;中间件&#xff08;高级&#xff09;会话JSONWebsockets密码哈希 你好世界 Go语言创建…

基于Multisim的烟雾报警电路设计与仿真

设计任务和要求&#xff1a; &#xff08; 1 &#xff09;需要有低浓度、中浓度和高浓度 3 个浓度范围。 &#xff08; 2 &#xff09;需要用电压比较器设置不同浓度的阈值。 &#xff08; 3 &#xff09;用蜂鸣器和二极管指示灯&#xff08; 3 个浓度范围的指示灯用 3 …

旅行是过于梦幻的镜月【西域之旅】

旅行的意义就是几个定格的“瞬间” 短暂的相遇 恰如涉水而过 每条河终究是 奔向属于它的海看到一句话&#xff1a;一个人的行走范围&#xff0c;就是他的世界。 快节奏的社会里&#xff0c;旅行也许不值得被歌颂&#xff0c;但它却实实在在拓宽一个人的世界。 当我没灵感时&…