V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
mofeiwo
V2EX  ›  分享发现

PHP 实现根据经纬度计算距离(已验证)

  •  
  •   mofeiwo · 2016-01-11 14:32:00 +08:00 · 6445 次点击
    这是一个创建于 3244 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在网上学习了根据经纬度计算距离的代码,很多的例子。特整理一份并且已经验证。

    /**
         * 根据两点间的经纬度计算距离
         * @param $lng1
         * @param $lat1
         * @param $lng2
         * @param $lat2
         * @return int
         */
        public static function getDistance($lng1, $lat1, $lng2, $lat2)
        {
            //将角度转为狐度
            $radLat1 = deg2rad($lat1);//deg2rad()函数将角度转换为弧度
            $radLat2 = deg2rad($lat2);
            $radLng1 = deg2rad($lng1);
            $radLng2 = deg2rad($lng2);
            $a = $radLat1 - $radLat2;
            $b = $radLng1 - $radLng2;
            $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137 * 1000;
            return $s;
        }
    

    PS :
    1 、返回的结果单位 m 。
    2 、测试 Google 地图经纬度和百度地图经纬度差 1m 左右。

    详情地址: http://blog.mofeiwo.com/?p=408

    欢迎指导。

    第 1 条附言  ·  2016-01-11 16:15:05 +08:00
    不会上传图片地址。汗。。。
    7 楼的测试图: http://blog.mofeiwo.com/wp-content/uploads/2016/01/测试.jpg
    21 条回复    2016-01-12 14:54:55 +08:00
    fising
        1
    fising  
       2016-01-11 14:35:07 +08:00
    这些不都是很成熟的东西了么
    mofeiwo
        2
    mofeiwo  
    OP
       2016-01-11 14:53:33 +08:00
    @fising 是的。 mark 下。
    imxz
        3
    imxz  
       2016-01-11 14:54:02 +08:00
    你可能没有考虑地球并不是一个完美的圆的问题。经纬度转距离跟所在位置是有关的。
    mofeiwo
        4
    mofeiwo  
    OP
       2016-01-11 14:59:17 +08:00
    @imxz 确实。稍后研究下
    BOYPT
        5
    BOYPT  
       2016-01-11 15:02:11 +08:00   ❤️ 1
    楼主辛苦了

    要是我的话,直接 google 搜索几个词"php distance longitude latitude"
    第一个结果就是 https://www.geodatasource.com/developers/php
    ferock
        6
    ferock  
       2016-01-11 15:47:47 +08:00
    @BOYPT #mark 这才是有意思的地方
    mofeiwo
        7
    mofeiwo  
    OP
       2016-01-11 16:07:59 +08:00
    @BOYPT 。测试了两个方法。发现 https://www.geodatasource.com/developers/php 方法返回的结果不对。

    使用的百度坐标是 118.703006,30.071796,118.834940,30.140164 。分别为龙须山和蓝天凹。
    从百度地图返回的距离是 14.9KM 左右。
    www.geodatasource.com 中的方法返回的是 0.9m 。
    文章中的方法返回的是: 14.8KM 。
    BOYPT
        8
    BOYPT  
       2016-01-11 16:32:10 +08:00
    @mofeiwo 那可能你算法更准吧,按你的数据,我用 geo 的程序结果是:

    echo distance(118.703006,30.071796,118.834940,30.140164, "K");
    //15.119024532788 KM

    0.9 其实是 statute miles ,不是米。
    BOYPT
        9
    BOYPT  
       2016-01-11 16:35:28 +08:00
    误差应该出在英里和公里的转换上, geo 的算法是以英里为基准的魔数 1.1515 ,而楼主的魔数 6378.137 是基于公里的;因此在公里为单位上,楼主的结果更准确;而如果在英里单位 i ,应当 geo 的更准了;

    其实代码都一样。
    hahasong
        10
    hahasong  
       2016-01-11 16:37:51 +08:00
    已经成熟的算法,网上大把,前几天刚看了一个。三角函数计算很消耗性能,有种优化的方案是只用一个 cos ,但是对精度几乎没有影响
    seki
        11
    seki  
       2016-01-11 16:39:21 +08:00
    haversine 公式嘛
    mofeiwo
        12
    mofeiwo  
    OP
       2016-01-11 16:39:50 +08:00
    @BOYPT
    地址中方法 distance($lat1, $lon1, $lat2, $lon2, $unit)。经纬度写反了。
    按照你的写法返回结果 15.119024533086KM 。

    两个方法计算方式不一样。不知道其他的情况哪个更准确了。
    mofeiwo
        13
    mofeiwo  
    OP
       2016-01-11 16:41:39 +08:00
    @BOYPT 说的有道理。
    mofeiwo
        14
    mofeiwo  
    OP
       2016-01-11 16:43:37 +08:00
    @hahasong 确实网上大把。有些还有点差异的。自己验证了下,也欢迎大牛指导,这样大家用的放心哈。
    Plumes
        15
    Plumes  
       2016-01-11 16:59:49 +08:00
    sin , cos 这些最好是使用泰勒级数展开吧,取到 o(x^3) 就可以了
    mofeiwo
        16
    mofeiwo  
    OP
       2016-01-11 17:23:04 +08:00
    @Plumes GG,表示看不懂 “泰勒级数”。 不妥的地方,补充下哈
    ty0716
        17
    ty0716  
       2016-01-11 22:17:59 +08:00
    这种距离没啥意义,计算实际路线到达距离才是正解
    mofeiwo
        18
    mofeiwo  
    OP
       2016-01-11 23:15:45 +08:00
    @ty0716 项目的需要。判断两个坐标点是否为同一个地区的。
    真实地地图中,确实没有意义的。
    NCE
        19
    NCE  
       2016-01-12 09:06:33 +08:00
    我觉得很有意义。
    NCE
        20
    NCE  
       2016-01-12 09:07:09 +08:00
    再就是,百度的坐标并不是正规的经纬度,,,这个不要和谷歌的搞混。
    mofeiwo
        21
    mofeiwo  
    OP
       2016-01-12 14:54:55 +08:00
    @NCE 接触到场景有限。百度地图在 GCJ02 协议的基础上又做了一次处理,变为 BD09 协议的坐标。与 Google 坐标有差异。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5529 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 07:02 · PVG 15:02 · LAX 23:02 · JFK 02:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.