计算球面上经纬度坐标方法比较

计算球面上的两点(坐标为经纬度)之间的距离可以直接通过公式计算得到,也可以先将经纬度坐标转化为墨卡托投影坐标来,然后用平面中两点之间的距离公式来计算。

在网上找了一些代码,然后简单进行了测试,发现前者精度更高:

 资料来源: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 }  
原文地址:https://www.cnblogs.com/chuang8/p/4556116.html