0

0

如何在集合中存储大量的经纬度数据_GeoHash算法与Map集合的结合

P粉602998670

P粉602998670

发布时间:2026-02-12 17:00:50

|

553人浏览过

|

来源于php中文网

原创

geohash比直接存经纬度更适合范围查询,因其将二维坐标转为具前缀相似性的字符串,支持用submap等区间操作逼近邻近查询,但需查多个相邻单元格并二次距离过滤。

如何在集合中存储大量的经纬度数据_geohash算法与map集合的结合

GeoHash 为什么比直接存 [lat, lng] 更适合做范围查询

因为原始经纬度是二维浮点数,用 Map 存键值对时无法天然支持“附近 N 公里”这类查询;而 GeoHash 把二维坐标转成单字符串,具备前缀相似性——相同前缀越多,地理位置越近。这使得你可以用 map.subMap("wx4g", "wx4h") 这类区间操作逼近地理邻近查询。

但要注意:GeoHash 是近似编码,存在边缘误差(比如两个紧邻单元格的编码可能完全不同),且精度随字符串长度增加而提高,但索引体积也线性增长。

  • 5 位 GeoHash(约 4.9km 精度)适合城市级粗筛
  • 8 位(约 19m)才能支撑 POI 级别定位
  • Java 中推荐用 geohash-java 库的 GeoHash.withCharacterPrecision(lat, lng, 8),别手写编码逻辑

TreeMap 存 GeoHash 字符串时的 key 设计陷阱

不能直接把 GeoHash 字符串当 key 存进 TreeMap 就完事——它只保证字典序,而 GeoHash 的字典序 ≠ 地理邻近性(尤其跨纬度带时)。真实场景中,一次“附近搜索”需要查 8~9 个相邻 GeoHash 单元格,再合并结果。

所以更合理的做法是:以 GeoHash 前缀为 key,value 是 Set<string></string>List<yourdata></yourdata>,例如:map.put("wx4g7x", List.of(poi1, poi2))

Knowt
Knowt

Knowt是一款AI驱动的在线学习工具

下载
  • key 长度统一取 6~7 位,平衡精度与内存占用
  • 避免用 HashMap,它不支持范围扫描,subMap() 会直接报错
  • 插入前务必调用 GeoHash#toBase32() 确保编码一致,有些库默认返回 base32,有些返回二进制字符串

查询“附近 500 米”数据时,如何生成正确的 GeoHash 范围集合

直接用中心点算一个 GeoHash 再查 subMap 会漏掉大量真实邻近点——GeoHash 单元格是矩形(实际是球面投影后的近似矩形),且边界不连续。正确做法是调用工具方法获取“覆盖目标半径的所有候选 GeoHash 前缀”,例如 Java 中用 GeoHashUtils.expandToCoverDistance(centerLat, centerLng, 500)(来自 spatial4j)。

  • 该方法返回的是字符串列表,如 ["wx4g7x", "wx4g7y", "wx4g7z", ...],共 8~9 个
  • 对每个前缀执行 map.get(prefix)map.subMap(prefix + "0000", prefix + "zzzz")(注意边界字符要选对)
  • 别信网上随手搜的“手动计算邻接格子”代码,容易漏掉极地/本初子午线附近的翻转 case

内存和性能的真实代价:千万级数据下 TreeMap<string list></string> 的瓶颈在哪

当存储超百万个点,每个 GeoHash 前缀对应几十到上百条记录时,TreeMap 的 key 数量本身不大(通常几万),但 value 的 List 可能成为 GC 压力源——特别是频繁增删改导致 list rehash 或扩容。

  • 如果读远多于写,考虑用 ImmutableList 替代可变 ArrayList
  • 若需支持按时间排序或分页,不要把所有数据塞进一个 list,改用嵌套结构:Map<string navigablemap yourdata>></string>
  • 真正卡顿往往不在 Map 查找,而在后续的“距离重过滤”——GeoHash 只缩小候选集,最终还得用 Haversine 公式逐个算球面距离剔除误召

GeoHash 和 Map 的组合不是银弹,它解决的是“快速圈出候选区域”的问题;真正的距离判断、排序、分页,得在内存里二次处理。这点很容易被忽略,直到线上查 1000 个点就超时。

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

708

2023.08.02

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

508

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

214

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1550

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

640

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

842

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

814

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

184

2025.07.29

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

1

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号