iOS | 地圖定位
阿新 • • 發佈:2018-12-11
在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];
}
演示
說到底,其實蘋果官方的框架已經做得不錯了,該有的功能基本都具備,而且使用起來不是怎麼困難,掌握起來也非常快.我這裡只是分享一些比較基礎的功能,歡迎工程師們賜教.
另外附上地理編碼的小演示.