根据中心点经纬度求经纬度距离排序,整理版本超级简单
已知中心点经纬度求一定范围内的距离排序,thinkphp经纬度距离排序,如3公里范围内的附近店铺,距离从近到远排序,整理后的代码如下
//先定义西安光电园的经纬度坐标 $start_lng = '108.882223'; //起点经度 $start_lat = '34.233231'; //起点维度 //获取6000米半径范围最大、最小经纬度数组 方法一 $nearby_data = getAround($start_lat,$start_lng,6000); //(`latitude` >= minLat) AND (`latitude` <=maxLat) $condition['lat'] = array(array('EGT',$nearby_data['minLat']),array('ELT',$nearby_data['maxLat']),'and'); //(`longitude` >= minLng) AND (`longitude` <= maxLng) $condition['lng'] = array(array('EGT',$nearby_data['minLng']),array('ELT',$nearby_data['maxLng']),'and'); //获取6000米半径范围最大、最小经纬度数组 方法二 $where = "ROUND(6378.138 * 2 * ASIN(SQRT( POW(SIN(($lat * PI() / 180 - lat * PI() / 180 ) / 2),2) + COS( $lat * PI() / 180) * COS(lat * PI() / 180) * POW( SIN(($lon * PI() / 180 - lng * PI() / 180) / 2),2))) * 1000) < 6000"; $condition['status'] = 1; //$condition['uid'] = 102; //自定义距离字段 $distance_feild = "*,ROUND(6378.138 * 2 * ASIN(SQRT( POW(SIN(($start_lat * PI() / 180 - lat * PI() / 180 ) / 2),2) + COS( $start_lat * PI() / 180) * COS(lat * PI() / 180) * POW( SIN(($start_lng * PI() / 180 - lng * PI() / 180) / 2),2))) * 1000) AS distance"; //求出6000米范围内的店铺数据 $data = D('StoreShop')->field($distance_feild)->where($condition)->order('distance asc')->page($page,30)->select(); //var_dump($data); //exit; /** * @desc 根据半径求范围最大、最小经纬度数组 * @param $latitude 纬度 * @param $longitude 经度 * @param $raidus 半径范围(单位:米) * @return multitype:number */ function getAround($latitude,$longitude,$raidus){ $PI = 3.14159265; $degree = (24901*1609)/360.0; $dpmLat = 1/$degree; $radiusLat = $dpmLat*$raidus; $minLat = $latitude - $radiusLat; $maxLat = $latitude + $radiusLat; $mpdLng = $degree*cos($latitude * ($PI/180)); $dpmLng = 1 / $mpdLng; $radiusLng = $dpmLng*$raidus; $minLng = $longitude - $radiusLng; $maxLng = $longitude + $radiusLng; return array (minLat=>$minLat, maxLat=>$maxLat, minLng=>$minLng, maxLng=>$maxLng); } //另外附加提供三种计算距离的方法 /** * 计算两个坐标之间的距离(米) * @param float $fP1Lat 起点(纬度) * @param float $fP1Lon 起点(经度) * @param float $fP2Lat 终点(纬度) * @param float $fP2Lon 终点(经度) * @return int */ function distanceBetween($fP1Lat, $fP1Lon, $fP2Lat, $fP2Lon){ $fEARTH_RADIUS = 6378137; //角度换算成弧度 $fRadLon1 = deg2rad($fP1Lon); $fRadLon2 = deg2rad($fP2Lon); $fRadLat1 = deg2rad($fP1Lat); $fRadLat2 = deg2rad($fP2Lat); //计算经纬度的差值 $fD1 = abs($fRadLat1 - $fRadLat2); $fD2 = abs($fRadLon1 - $fRadLon2); //距离计算 $fP = pow(sin($fD1/2), 2) + cos($fRadLat1) * cos($fRadLat2) * pow(sin($fD2/2), 2); return intval($fEARTH_RADIUS * 2 * asin(sqrt($fP)) + 0.5); } /** * @desc 根据两点间的经纬度计算距离 * @param float $lat 纬度值 * @param float $lng 经度值 */ function getDistanceLocal($lat1, $lng1, $lat2, $lng2){ $earthRadius = 6367000; //approximate radius of earth in meters $lat1 = ($lat1 * pi() ) / 180; $lng1 = ($lng1 * pi() ) / 180; $lat2 = ($lat2 * pi() ) / 180; $lng2 = ($lng2 * pi() ) / 180; $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 = $earthRadius * $stepTwo; return round($calculatedDistance); } /** * @param int $lat1 纬度1 * @param int $lng1 经度1 * @param int $lat2 纬度2 * @param int $lng2 经度2 * @return array */ function getDistance($lat1=0,$lng1=0,$lat2=0,$lng2=0) { $ak = '';//您的百度地图ak,可以去百度开发者中心去免费申请 $distance = array(); $distance['distance'] = 0.00;//距离 公里 $distance['duration'] = 0.00;//时间 分钟 $url = 'https://api.map.baidu.com/routematrix/v2/driving?output=json&origins='.$lat1.','.$lng1.'&destinations='.$lat2.','.$lng2.'&ak='.$ak; $data = file_get_contents($url); $data = json_decode($data,true); if (!empty($data) && $data['status'] == 0) { $distance['distance'] =preg_replace('/[^\.0123456789]/s', '', $data['result'][0]['distance']['text']); //计算距离 } return $distance; }