PHP中经纬度坐标距离计算及查询示例代码
近期有些网友想要了解PHP中经纬度坐标距离计算及查询示例代码的相关情况,小编通过整理给您分析,同时介绍一下有关信息。
在地理信息系统(GIS)和位置服务中,计算两点之间的距离是一个常见的需求。PHP作为一种广泛使用的服务器端脚本语言,提供了多种方法来计算经纬度坐标之间的距离。本文将详细介绍如何在PHP中计算两个经纬度坐标之间的距离,并提供示例代码,帮助开发者在实际项目中高效地实现这一功能。
1. 前言
想要测试本文提供的几个功能函数,可以使用下面这个数据表结构及其数据
CREATETABLE`user`( `id`int(10)unsignedNOTNULLAUTO_INCREMENTCOMMENT'用户id', `name`varchar(60)DEFAULTNULLCOMMENT'昵称', `longitude`varchar(64)DEFAULTNULLCOMMENT'经度', `latitude`varchar(64)DEFAULTNULLCOMMENT'纬度', `remark`varchar(50)DEFAULTNULLCOMMENT'备注', `distance`varchar(20)DEFAULTNULLCOMMENT'距离', PRIMARYKEY(`id`) )ENGINE=InnoDBCOMMENT='用户表'; INSERTINTO`user`(`name`,`longitude`,`latitude`,`remark`,`distance`)VALUES('中海九号公馆','113.899529','22.60063','深圳市宝安区中海九号公馆','3.66km'); INSERTINTO`user`(`name`,`longitude`,`latitude`,`remark`,`distance`)VALUES('平峦山公园','113.876462','22.608322','深圳市宝安区平峦山公园','2.88km'); INSERTINTO`user`(`name`,`longitude`,`latitude`,`remark`,`distance`)VALUES('铁仔山公园','113.86359','22.592355','深圳市宝安区铁仔山公园','1.16km'); INSERTINTO`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语言 */ functionget_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]))thrownew\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;//返回单位转换后的距离 }
使用示例:
我在 九方广场,手机上的高德地图导航至 中海九号公馆 显示的距离为 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))))ASjuli'; //根据距离升序查询(越近越靠前) $order='juliasc,iddesc'; //查询数据 Db::name('user')->field($field)->order($order)->select();
4. 经纬度范围查询
经纬度范围计算 功能函数
/** *经纬度范围计算 *@param$longitude经度 *@param$latitude纬度 *@param$radius半径(米) *@returnarray */ functionget_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; returncompact('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中经纬度坐标距离计算的详细解析,我们了解了多种计算方法及其应用场景。Haversine公式是最常用的方法,能够精确计算地球表面上两点之间的大圆距离。本文提供的示例代码展示了如何使用Haversine公式在PHP中计算两点之间的距离,并结合数据库查询实现了实际应用中的距离筛选功能。通过本文的学习,开发者可以掌握在PHP中处理经纬度坐标距离计算的方法,提高地理信息系统的开发效率和准确性。希望本文的内容能为读者在实际项目中提供有价值的参考和帮助。
推荐阅读
-
基于PyQt5的HTTP接口测试工具开发实战
-
Java中的URL编码(URLDecoder)与解码(URLEncoder)使用详解
-
Mysql修改root密码的四种方法详解
-
JavaScript中保留两位小数的多种实现方法
-
PHP调用API接口详解:从基础到实践
-
Python中使用PyYAML库来读取、解析和处理YAML文件的方法
近期有些网友想要了解Python中使用PyYAML库来读取、解析和处理YAML文件的方法的相关情况,小编通过整理给您分析,同时介绍...
-
使用Python中的BeautifulSoup (bs4) 解析复杂HTML内容的技巧与示例
-
Microsoft SQL Server 2012 数据库安装图文教程
-
PHP获取本机ip地址实例代码详解
-
C#使用iTextSharp库将图片转换为PDF的步骤及实例代码解析