文章目录

  • 1. 前言
  • 2. 计算经纬度坐标间的距离
  • 3. 根据经纬度坐标距离排序
  • 4. 经纬度范围查询

1. 前言


PHP 全栈技术群

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

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');

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

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

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


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

/*** 计算经纬度坐标间的距离* @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 时单位转为kmif ($distance < 1000) {$distance .= $m;} else {$distance = floatval(number_format($distance / 1000, 2)) . $km;}return $distance; // 返回单位转换后的距离
}

使用示例:

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

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

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


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

// 当前坐标
$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();

4. 经纬度范围查询


经纬度范围计算 功能函数

/*** 经纬度范围计算* @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');
}

使用示例

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

$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();

PHP 经纬度坐标相关计算方法相关推荐

  1. android 逆地址,Android高德获取逆地址编码(经纬度坐标-地址描述如省市区街道)

    Android高德获取逆地址编码(经纬度坐标-地址描述如省市区街道) 可以在非地图视图下直接获取,只要传入当前位置的经纬度 当然也可以在地图模式下获取详细信息 在非第三方地图集成下(系统自带功能)获取 ...

  2. 根据经纬度确定行政区域_基于JavaScript实现高德地图和百度地图提取行政区边界经纬度坐标...

    前言 近来由于工作需要,需要提取某些城市的经纬度坐标,稍微搜索了一下,发现百度地图和高德地图都提供了相关的函数和例子.那么剩余的工作也就比较简单了,保存坐标,然后转换为WGS坐标,这样才能和现有的GP ...

  3. python取省边界_提取行政区边界经纬度坐标(高德+百度)

    前言 近来由于工作需要,需要提取某些城市的经纬度坐标,稍微搜索了一下,发现百度地图和高德地图都提供了相关的函数和例子.那么剩余的工作也就比较简单了,保存坐标,然后转换为WGS坐标,这样才能和现有的GP ...

  4. iOS 火星坐标相关整理及解决方案汇总

    iOS之火星地图与地球坐标(MapKit&CoreLocation) (2013-01-15 23:43:02) 转载▼ 标签: ios mapkit corelocation 火星地图 火星 ...

  5. 根据经纬度坐标获得省市区县行政区划城市名称,自建数据库 java python php c# .net 均适用

    文章目录 步骤一.下载省市区边界数据 步骤二.解析CSV文件导入数据库 步骤三.在程序中根据坐标解析获得城市 在LBS应用中,根据坐标来解析获得对应是哪个城市是一个很常见的功能,比如App里面通过手机 ...

  6. 百度地图根据经纬度坐标,显示轨迹

    1.html 部分设置存放地图的div,定义id和宽高,并引入百度地图相关JS <div id="baiduMap" style="width:600px;heig ...

  7. 2020FME博客大赛——解放大脑 经纬度坐标自动重投影至常用投影坐标系

    作者:崔欣 单位:中国石油天然气管道工程有限公司 摘要:非测绘专业以及学艺不精的测绘人员对经纬度.投影带.带号.假东.假北.比例因子.高斯克吕格3度分带投影.高斯克吕格6度分带投影.墨卡托投影.通用横 ...

  8. 050:vue+openlayers使用Popup组件显示经纬度坐标(代码示例)

    第050个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers中使用popup的形式来显示出经纬度坐标,本示例是采用引用扩展的方式,相比以往的添加方式,减少了不少的代码量. 直 ...

  9. 瓦片地图坐标相关计算

    http://www.cnblogs.com/junyuz/archive/2011/04/19/2021035.html 瓦片地图坐标相关计算 在给定level下,把行号tileY和列号tileX转 ...

最新文章

  1. 《你的灯亮着吗》读书笔记1
  2. 关于self.用法的一些总结
  3. 【转载】使用 gnuplot 在网页中显示数据
  4. leetcode 911. Online Election | 911. 在线选举(加强堆 + 二分查找)
  5. gerber文件怎么导贴片坐标_PCBA贴片加工厂家的上机贴片编程
  6. ssl1597-石子合并问题【区间dp练习】
  7. bigdecimal js 判断等于0_为啥阿里禁用BigDecimal的equals方法做等值比较
  8. c语言实现语音检测vad_TWS+AI?国芯发布超低功耗语音芯片,可能是目前最理想方案...
  9. 计算机考研专业基础知识视频教程链接
  10. 设计模式之笔记--建造者模式(Builder)
  11. 性能为王:选择模拟监控的10大理由!
  12. HTTP1.1之后的长连接和WebSocket的长连接之间的区别
  13. kubernetes 如何彻底删除pod、deployment、service
  14. [升级凯立德地图] 升级凯立德地图 (车载 导航仪)
  15. java编程软件安装
  16. matlab 2010 win10,win10系统运行matlab2010找不到指定的程序的教程介绍
  17. 400元DIY实现手机 笔记本 GPS导航
  18. Win7系统电脑调节屏幕亮度的几种方法。
  19. 深度学习:GAN 对抗网络原理详细解析(零基础必看)
  20. Linux下如何彻底删除用户

热门文章

  1. oracle免费版本下载地址,Oracle各版本下载地址和方法
  2. Android9.0中应用如何通过SAF框架写入外置SD卡
  3. 单片机加密の硬件加密和软件加密
  4. 云和恩墨大讲堂电子期刊第四期
  5. 刘强东的“强式”回归
  6. 一文读懂凯利公式—一个多次被巴菲特芒格引用的投资方法
  7. 【技术贴】怎么 豆瓣网在线看书
  8. 怎样才能批量查询网站的谷歌PR权重?把手教你批量查询网站谷歌PR权重值
  9. java hibernate 是什么意思_Java开源项目Hibernate意义是什么?
  10. 幻方 java_Java三阶幻方的8种结果输出