背景
????緩沖區(qū)查詢是非常常見的空間查詢,用來(lái)查詢周邊的信息方庭。本文介紹了H3來(lái)進(jìn)行緩沖區(qū)查詢的方案翩瓜。
H3簡(jiǎn)介
????H3是由Uber開源的一個(gè)六邊形分層索引網(wǎng)格系統(tǒng),也是最近幾年實(shí)現(xiàn)數(shù)據(jù)聚合的主要趨勢(shì)序无,在H3出現(xiàn)之前大部分情況采用的是Geohash算法验毡,墨卡托投影,還有一些其他投影技術(shù)帝嗡,比如Google S2地理索引晶通。
????在不同緯度的地區(qū)使用等面積、等形狀的六邊形地理單元可以減少指標(biāo)和特征歸一化的成本哟玷。另一方面狮辽,在常用的地理范圍查詢中,基于矩形的查詢方法,存在 8 鄰域到中心網(wǎng)格的距離不相等的問題喉脖,四邊形存在兩類長(zhǎng)度不等的距離椰苟,而六邊形的周圍鄰居到中心網(wǎng)格的距離卻是有且僅有一個(gè),從形狀上來(lái)說(shuō)更加接近于圓形树叽。
具體思路步驟
????創(chuàng)建表按H3來(lái)分區(qū)尊剔,分區(qū)不超過(guò)一千個(gè)最好
CREATE TABLE pntsh3 ENGINE = MergeTree() PARTITION BY (geoh3) order by (geoh3,Lon,Lat) AS select id,geoToH3( toFloat64(Lon), toFloat64(Lat),3) geoh3,toFloat64(Lon) Lon, toFloat64(Lat) Lat from pnts
????計(jì)算需要緩沖區(qū)范圍內(nèi)幾個(gè)該級(jí)別下幾個(gè)格子可以覆蓋ceil(200000/h3EdgeLengthM(3)/2+1, 0)),得到H3集合菱皆。計(jì)算公式大概就是用距離處理六邊形兩邊和再加上一個(gè)一邊長(zhǎng)须误,結(jié)果向上取整
select Lon, Lat,id from pntsh3 where geoh3 in (select arrayJoin(h3kRing(geoToH3(-120.419219,34.889755999999998, 3), toInt64(ceil(200000/h3EdgeLengthM(3)/2+1, 0))))) and greatCircleDistance(Lon,Lat,-120.419219,34.889755999999998) <=200000
select Lon, Lat,id from pntsh3 where geoh3 in (select arrayJoin(h3kRing(geoToH3(-120.419219,34.889755999999998, 3), toInt64(ceil(200/h3EdgeLengthM(3)/2+1, 0))))) and greatCircleDistance(Lon,Lat,-120.419219,34.889755999999998) <=200
????相對(duì)于暴力計(jì)算,無(wú)論緩沖區(qū)大小均有一定提升
select Lon, Lat,id from pntsh3 where greatCircleDistance(Lon,Lat,-120.419219,34.889755999999998) <=200000
select Lon, Lat,id from pntsh3 where greatCircleDistance(Lon,Lat,-120.419219,34.889755999999998) <=200
????通過(guò)H3索引的合理使用仇轻,有效減少了全表掃描京痢,提升查詢速度
參考資料:
https://www.biaodianfu.com/uber-h3.html
https://github.com/uber/h3-js#module_h3.h3Distance
https://zhuanlan.zhihu.com/p/60861179