序言
在我们生活周围的应用中经常看到这样的现象就是有一个固定的大头针在地图中心,然后移动地图的时候,地址会发生变化,例如我们平常用的应用小黄车ofo,膜拜,小蓝单车等,都是在地图的中心固定一个大头针,当移动地图的时候就刷新周边的数据。
思路
这其实不是一个真正的大头针,其实是一个自定义的视图。一个图片添加到地图中心,然后在mapView拖动地图的代理方法中,去翻解析根据定位坐标,进行周边搜索。
示例代码
1、添加地图
self.mapView = [[MAMapView alloc] initWithFrame:CGRectMake(20, 64 + 100, self.view.frame.size.width - 40, self.view.frame.size.height - 64 - 150)];
self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.mapView.delegate = self;
self.mapView.mapType = MAMapTypeStandard;
// 禁止旋转
self.mapView.rotateEnabled = NO;
// 禁止立体旋转
self.mapView.rotateCameraEnabled = NO;
self.mapView.showsBuildings = NO;
self.mapView.showsCompass = YES;
self.mapView.showsUserLocation = YES;
self.mapView.userTrackingMode = MAUserTrackingModeFollow;
[self.view addSubview:self.mapView];
// 初始化搜索
self.searchAPI = [[AMapSearchAPI alloc] init];
self.searchAPI.delegate = self;
#pragma mark--创建假的大头针
- (void)creatPinView {
self.pinView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 48, 48)];
self.pinView.image = [UIImage imageNamed:@"mapimage"];
self.pinView.center = CGPointMake((self.view.frame.size.width - 40) * 0.5, (self.view.frame.size.height - 64 - 150) * 0.5);
self.pinView.hidden = NO;
[self.mapView addSubview:self.pinView];
}
2、创建地址显示标签
#pragma mark--creatPostionLabel
- (void)creatPostionLabel {
self.positonLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 64 + 20, self.view.frame.size.width - 40, 60)];
self.positonLabel.font = [UIFont systemFontOfSize:15];
self.positonLabel.textColor = [UIColor cyanColor];
self.positonLabel.backgroundColor = [UIColor grayColor];
self.positonLabel.numberOfLines = 2;
[self.view addSubview:self.positonLabel];
}
3、进行单次逆地理定位查出当前位置
-(void)configLocationManager {
self.locationManager = [[AMapLocationManager alloc] init];
[self.locationManager setDelegate:self];
//设置期望定位精度
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
//设置不允许系统暂停定位
[self.locationManager setPausesLocationUpdatesAutomatically:NO];
//设置允许在后台定位
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
//设置定位超时时间
[self.locationManager setLocationTimeout:DefaultLocationTimeout];
//设置逆地理超时时间
[self.locationManager setReGeocodeTimeout:DefaultReGeocodeTimeout];
//设置开启虚拟定位风险监测,可以根据需要开启
[self.locationManager setDetectRiskOfFakeLocation:NO];
//进行单次带逆地理定位请求
[self.locationManager requestLocationWithReGeocode:YES completionBlock:self.completionBlock];
[self.mapView setZoomLevel:17.5];
}
4、显示当前的位置
#pragma mark - Initialization
- (void)initCompleteBlock {
__weak ShowPostionViewController *weakSelf = self;
self.completionBlock = ^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
if (error != nil && error.code == AMapLocationErrorLocateFailed) {
//定位错误:此时location和regeocode没有返回值,不进行annotation的添加
// 重新进行,单次定位
[weakSelf.locationManager requestLocationWithReGeocode:YES completionBlock:weakSelf.completionBlock];
NSLog(@"定位错误:{%ld - %@};", (long)error.code, error.userInfo);
return;
} else if (error != nil
&& (error.code == AMapLocationErrorReGeocodeFailed
|| error.code == AMapLocationErrorTimeOut
|| error.code == AMapLocationErrorCannotFindHost
|| error.code == AMapLocationErrorBadURL
|| error.code == AMapLocationErrorNotConnectedToInternet
|| error.code == AMapLocationErrorCannotConnectToHost))
{
//逆地理错误:在带逆地理的单次定位中,逆地理过程可能发生错误,此时location有返回值,regeocode无返回值,进行annotation的添加
NSLog(@"逆地理错误:{%ld - %@};", (long)error.code, error.userInfo);
// 重新进行,单次定位
[weakSelf.locationManager requestLocationWithReGeocode:YES completionBlock:weakSelf.completionBlock];
} else if (error != nil && error.code == AMapLocationErrorRiskOfFakeLocation) {
//存在虚拟定位的风险:此时location和regeocode没有返回值,不进行annotation的添加
NSLog(@"存在虚拟定位的风险:{%ld - %@};", (long)error.code, error.userInfo);
return;
} else {
//没有错误:location有返回值,regeocode是否有返回值取决于是否进行逆地理操作,进行annotation的添加
}
//有无逆地理信息,annotationView的标题显示的字段不一样
if (regeocode) {
weakSelf.positonLabel.text = [NSString stringWithFormat:@"%@", regeocode.formattedAddress];
weakSelf.location = location;
} else {
}
};
}
5、在mapView被拖动时,更新位置发起翻解析搜索请求
#pragma mark--移动地图的时候点击事件
- (void)mapView:(MAMapView *)mapView mapDidMoveByUser:(BOOL)wasUserAction {
if (!wasUserAction) {
return;
}
CGPoint center = CGPointMake(self.mapView.bounds.size.width * 0.5, self.mapView.bounds.size.height * 0.5);
CLLocationCoordinate2D coor2d = [mapView convertPoint:center toCoordinateFromView:self.mapView];
self.lastLocation = coor2d;
// ReGEO解析
AMapReGeocodeSearchRequest *request = [[AMapReGeocodeSearchRequest alloc] init];
request.location = [AMapGeoPoint locationWithLatitude:coor2d.latitude longitude:coor2d.longitude];
[self.searchAPI AMapReGoecodeSearch:request];
}
6、更新位置
- (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response {
NSString *address = response.regeocode.formattedAddress;
self.positonLabel.text = address;
// 定位结果
NSLog(@"location:{lat:%f; lon:%f}", request.location.latitude, request.location.longitude);
self.pinView.hidden = NO;
[self.mapView setCenterCoordinate:self.lastLocation animated:YES];
}
案例demo如下:
https://github.com/Wululu6/MapKitDemo1.git
参考内容:
https://www.jianshu.com/p/0cd5260153c9
https://www.jianshu.com/p/2ede1fc70fe2
查看地图更多内容请点击以下链接:
定位