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系統調試實戰,流體布局兼容手機端瀏覽器

覺得有用可以給個關注哦

科技分類資訊推薦

大潤發卡回收平台 - 天天要聞

大潤發卡回收平台

隨著生活壓力的增大,以及人們的時間越來越有限,網購成為了現代年輕人的主要購物方式。它給消費者帶來了便利,同時也給實體購物場所帶來了壓力。很多人在將線下購物和網購進行對比後,認為網購更符合自己購物的喜好和要求,因此會選擇在網上購物,所以有線下實體購物卡也會選擇將其回收。
FedEx到了國內誰派送 - 天天要聞

FedEx到了國內誰派送

當我們在國內網購產品時,有時候會遇到一些需要美國FedEx快遞運送的商品。那麼當這些貨物運抵國內時,由誰來派送呢?在本文中,我們將從不同的角度來探討這個問題。首先,我們從FedEx國內合作夥伴的角度來考慮。
我國移動互聯網用戶數突破15億戶 - 天天要聞

我國移動互聯網用戶數突破15億戶

(致新/文)9月22日消息,據工信部統計,截至2023年8月末,我國移動互聯網用戶數達15.01億戶,比上年末凈增4710萬戶。2023年1—8月份,移動互聯網累計流量達1932億GB,同比增長14.7%,增速與1—7月份持平。8月當月戶均移動互聯網接入流量(DOU)達到16.
iPhone 15系列,換著花樣在中國撈錢! - 天天要聞

iPhone 15系列,換著花樣在中國撈錢!

華為被美國制裁這幾年,最受益的無疑是蘋果公司,因為在中國高端手機市場上,蘋果一家就獨佔了67%的市場份額。根據IDC公布的數據顯示,中國市場600美元以上價位,蘋果就佔據了67%的份額,排在第二名的華為只有15.6%的份額,其原因就是華為被美國制裁影響了產品的競爭力。