PHP 经纬度相关计算 坐标点之间的距离

根据两个坐标点,计算两点之间的距离

/**
	*  @desc 根据两点间的经纬度计算距离
	*  @param float $lat 纬度值
	*  @param float $lng 经度值
	*/
	public static function getDistance($lat1, $lng1, $lat2, $lng2)
	{
	     $earthRadius = 6371000; //approximate radius of earth in meters

	     /*
	       Convert these degrees to radians
	       to work with the formula
	     */

	     $lat1 = ($lat1 * pi() ) / 180;
	     $lng1 = ($lng1 * pi() ) / 180;

	     $lat2 = ($lat2 * pi() ) / 180;
	     $lng2 = ($lng2 * pi() ) / 180;

	     /*
	       Using the Haversine formula
	       http://en.wikipedia.org/wiki/Haversine_formula calculate the distance
	     */

	     $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 lng float 经度
	 *@param lat float 纬度
	 *@param distance float 该点所在圆的半径,该圆与此正方形内切,默认值为0.5千米
	 *@return array 正方形的四个点的经纬度坐标
	 */
	 public static function returnSquarePoint($lat, $lng, $distance = 1500){

		$dlng =  2 * asin(sin($distance / (2 * self::EARTH_RADIUS)) / cos(deg2rad($lat)));
		$dlng = rad2deg($dlng);

		$dlat = $distance/self::earthRadius;
		$dlat = rad2deg($dlat);

		return array(
					'left-top'=>array('lat'=>$lat + $dlat,'lng'=>$lng-$dlng),
					'right-top'=>array('lat'=>$lat + $dlat, 'lng'=>$lng + $dlng),
					'left-bottom'=>array('lat'=>$lat - $dlat, 'lng'=>$lng - $dlng),
					'right-bottom'=>array('lat'=>$lat - $dlat, 'lng'=>$lng + $dlng)
					);
	 }

判断经纬度是否在points组成的多边形内,凹凸多边形都适合

public static function isInPoly($lat, $lng, $points) {
		if (count($points) < 3) {
			return false;
		}

		$sum = 0;
		$count = count($points);

		for ($i = 0; $i < $count; $i++) {
			if ($i == $count - 1) {
				$lng1 = $points[$i]['lng'];
				$lat1 = $points[$i]['lat'];
				$lng2 = $points[0]['lng'];
				$lat2 = $points[0]['lat'];
			} else {
				$lng1 = $points[$i]['lng'];
				$lat1 = $points[$i]['lat'];
				$lng2 = $points[$i+1]['lng'];
				$lat2 = $points[$i+1]['lat'];
			}
		
			if (($lat >= $lat1 && $lat < $lat2) || ($lat >= $lat2 && $lat < $lat1)) {
				if (abs($lat1 - $lat2) > 0) {
					$dlng = $lng1 - (($lng1 - $lng2) * ($lat1 - $lat)) / ($lat1 - $lat2);
					if ($dlng < $lng) {
						$sum++;
					}
				}
			}
		}
		if ($sum % 2 != 0)
			return true;
		return false;
	}

根据地址查到经纬度

public function getLatLng($address, $proxy='') {
		if ($address == '')
			return array('code'=>-1,'lat'=>0,'lng'=>0);

		$url = "http://maps.googleapis.com/maps/api/geocode/json?address=" . urlencode($address) . "&sensor=false";
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		if (!empty(self::$proxy)) {
			$n = rand(0, count(self::$proxy)-1);
			$proxy = self::$proxy[$n];
			curl_setopt ($ch, CURLOPT_PROXY, $proxy);
		}
		curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)');
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 35);
		$content = curl_exec($ch);
		curl_close($ch);

		$lat = $lng = 0;
		$data = json_decode($content, true);
		if ($data == false) {
			return array('code'=>-1,'lat'=>$lat,'lng'=>$lng);
		}
		$status = $data['status'];
		switch ($status) {
			case	'OK':
				$code = 0;
				break;
			case	'ZERO_RESULTS':
				$code = 1;
				break;
			case	'OVER_QUERY_LIMIT':
				$code = -1;
				break;
			case	'REQUEST_DENIED':
				$code = -2;
				break;
			case	'INVALID_REQUEST':
				$code = -3;
				break;
			
		}
		if (empty($data['results'])||$code!==0) {
			return array('code'=>$code,'lat'=>$lat,'lng'=>$lng);
		}
		$result = $data['results'][0];
		$geometry = $result['geometry'];
		if (!array_key_exists('location', $geometry)) {
			return array('code'=>$code,'lat'=>$lat,'lng'=>$lng);
		}
		$location = $geometry['location'];
		$lat = $location['lat'];
		$lng = $location['lng'];
		return array('code'=>$code,'lat'=>$lat,'lng'=>$lng);
	}

根据坐标查询地址

public function getAddress($lat, $lng, $proxy='') {
		$url = "http://ditu.google.cn/maps/api/geocode/json?latlng={$lat},{$lng}&language=zh-CN&sensor=false";
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		if (!empty($proxy)) {
			curl_setopt ($ch, CURLOPT_PROXY, $proxy);
		}
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
		$content = curl_exec($ch);
		curl_close($ch);

		$data = json_decode($content, true);
		if ($data == false) {
			return array('code'=>-1,'province'=>'','city'=>'','area'=>'');
		}
		print_r($data);
		$status = $data['status'];
		switch ($status) {
			case	'OK':
				$code = 0;
				break;
			case	'ZERO_RESULTS':
				$code = 1;
				break;
			case	'OVER_QUERY_LIMIT':
				$code = -1;
				break;
			case	'REQUEST_DENIED':
				$code = -2;
				break;
			case	'INVALID_REQUEST':
				$code = -3;
				break;
			
		}
		if (empty($data['results'])||$code!==0) {
			return array('code'=>$code,'province'=>'','city'=>'','area'=>'');
		}
		$province = $area = $city = '';
		$results = $data['results'];
		$address_components = $results[0]['address_components'];
		foreach ($address_components as $a) {
			$types = $a['types'];
			if (in_array('sublocality', $types)) {
				$area = $a['long_name'];
			} else if (in_array('administrative_area_level_1', $types)) {
				$province = $a['long_name'];
			} else if (in_array('locality', $types)) {
				$city = $a['long_name'];
			}
		}
		return array('code'=>$code, 'province'=>$province, 'city'=>$city, 'area'=>$area);
	}

百度地址获取

public function getAddressBaidu($lat, $lng, $proxy='') {
		$url = "http://api.map.baidu.com/geocoder?location={$lat},{$lng}&output=json&key=iC95iWGwGrUSadjYeZcyOIiP";
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		if (!empty($proxy)) {
			curl_setopt ($ch, CURLOPT_PROXY, $proxy);
		}
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
		$content = curl_exec($ch);
		curl_close($ch);

		$data = json_decode($content, true);
		if ($data == false) {
			return array('code'=>-1,'province'=>'','city'=>'','area'=>'');
		}
		print_r($data);
		$status = $data['status'];
		switch ($status) {
			case	'OK':
				$code = 0;
				break;
			case	'ZERO_RESULTS':
				$code = 1;
				break;
			case	'OVER_QUERY_LIMIT':
				$code = -1;
				break;
			case	'REQUEST_DENIED':
				$code = -2;
				break;
			case	'INVALID_REQUEST':
				$code = -3;
				break;
			
		}
		if (empty($data['result'])||$code!==0) {
			return array('code'=>$code,'province'=>'','city'=>'','area'=>'');
		}
		$province = $area = $city = '';
		$result = $data['result'];
		$address_components = $result['addressComponent'];
		$city = $address_components['city'];
		$area = $address_components['district'];
		$province = $address_components['province'];
		return array('code'=>$code, 'province'=>$province, 'city'=>$city, 'area'=>$area);
	}

根据经纬度查询地址

//根据经纬度查询地址
	public function getAddressOld($lat, $lng, $proxy='') {
		$url = sprintf("http://ditu.google.cn/maps/geo?output=json&key=ABQIAAAAm5e8FerSsVCrPjUC9W8BqBShYm95JTkTs6vbZ7nB48Si7EEJuhQJur9kGGJoqUiYond0w-7lKR6JpQ&q=%s,%s", $lat, $lng);
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		if (!empty($proxy)) {
			curl_setopt ($ch, CURLOPT_PROXY, $proxy);
		}
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
		$content = curl_exec($ch);
		curl_close($ch);

		$arr = json_decode($content, true);
		if ($arr === false) {
			return array('code'=>-1,'province'=>'','city'=>'','area'=>'');
		}

		$status = $arr['Status']['code'];
		if ($status != 200) {
			return array('code'=>$status,'province'=>'','city'=>'','area'=>'');
		}

		$points = $arr['Placemark'];
		if (count($points) == 0) {
			return array('code'=>$status,'province'=>'','city'=>'','area'=>'');
		}
		
		$country = $points[0]['AddressDetails']['Country'];
		$adminArea = $country['AdministrativeArea'];
		$province = $adminArea['AdministrativeAreaName'];
		$city = $adminArea['Locality']['LocalityName'];
		$area = $adminArea['Locality']['DependentLocality']['DependentLocalityName'];
		return array('code'=>$status, 'province'=>$province, 'city'=>$city, 'area'=>$area);
	}

	public function getDataFromUrl($url){
		$ch = curl_init();
		// set URL and other appropriate options
		$options = array(
				CURLOPT_URL => $url,
				CURLOPT_HEADER => 0,
				CURLOPT_RETURNTRANSFER => 1,
				 CURLOPT_FOLLOWLOCATION => 1,
				 CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)',
				 CURLOPT_TIMEOUT => 60, // 1 minute timeout (should be enough)
				 CURLOPT_SSL_VERIFYPEER=>0,
				 CURLOPT_SSL_VERIFYHOST=>0
				 );
	       
		curl_setopt_array($ch, $options);
		$ret = curl_exec($ch);
		curl_close($ch);
		return $ret;
	}

根据谷歌座标转换百度座标

//根据谷歌座标转换百度座标
	public static function convertGoogle($lat, $lng, $from=2, $to=4) {
		$url = "http://api.map.baidu.com/ag/coord/convert?from={$from}&to={$to}&x={$lng}&y={$lat}";
		$ret = self::getDataFromUrl($url);
		if ($ret === false)
			return false;
		$arr = json_decode($ret, true);
		if ($arr == false)
			return false;
		$err = $arr['error'];
		if ($err != 0) 
			return false;	
		$lng = base64_decode($arr['x']);
		$lat = base64_decode($arr['y']);
		return array($lat, $lng);
	}

通过IP获取地址

public static function getAddressByIp($ipaddr) {
		$url = "http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=$ipaddr";
		$content = Utility::getDataFromUrl($url);
		$arr = json_decode($content, true);
		if ($arr == false) {
			return false;
		}
		return $arr;
	}
  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值