計算球面上經緯度座標方法比較

計算球面上的兩點(座標爲經緯度)之間的距離可以直接通過公式計算得到,也可以先將經緯度座標轉化爲墨卡託投影座標來,然後用平面中兩點之間的距離公式來計算。

在網上找了一些代碼,然後簡單進行了測試,發現前者精度更高:

 資料來源:http://0414.iteye.com/blog/2039199

     http://blog.sina.com.cn/s/blog_8ab3b2cf0100xd69.html

 

 1 package com.suncreate.spatialquery.web.utils;
 2 
 3 public class LatitudeLontitudeUtil2 {  
 4 
 5     // http://blog.charlee.li/location-search/  
 6 
 7     /** 地球半徑 */  
 8     private static final double EARTH_RADIUS = 6371393;  
 9 
10     static double M_PI = Math.PI;
11 
12     public LatitudeLontitudeUtil2() {  
13 
14     }  
15 
16     //經緯度轉墨卡託
17     public static double[] lonLat2Mercator(double lon,double lat)
18     {
19         double[] xy = new double[2];
20         double x = lon *20037508.342789/180;
21         double y = Math.log(Math.tan((90+lat)*M_PI/360))/(M_PI/180);
22         y = y *20037508.34789/180;
23         xy[0] = x;
24         xy[1] = y;
25         return xy;
26     }
27     
28     //點到點距離算法一
29     public static double getDistance2(double lat0, double lng0, double lat1, double lng1) {  
30         double[] xy = new double[2];
31         
32         System.out.println("----原始經緯度座標----");
33         System.out.println("lat0:"+lat0+",lng0:"+lng0);
34         System.out.println("lat1:"+lat1+",lng1:"+lng1);
35         
36         xy =LatitudeLontitudeUtil2.lonLat2Mercator(lng0, lat0);
37         double lat0m= xy[1];
38         double lng0m= xy[0];
39         
40         xy =LatitudeLontitudeUtil2.lonLat2Mercator(lng1, lat1);
41         double lat1m= xy[1];
42         double lng1m= xy[0];
43         
44         System.out.println("----轉化後墨卡託座標----");
45         System.out.println("lat0m:"+lat0m+",lng0m:"+lng0m);
46         System.out.println("lat1m:"+lat1m+",lng1m:"+lng1m);
47          
48         double distance = 0; 
49         distance= Math.sqrt((lat0m - lat1m) * (lat0m - lat1m) + (lng0m - lng1m) * (lng0m - lng1m));
50         return distance;  
51     }  
52     //點到點距離算法二
53     public static double getDistance(double lat0, double lng0, double lat1, double lng1) {  
54 
55         lat0 = Math.toRadians(lat0);  
56         lat1 = Math.toRadians(lat1);  
57         lng0 = Math.toRadians(lng0);  
58         lng1 = Math.toRadians(lng1);  
59 
60         double dlng = Math.abs(lng0 - lng1);  
61         double dlat = Math.abs(lat0 - lat1);  
62         double h = hav(dlat) + Math.cos(lat0) * Math.cos(lat1) * hav(dlng);  
63         double distance = 2 * EARTH_RADIUS * Math.asin(Math.sqrt(h));  
64 
65         return distance;  
66     }  
67     
68     public static double hav(double theta) {  
69         double s = Math.sin(theta / 2);  
70         return s * s;  
71     }  
72     
73     public static void main(String[] args) {  
74         //測試用例
75         //117.222009,31.815101   祁門路天鵝湖左
76         //117.238718,31.815132   祁門路天鵝湖右
77         
78         double lat = 31.815101;  
79         double lng = 117.222009;  
80         
81         double lat1 = 31.815132 ;  
82         double lng1 = 117.238718;  
83         
84         double d = LatitudeLontitudeUtil2.getDistance(lat, lng, lat1, lng1);  
85         double d2 = LatitudeLontitudeUtil2.getDistance2(lat, lng, lat1, lng1);
86         
87         System.out.println(d); 
88         System.out.println(d2); 
89         
90         //百度地圖測距約爲1.6km,可知直接計算球面距離較爲準確,而直接先將經緯度轉化爲墨卡託座標再求距離不準
91     }  
92 }  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章