已知经纬度计算距离

Author Avatar
ieayoio 12月 02, 2016
  • 在其它设备中阅读本文章

最近做了一些计算最近附近商店距离的工作,距离计算原以为两个数和的平方再开根号那么简单,然而真去做的时候才知道太天真了,经线上纬度每差一度可以有一个确定的值,然而,因为纬线圈的长度随着纬度的改变而改变,不能单纯的计算每个单位经度上距离的一个确定值。
经过一番的查找,原来计算距离有一个公式如下:
$$ S = 2 arcsin\sqrt{sin^2\frac a2 + cos(Lat1) × cos(Lat2) × sin^2\frac b2} × 6378.137 $$

  1. Lat1 Lung1 表示A点经纬度,Lat2 Lung2 表示B点经纬度,这里的单位是弧度而不是角度;

  2. a=Lat1 – Lat2 为两点纬度之差 b=Lung1 -Lung2 为两点经度之差;

  3. 6378.137为地球半径,单位为千米;

从公式中可以看到两点的经度Lung1和Lung2没有包含在公式中,而只是包含在差值之中。

知道公式了,网上的各种教程无非就是套用公式,例如数据库要查询可以写一个自定义的函数,一下以mysql为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
DROP FUNCTION IF EXISTS GetDistance;
DELIMITER $$
CREATE FUNCTION GetDistance(LatBegin DOUBLE, LngBegin DOUBLE, LatEnd DOUBLE, LngEnd DOUBLE)
RETURNS DOUBLE
BEGIN
DECLARE Distance DOUBLE;
DECLARE EARTH_RADIUS DOUBLE;
DECLARE RadLatBegin,RadLatEnd,RadLatDiff,RadLngDiff DOUBLE;
SET EARTH_RADIUS = 6378.137;
SET RadLatBegin = LatBegin * PI()/180.0;
SET RadLatEnd = LatEnd * PI()/180.0;
SET RadLatDiff = RadLatBegin - RadLatEnd;
SET RadLngDiff = LngBegin * PI()/180.0 - LngEnd * PI()/180.0;
SET Distance = 2 *ASIN(SQRT(POWER(SIN(RadLatDiff/2), 2)+COS(RadLatBegin)*COS(RadLatEnd)*POWER(SIN(RadLngDiff/2), 2)));
SET Distance = Distance * EARTH_RADIUS;
RETURN Distance;
END $$
DELIMITER ;

这样定义一个自定义函数之后就可以直接利用这个函数进行数据库的查询和排序,例如:

1
SELECT * FROM `shop` WHERE GetDistance(`double_latitude`,`double_longitude`,34.54,234.4) < 5 ORDER BY GetDistance(`double_latitude`,`double_longitude`,34.54,234.4) DESC LIMIT 1,20

另外再提供一个Java版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import static java.lang.Math.*;

/**
* Created by ieayoio on 16-12-2.
*/
public class DistanceUtils {

public static double getDistance(double LatBegin, double LngBegin, double LatEnd, double LngEnd) {

double EARTH_RADIUS = 6378.137;

double RadLatBegin = LatBegin * PI / 180.0;
double RadLatEnd = LatEnd * PI / 180.0;
double RadLatDiff = RadLatBegin - RadLatEnd;
double RadLngDiff = LngBegin * PI / 180.0 - LngEnd * PI / 180.0;

double Distance = 2 * asin(sqrt(pow(sin(RadLatDiff / 2), 2) + cos(RadLatBegin) * cos(RadLatEnd) * pow(sin(RadLngDiff / 2), 2)));
return Distance * EARTH_RADIUS;
}
}

参考资料:
https://zhidao.baidu.com/question/401287294.html
http://blog.csdn.net/smartsmile2012/article/details/45339787
http://blog.csdn.net/xiyang_1990/article/details/16803735


该博文来自于ieayoio的博客:ieayoio’s blog

本文链接:http://www.ieayoio.com/2016/12/02/已知经纬度计算距离/