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

前言

项目中要集成百度地图,百度的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 因为自己封装的约束所以重新改了才贴的代码,喜欢的能给个赞就好了。
关于百度地图模糊搜索的我下午写出来,我写的有什么不清楚的可以在评论里说,我每天都会看的
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容