你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> ios系統經緯度轉百度經緯度及經緯度轉地址

ios系統經緯度轉百度經緯度及經緯度轉地址

編輯:關於IOS

正在進行的項目中有這樣的需求:定位獲得當前經緯度,再用百度Place API使用經緯度查詢周邊信息。這裡不需要顯示地圖,只需要定位。看似思路很順暢,做起來卻不容易。

iPhone的GPS定位(CLLocationManager)獲得的經緯坐標是基於WGS-84坐標系(世界標准),Google地圖使用的是GCJ-02坐標系(中國特色的火星坐標系),這就是為什麼獲得的經緯坐標在google地圖上會發生偏移。我項目需求是使用百度Place API,百度的經緯坐標在GCJ-02的基礎上再做了次加密,就是DB-09坐標系。就想使用百度地圖的IOS SDK,裡面的坐標系統都是一致的而不用轉換,由於不想讓項目太大,所以沒有用百度的sdk,所以另辟蹊徑了。

在網上搜索一番,有現成百度的接口轉換坐標,經試驗 從WGS-84到GCJ-02,再到DB-09,經兩次轉換後,順利獲得當前正確地理位置信息和周邊信息,當然這些信息是來自百度的。

ZYLocationManager.h

[objc] view plaincopy

  1. #import <Foundation/Foundation.h>
  2. #import <CoreLocation/CoreLocation.h>
  3. #import "Singleton.h"
  4. typedef void(^locationBlock)(CLLocationCoordinate2D coor);
  5. typedef void(^addressBlock)(NSString *address);
  6. @interface ZYLocationManager : NSObject
  7. singleton_interface(ZYLocationManager)
  8. /**
  9.  *  獲取糾偏後的經緯度(百度地圖經緯度)
  10.  */
  11. - (void) getLocationCoordinate:(locationBlock) locaiontBlock;
  12. /**
  13.  *  獲取糾偏後的經緯度(百度地圖經緯度)和地址
  14.  */
  15. - (void) getLocationCoordinate:(locationBlock) locaiontBlock address:(addressBlock) addressBlock;
  16. @end

ZYLocationManager.m

[objc] view plaincopy

  1. #import "ZYLocationManager.h"
  2. #import "AFNetworking.h"
  3. #define IOS_Version [[UIDevice currentDevice].systemVersion floatValue]
  4. @interface ZYLocationManager ()<CLLocationManagerDelegate>{
  5. // 保存block
  6.     locationBlock _locationBlock;
  7.     addressBlock _addressBlock;
  8. }
  9. @property (nonatomic, strong) CLLocationManager *lm;
  10. @end
  11. @implementation ZYLocationManager
  12. singleton_implementation(ZYLocationManager)
  13. /**
  14.  *  懶加載
  15.  */
  16. - (CLLocationManager *)lm
  17. {
  18.     if (!_lm) {
  19.         _lm = [[CLLocationManager alloc] init];
  20.         _lm.delegate = self;
  21.         // 定位精准度
  22.         _lm.desiredAccuracy = kCLLocationAccuracyBest;
  23.         // 重新定位的距離
  24.         _lm.distanceFilter = 1000.0f;
  25.     }
  26.     return _lm;
  27. }
  28. /**
  29.  *  類第一次使用的時候被調用
  30.  */
  31. + (void)initialize
  32. {
  33.     ZYLocationManager *manager = [self sharedZYLocationManager];
  34.     // ios8後需要向用戶請求權限
  35.     if (IOS_Version >= 8.0) {
  36.         [manager.lm requestWhenInUseAuthorization];
  37.         [manager.lm requestAlwaysAuthorization];
  38.     }
  39.     // 開始定位
  40.     [manager.lm startUpdatingLocation];
  41. }
  42. #pragma mark - CLLocationManager獲取經緯度的代理方法
  43. - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
  44. {
  45.     CLLocation *location = [locations lastObject];
  46.     CLLocationCoordinate2D coor = location.coordinate;
  47. //    NSLog(@"緯度:%.6f 經度%.6f", coor.latitude, coor.longitude);
  48.     NSString *x1 = [NSString stringWithFormat:@"%f", coor.longitude];
  49.     NSString *y1 = [NSString stringWithFormat:@"%f", coor.latitude];
  50.     // http://api.map.baidu.com/ag/coord/convert?from=0&to=2&x=113.377346&y=23.132648
  51.     __block NSDictionary *dict1 = @{@"from":@"0",
  52.                             @"to":@"2",
  53.                             @"x":x1,
  54.                             @"y":y1
  55.                             };
  56.     AFHTTPRequestOperationManager *roManager = [AFHTTPRequestOperationManager manager];
  57.     // 1、ios系統經緯度(國際標准)轉谷歌經緯度
  58.     [roManager GET:@"http://api.map.baidu.com/ag/coord/convert" parameters:dict1 success:^(AFHTTPRequestOperation *operation, id responseObject) {
  59.         __block NSString *resultX = [self base64Decode:responseObject[@"x"]];
  60.         __block NSString *resultY = [self base64Decode:responseObject[@"y"]];
  61.         dict1 = @{@"from":@"2",
  62.                   @"to":@"4",
  63.                   @"x":resultX,
  64.                   @"y":resultY
  65.                   };
  66.         // 2、谷歌經緯度轉百度經緯度
  67.         [roManager GET:@"http://api.map.baidu.com/ag/coord/convert" parameters:dict1 success:^(AFHTTPRequestOperation *operation, id responseObject) {
  68.             resultX = [self base64Decode:responseObject[@"x"]];
  69.             resultY = [self base64Decode:responseObject[@"y"]];
  70.             CLLocationCoordinate2D resultCoor = CLLocationCoordinate2DMake([resultY floatValue], [resultX floatValue]);
  71.             // 給block賦值
  72.             if (_locationBlock) {
  73.                 _locationBlock(resultCoor);
  74.             }
  75.             [self getAddressWithCoordinate:resultCoor];
  76.         } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
  77.             NSLog(@"%@", error);
  78.         }];
  79.     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
  80.         NSLog(@"%@", error);
  81.     }];
  82.     // 停止定位
  83.     [self.lm stopUpdatingLocation];
  84. }
  85. - (void)getLocationCoordinate:(locationBlock)locaiontBlock
  86. {
  87.     _locationBlock = locaiontBlock;
  88. }
  89. - (void)getLocationCoordinate:(locationBlock)locaiontBlock address:(addressBlock)addressBlock
  90. {
  91.     _locationBlock = locaiontBlock;
  92.     _addressBlock = addressBlock;
  93. }
  94. #pragma mark - base64解密
  95. - (NSString *)base64Decode:(NSString *)str
  96. {
  97.     // 1、加密字符串轉二進制數據
  98.     NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
  99.     // 2、二進制數據轉字符串
  100.     return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
  101. }
  102. #pragma mark - 經緯度轉地址
  103. - (void)getAddressWithCoordinate:(CLLocationCoordinate2D)coor
  104. {
  105.     if (coor.latitude == 0 || coor.longitude == 0) return;
  106.     CLLocation *loca = [[CLLocation alloc] initWithLatitude:coor.latitude longitude:coor.longitude];
  107.     CLGeocoder *geocoder = [[CLGeocoder alloc] init];
  108.     [geocoder reverseGeocodeLocation:loca completionHandler:^(NSArray *placemarks, NSError *error) {
  109.         if (placemarks.count == 0 || error) return;
  110.         CLPlacemark *pm = [placemarks lastObject];
  111.         if (_addressBlock) {
  112.             _addressBlock(pm.thoroughfare);
  113.         }
  114.     }];
  115. }
  116. @end

IOS8後,請求定位需要請求權限,代碼ZYLocationManager.m已經寫好了,不過還需要在info.plist中,添加兩個屬性NSLocationAlwaysUsageDescription和NSLocationWhenInUseUsageDescription,屬性值即是你需要提示給用戶的信息,如下圖所示:
將ZYLocationManager.h和ZYLocationManager.m拖入項目中,即可直接調用ZYLocationManager.h定義的兩個方法,獲取到百度經緯度和地址。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved