編輯:關於Android編程
1、美國GPS使用的是WGS84坐標系統,以經緯度的形式來表示地球平面上的某一個位置。但在我國,出於國家安全考慮,國內所有導航電子地圖必須使用國家測繪局制定的加密坐標系統,即將一個真實的經緯度坐標(WGS84坐標系)通過中國國家測繪局制訂的加密算法加密成一個不正確的經緯度坐標(GCJ-02坐標系),我們在業內將前者稱之為地球坐標,後者稱之為火星坐標。
2、百度官方對百度坐標為何有偏移的解釋:
國際經緯度坐標標准為WGS-84,國內必須至少使用國測局制定的GCJ-02,對地理位置進行首次加密。百度坐標在此基礎上,進行了BD-09二次加密措施,更加保護了個人隱私。百度對外接口的坐標系並不是GPS采集的真實經緯度,需要通過坐標轉換接口進行轉換(見文章最後第5點)。
3、國內各地圖坐標系統比較:
地圖廠商
坐標系
百度地圖
百度坐標
騰訊地圖
火星坐標
高德地圖
火星坐標
谷歌地圖(中國)
火星坐標
搜狐搜狗地圖
搜狗坐標
4、 坐標系轉換方案1:網上的火星坐標系 (GCJ-02) 與百度坐標系 (BD-09) 的轉換算法:
C++:
#includeconst 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); }
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形式轉換,具體放大見上方鏈接中的說明。
Android開發的時候經常遇到端口號被占用的問題,經常使程序無法運行,很煩人。我總結了一個很好的方法,非常實用。方法如下: (1):方法1:第一步:1:netstat
一、 Binder概述1.1 為什麼要用binder出於安全性、穩定性和內存管理的考慮,Android的應用和系統服務運行在分離的進程中,但是它們之間需要通信和共享數據避
本文代碼以MTK平台Android 4.4為分析對象,與Google原生AOSP有些許差異,請讀者知悉。 本文主要介紹MTK Android開機時,SIM卡的Fram
關於滑動沖突在Android開發中,如果是一些簡單的布局,都很容易搞定,但是一旦涉及到復雜的頁面,特別是為了兼容小屏手機而使用了ScrollView以後,就會出現很多點擊