單次定位
- 初始化
@property (nonatomic, strong) AMapLocationManager *locationManager;
@property (nonatomic, copy) AMapLocatingCompletionBlock completionBlock;
//單次定位
self.locationManager = [[AMapLocationManager alloc] init];
[self.locationManager setDelegate:self];
//設(shè)置期望定位精度
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
//設(shè)置不允許系統(tǒng)暫停定位
[self.locationManager setPausesLocationUpdatesAutomatically:NO];
//設(shè)置允許在后臺(tái)定位
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
//設(shè)置定位超時(shí)時(shí)間
[self.locationManager setLocationTimeout:DefaultLocationTimeout];
//設(shè)置逆地理超時(shí)時(shí)間
[self.locationManager setReGeocodeTimeout:DefaultReGeocodeTimeout];
//設(shè)置開(kāi)啟虛擬定位風(fēng)險(xiǎn)監(jiān)測(cè),可以根據(jù)需要開(kāi)啟
[self.locationManager setDetectRiskOfFakeLocation:NO];
[self.mapView removeAnnotations:self.mapView.annotations];
//進(jìn)行單次帶逆地理定位請(qǐng)求
YES:返回帶逆定理 返回坐標(biāo)和地址信息
No:不帶逆地理定位請(qǐng)求
[self initCompleteBlock];// ps:需要在請(qǐng)求前調(diào)用
[self.locationManager requestLocationWithReGeocode:NO completionBlock:self.completionBlock];
或
[self.locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
}];
- Block 回調(diào)(單次定位請(qǐng)求后Block回調(diào))
//單次定位后的bolck回調(diào)
-(void)initCompleteBlock{
self.completionBlock = ^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
NSLog(@"===%@",location);
//帶逆地理
if (regeocode)
{
NSString * str =[NSString stringWithFormat:@"%@ \n %@-%@-%.2fm", regeocode.formattedAddress,regeocode.citycode, regeocode.adcode, location.horizontalAccuracy];
}
else
{
NSString * str = [NSString stringWithFormat:@"lat:%f;lon:%f \n accuracy:%.2fm", location.coordinate.latitude, location.coordinate.longitude, location.horizontalAccuracy];
}
};
}
持續(xù)定位
- 初始化
self.locationManager = [[AMapLocationManager alloc] init];
self.locationManager.delegate = self;
//設(shè)置定位最小更新距離方法如下,單位米
self.locationManager.distanceFilter = 200;
//設(shè)置不允許系統(tǒng)暫停定位
[self.locationManager setPausesLocationUpdatesAutomatically:NO];
//設(shè)置允許在后臺(tái)定位
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
//開(kāi)啟持續(xù)定位
[self.locationManager startUpdatingLocation];
//持續(xù)定位返回逆地理編碼信息
[self.locationManager setLocatingWithReGeocode:YES];
- 接收/處理位置更新
- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode
{
NSLog(@"location:{lat:%f; lon:%f; accuracy:%f; reGeocode:%@}", location.coordinate.latitude, location.coordinate.longitude, location.horizontalAccuracy, reGeocode.formattedAddress);
// //獲取到定位信息,更新annotation
// if (self.pointAnnotaiton == nil)
// {
// self.pointAnnotaiton = [[MAPointAnnotation alloc] init];
// [self.pointAnnotaiton setCoordinate:location.coordinate];
//
// [self.mapView addAnnotation:self.pointAnnotaiton];
// }
//
// [self.pointAnnotaiton setCoordinate:location.coordinate];
//
// [self.mapView setCenterCoordinate:location.coordinate];
// [self.mapView setZoomLevel:15.1 animated:NO];
}
方向定位
- 開(kāi)始定位
//開(kāi)始進(jìn)行連續(xù)定位
[self.locationManager startUpdatingLocation];
// headingAvailable 設(shè)備是否支持方向識(shí)別
YES:設(shè)備支持方向識(shí)別 ; NO:設(shè)備不支持支持方向識(shí)別
if ([AMapLocationManager headingAvailable] == YES)
{
[self.locationManager startUpdatingHeading];
}
- 停止定位
//停止定位
[self.locationManager stopUpdatingLocation];
[self.locationManager stopUpdatingHeading];
//移除地圖上的annotation
[self.mapView removeAnnotations:self.mapView.annotations];
self.pointAnnotaiton = nil;
_annotationView = nil;
- 回調(diào)(可用此修改方向之類(lèi)的)
@property (nonatomic, assign) CGFloat annotationViewAngle;
/**
* @brief 設(shè)備方向改變時(shí)回調(diào)函數(shù)
* @param manager 定位 AMapLocationManager 類(lèi)懂拾。
* @param newHeading 設(shè)備朝向影暴。
*/
- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
if (_annotationView != nil)
{
CGFloat angle = newHeading.trueHeading*M_PI/180.0f + M_PI - _annotationViewAngle;
NSLog(@"################### heading : %f - %f", newHeading.trueHeading, newHeading.magneticHeading);
_annotationViewAngle = newHeading.trueHeading*M_PI/180.0f + M_PI;
_heading = newHeading;
_annotationView.transform = CGAffineTransformRotate(_annotationView.transform ,angle);
}
}
后臺(tái)定位
//iOS 9(不包含iOS 9) 之前設(shè)置允許后臺(tái)定位參數(shù)夯秃,保持不會(huì)被系統(tǒng)掛起
[self.locationManager setPausesLocationUpdatesAutomatically:NO];
//iOS 9(包含iOS 9)之后新特性:將允許出現(xiàn)這種場(chǎng)景敦第,同一app中多個(gè)locationmanager:一些只能在前臺(tái)定位泛烙,另一些可在后臺(tái)定位课梳,并可隨時(shí)禁止其后臺(tái)定位距辆。
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
self.locationManager.allowsBackgroundLocationUpdates = YES;
}
地理圍欄
- 舊版
//創(chuàng)建圓形地理圍欄
AMapLocationCircleRegion *cirRegion200 = [[AMapLocationCircleRegion alloc] initWithCenter:coordinate
radius:200.0
identifier:@"circleRegion200"];
//添加地理圍欄
[self.locationManager startMonitoringForRegion:cirRegion200];
//添加地理圍欄對(duì)應(yīng)的Overlay,方便查看
MACircle *circle200 = [MACircle circleWithCenterCoordinate:coordinate radius:200.0];
[self.mapView addOverlay:circle200];
[self.mapView setVisibleMapRect: circle200.boundingMapRect];
停止地理圍欄
[self.regions enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[self.locationManager stopMonitoringForRegion:(AMapLocationRegion *)obj];
}];
- 新版
新版的高德地圖對(duì)地理圍欄進(jìn)行了優(yōu)化暮刃,把地理圍欄從AMapLocationManager中剝離跨算,有了自己?jiǎn)为?dú)的管理類(lèi)AMapGeoFenceManager。當(dāng)圍欄創(chuàng)建完畢椭懊,且圍欄創(chuàng)建成功時(shí)會(huì)啟動(dòng)定位诸蚕,這部分無(wú)需您來(lái)設(shè)置,SDK內(nèi)部執(zhí)行。 定位機(jī)制:通過(guò)“遠(yuǎn)離圍欄時(shí)逐漸降低定位頻率”來(lái)降低電量消耗背犯,“離近圍欄時(shí)逐漸提高定位頻率”來(lái)保證有足夠的定位精度從而完成圍欄位置檢測(cè)坏瘩。需要注意,在iOS9及之后版本的系統(tǒng)中漠魏,如果您希望程序在后臺(tái)持續(xù)檢測(cè)圍欄觸發(fā)行為倔矾,需要保證manager的allowsBackgroundLocationUpdates為YES,設(shè)置為YES的時(shí)候必須保證 Background Modes 中的 Location updates 處于選中狀態(tài)柱锹,否則會(huì)拋出異常哪自。
------來(lái)自網(wǎng)絡(luò)
初始化地理圍欄manager
self.geoFenceManager = [[AMapGeoFenceManager alloc] init];
self.geoFenceManager.delegate = self;
//需要進(jìn)行通知的行為
self.geoFenceManager.activeAction = AMapGeoFenceActiveActionInside | AMapGeoFenceActiveActionOutside | AMapGeoFenceActiveActionStayed; //進(jìn)入,離開(kāi)奕纫,停留都要進(jìn)行通知
self.geoFenceManager.allowsBackgroundLocationUpdates = YES; //允許后臺(tái)定位
添加圍欄
圓形圍欄
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(39.908692, 116.397477); //天安門(mén)
if (self.userLocation) {
coordinate = self.userLocation.coordinate;
}
[self.geoFenceManager addCircleRegionForMonitoringWithCenter:coordinate radius:300 customID:@"circle_1"];
多邊形圍欄
NSInteger count = 4;
CLLocationCoordinate2D *coorArr = malloc(sizeof(CLLocationCoordinate2D) * count);
coorArr[0] = CLLocationCoordinate2DMake(39.933921, 116.372927);
coorArr[1] = CLLocationCoordinate2DMake(39.907261, 116.376532);
coorArr[2] = CLLocationCoordinate2DMake(39.900611, 116.418161);
coorArr[3] = CLLocationCoordinate2DMake(39.941949, 116.435497);
[self doClear];
[self.geoFenceManager addPolygonRegionForMonitoringWithCoordinates:coorArr count:count customID:@"polygon_1"];
POI關(guān)鍵詞圍欄
[self.geoFenceManager addKeywordPOIRegionForMonitoringWithKeyword:@"北京大學(xué)" POIType:@"高等院校" city:@"成都" size:20 customID:@"poi_1"];
POI周邊圍欄
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(39.908692, 116.397477); //天安門(mén)
[self.geoFenceManager addAroundPOIRegionForMonitoringWithLocationPoint:coordinate aroundRadius:10000 keyword:@"肯德基" POIType:@"050301" size:20 customID:@"poi_2"];
行政區(qū)域圍欄
[self.geoFenceManager addDistrictRegionForMonitoringWithDistrictName:@"成都市" customID:@"district_1"];
獲取圍欄創(chuàng)建后的回調(diào)
- (void)amapGeoFenceManager:(AMapGeoFenceManager *)manager didAddRegionForMonitoringFinished:(NSArray<AMapGeoFenceRegion *> *)regions customID:(NSString *)customID error:(NSError *)error {
if (error) {
NSLog(@"創(chuàng)建失敗 %@",error);
} else {
NSLog(@"創(chuàng)建成功");
}
//添加地理圍欄對(duì)應(yīng)的Overlay提陶,方便查看
以圓形圍欄 為例
if ([customID hasPrefix:@"circle"]) {
if (error) {
NSLog(@"======= circle error %@",error);
} else {
AMapGeoFenceCircleRegion *circleRegion = (AMapGeoFenceCircleRegion *)regions.firstObject; //一次添加一個(gè)圓形圍欄烫沙,只會(huì)返回一個(gè)
MACircle *circleOverlay = [MACircle circleWithCenterCoordinate:coordinate radius:radius];
[self.mapView addOverlay:circleOverlay];
[self.mapView setVisibleMapRect:circleOverlay.boundingMapRect edgePadding:UIEdgeInsetsMake(20, 20, 20, 20) animated:YES]; //設(shè)置地圖的可見(jiàn)范圍匹层,讓地圖縮放和平移到合適的位置
}
}
圍欄狀態(tài)改變時(shí)的回調(diào)
- (void)amapGeoFenceManager:(AMapGeoFenceManager *)manager didGeoFencesStatusChangedForRegion:(AMapGeoFenceRegion *)region customID:(NSString *)customID error:(NSError *)error {
if (error) {
NSLog(@"status changed error %@",error);
}else{
NSLog(@"status changed success %@",[region description]);
}
}
移除圍欄
- (void)removeTheGeoFenceRegion:(AMapGeoFenceRegion *)region; //移除指定圍欄
- (void)removeGeoFenceRegionsWithCustomID:(NSString *)customID; //移除指定customID的圍欄
- (void)removeAllGeoFenceRegions; //移除所有圍欄
區(qū)域判斷
//設(shè)置一個(gè)目標(biāo)經(jīng)緯度
CLLocationCoordinate2D coodinate = CLLocationCoordinate2DMake(39.948691, 116.492479);
//返回是否在大陸或以外地區(qū),返回YES為大陸地區(qū)锌蓄,NO為非大陸升筏。
BOOL flag= AMapLocationDataAvailableForCoordinate(coodinate);