中國國測局地理座標(GCJ-02)、世界標準地理座標(WGS-84) 、百度地理座標(BD-09)座標系轉換

YJLocationConverter

中國國測局地理座標(GCJ-02)<火星座標>、世界標準地理座標(WGS-84) 、百度地理座標(BD-09)座標系轉換工具類

需求

一、在進行地圖開發過程中,我們一般能接觸到以下三種類型的地圖座標系:

  • 1.WGS-84原始座標系,一般用國際GPS紀錄儀記錄下來的經緯度,通過GPS定位拿到的原始經緯度,Google和高德地圖定位的的經緯度(國外)都是基於WGS-84座標系的;但是在國內是不允許直接用WGS84座標系標註的,必須經過加密後才能使用;

  • 2.GCJ-02座標系,又名“火星座標系”,是我國國測局獨創的座標體系,由WGS-84加密而成,在國內,必須至少使用GCJ-02座標系,或者使用在GCJ-02加密後再進行加密的座標系,如百度座標系。高德和Google在國內都是使用GCJ-02座標系,可以說GCJ-02是國內最廣泛使用的座標系;

  • 3.百度座標系:bd-09,百度座標系是在GCJ-02座標系的基礎上再次加密偏移後形成的座標系,只適用於百度地圖。(目前百度API提供了從其它座標系轉換爲百度座標系的API,但卻沒有從百度座標系轉爲其他座標系的API);

  • 4.LocationManager 中所用到的是國際標準的座標系統(WGS-84),使用 LocationManager 必須經過裝換才能準確;

  • 5.在MKMapView上通過定位自己位置所獲得的經緯度有是準確,由此可知,Apple已經對國內地圖做了偏移優化.

Installation

Cocoapods

YJBannerView is available through CocoaPods. To install it, simply add the following line to your Podfile:

    pod 'YJLocationConverter'

Support-Method

/**
 世界標準地理座標(WGS-84) 轉換成 中國國測局地理座標(GCJ-02)<火星座標> 超出中國依舊是世界標準地理座標

 @param location 世界標準地理座標(WGS-84)
 @return 中國國測局地理座標(GCJ-02)<火星座標>
 */
+ (CLLocationCoordinate2D)yj_WGS84ConvertToGCJ02:(CLLocationCoordinate2D)location;

/**
 中國國測局地理座標(GCJ-02)<火星座標>  轉換成  世界標準地理座標(WGS-84) 超出中國依舊是世界標準地理座標

 @param location 中國國測局地理座標(GCJ-02)<火星座標>
 @return 世界標準地理座標(WGS-84)
 */
+ (CLLocationCoordinate2D)yj_GCJ02ConvertToWGS84:(CLLocationCoordinate2D)location;

/**
 世界標準地理座標(WGS-84) 轉換成 百度地理座標(BD-09)

 @param location 世界標準地理座標(WGS-84)
 @return 百度地理座標(BD-09)
 */
+ (CLLocationCoordinate2D)yj_WGS84ConvertToBD09:(CLLocationCoordinate2D)location;

/**
 中國國測局地理座標(GCJ-02)<火星座標> 轉換成 百度地理座標(BD-09)

 @param location  中國國測局地理座標(GCJ-02)<火星座標>
 @return 百度地理座標(BD-09)
 */
+ (CLLocationCoordinate2D)yj_GCJ02ConvertToBD09:(CLLocationCoordinate2D)location;

/**
 百度地理座標(BD-09) 轉換成 中國國測局地理座標(GCJ-02)<火星座標>

 @param location 百度地理座標(BD-09)
 @return 中國國測局地理座標(GCJ-02)<火星座標>
 */
+ (CLLocationCoordinate2D)yj_BD09ConvertToGCJ02:(CLLocationCoordinate2D)location;

/**
 百度地理座標(BD-09) 轉換成 世界標準地理座標(WGS-84)此接口有1-2米左右的誤差,需要精確定位情景慎用

 @param location 百度地理座標(BD-09)
 @return 世界標準地理座標(WGS-84)
 */
+ (CLLocationCoordinate2D)yj_BD09ConvertToWGS84:(CLLocationCoordinate2D)location;

附加

1、使用IOS的私有類MKLocationManager來計算。
  這個做法是有風險的,蘋果不允許私有模塊被直接調用。換句話說,你的軟件可能會被Deny。因爲是私有模塊,我們需要聲明這個類和我們要用到的函數,代碼如下:
  

@interface MKLocationManager   
+ (id)sharedLocationManager;    // 創建並獲取MKLocationManager實例
- (BOOL)chinaShiftEnabled;     // 判斷IOS系統是否支持計算偏移
- (CLLocation*)_applyChinaLocationShift:(CLLocation*)arg;   // 傳入原始位置,計算偏移後的位置
@end

在CLLocationManager的位置監聽函數中,我們把newLocation(原始位置),轉換爲中國位置:

-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{

    if ([[MKLocationManager sharedLocationManager] chinaShiftEnabled]) {
        newLocation = [[MKLocationManager sharedLocationManager] _applyChinaLocationShift:newLocation];
        if (newLocation == nil) {  // 計算location好像是要聯網的,軟件剛啓動時前幾次計算會返回nil。
            return;
        }
    }
    ...
}

總結:這樣(只能在IOS5以前的系統中使用),經轉換後的newLocation,已經是中國的位置了。現在在映射到MKMapView上時,會顯示正確的所在位置。

2、打開MKMapView的showsUserLocation功能。
  初始化MKMapView時,將屬性showsUserLocation設置爲YES,MKMapView會啓動內置的位置監聽服務,當用戶位置變化時,調用delegate的回調函數:
  

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{
    // 這裏得到的userLocation,已經是偏移後的位置了
}

總結:這個方法不會用到IOS的私有類和函數,不會有被絕的風險。缺點可能是不能像CLLocationManager那樣進行豐富的配置,至少目前我還沒找到。

源碼查看鏈接:源碼地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章