计算球面上的两点(坐标为经纬度)之间的距离可以直接通过公式计算得到,也可以先将经纬度坐标转化为墨卡托投影坐标来,然后用平面中两点之间的距离公式来计算。
在网上找了一些代码,然后简单进行了测试,发现前者精度更高:
资料来源: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 }
时间: 2024-10-10 23:51:47