GPS坐标互转:WGS-84[GPS]\GCJ-02[Google\高德]\BD-09[百度](php版)

传说中的地球坐标为:WGS-84坐标系,既为GPS坐标(国内特殊手机不包括)

传说中的火星坐标为:GCJ-02坐标系,是谷歌和高德地图使用中的坐标系

百度坐标是。。。。。。。非地球和火星外的。。。。。。。。土星坐标。

 

class MapTransform{
	private $M_PI=3.14159265358979323846264338327950288;
	private function LAT_OFFSET_0($x,$y){$res=-100.0 + 2.0 * $x + 3.0 * $y + 0.2 * $y * $y + 0.1 * $x * $y + 0.2 * sqrt(abs($x));return $res;}
	private function LAT_OFFSET_1($x){$res=(20.0*sin(6.0 * $x * $this->M_PI)+20.0*sin(2.0*$x*$this->M_PI))*2.0/3.0;	return $res;}
	private function LAT_OFFSET_2($y){ $res=(20.0 * sin($y * $this->M_PI) + 40.0 * sin($y / 3.0 * $this->M_PI)) * 2.0 / 3.0;return $res;}
	private function LAT_OFFSET_3($y){$res=(160.0 * sin($y / 12.0 * $this->M_PI) + 320 * sin($y * $this->M_PI / 30.0)) * 2.0 / 3.0; return $res;}
	
	private function LON_OFFSET_0($x,$y){$res=300.0 + $x + 2.0 * $y + 0.1 * $x * $x + 0.1 * $x * $y + 0.1 * sqrt(abs($x)); return $res;}
	private function LON_OFFSET_1($x){$res=(20.0 * sin(6.0 * $x * $this->M_PI) + 20.0 * sin(2.0 * $x * $this->M_PI)) * 2.0 / 3.0; return $res;}
	private function LON_OFFSET_2($x){$res=(20.0 * sin($x * $this->M_PI) + 40.0 * sin($x / 3.0 * $this->M_PI)) * 2.0 / 3.0; return $res;}
	private function LON_OFFSET_3($x){$res=(150.0 * sin($x / 12.0 * $this->M_PI) + 300.0 * sin($x / 30.0 * $this->M_PI)) * 2.0 / 3.0; return $res;}
	
	private $RANGE_LON_MAX=137.8347;
	private $RANGE_LON_MIN=72.004;
	private $RANGE_LAT_MAX=55.8271;
	private $RANGE_LAT_MIN=0.8293;
	// jzA = 6378245.0, 1/f = 298.3
	// b = a * (1 - f)
	// ee = (a^2 - b^2) / a^2;
	private $jzA=6378245.0;
	private $jzEE=0.00669342162296594323;
	
	
	private function transformLat($x,$y)
	{
			$ret = $this->LAT_OFFSET_0($x, $y);
			$ret += $this->LAT_OFFSET_1($x);
			$ret += $this->LAT_OFFSET_2($y);
			$ret += $this->LAT_OFFSET_3($y);
			return $ret;
	}
	
	private function transformLon($x,$y)
	{
			$ret = $this->LON_OFFSET_0($x, $y);
			$ret += $this->LON_OFFSET_1($x);
			$ret += $this->LON_OFFSET_2($x);
			$ret += $this->LON_OFFSET_3($x);
			return $ret;
	}
	
	private function outOfChina($lat,$lon)
	{
			if ($lon < $this->RANGE_LON_MIN || $lon > $this->RANGE_LON_MAX)
					return true;
			if ($lat < $this->RANGE_LAT_MIN || $lat > $this->RANGE_LAT_MAX)
					return true;
			return false;
	}
	
	
	public function gcj02Encrypt($ggLat,$ggLon)
	{
			$resPoint=array();
			$mgLat=0;
			$mgLon=0;
			if ($this->outOfChina($ggLat,$ggLon)) {
					$resPoint['latitude'] = $ggLat;
					$resPoint['longitude'] = $ggLon;
					return $resPoint;
			}
			$dLat = $this->transformLat(($ggLon - 105.0),($ggLat - 35.0));
			$dLon = $this->transformLon(($ggLon - 105.0),($ggLat - 35.0));
			$radLat = $ggLat / 180.0 * $this->M_PI;
			$magic = sin($radLat);
			$magic = 1 - $this->jzEE * $magic * $magic;
			$sqrtMagic = sqrt($magic);
			$dLat = ($dLat * 180.0) / (($this->jzA * (1 - $this->jzEE)) / ($magic * $sqrtMagic) * $this->M_PI);
			$dLon = ($dLon * 180.0) / ($this->jzA / $sqrtMagic * cos($radLat) * $this->M_PI);
			$mgLat = $ggLat + $dLat;
			$mgLon = $ggLon + $dLon;
			
			$resPoint['latitude'] = $mgLat;
			$resPoint['longitude'] = $mgLon;
			return $resPoint;
	}
	
	public function gcj02Decrypt($gjLat,$gjLon) {
			$gPt = $this->gcj02Encrypt($gjLat,$gjLon);
			$dLon = $gPt['longitude'] - $gjLon;
			$dLat = $gPt['latitude'] - $gjLat;
			$pt=array();
			$pt['latitude'] = $gjLat - $dLat;
			$pt['longitude'] = $gjLon - $dLon;
			return $pt;
	}
	
	public function bd09Decrypt($bdLat,$bdLon)
	{
			$gcjPt=array();
			$x = $bdLon - 0.0065; $y = $bdLat - 0.006;
			$z = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * $this->M_PI);
			$theta = atan2($y, $x) - 0.000003 * cos($x * $this->M_PI);
			$gcjPt['longitude'] = $z * cos($theta);
			$gcjPt['latitude'] = $z * sin($theta);
			return $gcjPt;
	}
	
	public function bd09Encrypt($ggLat,$ggLon)
	{
			$bdPt=array();
			$x = $ggLon; $y = $ggLat;
			$z = sqrt($x * $x + $y * $y) + 0.00002 * sin($y * $this->M_PI);
			$theta = atan2($y, $x) + 0.000003 * cos($x * $this->M_PI);
			$bdPt['longitude'] = $z * cos($theta) + 0.0065;
			$bdPt['latitude'] = $z * sin($theta) + 0.006;
			return $bdPt;
	}
	
	
	public function wgs84ToGcj02($location=array())
	{
			return $this->gcj02Encrypt($location['latitude'],$location['longitude']);
	}
	
	public function gcj02ToWgs84($location=array())
	{
			return $this->gcj02Decrypt($location['latitude'],$location['longitude']);
	}
	
	
	public function wgs84ToBd09($location=array())
	{
			$gcj02Pt = $this->gcj02Encrypt($location['latitude'],$location['longitude']);
			return $this->bd09Encrypt($gcj02Pt['latitude'],$gcj02Pt['longitude']);
	}
	
	public function gcj02ToBd09($location=array())
	{
			return  $this->bd09Encrypt($location['latitude'],$location['longitude']);
	}
	
	public function bd09ToGcj02($location=array())
	{
			return $this->bd09Decrypt($location['latitude'],$location['longitude']);
	}
	
	public function bd09ToWgs84($location=array())
	{
			$gcj02 = $this->bd09ToGcj02($location);
			return $this->gcj02Decrypt($gcj02['latitude'],$gcj02['longitude']);
	}

}