1. 程式人生 > >iOS | 地圖定位

iOS | 地圖定位

在IOS開發中,最常見的功能之一就是地圖定位功能,不單單是百度地圖,高德地圖等專業的地圖導航軟體,還有美團,咕咚等一些美食購物類和運動類也需要這樣的功能,所以學會這項技能是一名IOS開發工程師必須的.
百度地圖
咕咚
美團

分享一些比較基礎的關於定位方面的小知識.

關於定位有兩個框架
1.CoreLocation ---->用於地理定位
2.Map Kit ---->用於地圖展示

兩個熱詞:

LBS: location based service
SLM: social local mobile

使用CoreLocation定位

首先在之前需要匯入corelocation框架,然後在標頭檔案匯入corelocation.h標頭檔案.
注意:coordinate是座標,latitude是緯度,longitude是經度.

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 1.建立位置管理者
    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    self.locationManager = locationManager;
    // 在iO8之前,只要匯入CoreLocation 會自動申請許可權
    // 在iOS8之後需要程式設計師手寫
    
    // 2.請求使用者授權    必須要配置info.plist檔案
    //在info裡面配置NSLocationAlwaysUsageDescription或者
    //NSLocationWhenInUseUsageDescription
    // 請求app始終授權  無論程式在前臺還是在後臺執行  都可以使用定位
//    [locationManager requestAlwaysAuthorization];
    // 請求app在使用期間授權   在前臺使用時才可以使用定位
    [locationManager requestWhenInUseAuthorization];
    
    if ([UIDevice currentDevice].systemVersion.floatValue >= 9.0) {
        // 臨時開啟後臺定位  配置info.plist檔案  不配置直接崩潰
        locationManager.allowsBackgroundLocationUpdates = YES;
    }
    // 3.設定屬性(兩個屬性是為了讓程式可以持續的進行定位)
//    // 距離篩選  單位:米  當用戶移動100.5米後呼叫定位方法
//    locationManager.distanceFilter = 100.5;
//    // 期望精度  單位:米  系統預設將100米範圍內作為一個位置
//    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    // 4.設定代理
    locationManager.delegate = self;
    // 5.開啟定位
    [locationManager startUpdatingLocation];
    // 開始更新移動方向
//    [locationManager startUpdatingHeading];


//代理方法,一旦開啟定位,會自動呼叫這個代理方法
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    // 獲取資料
//    NSLog(@"%@",locations);
    // 停止定位  省電
//    [manager stopUpdatingLocation];
}



// 比較位置的距離  比較的是兩點之間的直線距離
- (void)compareDistance
{
    // 北京的位置
    CLLocation *location = [[CLLocation alloc] initWithLatitude:39 longitude:115];
    // 上海的位置
    CLLocation *location1 = [[CLLocation alloc] initWithLatitude:30 longitude:120];
    // 比較北京到上海的位置(直線距離)
    double distance = [location distanceFromLocation:location1];
    // 單位:米
    NSLog(@"%f",distance / 1000);
}
    
使用MapKit定位

修改地圖型別   mapView.mapType
地圖實時交通狀態 mapView.showsTraffic
設定使用者跟蹤模式  mapView.userTrackingMode
代理方法,
//顯示在地圖中使用者定位的位置

-(void)mapView:(MKMapView\*)mapView didUpdateUserLocation:(MKUserLocation \*)userLocation

//獲取實時地圖變化的區域變化(中心點,區域跨度)

-(void)mapView:(MKMapView \*)mapView regionDidChangeAnimated:(BOOL)animated

注意:這裡需要匯入的是MapKit框架和MapKit.h標頭檔案.

- (void)viewDidLoad {
    [super viewDidLoad];
     
    // 修改地圖型別
    /*
     MKMapTypeStandard    標準(預設)
     MKMapTypeSatellite   衛星
     MKMapTypeHybrid      混合
     MKMapTypeSatelliteFlyover  在中國暫時不能使用
     MKMapTypeHybridFlyover  在中國暫時不能使用
     */
    self.mapView.mapType = MKMapTypeStandard;
    
    // 實時交通狀況 iOS9新增
    self.mapView.showsTraffic = YES;
    
    // 建立位置管理者
    self.locationManager = [[CLLocationManager alloc] init];
    // 請求使用者授權  配置info.plist
    [self.locationManager requestWhenInUseAuthorization];
    // 設定使用者的跟蹤模式
    /*
     MKUserTrackingModeFollow  跟蹤使用者的位置   MKUserTrackingModeFollowWithHeading  跟蹤使用者的位置和方向
     */
    self.mapView.userTrackingMode = MKUserTrackingModeFollow;
    
    // 設定代理
    self.mapView.delegate = self;
}

// 跟蹤到使用者位置時呼叫
// mapView:地圖
// userLocation:使用者位置的大頭針模型
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
    // 1.反地理編碼
    // 1.1建立地理編碼物件
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    // 1.2反地理編碼
    [geocoder reverseGeocodeLocation:userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
        // 1.3防錯處理
        if (error) {
            NSLog(@"%@",error);
            return ;
        }
        // 1.4獲取地標
        CLPlacemark *placemark = [placemarks firstObject];
        // 2.給標題和子標題賦值
        userLocation.title = placemark.locality;
        userLocation.subtitle = placemark.name;
    }];
}


// 回到當前使用者的位置
- (IBAction)backToCurrentLocation
{
    
    // 獲取當前的跨度
    MKCoordinateSpan span = MKCoordinateSpanMake(0.024967, 0.015407);
    // 設定回到使用者剛開始的區域 region(結構體) --1.中心點經緯度(結構體)--> 經度和緯度  2.經緯度跨度(結構體)-->經度跨度和緯度跨度
    // 設定區域並使用動畫
    [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.userLocation.location.coordinate, span) animated:YES];
}


- (IBAction)biggerMap
{
    // 修改經緯度跨度
    CGFloat latitudeDelta = self.mapView.region.span.latitudeDelta * 0.5;
    CGFloat longitudeDelta = self.mapView.region.span.longitudeDelta * 0.5;
    MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
    // 確定放大地圖後的區域
    [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.centerCoordinate, span) animated:YES];
}
- (IBAction)smallerMap
{
    // 修改經緯度跨度
    CGFloat latitudeDelta = self.mapView.region.span.latitudeDelta * 2;
    CGFloat longitudeDelta = self.mapView.region.span.longitudeDelta * 2;
    MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
    [self.mapView setRegion:MKCoordinateRegionMake(self.mapView.centerCoordinate, span) animated:YES];
}

演示

效果演示

說到底,其實蘋果官方的框架已經做得不錯了,該有的功能基本都具備,而且使用起來不是怎麼困難,掌握起來也非常快.我這裡只是分享一些比較基礎的功能,歡迎工程師們賜教.
另外附上地理編碼的小演示.

地理編碼.gif