最近创业的一个产品要用到计算两个GIS点的距离,搜了下网上,关于这个的还真少。高中时读的X科是地理,结合了一下解释几何,收集了如下解决方案。
一、代码实现(oracle)
一、代码实现(oracle)
Create Or Replace Function get_earth_distance(lon1 Number,
lat1 Number,
lon2 Number,
lat2 Number) Return Number As
rad_lon1 Number(12, 8);
rad_lat1 Number(12, 8);
rad_lon2 Number(12, 8);
rad_lat2 Number(12, 8);
a Number(12, 8);
b Number(12, 8);
pi Number := 3.14159265;
s Number(20, 8);
EARTH_RADIUS Number := 6378.137;
Begin
rad_lat1 := lat1 * pi / 180.0;
rad_lat2 := lat2 * pi / 180.0;
rad_lon1 := lon1 * pi / 180.0;
rad_lon2 := lon2 * pi / 180.0;
a := rad_lat1 - rad_lat2;
b := rad_lon1 - rad_lon2;
s := 2 * asin(sqrt(power(sin(a / 2), 2)
cos(rad_lat1) * cos(rad_lat2) *
power(sin(b / 2), 2)));
s := s * EARTH_RADIUS;
s := round(s * 100000) / 100000;
s := s * 1000;
Return s;
End get_earth_distance;
计算精度与谷歌地图的距离精度差不多,相差范围在0.2米以下。
二、关于经纬度十进制表示法
对于两个点,在纬度相等的情况下:
经度每隔0.00001度,距离相差约1米;每隔0.0001度,距离相差约10米;每隔0.001度,距离相差约100米;每隔0.01度,距离相差约1000米;每隔0.1度,距离相差约10000米。
对于两个点,在经度相等的情况下:
纬度每隔0.00001度,距离相差约1.1米;每隔0.0001度,距离相差约11米;每隔0.001度,距离相差约111米;每隔0.01度,距离相差约1113米;每隔0.1度,距离相差约11132米
方便的改成sql语句
假设计算118.041 36.793与数据库内坐标点的距离
mysql> select 6378137*2*asin(Sqrt(power(sin((36.793-domlat)*pi()/360),2) + Cos(36.793*pi()/180)*Cos(domlat*pi()/180)*power(sin((118.041-domlon)*pi()/360),2))) as distance,domip from dominfo order by distance;
精简一下啊
select 12756274*asin(Sqrt(power(sin((36.793-domlat)*0.008726646),2) + Cos(36.793*0.0174533)*Cos(domlat*0.0174533)*power(sin((118.041-domlon)*0.008726646),2))) as distance,domip from dominfo order by distance;
三、 Java算法
三、 Java算法
public static double geographicDistance(double lng1, double lat1, double lng2, double lat2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLng = Math.toRadians(lng2 - lng1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double distance = EARTH_RADIUS * c;
return new BigDecimal(distance).intValue();
}
地理知识我就不再说了,可以翻高中的课本,呵呵。