如題所描述的場(chǎng)景有很多,比如以自己所在的位置為圓點(diǎn)乡革,搜索附近的商鋪或者銀行等寇僧;再或者通過打車軟件叫車時(shí),以自己所在位置為圓點(diǎn)沸版,搜索附近可供服務(wù)的車輛或司機(jī)等嘁傀。
1 所需要的信息
圓點(diǎn)的位置信息(1個(gè)),附近物體上報(bào)的位置信息(N個(gè))视粮。
2 常用的技術(shù)方案
利用數(shù)據(jù)庫(mysql细办、oracle)提供的空間解析函數(shù),掃表逐個(gè)計(jì)算兩點(diǎn)之間的距離蕾殴,然后進(jìn)行比較判斷笑撞。此方案當(dāng)位置表數(shù)據(jù)量很大時(shí)岛啸,速度很慢。
3 優(yōu)化后的方案:Geohash算法+數(shù)據(jù)庫空間解析函數(shù)
實(shí)現(xiàn)流程簡(jiǎn)要如下:
(1)司機(jī)或車輛的位置信息上報(bào)時(shí)茴肥,使用Geohash算法進(jìn)行編碼后坚踩,保存入庫。
(2)查詢時(shí)根據(jù)圈選半徑選取合適的精讀分段級(jí)別瓤狐,依據(jù)指定級(jí)別查詢數(shù)據(jù)庫瞬铸。
(3)查詢的同時(shí),使用空間解析函數(shù)進(jìn)行距離計(jì)算并進(jìn)行過濾芬首。
補(bǔ)充說明:
(1)未防止查詢到的數(shù)據(jù)量過大赴捞,可根據(jù)距離默認(rèn)進(jìn)行排序,限制返回?cái)?shù)據(jù)的條數(shù)郁稍。
(2)為減少前期計(jì)算的數(shù)據(jù)量赦政,可通過對(duì)數(shù)據(jù)提前標(biāo)記業(yè)務(wù)標(biāo)簽的方式進(jìn)行提前初篩過濾。
4 實(shí)例:
以所處時(shí)間(2023-05-16 15:51:36)耀怜,圈選司機(jī)入?yún)? lng:113.814829, lat:22.633092, 圈選半徑:50000米, 時(shí)間窗口:5min恢着,物理車型:1018,1019,1020,圈選司機(jī):
select tt.driver_id from
(
select
t1.driver_id,
st_distance_sphere(ST_POINTFROMTEXT('POINT(113.814829 22.633092)'),t1.gis) as distance
from driver_location_info t1
inner join driver_tag_info t2
on t1.driver_id = t2.driver_id
where
t1.geo_hash_three in ( 'ws0' , 'ws2' , 'ws3' , 'ws1' , 'wec' , 'web' , 'w7z' , 'wkp' , 'wkr' )
and t2.physics_vehicle_id in (1018,1019,1020)
and t1.location_time BETWEEN '2023-05-16 15:46:36' and '2023-05-16 15:51:36'
) as tt
where tt.distance <= 50000 order by tt.distance asc limit 1000;
MySQL官方提供的空間解析函數(shù)
1财破、Point(x, y)
作用:構(gòu)造坐標(biāo)掰派,后面的空間函數(shù)會(huì)用到。以地球?yàn)槔罅。谶@個(gè)函數(shù)里x代表經(jīng)度靡羡,y代表緯度。2俊性、ST_Distance(g1, g2)
作用:計(jì)算 g1 和 g2 之間的直線距離略步。3、ST_Distance_Sphere(g1, g2 [, radius])
作用:MySQL5.7版本新增定页,用于計(jì)算球體上兩點(diǎn)之間的最短球面距離(以米為單位)趟薄,默認(rèn)半徑值為:6,370,986米(地球的半徑),不輸入radius參數(shù)默認(rèn)計(jì)算地球兩點(diǎn)之間的最短球面距離典徊。
實(shí)例1-使用Mysql空間解析函數(shù)杭煎,計(jì)算兩個(gè)經(jīng)緯度點(diǎn)之間的最短球面距離
實(shí)例2-使用Mysql空間解析函數(shù),搜索指定范圍之內(nèi)的數(shù)據(jù)
更多空間解析函數(shù)見官方文檔:
MySQL5.7版本:
https://dev.mysql.com/doc/refman/5.7/en/spatial-function-reference.html
MySQL8.0版本:
https://dev.mysql.com/doc/refman/8.0/en/spatial-function-reference.html