IOS 高德地图开发相关问题汇总
前言
本篇是本人在使用高德地图相关功能在开发中遇到的一些问题汇总,也包括简单的使用,具体的集成可以看官方的文档说明
相关问题
一、地图2D/3D SDK切换报错问题
之前项目中使用的是2D 地图,切换到 3D 后,一直报错,如下
![](https://img.haomeiwen.com/i4790087/e856aebef6d4a8f8.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 就报错,
![](https://img.haomeiwen.com/i4790087/b8e96ba5e96236c3.png)
![](https://img.haomeiwen.com/i4790087/a30f1a130f7e1642.png)
上面这是今天使用 cocoapods 自动部署报的错误,搞了半天也没能解决,目前察觉到原因是因为项目中之前集成了 AMapFoundationKit.framework
但是版本是:
1.4.0+foundation-no-idfa.e669e61
而目导入的 AMapLocationKit.framework
版本是 2.6.1 ,所依赖的 AMapFoundationKit.framework
版本的文件结构已经不一样了,如下:
- 之前的老版本
![](https://img.haomeiwen.com/i4790087/1e4cca36754dda76.png)
- 现在的版本
![](https://img.haomeiwen.com/i4790087/4f1cd881c2d5211d.png)
目录结构不一样,所以编译一直会报错,如:
Include of non-modular header inside framework module 'AMapLocationKit.AMapLocationVersion'
![](https://img.haomeiwen.com/i4790087/18781c0d6afa8a21.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 = @"住宅|楼宇|商场";
可以设置各种过滤条件, 筛选,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;
但是也是没有效果的,因为:
![](https://img.haomeiwen.com/i4790087/743c7615c633f5f6.png)
所以需要手动设置一下就可以了:
// 手动获取市区
poi.city = reGeocode.addressComponent.city;
poi.district = reGeocode.addressComponent.district;
搜索周边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];
}
但是回一个问题,就是可能在起点或终点绕圈,因为把起始点也加到规划的途经点中了,所以会导致这种情况,如图:
![](https://img.haomeiwen.com/i4790087/d16d621b0df21983.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];
}
}
这样就可以了。