美文网首页iOS开发iOS实战我的ios进阶
iOS高德地图使用-搜索,路径规划

iOS高德地图使用-搜索,路径规划

作者: 简单也好 | 来源:发表于2016-05-06 11:43 被阅读14027次

    最近赶项目,好久没更新。抽出时间把高德地图的搜索和路径规划整理一下
    项目中想加入地图功能,使用高德地图第三方,想要实现确定一个位置,搜索路线并且显示的方法。耗了一番功夫,总算实现了。

    效果

    WeChat_1462507820.jpeg

    一、配置工作

    1.申请key

    访问 http://lbs.amap.com/dev/key/ 在高度地图第三方开发平台申请一个key,注册账户,新建应用,这个没什么门槛。
    得到这个key

    屏幕快照 2016-05-06 上午10.34.15.png
    提示一下,这个key对应的bundle ID 要和工程里面的bundle ID 相同,不然每次打开地图都会报一个Invalid_user_scode的提示。
    2.导入第三方

    方便起见 pod导入

    pod 'AMap3DMap' #3D地图SDK
    #pod 'AMap2DMap' #2D地图SDK(2D地图和3D地图不能同时使用,2选1)
    pod 'AMapSearch' #搜索服务SDK
    
    3.打开工程的后台定位功能 更改info.plist

    增加两条,一条请求位置时提示,一条https


    屏幕快照 2016-05-06 上午11.02.06.png 屏幕快照 2016-05-06 上午10.48.19.png

    二、地图基本显示

    把地图添加到view即可显示

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        //配置用户Key
        [MAMapServices sharedServices].apiKey = @"76bb9bc3718375ad03acba7c333694c4";
        
        //把地图放在底层
        [self.view insertSubview:self.mapView atIndex:0];
        
    }
    //地图懒加载
    - (MAMapView *)mapView
    {
        if (!_mapView) {
            _mapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds))];
            _mapView.delegate = self;
            _mapView.showsUserLocation = YES;    //YES 为打开定位,NO为关闭定位
            
            [_mapView setUserTrackingMode: MAUserTrackingModeFollow animated:NO]; //地图跟着位置移动
            
            //自定义定位经度圈样式
            _mapView.customizeUserLocationAccuracyCircleRepresentation = NO;
            //地图跟踪模式
            _mapView.userTrackingMode = MAUserTrackingModeFollow;
            
            //后台定位
            _mapView.pausesLocationUpdatesAutomatically = NO;
            
            _mapView.allowsBackgroundLocationUpdates = YES;//iOS9以上系统必须配置
        
        }
        return _mapView;
    }
    

    三、地图搜索功能

    遵守协议 AMapSearchDelegate

    高德提供了多种搜索方式,POI搜索(关键字查询、周边搜索、多边形查询),检索现实中真实存在的地物。

    提示搜索,就是在还没有输入完全时,根据已有字符进行的搜索

    //搜索框激活时,使用提示搜索
    -(void)updateSearchResultsForSearchController:(UISearchController *)searchController
    {
        //发起输入提示搜索
        AMapInputTipsSearchRequest *tipsRequest = [[AMapInputTipsSearchRequest alloc] init];
       //关键字
        tipsRequest.keywords = _searchController.searchBar.text;
       //城市
        tipsRequest.city = _currentCity;
    
        //执行搜索
        [_search AMapInputTipsSearch: tipsRequest];
    
    }
    
    //实现输入提示的回调函数
    -(void)onInputTipsSearchDone:(AMapInputTipsSearchRequest*)request response:(AMapInputTipsSearchResponse *)response
    {
        if(response.tips.count == 0)
        {
            return;
        }
        //通过AMapInputTipsSearchResponse对象处理搜索结果
        //先清空数组
        [self.searchList removeAllObjects];
        for (AMapTip *p in response.tips) {    
            //把搜索结果存在数组
            [self.searchList addObject:p];
        }
        _isSelected = NO;
        //刷新表视图
        [self.tableView reloadData];
    }
    

    点击进行poi搜索

    
    //周边搜索
    - (IBAction)searchAction:(id)sender {
        //初始化检索对象
        _search = [[AMapSearchAPI alloc] init];
        _search.delegate = self;
        
        //构造AMapPOIAroundSearchRequest对象,设置周边请求参数
        AMapPOIAroundSearchRequest *request = [[AMapPOIAroundSearchRequest alloc] init];
      
        //当前位置
        request.location = [AMapGeoPoint locationWithLatitude:_currentLocation.coordinate.latitude longitude:_currentLocation.coordinate.longitude];
        
        //关键字
        request.keywords = _searchController.searchBar.text;
        NSLog(@"%@",_searchController.searchBar.text);
        // types属性表示限定搜索POI的类别,默认为:餐饮服务|商务住宅|生活服务
        // POI的类型共分为20种大类别,分别为:
        // 汽车服务|汽车销售|汽车维修|摩托车服务|餐饮服务|购物服务|生活服务|体育休闲服务|
        // 医疗保健服务|住宿服务|风景名胜|商务住宅|政府机构及社会团体|科教文化服务|
        // 交通设施服务|金融保险服务|公司企业|道路附属设施|地名地址信息|公共设施
        //    request.types = @"餐饮服务|生活服务";
        request.radius =  5000;//<! 查询半径,范围:0-50000,单位:米 [default = 3000]
        request.sortrule = 0;
        request.requireExtension = YES;
        
        //发起周边搜索
        [_search AMapPOIAroundSearch:request];
    }
    
    //实现POI搜索对应的回调函数
    - (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response
    {
        if(response.pois.count == 0)
        {
            return;
        }
        
        //通过 AMapPOISearchResponse 对象处理搜索结果
      
        [self.dataList removeAllObjects];
        for (AMapPOI *p in response.pois) {
            NSLog(@"%@",[NSString stringWithFormat:@"%@\nPOI: %@,%@", p.description,p.name,p.address]);
            
            //搜索结果存在数组
            [self.dataList addObject:p];
        }
        
        _isSelected = YES;
        [self.tableView reloadData];
      
    }
    

    四、路径规划

    规划路径查询(驾车路线搜索、公交换成方案查询、步行路径检索),提前知道出行路线

    //规划线路查询
    - (IBAction)findWayAction:(id)sender {
        //构造AMapDrivingRouteSearchRequest对象,设置驾车路径规划请求参数
        AMapWalkingRouteSearchRequest *request = [[AMapWalkingRouteSearchRequest alloc] init];
        //设置起点,我选择了当前位置,mapView有这个属性
        request.origin = [AMapGeoPoint locationWithLatitude:_currentLocation.coordinate.latitude longitude:_currentLocation.coordinate.longitude];
        //设置终点,可以选择手点
        request.destination = [AMapGeoPoint locationWithLatitude:_destinationPoint.coordinate.latitude longitude:_destinationPoint.coordinate.longitude];
            
    //    request.strategy = 2;//距离优先
    //    request.requireExtension = YES;
        
        //发起路径搜索,发起后会执行代理方法
        //这里使用的是步行路径
        [_search AMapWalkingRouteSearch: request]; 
    }
    
    //长按手势响应方法,选择路径规划的终点,手势自己加
    - (void)handleLongPress:(UILongPressGestureRecognizer *)gesture
    {
        if (gesture.state == UIGestureRecognizerStateBegan)
        {
           //在地图上长按的位置
            CGPoint p = [gesture locationInView:_mapView];
            NSLog(@"press on (%f, %f)", p.x, p.y);
        }
         //转换成经纬度
        CLLocationCoordinate2D coordinate = [_mapView convertPoint:[gesture locationInView:_mapView] toCoordinateFromView:_mapView];
         
       //赋值给目标点
        _destinationPoint = [[MAPointAnnotation alloc] init];
        _destinationPoint.coordinate = coordinate;
    }
    

    执行路径搜索后会执行代理方法

    
    //实现路径搜索的回调函数
    - (void)onRouteSearchDone:(AMapRouteSearchBaseRequest *)request response:(AMapRouteSearchResponse *)response
    {
        if(response.route == nil)
        {
            return;
        }
        
        //通过AMapNavigationSearchResponse对象处理搜索结果
        NSString *route = [NSString stringWithFormat:@"Navi: %@", response.route];
        
        AMapPath *path = response.route.paths[0]; //选择一条路径
        AMapStep *step = path.steps[0]; //这个路径上的导航路段数组
        NSLog(@"%@",step.polyline);   //此路段坐标点字符串
          
        if (response.count > 0)
        {
            //移除地图原本的遮盖
            [_mapView removeOverlays:_pathPolylines];
            _pathPolylines = nil;
            
            // 只显⽰示第⼀条 规划的路径
            _pathPolylines = [self polylinesForPath:response.route.paths[0]];
            NSLog(@"%@",response.route.paths[0]);
            //添加新的遮盖,然后会触发代理方法进行绘制
            [_mapView addOverlays:_pathPolylines];
        }
    }
    

    每次添加路线,区域,或者大头针等都会触发下面的代理方法

    //绘制遮盖时执行的代理方法
    - (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id <MAOverlay>)overlay
    {
        /* 自定义定位精度对应的MACircleView. */
        
        //画路线
        if ([overlay isKindOfClass:[MAPolyline class]])
        {
           //初始化一个路线类型的view
            MAPolylineRenderer *polygonView = [[MAPolylineRenderer alloc] initWithPolyline:overlay];
            //设置线宽颜色等
            polygonView.lineWidth = 8.f;
            polygonView.strokeColor = [UIColor colorWithRed:0.015 green:0.658 blue:0.986 alpha:1.000];
            polygonView.fillColor = [UIColor colorWithRed:0.940 green:0.771 blue:0.143 alpha:0.800];
            polygonView.lineJoinType = kMALineJoinRound;//连接类型
            //返回view,就进行了添加
            return polygonView;
        }
        return nil;
        
    }
    

    最后,这是demo,最好真机测试,模拟器的定位不好用
    https://github.com/DaLiWangCC/MyOpen

    相关文章

      网友评论

      • 陌上北辰:如何把规划的步行路径全显示出来?
        hament:我实现过类似的,就是计算适当的缩放系数,并居中显示
      • alelaile:兄弟 我自己写 规划三条线 有什么办法确定点击事件吗
      • 4a5a6523f8d2:牛逼牛逼 ,已实现,谢谢楼主
        简单也好:@肉侦喵 终于有人自己实现了,牛逼的是你sdk更新了,而我也懒得看了,很多被人问的我也懒得答了
      • __阳阳:AMapInputTipsSearchRequest 我用这个获取搜索提示请求, 获取到的结果如果是市的话, 怎么没有对应的经纬度呢, 经纬度都是 0, 我需要这个经纬度, 怎么办?
      • ae17d0264ad4:两点规划?
      • 云之彼岸君:楼主,画路线的时候有没有办法把路线的断层全部去掉?
      • 码农进城:楼主 得到了路径怎么根据路径导航啊
      • 断剑:你好,问一下,如果再同一个地图上面添加多中路径规划,比如同时显示公交、不行路径规划;或者同一个地图上面显示3条不同的公交路径规划,这个怎么处理啊?
      • 5e3776730351:西安的啊,怪不得第一眼看地图的时候莫名的熟悉
      • 6a4365eaad5f:试了一下 绘制不到地图上
      • 时间戳:请问一下,路径规划除了用经纬度作为起始点,能不能用地理位置作为起始点(比如:杭州-上海),我看了百度地图的有,但是高德我没有找到.
        __weak:我现在也在做路径规划,就是点击中心点坐标到指定大头针的路线,可是按照作者的demo怎么都显示不出来,不知道哪里有问题。。
        时间戳:@简单也好 那就只有编码了
        简单也好:@时间戳 用其他接口查出坐标,然后根据坐标查路线
      • 峰子1994:你好使用这个路线规划出现了内存泄漏你发现了吗memory在一直上升
        峰子1994:@简单也好 真的我现在就是遇到这个问题了该如何解决呀
        简单也好:@峰子1994 哦 谢谢啊 没注意过
      • 其实也是:么么哒
      • 帅的流油:这个如果在室内就不行了
      • 学习之路:楼主 这个是路径规划 公交的实时导航能做吗 ?
      • afa38ae8399f:您好,楼主,问下高德地图3d的用这个规划可以吗?高德地图api更新了,用这个方法还可以吗
        简单也好:@旺仔QQ糖 3d可以,更新了要具体看了,会有说明的
      • lucky_幸运:路线规划的包和定位的包冲突吧
        简单也好: @lucky_幸运 好像没有
      • 厚脸皮小强打不死的小强:我要把导航路线绘制成3d的怎么去实现
      • 厚脸皮小强打不死的小强:请问一下,导航路行能绘制成3d的吗
      • 敲代码的香蕉片:为什么有的坐标能画出路线,有的不能....在高德的demo上是都可以的....
      • 不要动:有没有高德地图的运动轨迹啊
      • 知了此生:解决了我的问题,多谢作者 :clap:
      • 缘來諟夢:下载了Demo 在真机上运行后 点击路线没反应 :pray: 怎么办
        缘來諟夢:解决了 少替换了一个key :blush: 谢谢楼主
      • 简单也好:https://github.com/DaLiWangCC/MyOpen
        后来也没有维护,不知道你要什么功能
      • 你好牛:我是下载错了吗 为什么效果不一样 好多功能没用
      • 啦啦德玛西亚:楼主问一下 ,有接下来的指引到点的demo么,如果可以,发个demo可以么?498400985@qq.com,谢谢楼主!
        啦啦德玛西亚:@简单也好 好吧,那也谢了
        简单也好:@啦啦德玛西亚 什么叫指引到点,导航么,没有
      • 56ec46ffa430:谢谢楼主,刚好需要这个! :clap:
      • c293580a2161:蟹蟹蟹蟹
      • cfab6b1a4452:实在是找不到[self polylinesForPath:response.route.paths[0]] 这个方法,麻烦楼主补充一下 :sweat:
        cfab6b1a4452:@简单也好 看到了 谢谢up :blush:
        简单也好:@JMcn 这个是自写方法,在demo里面有,代码太长就没贴
      • EdLiya:学习啦 ! 一颗赛艇 !
      • BadMao:把地图放大的时候为何路径规划不是直接从我们的起点开始的???而是距离我们起点几十米的地方开始?
        BadMao:嗯!好多!感谢楼主的分享!
        简单也好:@BadMao 好像是因为要从有路的地方开始 ,你可以试试,驾车路径和公交路径,看看区别
      • ff54948505f9:解决了,谢谢
      • ff54948505f9:为什么提示“INVALID_USER_SCODE”
        简单也好: @身是浮尘 高德上面的bundle ID和工程的不一样,如果是短时间内申请的高德,可能过几小时就好
      • 来宝:大神,我的搜索出现[AMapFoundationKit][Info] : Key验证失败 - INVALID_USER_KEY[] - [AMapSearchKi,我已经申请了key的,怎么还是出现这个呢?
        敲代码的香蕉片:@来宝 你把写key值的那句话在你页面的viewdidload在写一遍应该就能解决了
        来宝:@来宝 一直显示验证失败,但是不影响功能
        简单也好: @来宝 这个没遇到过,确认key对应了没有,解决了告诉我一下
      • ztlucky:[self polylinesForPath:response.route.paths[0]] 这方法在哪里啊
        简单也好: @ztlucky 搜索一下
      • 小王子sl:楼主 规划路径后怎么拿到这条路径对应的路况啊
        简单也好:@小王子sl 原来如此,辛苦辛苦
        小王子sl:@简单也好 我找到了 原来是在实时导航那里 妈蛋 找死我了
        简单也好:@小王子sl
        找了半天没找到,可能他没开放这个接口?
      • dd916d1c1a4b:不错,谢谢楼主
        简单也好:@为神马 谢啦
      • 红成:不语
        简单也好:@红成笑 ..什么鬼

      本文标题:iOS高德地图使用-搜索,路径规划

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