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的關鍵部件供應商名單,近期相關部件已送樣測試;但要...