PHP中經(jīng)緯度坐標(biāo)相關(guān)計(jì)算方法小結(jié)
1. 前言
想要測(cè)試本文提供的幾個(gè)功能函數(shù),可以使用下面這個(gè)數(shù)據(jù)表結(jié)構(gòu)及其數(shù)據(jù)
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 '經(jīng)度', `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 ('中海九號(hào)公館', '113.899529', '22.60063', '深圳市寶安區(qū)中海九號(hào)公館', '3.66km'); INSERT INTO `user` (`name`, `longitude`, `latitude`, `remark`, `distance`) VALUES ('平巒山公園', '113.876462', '22.608322', '深圳市寶安區(qū)平巒山公園', '2.88km'); INSERT INTO `user` (`name`, `longitude`, `latitude`, `remark`, `distance`) VALUES ('鐵仔山公園', '113.86359', '22.592355', '深圳市寶安區(qū)鐵仔山公園', '1.16km'); INSERT INTO `user` (`name`, `longitude`, `latitude`, `remark`, `distance`) VALUES ('寶安公園', '113.902671', '22.58621', '深圳市寶安區(qū)寶安公園', '3.45km');
本文內(nèi)容測(cè)試各個(gè)功能函數(shù)時(shí),使用的當(dāng)前位置坐標(biāo)均為:
// 深圳市寶安區(qū)西鄉(xiāng)街道九方廣場(chǎng) $longitude = '113.869205';//經(jīng)度 $latitude = '22.583286';//緯度
2. 計(jì)算經(jīng)緯度坐標(biāo)間的距離
計(jì)算經(jīng)緯度坐標(biāo)間的距離 功能函數(shù) (前四個(gè)參數(shù)為兩組經(jīng)緯度坐標(biāo))
/** * 計(jì)算經(jīng)緯度坐標(biāo)間的距離 * @param $lng1 經(jīng)度 * @param $lat1 緯度 * @param $lng2 經(jīng)度 * @param $lat2 緯度 * @param $lang 語(yǔ)言 */ function get_distance($lng1, $lat1, $lng2, $lat2, $lang = 'en') { // 地球的近似半徑(單位:米) $earthRadius = 6367000; // 將這些度數(shù)轉(zhuǎn)換為弧度以使用公式 $lat1 = ($lat1 * pi()) / 180; $lng1 = ($lng1 * pi()) / 180; $lat2 = ($lat2 * pi()) / 180; $lng2 = ($lng2 * pi()) / 180; // 使用 Haversine 公示計(jì)算距離 // 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))); // 兩個(gè)經(jīng)緯度坐標(biāo)的距離(單位: 米) $calculatedDistance = round($earthRadius * $stepTwo); // 距離單位 $language = [ 'en' => ['m' => 'm', 'km' => 'km'], 'cn' => ['m' => '米', 'km' => '公里'], ]; if (!isset($language[$lang])) throw new \Exception('不支持的語(yǔ)言:' . $lang); foreach ($language[$lang] as $key => $value) $$key = $value; // 兩個(gè)坐標(biāo)間的距離,單位:米 $distance = round($calculatedDistance); // 距離單位轉(zhuǎn)換:超出 1000m 時(shí)單位轉(zhuǎn)為km if ($distance < 1000) { $distance .= $m; } else { $distance = floatval(number_format($distance / 1000, 2)) . $km; } return $distance; // 返回單位轉(zhuǎn)換后的距離 }
使用示例:
我在 九方廣場(chǎng),手機(jī)上的高德地圖導(dǎo)航至 中海九號(hào)公館 顯示的距離為 3.6公里,計(jì)算結(jié)果還是很準(zhǔn)確的
// 深圳市寶安區(qū)西鄉(xiāng)街道九方廣場(chǎng): 113.869205, 22.583286 // 深圳市寶安區(qū)西鄉(xiāng)街道中海九號(hào)公館: 113.899529, 22.60063 $distance = get_distance(113.869205, 22.583286, 113.899529, 22.60063); echo $distance; //3.66km
3. 根據(jù)經(jīng)緯度坐標(biāo)距離排序
項(xiàng)目中經(jīng)常有距離顯示數(shù)據(jù)的場(chǎng)景,根據(jù)距離排序,越近越靠前顯示;比如: 店鋪地址、房源信息等。代碼示例:
// 當(dāng)前坐標(biāo) $longitude = '113.869205'; $latitude = '22.583286'; // 數(shù)據(jù)庫(kù)中經(jīng)緯度字段分別為: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'; // 根據(jù)距離升序查詢(越近越靠前) $order = 'juli asc,id desc'; // 查詢數(shù)據(jù) Db::name('user')->field($field)->order($order)->select();
4. 經(jīng)緯度范圍查詢
經(jīng)緯度范圍計(jì)算 功能函數(shù)
/** * 經(jīng)緯度范圍計(jì)算 * @param $longitude 經(jīng)度 * @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 公里內(nèi)的數(shù)據(jù)。首先,根據(jù)當(dāng)前位置獲取 3 公里內(nèi)的經(jīng)緯度范圍,然后帶上查詢條件查詢數(shù)據(jù)庫(kù)即可
$longitude = 113.869205; //經(jīng)度 $latitude = 22.583286; //緯度 $radius = 3000; //單位:米 // 經(jīng)緯度范圍 $around = get_around($longitude, $latitude, $radius); // 構(gòu)造查詢條件 // 數(shù)據(jù)庫(kù)經(jīng)緯度字段分別為:longitude,latitude $where = [ ['longitude', '>=', $around['minLng']], ['longitude', '<=', $around['maxLng']], ['latitude', '>=', $around['minLat']], ['latitude', '<=', $around['maxLat']], ]; // 按照經(jīng)緯度范圍查詢數(shù)據(jù) // 建議使用 where 的閉包查詢(TP6.0) // 因?yàn)殚]包可以生成以下SQL,標(biāo)明這幾個(gè)查詢條件是一個(gè)整體,便于后期維護(hù) // SQL語(yǔ)句示例: SELECT * FROM `user` WHERE ( 經(jīng)緯度查詢條件 ) and 其他條件 $data = Db::name('user') ->where(function ($query) use ($where) { $query->where($where); }) ->select();
到此這篇關(guān)于PHP中經(jīng)緯度坐標(biāo)相關(guān)計(jì)算方法小結(jié)的文章就介紹到這了,更多相關(guān)PHP經(jīng)緯度坐標(biāo)計(jì)算內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
php+ajax無(wú)刷新上傳圖片的實(shí)現(xiàn)方法
這篇文章主要介紹了php+ajax無(wú)刷新上傳圖片的實(shí)現(xiàn)方法,涉及php結(jié)合ajax進(jìn)行文件傳輸操作相關(guān)技巧,需要的朋友可以參考下2016-12-12php過(guò)濾所有惡意字符(批量過(guò)濾post,get敏感數(shù)據(jù))
最近dedecms報(bào)漏洞不斷,這里分享下php的過(guò)濾函數(shù),大牛飄過(guò)吧,給小黑闊們學(xué)習(xí)交流用2014-03-03PHP使用gmdate實(shí)現(xiàn)將一個(gè)UNIX 時(shí)間格式化成GMT文本的方法
這篇文章主要介紹了PHP使用gmdate實(shí)現(xiàn)將一個(gè)UNIX 時(shí)間格式化成GMT文本的方法,實(shí)例分析了php中g(shù)mdate函數(shù)的功能及使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03dedecms系統(tǒng)的廣告設(shè)置代碼 基礎(chǔ)版本
dedecms系統(tǒng)的廣告設(shè)置代碼 基礎(chǔ)版本,需要的朋友可以參考下。2010-04-04令PHP初學(xué)者頭疼十四條問(wèn)題大總結(jié)
今天為大家奉上令PHP初學(xué)者頭疼問(wèn)題大總結(jié),下面提出的14個(gè)問(wèn)題希望對(duì)PHP初學(xué)者有所幫助。2008-11-11PHP curl CURLOPT_RETURNTRANSFER參數(shù)的作用使用實(shí)例
這篇文章主要介紹了PHP curl CURLOPT_RETURNTRANSFER參數(shù)的作用使用實(shí)例,CURLOPT_RETURNTRANSFER參數(shù)的作用是把CRUL獲取的內(nèi)容賦值到變量,需要的朋友可以參考下2015-02-02php實(shí)現(xiàn)獲取農(nóng)歷(陰歷)、節(jié)日、節(jié)氣的類與用法示例
這篇文章主要介紹了php實(shí)現(xiàn)獲取農(nóng)歷(陰歷)、節(jié)日、節(jié)氣的類與用法,結(jié)合實(shí)例形式分析了php日期工具類Lunar的具體定義與獲取農(nóng)歷日期、節(jié)氣等相關(guān)操作技巧,需要的朋友可以參考下2017-11-11