这两天做了一个关于定位的需求,此时做一下记录。
对于需求的解析:
需求:需要根据用户输入的地址返回经纬度,可以在地图上选择点,细微修改。
① 用户输入地址,可以模糊查询。
② 选择模糊查询地址,可以在地图上定点,并且用户点击可以改变定点。
方法:
① 使用高德的地图SDK以及搜索SDK
② 在录入数据页面点击地图按钮,创建一个地图,在地图上显示选中的地址视图;
③ 点击视图,跳转到搜索控制器,选择模糊查询地址返回地图控制器,并返回选中的地址;
④ 在地图控制器更新选中的地址,并且更新地址视图;
⑤ 点击返回定位,返回录入数据页面并返回经纬度及地址。
地图控制器实现:
typedef void(^SelectedTipCallback)(NSDictionary * _Nullable dataDict);
@interface TipViewController : UIViewController
@property(nonatomic,copy)SelectedTipCallback selectedTipCallBack;
@end
#import "TipViewController.h"
#import "AMapTipAnnotation.h"
#import "SearchTipsViewController.h"
#import "ReGeocodeAnnotation.h"
@interface TipViewController ()
@property (nonatomic, strong) MAMapView *mapView;
@property (nonatomic, strong) AMapSearchAPI *search;
@property (nonatomic, strong) MAPointAnnotation *poiAnnotation;
@property (nonatomic, strong) AMapTipAnnotation *tipAnnotation;
@property (nonatomic, strong) UILabel *addressLbl;
@property (nonatomic, strong) NSMutableDictionary *addressDic;
//地图
@end
@implementation TipViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = kBackGroudColor;
self.title = @"获取经纬度";
self.automaticallyAdjustsScrollViewInsets = NO;
self.navigationController.navigationBarHidden = NO;
[self navigationItemInit];
//创建地图
///地图需要v4.5.0及以上版本才必须要打开此选项(v4.5.0以下版本,需要手动配置info.plist)
[AMapServices sharedServices].enableHTTPS = YES;
self.mapView = [[MAMapView alloc] initWithFrame:self.view.bounds];
// 自动调整view的宽度,保证左边距和右边距不变
// 自动调整view与父视图上边距,以保证下边距不变
self.mapView.autoresizingMask =
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
//地图比例
self.mapView.zoomLevel = 14;
//可以点击
self.mapView.touchPOIEnabled = YES;
self.mapView.delegate = self;
// 开启当前定位
self.mapView.showsUserLocation = YES;
self.mapView.userTrackingMode = MAUserTrackingModeFollow;
[self.view addSubview:self.mapView];
UIView *addressView = [[UIView alloc] init];
addressView.backgroundColor = kBackGroudColor;
addressView.layer.masksToBounds = YES;
addressView.layer.cornerRadius = 15;
[self.view addSubview:addressView];
[addressView mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.mas_equalTo(self.view.mas_centerX);
make.left.mas_equalTo(30);
make.height.mas_equalTo(80);
make.top.mas_equalTo(20);
}];
self.addressLbl = [UILabel labelWithFrame:CGRectMake(5, 5, kFit(ScreenWidth-70), kFit(70)) text:@"" textColor:UIColorFromHex(0X666666) fontSize:kFit(15) textAlignment:NSTextAlignmentLeft];
self.addressLbl.numberOfLines = 0;
[addressView addSubview:self.addressLbl];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(selectAdress)];
[addressView addGestureRecognizer:tap];
//搜索,用户逆编码
self.search = [[AMapSearchAPI alloc] init];
self.search.delegate = self;
self.addressDic = [NSMutableDictionary dictionaryWithCapacity:0];
}
#pragma mark - Initialization
//导航栏
- (void)navigationItemInit {
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 20, 44)];
[btn addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
[btn setImage:[UIImage imageNamed:@"back-nav"] forState:UIControlStateNormal];
UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithCustomView:btn];
UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc ] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:self action:@selector(back)];
negativeSpacer.width = -5;
self.navigationItem.leftBarButtonItems = [NSArray arrayWithObjects:negativeSpacer, item, nil];
UIButton *btn2 = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 20, 44)];
[btn2 addTarget:self action:@selector(confirm) forControlEvents:UIControlEventTouchUpInside];
[btn2 setTitle:@"返回定位" forState:UIControlStateNormal];
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc]initWithCustomView:btn2];
self.navigationItem.rightBarButtonItem = rightItem;
}
#pragma mark - action
//跳转到搜索控制器
- (void)selectAdress{
__weak typeof(self)weakSelf = self;
//搜索控制器
SearchTipsViewController *searchTipsVC = [[SearchTipsViewController alloc] init];
searchTipsVC.searchTipCallBack = ^(AMapTip * _Nonnull aMapTip) {
[weakSelf clearAndShowAnnotationWithTip:aMapTip];
weakSelf.addressLbl.text = aMapTip.address;
weakSelf.poiAnnotation =nil;
[weakSelf.addressDic setValue:[NSString stringWithFormat:@"%f",aMapTip.location.latitude] forKey:@"latitude"];
[weakSelf.addressDic setValue:[NSString stringWithFormat:@"%f",aMapTip.location.longitude] forKey:@"longitude"];
//获取逆编码地址
AMapReGeocodeSearchRequest *regeo = [[AMapReGeocodeSearchRequest alloc] init];
regeo.location = [AMapGeoPoint locationWithLatitude:aMapTip.location.latitude longitude:aMapTip.location.longitude];
regeo.requireExtension = YES;
[self.search AMapReGoecodeSearch:regeo];
};
[self.navigationController pushViewController:searchTipsVC animated:YES];
}
//根据经纬度逆编码
- (void)searchReGeocodeWithCoordinate:(CLLocationCoordinate2D)coordinate
{
AMapReGeocodeSearchRequest *regeo = [[AMapReGeocodeSearchRequest alloc] init];
regeo.location = [AMapGeoPoint locationWithLatitude:coordinate.latitude longitude:coordinate.longitude];
regeo.requireExtension = YES;
[self.search AMapReGoecodeSearch:regeo];
}
- (void)back {
[self.navigationController popViewControllerAnimated:YES];
}
//返回定位
-(void)confirm{
if (self.selectedTipCallBack) {
self.selectedTipCallBack(self.addressDic?:nil);
}
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - AMapSearchDelegate
//报错
- (void)AMapSearchRequest:(id)request didFailWithError:(NSError *)error
{
}
/* 逆地理编码回调. */
- (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response
{
self.addressLbl.text = response.regeocode.formattedAddress;
[self.addressDic setValue:response.regeocode.formattedAddress forKey:@"address"];
}
#pragma mark - MAMapViewDelegate
//在后台开启定位,需要实现这个方法
- (void)mapViewRequireLocationAuth:(CLLocationManager *)locationManager
{
[locationManager requestAlwaysAuthorization];
}
/**
* @brief 地图初始化完成(在此之后,可以进行坐标计算)
* @param mapView 地图View
*/
- (void)mapInitComplete:(MAMapView *)mapView{
[self searchReGeocodeWithCoordinate:mapView.centerCoordinate];
[self.addressDic setValue:[NSString stringWithFormat:@"%f",mapView.centerCoordinate.latitude] forKey:@"latitude"];
[self.addressDic setValue:[NSString stringWithFormat:@"%f",mapView.centerCoordinate.longitude] forKey:@"longitude"];
}
//地图上的蓝点或者是小钉子-annotation
- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id)annotation
{
if ([annotation isKindOfClass:[MAUserLocation class]]) {
return nil;
}
if ([annotation isKindOfClass:[MAPointAnnotation class]])
{
static NSString *touchPoiReuseIndetifier = @"touchPoiReuseIndetifier";
MAPinAnnotationView *annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:touchPoiReuseIndetifier];
if (annotationView == nil)
{
annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:touchPoiReuseIndetifier];
}
annotationView.canShowCallout = YES;
annotationView.animatesDrop = NO;
annotationView.draggable = NO;
return annotationView;
}
return nil;
}
//单击地图使用该回调获取POI信息
- (void)mapView:(MAMapView *)mapView didTouchPois:(NSArray *)pois
{
if (pois.count == 0)
{
return;
}
MAPointAnnotation *annotation = [self annotationForTouchPoi:pois[0]];
/* 清除annotations & overlays */
[self clear];
/* Remove prior annotation. */
[self.mapView removeAnnotation:self.poiAnnotation];
[self.mapView addAnnotation:annotation];
[self.mapView selectAnnotation:annotation animated:YES];
self.poiAnnotation = annotation;
self.tipAnnotation = nil;
[self searchReGeocodeWithCoordinate:annotation.coordinate];
[self.addressDic setValue:[NSString stringWithFormat:@"%f",annotation.coordinate.latitude] forKey:@"latitude"];
[self.addressDic setValue:[NSString stringWithFormat:@"%f",annotation.coordinate.longitude] forKey:@"longitude"];
}
//根据点击创建Annotation
/* Convert MATouchPoi to MAPointAnnotation. */
- (MAPointAnnotation *)annotationForTouchPoi:(MATouchPoi *)touchPoi
{
if (touchPoi == nil)
{
return nil;
}
MAPointAnnotation *annotation = [[MAPointAnnotation alloc] init];
annotation.coordinate = touchPoi.coordinate;
annotation.title = touchPoi.name;
return annotation;
}
#pragma mark - 地图处理
/* 清除annotations & overlays */
- (void)clear
{
[self.mapView removeAnnotations:self.mapView.annotations];
[self.mapView removeAnnotation:self.mapView.userLocation];
[self.mapView removeOverlays:self.mapView.overlays];
}
//清除当前的点以及更新搜索出来的点
- (void)clearAndShowAnnotationWithTip:(AMapTip *)tip
{
/* 清除annotations & overlays */
[self clear];
if (tip.uid != nil && tip.location != nil) /* 可以直接在地图打点 */
{
AMapTipAnnotation *annotation = [[AMapTipAnnotation alloc] initWithMapTip:tip];
self.tipAnnotation = annotation;
[self.mapView addAnnotation:annotation];
[self.mapView setCenterCoordinate:annotation.coordinate];
[self.mapView selectAnnotation:annotation animated:YES];
}
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end