o2o附近的商家功能常见的算法:geohash和spatial4j调试实战

2019年12月06日07:55:05 科技 1861

开篇

我调试了很多开源项目,包括开源商城、IM即时通讯等很多,感兴趣的可以看看源码点我头像进去,觉得有用给个关注吧。

最近在看o2o相关的原理,网上说了很多geohash算法的原理。但其实原理网上有很多,但真正的调试少之又少,今天就来写代码调试一下geo算法和spatial4工具j。轻松实现,附近的商家功能。觉得有用,就点个赞转个发吧。看文章的时候最好是跟着做,如果没时间就收藏转发吧。


o2o附近的商家功能常见的算法:geohash和spatial4j调试实战 - 天天要闻

geohash算法原理简单介绍

geo 是地理位置的geography 的缩写,hash其实就是hash算法。大家都知道,我们平常用的百度地图,高德地图其实每一个点都是有经纬度的。你可以理解为geohash,其实就是经纬度经过一些列运算出来的hash值,相似的经纬度得到的geohash值前缀几乎一致,这样就可以把一个区域内的点都可以直接在数据库中查出来,当然具体原理自己可以去搜索。这里就不介绍了,今天重点介绍,如何使用。

源码可以到github上看:https://github.com/kungfoo/geohash-java


o2o附近的商家功能常见的算法:geohash和spatial4j调试实战 - 天天要闻

spatial4j工具

其实地球是球形的大家都知道,但基本上在地图上你可以认为是平面。例如查询附近1km的范围你怎么查呢?给定圆心坐标和半径,求该圆外切正方形四个顶点的坐标。不是吗?这个计算我们就用到spatial4j了。github上的地址是:https://github.com/locationtech/spatial4j


o2o附近的商家功能常见的算法:geohash和spatial4j调试实战 - 天天要闻

核心调试

1、建表,建工程

新建一个spring boot 工程,集成mybatis等,当然建个商户表,有商户名称,经纬度,geohash等字段。

CREATE TABLE `merchant` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`merchant_name` VARCHAR(64) NOT NULL COMMENT '名称',
`longitude` DOUBLE(9,6) NOT NULL COMMENT '经度',
`latitude` DOUBLE(8,6) NOT NULL COMMENT '纬度',
`geo_code` CHAR(12) NOT NULL COMMENT 'geohash编码',
PRIMARY KEY (`id`),
KEY `idx_merchant_longitude_latitude` (`longitude`,`latitude`),
KEY `idx_merchant_geo_code` (`geo_code`)
)COMMENT='商户表' CHARSET=utf8mb4 ENGINE=InnoDB;


o2o附近的商家功能常见的算法:geohash和spatial4j调试实战 - 天天要闻

2、方法一、查询附近的1km的用spatial4j实现

A、首先引入jar包:

 <dependency>
<groupId>com.spatial4j</groupId>
<artifactId>spatial4j</artifactId>
<version>0.5</version>
</dependency>


o2o附近的商家功能常见的算法:geohash和spatial4j调试实战 - 天天要闻

B、计算四个点的的值

public static void main(String[] args) {
//起始点经纬度
double lon = 116.312528, lat = 39.983733;
// 千米
int radius = 1;
SpatialContext geo = SpatialContext.GEO;
Rectangle rectangle = geo.getDistCalc().calcBoxByDistFromPt(
geo.makePoint(lon, lat),
radius * DistanceUtils.KM_TO_DEG, geo, null);

System.out.println(rectangle.getMinX() +
"-" + rectangle.getMaxX());// 经度范围
System.out.println(rectangle.getMinY() +
"-" + rectangle.getMaxY());// 纬度范围
}


o2o附近的商家功能常见的算法:geohash和spatial4j调试实战 - 天天要闻

C、根据范围,在数据库中查找即可,查到附近1km的数据。当然,经纬度最好做联合索引。这两个数据是上面算出来的。

SELECT id, merchant_name
FROM merchant
WHERE (longitude BETWEEN ? AND ?) AND (latitude BETWEEN ? AND ?);

3、根据geohash查询。此时会用到geo_code 字段。

A、引入geohash的jar包

<!-- https://mvnrepository.com/artifact/ch.hsr/geohash -->
<dependency>
<groupId>ch.hsr</groupId>
<artifactId>geohash</artifactId>
<version>1.3.0</version>
</dependency>


o2o附近的商家功能常见的算法:geohash和spatial4j调试实战 - 天天要闻

B、对照geohash的长度对应范围表,我们可以知道,查询附近1km的数据,只要长度是5就可以了。具体计算,GeohashUtils.encodeLatLon(lat, lon, 5),代入底线sql即可。

SELECT id, merchant_name
FROM merchant
WHERE geo_code LIKE CONCAT(?, '%');

o2o附近的商家功能常见的算法:geohash和spatial4j调试实战 - 天天要闻

C、但geohash有边界问题误差。因为geohash是某个区域的共同的hash,索引边界以外的距离很近的点可能造成geohash完全不同,那么怎么办呢?其实也不难解决,你这个时候把周围的八个区域的geohash都算出来即可。

public static void main(String[] args) {
// 移动设备经纬度
double lon = 116.312528, lat = 39.983733;
GeoHash geoHash = GeoHash.
withCharacterPrecision
(lat, lon, 6);
// 当前
System.out.println(geoHash.toBase32());
// N, NE, E, SE, S, SW, W, NW
System.out.println("---------------------------");
//东南西北,东北、西北、东南、西南等
GeoHash[] adjacent = geoHash.getAdjacent();
for (GeoHash hash : adjacent) {
System.out.println(hash.toBase32());
}
}

o2o附近的商家功能常见的算法:geohash和spatial4j调试实战 - 天天要闻


o2o附近的商家功能常见的算法:geohash和spatial4j调试实战 - 天天要闻

D、mysql查询,查询出这几个区域的商家即可,geohash边界问题就可以解决。

SELECT id, merchant_name
FROM merchant
WHERE geo_code IN (?, ?, ?, ?, ?, ?, ?, ?, ?);

结语

o2o中最常见的应用场景就是附近的商家,希望此篇文章对于o2o的同学有些帮助。觉得有用就点个赞转发一下吧。

另外我还调试了其他很多开源项目

Java 开源的基于微服务 Spring cloud 快速开发脚手架调试实战

超好用的 Java 开源 验证码 神器

Java 搭建的开源的spring boot商城系统实战

前后端分离的开源在线考试系统调试实战

调试个开源Java 轻量级高性能IM,单机支持几十万至百万在线用户

Java 百分之百开源 CMS 系统项目调试实战

前端牛人写的开源的CMS系统调试实战,流体布局兼容手机端浏览器

觉得有用可以给个关注哦

科技分类资讯推荐

大疆OSMO 360 完整规格 7月29日发布 - 天天要闻

大疆OSMO 360 完整规格 7月29日发布

对于那些一直在等待大疆 Osmo 360 的人来说,听到在本月底7月29日开售的消息,你们一定会很高兴。今天我偶然发现了这两款产品的完整网店描述和图片已经上线。所以,我们先来深入了解一下那款“革命性 8K” Osmo 360 的描述。
iPhone一键降温?苹果这隐藏模式有点过分啊 - 天天要闻

iPhone一键降温?苹果这隐藏模式有点过分啊

为了解决发热这亘古难题,手机厂商绞尽脑汁,往手机里塞散热膜、均热板、填充硅脂,甚至还用上了主动风扇。 但到了夏天三四十度的室外,该发热还是发热,该烫手还是烫手。 国产安卓如此。 ....
三星Galaxy S26Ultra不装了,性能太炸裂了! - 天天要闻

三星Galaxy S26Ultra不装了,性能太炸裂了!

三星Galaxy S26 Ultra即将亮相,带来多方面升级。·该机型将采用6.9英寸QHD+LTPO AMOLED显示屏,支持120Hz自适应刷新率和3000尼特峰值亮度,确保在各种光照条件下都能提供清晰的视觉体验。
中集洋山集装箱第三季度订单饱满 开拓氢能集成装备求新|公司调研 - 天天要闻

中集洋山集装箱第三季度订单饱满 开拓氢能集成装备求新|公司调研

财联社7月5日讯(记者 胡皓琼)中美关税缓和之下,外贸企业对美出货恢复,带动中集洋山集装箱制造订单增长。集装箱制造厂在提升自动化水平的同时,为提高自身抗风险能力,还正布局新赛道。财联社记者近日走访中集集团(000039.SZ)旗下中集洋山,眼见一片片钢板,经历冲压、焊接组装、打砂等一道道工序,逐渐成形。产线上布...
数据宝一体机实机首秀2025生态文明贵阳国际论坛 - 天天要闻

数据宝一体机实机首秀2025生态文明贵阳国际论坛

7月5日至6日,2025年生态文明贵阳国际论坛召开,数据宝携其AI技术领先成果重磅亮相论坛人工智能展区,并以“企业私域业务模型一体机”实机首秀,现场演绎数据资产与AI深度赋能绿色发展的创新融合实践。数据宝“企业私域业务模型一体机”。
登上C909样机,听听中国商飞工程总师怎么说?《明青讲习所》又上新了 - 天天要闻

登上C909样机,听听中国商飞工程总师怎么说?《明青讲习所》又上新了

名师金课《明青讲习所》今又上新,这期节目《“科学家精神”的回响》聚焦于“科学家精神的时代传承”,定于7月5日(周六)19:30 在上海教育电视台首播。陈明青老师带领华东师范大学第一附属中学、上海市鲁迅中学、上海南湖职业技术学院的学生们,踏上沉浸式学习之旅,走进钱学森图书馆、中国商飞上海飞机设计研究院、上海科...