在作和地圖有關的項目的時候,有時候會遇到這樣的需求,好比:
已知圓中心的經緯度(lng, lat)
,手動輸入它的半徑radius
,獲得這個圓範圍內全部的隨機點。java
我用的是百度地圖js-sdk。
理論部分,喜歡看代碼能夠直接跳過:sql
從上圖能夠看出,圓1的經緯度是(114.132384, 22.539816)用(x1, y1)表示,圓2的經緯度是(114.131888, 22.533516)用(x2, y2)表示
我不可能用abs(x1 - x2) + abs(y1 - y2) <= radius
這樣的邏輯去判斷圓1是否在以圓2爲中心點,radius爲半徑的圓範圍內,由於這樣不是兩點之間的最佳路徑。(abs爲取絕對值函數)數據庫
我須要用到初中數學學到過的勾股定理知識,用(abs(x1-x2))^2 + (abs(y1-y2))^2 <= radius^2
來得到兩點之間最短路徑,也就是把這個想象成一個直角三角形,求它的斜邊。mybatis
我經過js將原點的經緯度和半徑傳到後臺,後臺用java,用的是mybatis框架,數據庫用的Oracle。
js和java就是簡單的數據傳輸,能夠省略,業務邏輯主要在sql部分:框架
表結構:車牌號,緯度,經度,時間。
先根據相同車牌號用GROUP BY去重,取最大時間的一條數據。函數
求圓半徑內點的sql代碼:spa
SELECT G1.* FROM ${tableName} G1, ( SELECT MIN(UUID) AS UUID, MAX(LOCATIONTIME) FROM ${tableName} GROUP BY VEHICLENO ) G2 WHERE G1.UUID = G2.UUID AND POWER(ABS((G1.LAT / 0.00000899 - #{lat} / 0.00000899)), 2) + POWER(ABS((G1.LON / 0.00001141 - #{lon} / 0.00001141)), 2) <![CDATA[<=]]> POWER(#{radius}, 2) AND VEHICLENO LIKE CONCAT(#{chepaihao}, '%')
主要的業務是這句:code
POWER(ABS((G1.LAT / 0.00000899 - #{lat} / 0.00000899)), 2) + POWER(ABS((G1.LON / 0.00001141 - #{lon} / 0.00001141)), 2) <![CDATA[<=]]> POWER(#{radius}, 2)
0.00000899是緯度和米的比例關係: 1m = 0.00000899°
0.00001141是經度和米的比例關係: 1m = 0.00001141°blog
最後根據車牌號模塊查詢。ip