Java,Mysql-根據一個給定經緯度的點,進行附近500米地點查詢–合理利用算法

最近作一個項目:須要查詢一個站點(已知該站點經緯度)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;  
    }
相關文章
相關標籤/搜索