京东6.18大促主会场领京享红包更优惠

 找回密码
 立即注册

QQ登录

只需一步,快速开始

PHP中经纬度坐标相关计算方法小结

2024-11-4 08:38| 发布者: c2688| 查看: 144| 评论: 0

摘要: 目录1. 媒介2. 计算经纬度坐标间的距离3. 根据经纬度坐标距离排序4. 经纬度范围查询1. 媒介 想要测试本文提供的几个功能函数,可以使用下面这个数据表布局及其数据 [code]CREATE TABLE `user` ( `id` int(10) unsign
目录

1. 媒介

想要测试本文提供的几个功能函数,可以使用下面这个数据表布局及其数据

[code]CREATE TABLE `user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id', `name` varchar(60) DEFAULT NULL COMMENT '昵称', `longitude` varchar(64) DEFAULT NULL COMMENT '经度', `latitude` varchar(64) DEFAULT NULL COMMENT '纬度', `remark` varchar(50) DEFAULT NULL COMMENT '备注', `distance` varchar(20) DEFAULT NULL COMMENT '距离', PRIMARY KEY (`id`) ) ENGINE=InnoDB COMMENT='用户表'; INSERT INTO `user` (`name`, `longitude`, `latitude`, `remark`, `distance`) VALUES ('中海九号公馆', '113.899529', '22.60063', '深圳市宝安区中海九号公馆', '3.66km'); INSERT INTO `user` (`name`, `longitude`, `latitude`, `remark`, `distance`) VALUES ('平峦山公园', '113.876462', '22.608322', '深圳市宝安区平峦山公园', '2.88km'); INSERT INTO `user` (`name`, `longitude`, `latitude`, `remark`, `distance`) VALUES ('铁仔山公园', '113.86359', '22.592355', '深圳市宝安区铁仔山公园', '1.16km'); INSERT INTO `user` (`name`, `longitude`, `latitude`, `remark`, `distance`) VALUES ('宝安公园', '113.902671', '22.58621', '深圳市宝安区宝安公园', '3.45km');[/code]

本文内容测试各个功能函数时,使用的当前位置坐标均为:

[code]// 深圳市宝安区西乡街道九方广场 $longitude = '113.869205';//经度 $latitude = '22.583286';//纬度[/code]

2. 计算经纬度坐标间的距离

计算经纬度坐标间的距离 功能函数 (前四个参数为两组经纬度坐标)

[code]/** * 计算经纬度坐标间的距离 * @param $lng1 经度 * @param $lat1 纬度 * @param $lng2 经度 * @param $lat2 纬度 * @param $lang 语言 */ function get_distance($lng1, $lat1, $lng2, $lat2, $lang = 'en') { // 地球的近似半径(单位:米) $earthRadius = 6367000; // 将这些度数转换为弧度以使用公式 $lat1 = ($lat1 * pi()) / 180; $lng1 = ($lng1 * pi()) / 180; $lat2 = ($lat2 * pi()) / 180; $lng2 = ($lng2 * pi()) / 180; // 使用 Haversine 公示计算距离 // http://en.wikipedia.org/wiki/Haversine_formula $calcLongitude = $lng2 - $lng1; $calcLatitude = $lat2 - $lat1; $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2); $stepTwo = 2 * asin(min(1, sqrt($stepOne))); // 两个经纬度坐标的距离(单位: 米) $calculatedDistance = round($earthRadius * $stepTwo); // 距离单位 $language = [ 'en' => ['m' => 'm', 'km' => 'km'], 'cn' => ['m' => '米', 'km' => '公里'], ]; if (!isset($language[$lang])) throw new \Exception('不支持的语言:' . $lang); foreach ($language[$lang] as $key => $value) $$key = $value; // 两个坐标间的距离,单位:米 $distance = round($calculatedDistance); // 距离单位转换:超出 1000m 时单位转为km if ($distance < 1000) { $distance .= $m; } else { $distance = floatval(number_format($distance / 1000, 2)) . $km; } return $distance; // 返回单位转换后的距离 }[/code]

使用示例:

我在 九方广场,手机上的高德地图导航至 中海九号公馆 表现的距离为 3.6公里,计算结果还是很精确的

[code]// 深圳市宝安区西乡街道九方广场: 113.869205, 22.583286 // 深圳市宝安区西乡街道中海九号公馆: 113.899529, 22.60063 $distance = get_distance(113.869205, 22.583286, 113.899529, 22.60063); echo $distance; //3.66km[/code]

3. 根据经纬度坐标距离排序

项目中常常有距离表现数据的场景,根据距离排序,越近越靠前表现;比如: 店肆地址、房源信息等。代码示例:

[code]// 当前坐标 $longitude = '113.869205'; $latitude = '22.583286'; // 数据库中经纬度字段分别为:longitude、latitude $field = '*,( 2 * 6378.137 * ASIN( SQRT( POW( SIN( PI() * (' . $longitude . ' - longitude) / 360 ), 2 ) + COS(PI() * ' . $latitude . ' / 180) * COS(latitude * PI() / 180) * POW( SIN( PI() * (' . $latitude . ' - latitude) / 360 ), 2 ) ) ) ) AS juli'; // 根据距离升序查询(越近越靠前) $order = 'juli asc,id desc'; // 查询数据 Db::name('user')->field($field)->order($order)->select(); [/code]

4. 经纬度范围查询

经纬度范围计算 功能函数

[code]/** * 经纬度范围计算 * @param $longitude 经度 * @param $latitude 纬度 * @param $radius 半径(米) * @return array */ function get_around($longitude, $latitude, $radius) { $PI = 3.14159265; $degree = (24901 * 1609) / 360.0; $dpmLat = 1 / $degree; $radiusLat = $dpmLat * $radius; $minLat = $latitude - $radiusLat; $maxLat = $latitude + $radiusLat; $mpdLng = $degree * cos($latitude * ($PI / 180)); $dpmLng = 1 / $mpdLng; $radiusLng = $dpmLng * $radius; $minLng = $longitude - $radiusLng; $maxLng = $longitude + $radiusLng; return compact('minLat', 'maxLat', 'minLng', 'maxLng'); } [/code]

使用示例

查询 3 公里内的数据。起首,根据当前位置获取 3 公里内的经纬度范围,然后带上查询条件查询数据库即可

[code]$longitude = 113.869205; //经度 $latitude = 22.583286; //纬度 $radius = 3000; //单位:米 // 经纬度范围 $around = get_around($longitude, $latitude, $radius); // 构造查询条件 // 数据库经纬度字段分别为:longitude,latitude $where = [ ['longitude', '>=', $around['minLng']], ['longitude', '<=', $around['maxLng']], ['latitude', '>=', $around['minLat']], ['latitude', '<=', $around['maxLat']], ]; // 按照经纬度范围查询数据 // 建议使用 where 的闭包查询(TP6.0) // 由于闭包可以生成以下SQL,标明这几个查询条件是一个团体,便于后期维护 // SQL语句示例: SELECT * FROM `user` WHERE ( 经纬度查询条件 ) and 其他条件 $data = Db::name('user') ->where(function ($query) use ($where) { $query->where($where); }) ->select(); [/code]

到此这篇关于PHP中经纬度坐标相关计算方法小结的文章就先容到这了,更多相关PHP经纬度坐标计算内容请搜刮脚本之家从前的文章或继续欣赏下面的相关文章盼望各人以后多多支持脚本之家!


来源:https://www.jb51.net/program/319898l8a.htm
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
关闭

站长推荐上一条 /6 下一条

QQ|手机版|小黑屋|梦想之都-俊月星空 ( 粤ICP备18056059号 )|网站地图

GMT+8, 2025-7-1 22:36 , Processed in 0.031651 second(s), 18 queries .

Powered by Mxzdjyxk! X3.5

© 2001-2025 Discuz! Team.

返回顶部