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


LBS 球面距離公式

http://wiki.myoa.info/zh-blog:20

 

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

最近做一個項目:需要查詢一個站點(已知該站點經緯度)500米范圍內的其它站點。所以,我首先想到的是,對每條記錄,去進行遍歷,跟數據庫中的每一個點進行距離計算,當距離小於500米時,認為匹配。這樣做確實能夠得到結果,但是效率極其低下,因為每條記錄都要去循環匹配n條數據,其消耗的時間可想而知。

於是我就想到一個先過濾出大概的經緯度范圍再進行計算。比方說正方形的四個點,於是我在網上搜索,意外的,查詢到了一個關於這個計算附近地點搜索初探,里面使用python實現了這個想法。所以參考了一下原文中的算法,使用JAVA進行了實現。

實現原理也是很相似的,先算出該點周圍的矩形的四個點,然后使用經緯度去直接匹配數據庫中的記錄。

思路:首先算出“給定坐標附近500米”這個范圍的坐標范圍。 雖然它是個圓,但我們可以先求出該圓的外接正方形,然后拿正方形的經緯度范圍去搜索數據庫。

先來求東西兩側的的范圍邊界。在haversin公式中令φ1 = φ2,可得

然后求南北兩側的范圍邊界,在haversin公式中令 Δλ = 0,可得

    ⊿φ = d/R

用Java代碼寫就是

/先計算查詢點的經緯度范圍<span style="font-family: 微軟雅黑, Helvetica, Times, Arial, serif;">lat已知緯度,lng已知經度</span>  
        double R = 6371.137;//R為地球半徑,可取平均值 6371.137km
        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)
綜合也就是這樣進行篩選查詢

 

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;  
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM