在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