经纬度哈希编码实现方式

背景:在大数据数仓建设的过程中,有时会遇到经纬度类型的数据信息,但在进行关联分析和数仓建设的时候用经纬度去关联,难免不够便捷,于是我们可以开发UDF使用地理经纬度信息哈希编码的方案进行开发,非常有效
地理哈希算法(Geohash) 采用方案

适合场景:在需要可变精度表示位置,且便于进行范围查询和空间索引的场景中表现出色。例如在基于位置的服务中,用户可能在不同场景下需要不同精度的位置信息(如粗略定位城市或精确到街道),Geohash 可以通过调整字符串长度满足这一需求,同时其前缀匹配特性利于快速查询附近位置。
不适合场景:如果对边界连续性要求极高,Geohash 在边界处的精度和连续性问题可能带来困扰,例如在需要精确计算边界距离或进行严格的空间拓扑分析时。
某个格点温度,后面想粗略看周围格点的温度变化情况,另外编码后可解析经纬度信息,无需额外的经纬度字段数据,编码可逆
根据接入层经纬度范围,囊括山东的经度维度范围,有效编码解码范围区间
经度【110,130】 纬度【30,45】
(123.4196,44.2848)->xt7z16sv 八位地理编码

public class GeohashUtils {// 每个Geohash字符对应的二进制位数private static final int BITS = 5;// Base32编码表,用于将二进制转换为字符表示private static final String BASE32 = "0123456789bcdefghjkmnpqrstuvwxyz";// 经度范围的最小值private static final double MIN_LON = 110;// 经度范围的最大值private static final double MAX_LON = 130;// 纬度范围的最小值private static final double MIN_LAT = 30;// 纬度范围的最大值private static final double MAX_LAT = 45;// 编码方法,将经纬度编码为Geohash字符串public static String encode(double lat, double lon, int precision) {// 初始化纬度范围double[] latRange = {MIN_LAT, MAX_LAT};// 初始化经度范围double[] lonRange = {MIN_LON, MAX_LON};// 用于存储最终的Geohash字符串StringBuilder geohash = new StringBuilder();// 用于临时存储二进制位StringBuilder bits = new StringBuilder();// 用于交替处理经度和纬度,初始为true表示先处理经度boolean isEven = true;// 当前处理的二进制位索引int bit = 0;// 用于累积二进制位以转换为Base32字符int ch = 0;// 循环直到生成的Geohash字符串达到指定精度while (geohash.length() < precision) {double mid;if (isEven) {// 计算经度范围的中间值mid = (lonRange[0] + lonRange[1]) / 2;if (lon > mid) {// 如果当前经度大于中间值,设置相应的二进制位ch |= (1 << (BITS - 1 - bit));// 更新经度范围的下限lonRange[0] = mid;} else {// 如果当前经度小于等于中间值,更新经度范围的上限lonRange[1] = mid;}} else {// 计算纬度范围的中间值mid = (latRange[0] + latRange[1]) / 2;if (lat > mid) {// 如果当前纬度大于中间值,设置相应的二进制位ch |= (1 << (BITS - 1 - bit));// 更新纬度范围的下限latRange[0] = mid;} else {// 如果当前纬度小于等于中间值,更新纬度范围的上限latRange[1] = mid;}}// 切换处理经度或纬度isEven =!isEven;if (bit < BITS - 1) {// 如果还未处理完一个字符的所有二进制位,增加位索引bit++;} else {// 当处理完一个字符的所有二进制位,将累积的二进制值转换为Base32字符并添加到Geohash字符串中geohash.append(BASE32.charAt(ch));// 重置位索引和累积值,准备下一个字符的处理bit = 0;ch = 0;}}// 返回生成的Geohash字符串return geohash.toString();}// 解码方法,将Geohash字符串解码为经纬度public static double[] decode(String geohash) {// 初始化纬度范围double[] latRange = {MIN_LAT, MAX_LAT};// 初始化经度范围double[] lonRange = {MIN_LON, MAX_LON};// 用于交替处理经度和纬度,初始为true表示先处理经度boolean isEven = true;// 遍历Geohash字符串的每个字符for (int i = 0; i < geohash.length(); i++) {// 获取当前字符在Base32编码表中的索引,即对应的整数值int cd = BASE32.indexOf(geohash.charAt(i));// 对每个字符的5个二进制位进行处理for (int j = BITS - 1; j >= 0; j--) {int mask = 1 << j;if (isEven) {if ((cd & mask) != 0) {// 如果当前二进制位为1,更新经度范围的下限lonRange[0] = (lonRange[0] + lonRange[1]) / 2;} else {// 如果当前二进制位为0,更新经度范围的上限lonRange[1] = (lonRange[0] + lonRange[1]) / 2;}} else {if ((cd & mask) != 0) {// 如果当前二进制位为1,更新纬度范围的下限latRange[0] = (latRange[0] + latRange[1]) / 2;} else {// 如果当前二进制位为0,更新纬度范围的上限latRange[1] = (latRange[0] + latRange[1]) / 2;}}// 切换处理经度或纬度isEven =!isEven;}}// 计算并返回解码后的纬度double lat = (latRange[0] + latRange[1]) / 2;// 计算并返回解码后的经度double lon = (lonRange[0] + lonRange[1]) / 2;return new double[]{lat, lon};}// 主方法,用于测试编码和解码功能public static void main(String[] args) {double lat = 35;double lon = 120;int precision = 6;// 调用编码方法生成Geohash字符串String geohash = encode(lat, lon, precision);System.out.println("Geohash: " + geohash);// 调用解码方法将Geohash字符串解码回经纬度double[] decoded = decode(geohash);System.out.println("Decoded Latitude: " + decoded[0]);System.out.println("Decoded Longitude: " + decoded[1]);}
}

功能总结

  1. 编码 (encode 方法)

    • 从给定的经纬度范围开始,通过二分法逐步缩小范围,并根据经纬度与范围中间值的比较结果,确定二进制位的值。
    • BITS 个二进制位组合成一个Base32编码的字符,添加到Geohash字符串中。
    • 重复上述过程,直到生成的Geohash字符串达到指定的精度。
  2. 解码 (decode 方法)

    • 从给定的Geohash字符串的每个字符中提取二进制位。
    • 根据二进制位的值,通过二分法逐步缩小经纬度范围。
    • 最终计算并返回解码后的经纬度。
  3. main 方法

    • 提供了一个简单的测试示例,对给定的经纬度进行编码,并将生成的Geohash字符串解码回经纬度,输出结果用于验证编码和解码的正确性。

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

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

相关文章

支持向量机(SVM)深度解析:从数学根基到工程实践

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…

矩阵的范数和逆矩阵的范数的关系

文章目录 前提条件关键结论推导过程简述注意事项示例说明&#x1f4d8; 谱范数定义✅ 步骤一&#xff1a;计算 A T A A^T A ATA✅ 步骤二&#xff1a;求 A T A A^T A ATA 的特征值✅ 步骤三&#xff1a;取最大特征值的平方根✅ 对 A − 1 A^{-1} A−1 做同样的操作✅ 最终结…

成像光谱遥感技术中的AI革命:ChatGPT在遥感领域中的应用

课程将最新的人工智能技术与实际的遥感应用相结合&#xff0c;提供不仅是理论上的&#xff0c;而且是适用和可靠的工具和方法。无论你是经验丰富的研究人员还是好奇的从业者&#xff0c;本课程都将为分析和解释遥感数据开辟新的、有效的方法&#xff0c;使你的工作更具影响力和…

Debian12 安装 sippts

试了试&#xff0c;貌似不复杂&#xff0c;记录如下&#xff1a; apt-get install -y python3 python3 --version # 3.11.2 apt-get install -y python3-pip pip3 --version # 24.3.1 rm /usr/lib/python3.11/EXTERNALLY-MANAGED cd /usr/src git clone https://github.com/…

VR Panorama 360 PRO Renderer保姆级别教程

总览: 全景图及全景视频录制插件有两个 一个是件(以下简称VR360插件) 一个是Unity官方的Unity Recorder插件(以下简称Recorder插件) 在图片清晰度上VR 360插件要高于Recorder插件,所以渲染全景图时,优先使用VR 360插件,当然全景视频也可以使用VR360插件。 但VR 360插件…

cv610将音频chn0配置为g711a,chn1配置为 aac编码,记录

cv610将音频chn0配置为g711a,chn1配置为 aac编码,记录 工程代码在文章底部 编译时放在 sdk的同级目录 sdk_version: sdk_V010,打了AOV的补丁 aenc可以配置为 chn0=g711a, chn1=aac 设置两个编码通道为不同编码属性 主要思路为在 ss_mpi_aenc_create_chn时将 chn1配置编码为…

CAD2018,矩形设计,新增文字,块新增与打散

一、矩形设计 1.选择页面&#xff0c;点击左键&#xff0c;直接输入【rec】&#xff0c;回车&#xff1b; 2.长按鼠标左键&#xff0c;拉出矩形&#xff0c;抬起左键。 3. 会生成一个矩形框。 4. ①输入宽度数值&#xff0c;②输入逗号切换到高度&#xff0c;③输入高度。 5.成…

day047-部署我的世界-java版服务器

文章目录 1. 官方地址2. Ubuntu配置服务端2.1 下载服务端jar包&#xff0c;并上传2.2 安装jdk2.3 启动服务端2.4 设置云安全组 3. 客户端-我的世界启动器 1. 官方地址 官方服务端下载地址&#xff1a;[Minecraft 服务器下载 | Minecraft](https://www.minecraft.net/zh-hans/d…

飞算JavaAI:精准切中开发者痛点,专治“AI生成代码不可用、逻辑混乱”的顽疾

飞算JavaAI&#xff1a;精准切中开发者痛点&#xff0c;专治“AI生成代码不可用、逻辑混乱”的顽疾 一、前言二、关于飞算JavaAI2.1 飞算JavaAI来源2.2 飞算JavaAI超能力 三、飞算JavaAI我的另一半3.1 Idea安装配置3.2 Main方法写个九九乘法表3.3 Main方法写个冒泡排序3.4 老项…

伞兵 钓鱼的肝

题目描述 为了在敌国渗透作战&#xff0c;指挥官决定&#xff1a;派出伞兵前往敌国&#xff01;然而敌国的风十分强烈&#xff0c;能让伞兵在同一高度不停转悠&#xff0c;直到被刮到一个无风区…… 输入格式 第一行两个整数 n,m&#xff0c;表示敌国的大小。 以下 n 行&am…

GoFastDFS:轻量级高性能分布式文件存储解决方案(Linux安装部署)

一、GoFastDFS概述 GoFastDFS是一个基于HTTP协议的分布式文件存储系统&#xff0c;采用Go语言开发&#xff0c;具有轻量级、高性能、易部署等特点。它专为互联网应用设计&#xff0c;特别适合图片、视频、文档等中小文件的存储与分发场景。 它基于大道至简的设计理念&#xf…

python 原型污染 perl符号表污染 -- Google 2025 MYTHOS

题目实现了一个Game,分为前后端 part 1 前端存在明显原型污染 def copy(src, dst):for k, v in src.items():if hasattr(dst, "__getitem__"):if dst.get(k) and type(v) dict:copy(v, dst.get(k))else:dst[k] velif hasattr(dst, k) and type(v) dict:copy(v, ge…

数据结构day4——栈

目录 一、栈的核心概念 什么是栈&#xff1f; 栈的核心特性 二、栈的基本操作 三、C 语言实现栈的两种方式 1. 顺序栈&#xff08;基于数组实现&#xff09; 实现代码 顺序栈的优缺点 2. 链式栈&#xff08;基于链表实现&#xff09; 实现代码 链式栈的优缺点 四、…

用户系统的架构设计与实现策略(二)

一个用户系统除了基本的用户业务功能&#xff0c;还应囊括用户的权限设计及其实现。这本文中我们将探讨一下关于用户权限的设计与实现方法论。 简介 在构建现代应用系统的过程中&#xff0c;很少有设计决策会像访问控制机制那样&#xff0c;对安全性、可扩展性和用户体验产生…

深度学习-逻辑回归

逻辑回归的目的 逻辑回归只判断样本属于正类的概率是多大&#xff0c;0-1之间 找到一组最佳的权重&#xff08;w1,w2,w3,…&#xff09; &#xff0c;b&#xff0c;使得模型预测的概率 P(Y1) 尽可能接近样本的真实标签&#xff08;1 或 0&#xff09;。 计算过程 前向传播过程…

对象池模式:减少GC的Kotlin实战指南

对象池模式通过对象复用机制&#xff0c;将对象生命周期从"创建-销毁"转变为"借出-归还"&#xff0c;显著减少GC压力。下面通过完整实例展示其实现细节。 一、对象池工作原理图解 #mermaid-svg-Edrz4np9hD6DJdNi {font-family:"trebuchet ms",v…

Java接口报错:Packet for query is too large - 解决方案与架构思考

Java接口报错&#xff1a;Packet for query is too large - 解决方案与架构思考 背景与技术原理解决方案体系&#xff08;扩展版&#xff09;一、MySQL服务端配置&#xff08;永久生效&#xff09;配置文件修改&#xff08;推荐生产环境&#xff09; 文件路径参考Linux: /etc/m…

7月2日作业

思维导图 一、创建一个进程扇 代码 #include <25041head.h>int main(int argc, const char *argv[]) {pid_t pid;for(int i1;i<4;i){pidfork();if(pid>0){sleep(1);}if(pid0){printf("我是子进程%d:%d,父进程%d\n",i,getpid(),getppid());sleep(1);re…

设计模式(九)

职责链模式&#xff08;Chain of Responsibility&#xff09;详解 一、核心概念 职责链模式将请求的发送者和接收者解耦&#xff0c;使多个对象都有机会处理请求。这些对象连接成一条链&#xff0c;请求沿着链传递&#xff0c;直到有一个对象处理它为止。该模式允许动态调整处…

左神算法之Zigzag方式打印矩阵

目录 Zigzag方式打印矩阵1. 题目2. 解释3. 思路4. 代码5. 总结 Zigzag方式打印矩阵 1. 题目 用zigzag的方式打印矩阵&#xff0c;比如下面的矩阵&#xff1a; 0 1 2 3 4 5 6 7 8 9 10 11打印顺序为&#xff1a;0 1 4 8 5 2 3 6 9 10 7 11 2. 解释 Zigzag打印矩阵是指按照…