計算球面上的兩點(座標爲經緯度)之間的距離可以直接通過公式計算得到,也可以先將經緯度座標轉化爲墨卡託投影座標來,然後用平面中兩點之間的距離公式來計算。
在網上找了一些代碼,然後簡單進行了測試,發現前者精度更高:
資料來源: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 }