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系统调试实战,流体布局兼容手机端浏览器

觉得有用可以给个关注哦

科技分类资讯推荐

机器狗Go1存在后门安全漏洞,宇树科技回应;OpenAI重大变化!任命了一位新CEO,奥特曼让出部分职权丨AI周报 - 天天要闻

机器狗Go1存在后门安全漏洞,宇树科技回应;OpenAI重大变化!任命了一位新CEO,奥特曼让出部分职权丨AI周报

全球AI产业周报为你精选过去一周(5.3-5.9)最值得关注的AI新闻和国内外热门AI投融资事件,帮助大家及时了解全球AI市场动向。本周AI热点资讯国内大事宇树科技回应机器狗Go1存在后门漏洞记者了解到,针对此前一些博主声称“宇树科技的Go1机器狗存在后门漏洞”的情况,宇树科技公布了调查结果。宇树科技表示,黑客非法获取了...
2025一季度算力领域增长最快的10家公司 - 天天要闻

2025一季度算力领域增长最快的10家公司

近日,据2025年5月相关消息,一季度算力增长较快的公司有纵横通信、迈信林、鸿博股份、恒润股份、康盛股份、歌华有线、全志科技、协创数据、青云科技-U、润建股份等。
“转人工”咋就这么难? - 天天要闻

“转人工”咋就这么难?

真正的智能化,应该是技术与人性化服务的有机结合,任何时候都不能偏离“以人为本”的初衷。客服的核心是“服务”,而非“应付”。“您好,有什么可以帮您?”“转人工服务。”“人工座席繁忙,请稍后再拨……”转人工,转人工,转人工……你是否也常被智能客
刘强东继外卖后又入局出租车,注册新商标 - 天天要闻

刘强东继外卖后又入局出租车,注册新商标

5月6日,天眼查财产线索信息显示,京东集团旗下子公司北京京东叁佰陆拾度电子商务有限公司,申请注册多枚“Joyrobotaxi”商标,国际分类涵盖运输工具、科学仪器、运输贮藏等核心领域,当前商标状态均为等待实质审查。这一动作被业界普遍解读为,
周单品销量榜变天,小米、华为真长国人志气 - 天天要闻

周单品销量榜变天,小米、华为真长国人志气

虽然现在苹果在国内的销量排名第六,但论单品销量谁也不是iPhone 16系列的对手。每次周单品畅销榜发布,排名前三的机型都被iPhone 16系列霸占。面对这种情况真是让人无可奈何。但是W18周这种情况没有再出来,我们先来看一下榜单再给大家
苹果宣布降价!最高便宜超1440元 - 天天要闻

苹果宣布降价!最高便宜超1440元

《科创板日报》5月10日讯,苹果向渠道商下发了调价通知,这也是苹果首次在周六宣布调价。苹果iPhone 16 Pro Max 所有容量版本降价160美元,(折合人民币1313.06元);而 iPhone 16 Pro的128GB版本降价176美元,(折合人民币1445.27元),其他版本同样降价160美元。今年的“6·18”活动将于5月13日开始,因此有渠道
2024年A股年报披露上市粤企韧性凸显,研发投入成增长新引擎 - 天天要闻

2024年A股年报披露上市粤企韧性凸显,研发投入成增长新引擎

2024年A股上市公司年报披露日前落下帷幕,面对复杂多变的国内外环境,A股上市公司营收与净利润增速小幅回落,但盈利面有所优化:74.55%的公司实现盈利,63.78%的公司净利润同比正增长,盈利企业数量与利润增长比例均较上年提升。这一表现折射出中国经济的韧性——企业通过降本增效、技术创新等方式改善盈利情况。作为上市公...
日本松下集团宣布将全球裁员1万人;苹果首款折叠屏iPhone关键部件已送样|Do早报 - 天天要闻

日本松下集团宣布将全球裁员1万人;苹果首款折叠屏iPhone关键部件已送样|Do早报

【供应链公司:苹果首款折叠屏iPhone关键部件已送样】有媒体从供应链公司人士处获悉,苹果给供应商提供的出货目标指引为2026年下半年推出首款折叠屏手机,是一款“大折叠屏iPhone”。该供应链公司是苹果手机的多个零部件供应商。该供应链公司表示,希望进入折叠屏iPhone的关键部件供应商名单,近期相关部件已送样测试;但要...