获取地球上2个坐标之间的距离

时间:2015-10-04 00:58:39

标签: mysql haversine

我尝试使用here

中的公式获得2个坐标之间的距离

坐标为1.5378236000,110.3372347000和1.5395056000,110.3373156000。

不知何故,结果变得非常不同。我相信" dist1"是在KM但不确定" dist2"。

CREATE DEFINER=`root`@`localhost` FUNCTION `GetDistance`(
 lat1  numeric (9,6),
 lon1  numeric (9,6),
 lat2  numeric (9,6),
 lon2  numeric (9,6)
) RETURNS decimal(10,5)
    READS SQL DATA
BEGIN
/* http://www.codecodex.com/wiki/Calculate_distance_between_two_points_on_a_globe#MySQL */
  DECLARE  x  decimal (20,10);
  DECLARE  pi  decimal (21,20);
  SET  pi = 3.14159265358979323846;
  SET  x = sin( lat1 * pi/180 ) * sin( lat2 * pi/180  ) + cos(
 lat1 *pi/180 ) * cos( lat2 * pi/180 ) * cos(  abs( (lon2 * pi/180) -
 (lon1 *pi/180) ) );
  SET  x = acos( x );
  RETURN  ( 1.852 * 60.0 * ((x/pi)*180) ) / 1.609344;
END

结果 dist1:12091.536526805385
dist2:0.11190

GetDistance功能

{yourImageName.Source = new BitmapImage(new Uri("ms-appx:///Assets/LOGO.png"));}

3 个答案:

答案 0 :(得分:1)

这是准确的方法

    public static double elongation(double longitude1, double latitude1, 
            double longitude2, double latitude2)
    {
        return Math.Acos(1 - 2 * (hav(latitude1 - latitude2)
            + Math.Cos(RAD * latitude1) * math.Cos(RAD * latitude2)
            * hav(longitude1 - longitude2))) / RAD;
    }

当功能“hav”

    static public double hav(double x)
    {
        return 0.5 - 0.5 * Math.Cos(RAD * x);
    }

答案 1 :(得分:0)

第一个函数获得长距离(如果你在全球范围内走很远的距离)

如果你采取捷径,第二个是距离。

看看这两点,他们非常接近另一个。这就像环游世界只是为了过马路。 :d

第二个距离仍在KM中,它只是很短。地球的周长刚超过12,000公里。

答案 2 :(得分:0)

你的第一个表达有错误。你正在考虑纬度和经度之差的余弦。在这个术语中,你应该考虑起始和结束经度之间的差异。

用于计算纬度和经度点对之间距离的余弦定律(或半正弦)公式如下:

   DEGREES(ACOS(COS(RADIANS(lat1)) * COS(RADIANS(lat2)) *
                COS(RADIANS(long1) - RADIANS(long2)) +
                SIN(RADIANS(lat1)) * SIN(RADIANS(lat2))))

这会产生度数结果。

您问题中的第一个表达式采用此形式。如您所见,您有正确的公式,但是您输入的参数不正确。

 6371 * acos( cos( radians(lat1)) * cos( radians( long1 )) * /*should be lat1, lat 2*/
              cos( radians( lat1) - radians(long1 ))         /*should be long1,long2*/
              sin( radians(lat1) ) * sin( radians(long2 )))  /*should be lat1, lat2 */

你的第一点似乎是在马来西亚的古晋,就在Green和Ahmad Zaidi街道交界处的南边。第二点是那里的一个街区。 (根据你的第二个结果,它位于北方约112米处)。请注意,我写的距离公式以弧度为单位。你以度数给它lat / long点,它返回一个以度为单位的距离。为了将度数转换为km(更有用的测量),您需要知道每度数多少km。

请注意,您的公式版本包含幻数6371.这会将ACOS()函数产生的弧度转换为度数,然后转换为km,使用每度111.195 km的常量。这是可接受的价值;地球在赤道上略微膨胀。

此外,您存储的函数在同一个术语中具有不必要的ABS。由于十进制算术,它的效率也非常低。 MySQL使用DOUBLE(ieee 64位浮动)算法来完成所有计算,但它编码的方式需要大量浪费且可能精确丢失的转换来回到十进制。

如果你使用商业级GPS坐标,32位FLOAT算法就足够了。

以下是对此材料的详尽解释。 http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/