準備工作
1、含有城市名稱和經緯度的數據表(lat爲經度,lng爲緯度):
2、百度地圖api,用來獲取每個城市的經緯度:
http://api.map.baidu.com/geocoder?address=%E9%9D%92%E5%B2%9B&output=json&key=rKNhRRsTd47pjY3VCbvCOHraF0FOft5O
代碼實現
實現邏輯:以
濟南爲起點
,算出濟南到每個城市之間的距離,並按照距離從近到遠依次排序。
/**
處理排序的邏輯
**/
public function cityorder(){
//找一個排序的起點,爲濟南
$jinan = db::name("ceshi")
->where("address","濟南")
->find();
//查詢城市表裏不是濟南的所有城市
$sql = db::name("ceshi")
->where("address",'neq',"濟南")
->select();
//以濟南的距離爲起點,依次算出從濟南到每個城市的距離,並放入數組
for($i = 0; $i< count($sql) ; $i++){
$arr[$i]["space"] = $this->getdistance($jinan["lat"],$jinan["lng"],$sql[$i]["lat"],$sql[$i]["lng"]);
$arr[$i]["name"] = $sql[$i]["address"];
}
//進行冒泡排序
$a = $this->mpSort($arr,"space");
print_r($a);die;
}
/**
php二維數組冒泡排序
**/
function mpSort($arr,$key){
for($i=0;$i<count($arr);$i++){
for($j=$i;$j<count($arr);$j++){
if($arr[$i][$key]>$arr[$j][$key]){
$temp=$arr[$i];
$arr[$i]=$arr[$j];
$arr[$j]=$temp;
}
}
}
return $arr;
}
/**
* 求兩個已知經緯度之間的距離,單位爲米
*
* @param lng1 $ ,lng2 經度
* @param lat1 $ ,lat2 緯度
* @return float 距離,單位米
* @author www.Alixixi.com
*/
function getdistance($lng1, $lat1, $lng2, $lat2) {
// 將角度轉爲狐度
$radLat1 = deg2rad($lat1); //deg2rad()函數將角度轉換爲弧度
$radLat2 = deg2rad($lat2);
$radLng1 = deg2rad($lng1);
$radLng2 = deg2rad($lng2);
$a = $radLat1 - $radLat2;
$b = $radLng1 - $radLng2;
$s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137 * 1000;
return $s;
}
postman打印出來後的效果(space是濟南到某個城市之間的距離):
Array
(
[0] => Array
(
[space] => 509381.83926484
[name] => 鄭州
)
[1] => Array
(
[space] => 534136.67762135
[name] => 合肥
)
[2] => Array
(
[space] => 622342.83636755
[name] => 南京
)
[3] => Array
(
[space] => 726371.61725314
[name] => 上海
)
[4] => Array
(
[space] => 1264244.2118345
[name] => 福建
)
[5] => Array
(
[space] => 1563068.6975839
[name] => 廣東
)
[6] => Array
(
[space] => 2096074.5595435
[name] => 海南
)
[7] => Array
(
[space] => 2523006.4189404
[name] => 拉薩
)
)
從打印效果中來看,確實如此,濟南在這些城市的最北邊,依次爲鄭州、合肥、南京:
如果你感覺數據不對,可以使用百度地圖等直接搜兩個城市之間的距離來進行測試。
該邏輯放到項目中即可使用。