iOS开发

IOS 高德地图开发相关问题汇总

2018-11-01  本文已影响0人  Superman168

前言

本篇是本人在使用高德地图相关功能在开发中遇到的一些问题汇总,也包括简单的使用,具体的集成可以看官方的文档说明

高德地图iOS SDK简介

相关问题

一、地图2D/3D SDK切换报错问题

之前项目中使用的是2D 地图,切换到 3D 后,一直报错,如下

image.png

高德开放平台相关问题
https://lbs.amap.com/faq/ios/ios-map
地图2D/3D SDK切换方法
https://lbs.amap.com/faq/ios/ios-map/315

没有这里说的这么简单,如果顺利的话,可能是这样吧!

百度贴吧中关于--高德地图更换SDK包从2D地图更换3D地图报错
http://tieba.baidu.com/p/5075787546

查了不少,始终没有解决方法,不知为何!!!和下面定位SDK API 编译报错的原因应该是一个问题,现在没换。

二、定位SDK API 编译报错

初始化定位对象 AMapLocationManager 就报错,

image.png 定位API 报错

上面这是今天使用 cocoapods 自动部署报的错误,搞了半天也没能解决,目前察觉到原因是因为项目中之前集成了 AMapFoundationKit.framework 但是版本是:
1.4.0+foundation-no-idfa.e669e61

而目导入的 AMapLocationKit.framework 版本是 2.6.1 ,所依赖的 AMapFoundationKit.framework 版本的文件结构已经不一样了,如下:

image.png image.png

目录结构不一样,所以编译一直会报错,如:

Include of non-modular header inside framework module 'AMapLocationKit.AMapLocationVersion'

image.png

Could not build module 'AMapLocationKit'

切换为与 AMapLocationKit.framework 匹配的AMapFoundationKit.framework 即可,编译 OK!!!

三、高德地图POI周边搜索返回的AMapPOI不全

附近位置搜索AMapPOI不全

//搜索周边POI
- (void)searchAllPOIAround:(CLLocationCoordinate2D)coordinate
{
    AMapPOIAroundSearchRequest *request = [[AMapPOIAroundSearchRequest alloc] init];
    request.sortrule = 0;
    request.offset = 30;
    request.location = [AMapGeoPoint locationWithLatitude:coordinate.latitude longitude:coordinate.longitude];
    request.radius = 500;
    [self.search AMapPOIAroundSearch:request];
}

搜索附近位置回调

/// 搜索附近位置回调
- (void)onPOISearchDone:(AMapPOISearchBaseRequest *)request response:(AMapPOISearchResponse *)response
{
    if (response.pois.count>10) {
        /// 只取 10 个
        NSMutableArray *poisArr = [NSMutableArray array];
        for (int i =0; i < 10; i++) {
            AMapPOI *poi = [response.pois objectAtIndex:i];
            [poisArr addObject:poi];
        }
        self.POIDataArray = poisArr;
        // 默认选中第一条
        selectPOI = poisArr.firstObject;
        self.poiResultVC.resultListArray = poisArr;
    }else{
        self.POIDataArray = response.pois;
        // 默认选中第一条
        selectPOI = response.pois.firstObject;
        self.poiResultVC.resultListArray = response.pois;
    }
}

开始因为没有细看,调用高德的 POI周边搜索,返回的 AMapPOI 信息一直返回的不全,像 City,district 都为空,一直不知道为啥的,后来细细的查看一番,找到了原因:
加上这个即可,

    // 是否返回扩展信息,默认为 NO。不设置的话,city district 等会返空
    request.requireExtension    = YES;
设置关键词
//    request.keywords = @"";
    ///类型
//    request.types = @"商务住宅|公司企业|地名地址信息|公共设施";
//   request.types = @"地名地址信息|交通设施服务|地铁站|商务住宅|楼宇|商务写字楼|生活服务|餐饮服务|中餐厅|特色/地方风味餐厅|购物服务|便民商店/便利店";
    request.radius   = 1000;
    request.types = @"住宅|楼宇|商场";

高德的获取POI数据API

可以设置各种过滤条件, 筛选,API 文档有详细的说明,但是怎么筛选始终没能满足需求,后就改为下面逆地理编码的方式。

四、逆地理编码(坐标转地址)搜索返回的AMapPOI不全

#pragma mark -- 设置逆地理编码查询参数
// 根据中心点坐标来请求逆地理编码
- (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];
}

在回调中处理数据

#pragma mark --- AMapSearchDelegate 搜索结果的代理
#pragma mark -- 拖动地图停止后的方法
// 逆地理编码查询回调函数
-(void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response
{
    if (response.regeocode != nil){
        AMapReGeocode *reGeocode = response.regeocode;
        // 返回标准化的地址
//        self.currentAddress = reGeocode.formattedAddress;
        NSLog(@"%@ %f %f",response.regeocode.formattedAddress,request.location.latitude,request.location.longitude);
//        self.textLabel.text = [NSString stringWithFormat:@"%@\n%f\n%f",response.regeocode.formattedAddress,request.location.latitude,request.location.longitude];
        //解析response获取地址描述
//        if (reGeocode.pois.count>10) {
            /// 最多只取 10 个
            NSMutableArray *poisArr = [NSMutableArray array];
            NSUInteger count = reGeocode.pois.count>10?10:reGeocode.pois.count;
            for (int i =0; i < count; i++) {
                AMapPOI *poi = [reGeocode.pois objectAtIndex:i];
                // 手动获取市区
                poi.city = reGeocode.addressComponent.city;
                poi.district = reGeocode.addressComponent.district;
                [poisArr addObject:poi];
            }
            self.POIDataArray = poisArr;
            // 默认选中第一条
            selectPOI = poisArr.firstObject;
            self.poiResultVC.resultListArray = poisArr;
//        }else{
//            self.POIDataArray = reGeocode.pois;
//            // 默认选中第一条
//            selectPOI = reGeocode.pois.firstObject;
//            self.poiResultVC.resultListArray = reGeocode.pois;
//        }
    }
}

开始不注意的话,你会发现返回的 reGeocode.pois 中的 AMapPOI 仍然没有市区等字段,虽然在开始的时候设置了:

regeo.requireExtension            = YES;

但是也是没有效果的,因为:

image.png

所以需要手动设置一下就可以了:

// 手动获取市区
poi.city = reGeocode.addressComponent.city;
poi.district = reGeocode.addressComponent.district;

逆地理查询的 API

搜索周边POI 和 逆地理编码查询很相似,雷同。

五、车辆路径规划展示线路有误(绕圈等情况)

起初,车辆路径规划是这样的:

#pragma mark - 车辆路径规划 do search 路径
- (void)searchRoutePlanningDrive
{
    self.startAnnotation.coordinate = self.startCoordinate;
    self.destinationAnnotation.coordinate = self.destinationCoordinate;
    
    AMapDrivingRouteSearchRequest *navi = [[AMapDrivingRouteSearchRequest alloc] init];
    navi.requireExtension = YES;
    
    NSLog(@"%@",carType);
    //路线策略
    navi.strategy = carType.integerValue;
    
    /* 出发点. */
    navi.origin = [AMapGeoPoint locationWithLatitude:self.startCoordinate.latitude
                                           longitude:self.startCoordinate.longitude];
    /* 目的地. */
    navi.destination = [AMapGeoPoint locationWithLatitude:self.destinationCoordinate.latitude
                                                longitude:self.destinationCoordinate.longitude];
    if (self.allStationsModelArr.count>2) {
        //建立途经点数组
        NSMutableArray * arr = [[NSMutableArray alloc]init];
        // 一定记得去掉起始点,否则规划错误
        for (int i=0; i< self.allStationsModelArr.count; i++) {
            NewRoutesModel * model = [self.allStationsModelArr objectAtIndex:i];
            AMapGeoPoint * geoPoint = [[AMapGeoPoint alloc]init];
            geoPoint.latitude = model.lat.floatValue;
            geoPoint.longitude = model.lng.floatValue;
            [arr addObject:geoPoint];
        }
        
        navi.waypoints = arr;
    }
   
    [self.search AMapDrivingRouteSearch:navi];
}

在 路径规划搜索回调. 中展示当前规划方案即可,绘制折线 OK

pragma mark /* 展示当前路线方案. */
- (void)presentCurrentCourse
{
    MANaviAnnotationType type = MANaviAnnotationTypeDrive;
    self.naviRoute = [MANaviRoute naviRouteForPath:self.route.paths[self.currentCourse] withNaviType:type showTraffic:YES startPoint:[AMapGeoPoint locationWithLatitude:self.startAnnotation.coordinate.latitude longitude:self.startAnnotation.coordinate.longitude] endPoint:[AMapGeoPoint locationWithLatitude:self.destinationAnnotation.coordinate.latitude longitude:self.destinationAnnotation.coordinate.longitude]];
    [self.naviRoute addToMapView:self.mapView];
    
    /* 缩放地图使其适应polylines的展示. */
    [_mapView setVisibleMapRect:[CommonUtility mapRectForOverlays:self.naviRoute.routePolylines]
                    edgePadding:UIEdgeInsetsMake(RoutePlanningPaddingEdge, RoutePlanningPaddingEdge, RoutePlanningPaddingEdge, RoutePlanningPaddingEdge)
                       animated:YES];
}

但是回一个问题,就是可能在起点或终点绕圈,因为把起始点也加到规划的途经点中了,所以会导致这种情况,如图:

IMG_4447F0F70A35-1.jpeg

修改方法:

    if (self.allStationsModelArr.count>2) {
        // 大于 2 才有途经点
        //建立途经点数组
        NSMutableArray * arr = [[NSMutableArray alloc]init];
        // 一定记得去掉起始点,否则规划错误
        for (int i=1; i< self.allStationsModelArr.count-1; i++) {
            NewRoutesModel * model = [self.allStationsModelArr objectAtIndex:i];
            AMapGeoPoint * geoPoint = [[AMapGeoPoint alloc]init];
            geoPoint.latitude = model.lat.floatValue;
            geoPoint.longitude = model.lng.floatValue;
            [arr addObject:geoPoint];
        }
        
        navi.waypoints = arr;
    }

高德地图 车辆规划文档

六、高德地图我的位置不停变动

初始化地图的时候就有一个显示用户位置的设置:

//显示用户位置
self.mapView.showsUserLocation = YES;

设置后地图上会有一个自带的蓝色的小圆圈,会随着用户位置的变化而变化,另外一种方式就是 设置定位用户位置的模式:

/**
 * @brief 设置定位用户位置的模式
 * @param mode 要设置的模式
 * @param animated 是否动画设置
 */
- (void)setUserTrackingMode:(MAUserTrackingMode)mode animated:(BOOL)animated;

///用户跟踪模式
typedef NS_ENUM(NSInteger, MAUserTrackingMode)
{
    MAUserTrackingModeNone              = 0,    ///< 不追踪用户的location更新
    MAUserTrackingModeFollow            = 1,    ///< 追踪用户的location更新
    MAUserTrackingModeFollowWithHeading = 2     ///< 追踪用户的location与heading更新
};

这样也可以实现我的位置一样的效果。

但是有一个问题就出来了,当前位置并没有变动,拖动地图后,用户位置会动来动去的,但是我并没有变位置,跟用户跟踪模式有关,但是我不要这样的
设置一系列的 属性,

 设置定位用户位置的模式
    self.mapView.userTrackingMode = MAUserTrackingModeFollow;
    self.mapView.distanceFilter = kCLLocationAccuracyNearestTenMeters;//定位最小更新距离  单位米
///设定定位精度。默认为kCLLocationAccuracyBest
    self.mapView.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
设置这个也不管用

这些都是无济于事的,最后不得不采用了一种简单粗暴的方式,不显示用户位置

不显示用户位置
self.mapView.showsUserLocation = NO

首页定位当前位置,传入到地图页面,设置一个固定坐标,缺点是,位置变动时,不会随着变动。

七、高德地图 设置指定坐标中心点 问题

本来设置中心点是一个及其简单的功能,调一下 高德的设置中心点API,传一个坐标即可:

高德的设置中心点API

/**
 * @brief 设置当前地图的中心点,改变该值时,地图的比例尺级别不会发生变化
 * @param coordinate 要设置的中心点
 * @param animated 是否动画设置
 */
- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;

但是你在初始化地图时

    //地图初始化
    self.mapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, _navBarHeight, ScreenW, MapH)];
    self.mapView.delegate = self;
    self.mapView.zoomLevel = 18;
//    self.mapView.showsIndoorMap = YES;
    //显示用户位置
    self.mapView.showsUserLocation = YES;
    ///是否显示比例尺, 默认YES
    self.mapView.showsScale = NO;
    self.mapView.showsCompass = NO;
    self.mapView.mapType = MAMapTypeStandard;
    //NO表示禁用旋转手势,YES表示开启
    self.mapView.rotateEnabled= NO;
//    self.mapView.showsBuildings = NO;
    // 倾斜手势
    self.mapView.rotateCameraEnabled = NO;
    self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
//    self.mapView.distanceFilter = kCLLocationAccuracyNearestTenMeters;//定位最小更新距离  单位米
    ///设定定位精度。默认为kCLLocationAccuracyBest
    self.mapView.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;

    [self.view addSubview:self.mapView];

设置了

//显示用户位置
self.mapView.showsUserLocation = YES;

之后,再设置中心点的时候,你会发现并没有效果,一个调用先后的问题,简单的解决方法是:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    if (self.latitude > 0 && self.longitude >0) {
        // 如果有传入的经纬度
        [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(self.latitude, self.longitude) animated:YES];
//        [self.mapView setZoomLevel:16 animated:YES];
    }else{
        // 默认的,或者不传时
//        [self startLocation];
    }
}

这样就可以了。

上一篇 下一篇

猜你喜欢

热点阅读