Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 火星坐標系 (GCJ-02) 與百度坐標系 (BD-09) 簡介及轉換算法

火星坐標系 (GCJ-02) 與百度坐標系 (BD-09) 簡介及轉換算法

編輯:關於Android編程

1、美國GPS使用的是WGS84坐標系統,以經緯度的形式來表示地球平面上的某一個位置。但在我國,出於國家安全考慮,國內所有導航電子地圖必須使用國家測繪局制定的加密坐標系統,即將一個真實的經緯度坐標(WGS84坐標系)通過中國國家測繪局制訂的加密算法加密成一個不正確的經緯度坐標(GCJ-02坐標系),我們在業內將前者稱之為地球坐標,後者稱之為火星坐標

 

2、百度官方對百度坐標為何有偏移的解釋:

國際經緯度坐標標准為WGS-84,國內必須至少使用國測局制定的GCJ-02,對地理位置進行首次加密。百度坐標在此基礎上,進行了BD-09二次加密措施,更加保護了個人隱私。百度對外接口的坐標系並不是GPS采集的真實經緯度,需要通過坐標轉換接口進行轉換(見文章最後第5點)。

 

3、國內各地圖坐標系統比較:

地圖廠商

坐標系

百度地圖

百度坐標

騰訊地圖

火星坐標

高德地圖

火星坐標

谷歌地圖(中國)

火星坐標

搜狐搜狗地圖

搜狗坐標

 

4、 坐標系轉換方案1:網上的火星坐標系 (GCJ-02) 與百度坐標系 (BD-09) 的轉換算法:

C++:

 

#include   
  
const double x_pi = 3.14159265358979324 * 3000.0 / 180.0;  
  
void bd_encrypt(double gg_lat, double gg_lon, double &bd_lat, double &bd_lon)  
{  
    double x = gg_lon, y = gg_lat;  
    double z = sqrt(x * x + y * y) + 0.00002 * sin(y * x_pi);  
    double theta = atan2(y, x) + 0.000003 * cos(x * x_pi);  
    bd_lon = z * cos(theta) + 0.0065;  
    bd_lat = z * sin(theta) + 0.006;  
}  
  
void bd_decrypt(double bd_lat, double bd_lon, double &gg_lat, double &gg_lon)  
{  
    double x = bd_lon - 0.0065, y = bd_lat - 0.006;  
    double z = sqrt(x * x + y * y) - 0.00002 * sin(y * x_pi);  
    double theta = atan2(y, x) - 0.000003 * cos(x * x_pi);  
    gg_lon = z * cos(theta);  
    gg_lat = z * sin(theta);  
}  

Java:

 

 

public class GCJ02_BD09 {

	public static double pi = 3.141592653589793 * 3000.0 / 180.0;

	public static void main(String[] args) {

		// GCJ02 ——> BD09
		gcj02_To_Bd09(116.422954, 40.010749).print();

		// BD09 ——> GCJ02
		bd09_To_Gcj02(121.481085, 31.236173).print();

	}

	/**
	 * 火星坐標系 (GCJ-02) 與百度坐標系 (BD-09) 的轉換算法 將 GCJ-02 坐標轉換成 BD-09 坐標
	 * 
	 * @param gg_lat
	 * @param gg_lon
	 * @return
	 */
	public static Gps gcj02_To_Bd09(double gg_lon, double gg_lat) {
		double x = gg_lon, y = gg_lat;
		double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi);
		double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi);
		double bd_lon = z * Math.cos(theta) + 0.0065;
		double bd_lat = z * Math.sin(theta) + 0.006;
		return new Gps(bd_lon, bd_lat);
	}

	/**
	 * 火星坐標系 (GCJ-02) 與百度坐標系 (BD-09) 的轉換算法   將 BD-09 坐標轉換成GCJ-02 坐標 
	 * 
	 * @param bd_lon
	 * @param bd_lat
	 * @return
	 */
	public static Gps bd09_To_Gcj02(double bd_lon, double bd_lat) {
		double x = bd_lon - 0.0065, y = bd_lat - 0.006;
		double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
		double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
		double gg_lon = z * Math.cos(theta);
		double gg_lat = z * Math.sin(theta);
		return new Gps(gg_lon, gg_lat);
	}

	//Gps類
	public static class Gps {

		public double lat;
		public double lon;

		public Gps(double lon, double lat) {
			this.lat = lat;
			this.lon = lon;
		}

		public void print() {
			System.out.println(this.lon + "," + this.lat);
		}
	}

}



代碼效果測試:

北京地區:GCJ02 ——>BD09

\ \\

\

\ \

 

北京地區:BD-09 ——> GCJ02

\\\

\

 

結論:北京地區坐標轉換誤差基本在10米左右

 

東北地區(漠河縣):GCJ02 ——> BD09

\

\

\ \

 

東北地區(漠河縣):BD-09 ——> GCJ02

 

\

\

\

\

結論:漠河地區坐標轉換誤差在10米左右

 

西北地區(新疆烏魯木齊)GCJ02 ——> BD09

\

\

\ \

 

西北地區(新疆烏魯木齊)BD-09 ——> GCJ02

\\ \

\

 

結論:烏魯木齊地區坐標轉換誤差10米以內

 

中部地區(陝西西安)GCJ02 ——> BD09

\

\

\ \

 

中部地區(陝西西安)BD-09 ——> GCJ02

\\ \

\

 

結論:西安地區坐標轉換誤差10米以內

 

東部地區(上海)GCJ02 ——> BD09

\

\

\ \

 

東部地區(上海)BD-09 ——> GCJ02

\

\

\ \

結論:上海地區坐標轉換誤差10米以內

 

南方地區(海南三亞)GCJ02 ——> BD09

\\ \

\

 

南方地區(海南三亞)BD-09 ——> GCJ02

\\ \

\

結論:海南三亞地區坐標轉換誤差10米以內

5、 坐標系轉換方案2:百度坐標轉換API(只能進行GCJ-02 ——> BD-09)

百度地圖坐標轉換API是一套以HTTP形式提供的坐標轉換接口,用於將常用的非百度坐標(目前支持GPS設備獲取的坐標、google地圖坐標、soso地圖坐標、amap地圖坐標、mapbar地圖坐標)轉換成百度地圖中使用的坐標。

http://lbsyun.baidu.com/index.php?title=webapi/guide/changeposition

該方法局限性:只能進行GCJ-02 ——> BD-09的轉換,無法將百度坐標(BD-09)轉為火星坐標(GCJ-02),且調用一次最多只能轉換100個坐標,無法支持大規模的轉換需求。

總結:最簡單的方式:統一客戶端、服務端的SDK,避免坐標轉換;

較簡單的方式:使用本文最上面的算法,進行火星——百度坐標轉換;

較麻煩的方式:調用百度的API,使用Http形式轉換,具體放大見上方鏈接中的說明。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved