欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP中經(jīng)緯度坐標(biāo)相關(guān)計(jì)算方法小結(jié)

 更新時(shí)間:2024年04月20日 09:33:48   作者:超酷的站長(zhǎng)  
這篇文章主要為大家詳細(xì)介紹了PHP中經(jīng)緯度坐標(biāo)相關(guān)計(jì)算方法的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

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)文章

最新評(píng)論