最近作一個項目:須要查詢一個站點(已知該站點經緯度)500米範圍內的其它站點。因此,我首先想到的是,對每條記錄,去進行遍歷,跟數據庫中的每個點進行距離計算,當距離小於500米時,認爲匹配。這樣作確實可以獲得結果,可是效率極其低下,由於每條記錄都要去循環匹配n條數據,其消耗的時間可想而知。java
因而我就想到一個先過濾出大概的經緯度範圍再進行計算。比方說正方形的四個點,因而我在網上搜索,意外的,查詢到了一個關於這個計算附近地點搜索初探,裏面使用python實現了這個想法。因此參考了一下原文中的算法,使用JAVA進行了實現。python
實現原理也是很類似的,先算出該點周圍的矩形的四個點,而後使用經緯度去直接匹配數據庫中的記錄。git
思路:首先算出「給定座標附近500米」這個範圍的座標範圍。 雖然它是個圓,但咱們能夠先求出該圓的外接正方形,而後拿正方形的經緯度範圍去搜索數據庫。算法
先來求東西兩側的的範圍邊界。在haversin公式中令φ1 = φ2,數據庫
用Java代碼寫就是code
//先計算查詢點的經緯度範圍lat已知緯度,lng已知經度 double r = 6371;//地球半徑公里 double dis = 0.5;//0.5公里距離 double dlng = 2*Math.asin(Math.sin(dis/(2*r))/Math.cos(lat*Math.PI/180)); dlng = dlng*180/Math.PI;//角度轉爲弧度 double dlat = dis/r; dlat = dlat*180/Math.PI;
最後,就能夠得出四個點的座標:
left-top : (lat + dlat, lng – dlng)
right-top : (lat + dlat, lng + dlng)
left-bottom : (lat – dlat, lng – dlng)
right-bottom: (lat – dlat, lng + dlng)
綜合也就是這樣進行篩選查詢get
public List<Property> findNeighPosition(double longitude,double latitude){ //先計算查詢點的經緯度範圍 double r = 6371;//地球半徑公里 double dis = 0.5;//0.5公里距離 double dlng = 2*Math.asin(Math.sin(dis/(2*r))/Math.cos(latitude*Math.PI/180)); dlng = dlng*180/Math.PI;//角度轉爲弧度 double dlat = dis/r; dlat = dlat*180/Math.PI; double minlat =latitude-dlat; double maxlat = latitude+dlat; double minlng = longitude -dlng; double maxlng = longitude + dlng; String hql = "from Property where longitude>=? and longitude =<? and latitude>=? latitude=<? and state=0"; Object[] values = {minlng,maxlng,minlat,maxlat}; List<Property> list = find(hql, values); return list; }