美文网首页iOS
iOS 百度地图实现模糊搜索和定位、跳转本机地图 上

iOS 百度地图实现模糊搜索和定位、跳转本机地图 上

作者: Bales_chu | 来源:发表于2017-07-09 11:57 被阅读1534次

    前言

    项目中要集成百度地图,百度的api文档写的很乱,说一下我们项目需求,我们有两个界面需要用到百度地图。

    1.一个需要点击地理位置在地图上搜索定位。
    2.另一个类似于微信发朋友圈输入关键词模糊搜索地理位置信息

    <br />

    开发过程中遇到的问题先跟大家分享一下,我在导入百度地图之后,跳转到地图界面不能滑动不能缩放,心里很纳闷,而且我也没有在这里用到手势缩放、和一些带滑动的控制器呀,后来我看上个控制器我发现我把 这个控制器imageVIew和他上边的一些按钮整到 window最上层,控制器结束了跳转到这个界面之后imageView还在Window最上层上,所以你创建的地图就相当于一个在image上当然不可能拖动。所以对于这种问题要向相似的地方想,很快就能找到问题的所在。

    <br />


    搜索定位调起本机地图.gif

    <br />

    类似微信模糊搜索.gif

    <br />

    定位功能的实现步骤

    1.配置环境

    建议使用cocoaPods,这样减少好多无用功

    2.在delegate设置AppKey、创建百度manager

    如果你导入的第三方太多导致APPdelegate代码太多,你也可以把各个第三方在delegate里边的内容用类的类别分成一个一个的这样比较好管理.

    .h 文件

    
    
    
    #import "AppDelegate.h"
    #import <BaiduMapAPI_Base/BMKMapManager.h>
    
    
    @interface AppDelegate (BaiDu)
    
    - (void)initBaiduMapApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
    
    @end
    
    
    
    .m文件
    #import "AppDelegate+BaiDu.h"
    
    @implementation AppDelegate (BaiDu)
    - (void)initBaiduMapApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    
        //创建并初始化一个引擎对象
        BMKMapManager *manager = [[BMKMapManager alloc] init];
        //启动地图引擎
        BOOL success =  [manager start:@"LV7PXGmnzecWjEZZ9leZADGUoYXeaVzd" generalDelegate:nil];
        
        if (!success) {
            NSLog(@"失败");
        }
        // Override point for customization after application launch.
        
    
    }
    
    
    
    然后在APPdelegate里边调用这个方法就行了

    <br />

    3.在相应的 controller 里边导入需要的头文件、设置百度地图的代理

    #import "TJLocationMapViewController.h"
    /***
     <自己定义的大头针>
     ****/
    #import "mapMark.h"
    /***
     <最下边的点击调起本机地图视图>
     ****/
    #import "TJGuideView.h"
    /***
     <系统地图头文件>
     ****/
    #import <MapKit/MapKit.h>
    
    
    
    #import <BaiduMapAPI_Map/BMKMapView.h>
    #import <BaiduMapAPI_Map/BMKMapComponent.h>
    #import <BaiduMapAPI_Location/BMKLocationComponent.h>
    #import <BaiduMapAPI_Search/BMKSearchComponent.h>
    
    @interface TJLocationMapViewController ()<BMKMapViewDelegate,BMKLocationServiceDelegate,BMKPoiSearchDelegate,UIActionSheetDelegate>
    @property (nonatomic,strong) BMKMapView *mapView;//地图视图
    @property (nonatomic,strong) BMKLocationService *locationService;//定位服务
    @property (nonatomic,strong)BMKPoiSearch *poiSearch;
    @property (nonatomic , strong)NSMutableArray *dataArr;
    
    
    /***
     <存储地图定位自己和目标位置坐标>
     ***/
    @property (nonatomic)CLLocationCoordinate2D beginingCoordinate;
    
    @property (nonatomic)CLLocationCoordinate2D destinationCoordinate;
    
    /***
     <存储定位地图的位置名称>
     ***/
    @property (nonatomic , strong)NSString *myNameStr;
    @property (nonatomic , strong)NSString *toNameStr;
    
    
    
    
    /***
     <返回到上个控制器的button和点击回到自己位置的button>
     ***/
    @property (nonatomic , strong)UIButton *backBtn;
    @property (nonatomic , strong)UIButton *backToMyselfLocatinBtn;
    
    
    @property (nonatomic , strong)TJGuideView *guideView;
    
    
    @end
    

    <br />

    注:前三步看百度文档应该没问题,好了预备工作做完了下面开始写基本功能了

    4.创建_mapView、_locationService、_poiSearch并且在-(void)viewWillAppear:(BOOL)animated、-(void)viewWillDisappear:(BOOL)animated里边设置和取消他们的代理,设置地图的一些基本信息

    <br />

    创建 mapView
           self.mapView = [[BMKMapView alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, SCREEN_HEIGHT - 105*ADAPTERWIDTH)];
        
        /****
         地图样式
         ***/
        self.mapView.mapType = BMKMapTypeStandard;
         self.mapView.userTrackingMode = BMKUserTrackingModeNone;
        self.mapView.scrollEnabled = YES;
        self.mapView.showsUserLocation = YES;
        //在手机上当前可使用的级别为3-21级
        self.mapView.zoomLevel = 18;
        /***
         <定位服务>
         ****/
        _locationService = [[BMKLocationService alloc] init];
        _locationService.distanceFilter = 10.f;
        _locationService.desiredAccuracy = kCLLocationAccuracyBest;
        [_locationService startUserLocationService];//开始定位
        [self.view addSubview:self.mapView];
    
    
    设置取消代理
    -(void)viewWillAppear:(BOOL)animated
    {
        [_mapView viewWillAppear];
        
        self.navigationController.navigationBar.hidden = YES;
    
        _mapView.delegate = self; // 此处记得不用的时候需要置nil,否则影响内存的释放
        _poiSearch.delegate = self;
        _locationService.delegate = self;
    
        
    }
    -(void)viewWillDisappear:(BOOL)animated
    {
        [_mapView viewWillDisappear];
        [self.navigationController setNavigationBarHidden:NO animated:YES];
        _mapView.delegate = nil; // 不用时,置nil
         _poiSearch.delegate = nil;
        _locationService.delegate = nil;
    }
    

    <br />

    5.一些代理方法的实现

    #pragma mark - BMK Location delegate
    /***
     <定位>
     ***/
    -(void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation{
        CLLocation *location = userLocation.location;
        
        mapMark *nowAnno = [[mapMark alloc] init];
        nowAnno.coordinate = location.coordinate;
        nowAnno.title = @"我的位置";
        nowAnno.type = 0;
        [self.mapView addAnnotation:nowAnno];
        BMKCoordinateSpan span;
        span.latitudeDelta = 0.5;
        span.longitudeDelta = 0.5;
        BMKCoordinateRegion region;
        region.center = location.coordinate;
        region.span = span;
        [self.mapView setRegion:region animated:YES];
        //停止定位
        [_locationService stopUserLocationService];
        //检索
        [self addBMKCloudSearchWith:userLocation];
    }
    - (void)addBMKCloudSearchWith:(BMKUserLocation *)userLocation{
        // 初始化云检索服务
        _poiSearch = [[BMKPoiSearch alloc] init];
        _poiSearch.delegate = self;
        // 设置地图级别
        [self.mapView setZoomLevel:17];
        self.mapView.isSelectedAnnotationViewFront = YES; //设定是否总让选中的annotaion置于最前面
        BMKNearbySearchOption * option = [[BMKNearbySearchOption alloc]init];
    
    /***
     <这个值本来是传过来的不是固定的,我这里写的固定是方便大家看>
     ***/
        option.keyword = @"成都市金牛区万达广场";
        option.location = userLocation.location.coordinate;
        
        self.beginingCoordinate = option.location;
         NSLog(@"option.loction == %f  %f", self.beginingCoordinate.latitude, self.beginingCoordinate.longitude);
        option.radius = 10000;
    
    /***
     <因为我需要一个定位所以我就拿一个位置的信息>
     ***/
        option.pageCapacity = 1;
    
        BOOL flag = [_poiSearch poiSearchNearBy:option];
        if (flag) {
            NSLog(@"检索发送成功");
        }else{
            NSLog(@"检索发送失败");
            
        }
    }
    
    
    #pragma mark implement BMKSearchDelegate
    /***
     <检索数据回调,数据都在BMKPoiResult里边,拿出来想怎么用都行>
     ***/
    - (void)onGetPoiResult:(BMKPoiSearch *)searcher result:(BMKPoiResult*)result errorCode:(BMKSearchErrorCode)error{
        
        if (error == BMK_SEARCH_NO_ERROR) {
            NSMutableArray *annotations = [NSMutableArray array];
            result.currPoiNum = 1;
            for (int i = 0; i < result.poiInfoList.count; i++) {
                BMKPoiInfo* poi = [result.poiInfoList objectAtIndex:i];
                
                mapMark* item = [[mapMark alloc]init];
                item.coordinate = poi.pt;
                self.destinationCoordinate = item.coordinate;
                NSLog(@"%f  %f", self.destinationCoordinate.longitude ,  self.destinationCoordinate.latitude);
    
                item.title = poi.name;
                NSLog(@"self.title%@",item.title);
                item.type = 1;
                [self.dataArr addObject:poi];
                [annotations addObject:item];
            }
            [self.mapView addAnnotations:annotations];//添加大头针
            [self.mapView showAnnotations:annotations animated:YES];//显示
        } else if (error == BMK_SEARCH_PERMISSION_UNFINISHED){
            NSLog(@"用户没有授权");
        }else{
            NSLog(@"检索失败:%d",error);
        }
    }
    

    <br />

    6.添加大头针

    /***
     <大头针>
     ***/
    - (BMKAnnotationView *)mapView:(BMKMapView *)view viewForAnnotation:(id <BMKAnnotation>)annotation{
        if ([annotation isKindOfClass:[mapMark class]]) {
            mapMark *anno = (mapMark *)annotation;
            // 生成重用标示identifier
            NSString *AnnotationViewID = @"xidanMark";
            // 检查是否有重用的缓存
            BMKAnnotationView* annotationView = [view dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
            
            // 缓存没有命中,自己构造一个,一般首次添加annotation代码会运行到此处
            if (annotationView == nil) {
                annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
                if (anno.type == 0) {
                    ((BMKPinAnnotationView*)annotationView).pinColor = BMKPinAnnotationColorPurple;
                }else if (anno.type == 1){
                    ((BMKPinAnnotationView*)annotationView).pinColor = BMKPinAnnotationColorRed;
                }
                // 设置重天上掉下的效果(annotation)
                ((BMKPinAnnotationView*)annotationView).animatesDrop = YES;
            }
            // 设置位置
            annotationView.centerOffset = CGPointMake(0, -(annotationView.frame.size.height * 0.5));
            annotationView.annotation = annotation;
            annotationView.canShowCallout = YES;
            [self.mapView selectAnnotation:anno animated:YES];
            
            // 设置是否可以拖拽
            annotationView.draggable = NO;
            
            return annotationView;
            
        }
        
        return nil;
    }
    

    好了基本的定位功能就实现了

    <br />

    下边就是实现点击回到自己位置功能和调起本机地图功能

    1.点击回到自己位置

    其实这个功能很简单,只要拿到自己的位置数据,只需要把自己的位置再次设置到地图中心点就行了.
    /***
     <点击回到自己的位置>
     ***/
    -(void)backToMyselfLocatin:(UIButton *)sender{
        BMKCoordinateRegion region ;//表示范围的结构体
        //设置自己为中心点
        region.center = self.beginingCoordinate;//中心点
        region.span.latitudeDelta = 0.01;//经度范围(设置为0.1表示显示范围为0.2的纬度范围)
        region.span.longitudeDelta = 0.01;//纬度范围
        [_mapView setRegion:region animated:YES];
    }
    

    2.调起本机地图

    我只写主要代码就好了,苹果地图使用option就行了不用 URL 调起,而百度地图需要配置URL才能调起不过性质大概都一样

    <br />

    调起百度地图

    //主要是配置自己和目的地的一些左边参数,另外百度地图如果那个mode参数里边你不加经纬度格式参数的话它默认就是百度地图用的参数,加的话记得要和百度地图的一致
    NSString *url = [[NSString stringWithFormat:@"baidumap://map/direction?origin=latlng:%f,%f|name:我的位置&destination=latlng:%f,%f|name:%@&mode=driving&region=成都",self.beginingCoordinate.longitude, self.beginingCoordinate.latitude,self.destinationCoordinate.longitude,self.destinationCoordinate.latitude,@"成都市万达广场"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] ;
                if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"baidumap://map/"]])
                {
                    if ([[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]] == NO)
                    {
                       [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms://itunes.apple.com/cn/app/百度地图-智能的手机导航-公交地铁出行必备/id452186370?mt=8"]];
                    }
                }else{
                    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms://itunes.apple.com/cn/app/百度地图-智能的手机导航-公交地铁出行必备/id452186370?mt=8"]];
                }
    
    

    <br />

    调起苹果地图

    MKMapItem *currentLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc]                         initWithCoordinate:CLLocationCoordinate2DMake((self.beginingCoordinate.latitude),(self.beginingCoordinate.longitude)) addressDictionary:nil]];
                currentLocation.name =@"我的位置";
                
                
                //目的地的位置
                
                MKMapItem *toLocation = [[MKMapItem alloc] initWithPlacemark:[[MKPlacemark alloc] initWithCoordinate:self.destinationCoordinate addressDictionary:nil]];
                
                toLocation.name = @"成都万达广场";
                
                NSArray *items = [NSArray arrayWithObjects:currentLocation, toLocation, nil];
                
                NSDictionary *options = @{ MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving, MKLaunchOptionsMapTypeKey: [NSNumber numberWithInteger:MKMapTypeStandard], MKLaunchOptionsShowsTrafficKey:@YES };
                
                //打开苹果自身地图应用,并呈现特定的item
                
                [MKMapItem openMapsWithItems:items launchOptions:options];
    

    <br />

    楼主一周休息一天,能在周末早上爬起来写这个也是挺心疼自己的,楼主不单身,但是楼主爱工作,注释什么的都是新加上去的,还有定义的 frame 因为自己封装的约束所以重新改了才贴的代码,喜欢的能给个赞就好了。
    关于百度地图模糊搜索的我下午写出来,我写的有什么不清楚的可以在评论里说,我每天都会看的

    相关文章

      网友评论

      • _de_bug_life:poi实现模糊搜索,当搜索的内容时门址信息时(如在南京市搜索 :恒竞路30号)获取的结果address为空字符串,大神是怎么解决的?
      • 像羽毛那样轻:就不能给个DEMo
        1b468a290949:15008226414
        1b468a290949:可以加一个微信吗,我也是成都的,哈哈,写的很好,学习中
        Bales_chu:这是公司项目中的,没单独写的 demo,不过有什么问题你可以问呀
      • SJon:很好很好,先Mark了

      本文标题:iOS 百度地图实现模糊搜索和定位、跳转本机地图 上

      本文链接:https://www.haomeiwen.com/subject/hipjhxtx.html