效果图:
地图.gif
在使用cocoapod接入百度地图时候,遇到的一些问题,总结如下。
首先是网络配置以及环境配置:
网络配置
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
定位允许
<key>NSLocationWhenInUseUsageDescription</key>
接入流程 配置appkey,需要注意的是,百度地图添加了安全码,bundle ID 以及 appkey ,项目名字是一一对应的,否则地图是加载不出来的:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
_mapManager = [[BMKMapManager alloc]init];
// 如果要关注网络及授权验证事件,请设定 generalDelegate参数
BOOL ret = [_mapManager start:KBaiduMapKey generalDelegate:nil];
if (!ret) {
NSLog(@"manager start failed!");
}
return YES;
}
几个技术点
1.地图的精度圈的处理
2.是否隐藏我的位置的气泡以及其他气泡。
3.计算离我最近点的距离以及显示。
4.计算离我最近点的距离,然后添加折线(覆盖物)
5.点击其他位置时更新连线(我的位置到点击的大头针的连线, 以及计算距离)
1地图的精度圈的处理:
-(BMKMapView *)mapView{
if (!_mapView) {
_mapView =[[BMKMapView alloc]initWithFrame:CGRectMake(0, 104 , Device_Width , Device_Height - 104)];
_mapView.zoomLevel = 15;
_mapView.minZoomLevel = 5;
_mapView.maxZoomLevel = 17;
BMKLocationViewDisplayParam *displayParam = [[BMKLocationViewDisplayParam alloc]init];
displayParam.isRotateAngleValid = true;//跟随态旋转角度是否生效
displayParam.isAccuracyCircleShow = false;//精度圈是否显示
displayParam.locationViewOffsetX = 0;//定位偏移量(经度)
displayParam.locationViewOffsetY = 0;//定位偏移量(纬度)
[_mapView updateLocationViewWithParam:displayParam];
}
return _mapView;
}
2大头针的初始化,annotationView.canShowCallout = NO;//是否显示起泡泡
#pragma mark---大头针---
- (BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id <BMKAnnotation>)annotation
{
if ([annotation isKindOfClass:[BMKPointAnnotation class]]) {
NSString *AnnotationViewID = @"renameMark";
BMKPinAnnotationView *annotationView = (BMKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil) {
annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
//设置颜色
annotationView.pinColor = BMKPinAnnotationColorPurple;
// 从天上掉下效果
annotationView.animatesDrop = YES;
// 设置可拖拽
annotationView.draggable = YES;
// annotationView.canShowCallout = NO;//是否显示起泡泡
annotationView.image =[UIImage imageNamed:@"icon_green"];
}
return annotationView;
}
return nil;
}
上面的方法可以隐藏其他的气泡。但是我的位置的气泡是没办法隐藏的,查看百度的API,在点击大头针的时候首先会调用下面的方法,所以我们需要在下面处理。
/**
*当选中一个annotation views时,调用此接口
*@param mapView 地图View
*@param views 选中的annotation views
*/
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view;
处理如下,在点击我的位置的时候可以发现和其他的大头针不一样,是LocationView
类型,所以做个判断即可。
#pragma mark---点击位置的方法 可屏蔽掉我的位置的气泡--
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view{
// NSLog(@"%@",view);
if (![view isKindOfClass:NSClassFromString(@"LocationView")]) {
view.canShowCallout = YES;
[mapView bringSubviewToFront:view];
}else{
view.canShowCallout = NO;
}
}
3,4.计算离我最近点的距离、显示,以及初始化,最近点的连线。
在计算离我最近点距离时候,我们需要在每次更新用户位置的时候进行处理。最新的地图API中下面的方法会不停调用,所以判断是否更新了位置,避免计算距离。计算距离用到百度地图的反编码。BMKReverseGeoCodeOption
#pragma mark 用户位置更新后,会调用此函数 新的用户位置---
- (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation
{
NSLog(@"didUpdateUserLocation lat %f,long %f",userLocation.location.coordinate.latitude,userLocation.location.coordinate.longitude);
[_mapView updateLocationData:userLocation];
if (self.userLocation != userLocation) {
self.userLocation = userLocation;
[self.mapView setCenterCoordinate:userLocation.location.coordinate ];
double minDistance = MAXFLOAT;
CLLocationCoordinate2D mincoordinate;
//获取最近点的距离,然后显示
for (BMKPointAnnotation *animation in self.mapView.annotations) {
BMKMapPoint point1 = BMKMapPointForCoordinate(userLocation.location.coordinate);
BMKMapPoint point2 = BMKMapPointForCoordinate(animation.coordinate);
CLLocationDistance distance = BMKMetersBetweenMapPoints(point1,point2);
if (distance <= minDistance) {
minDistance= distance;
mincoordinate = animation.coordinate; //获得距离最小的经纬度。
}
}
//距离
self.ditanceLabel.text = [NSString stringWithFormat:@"离我最近%.f 米",minDistance];
//计算最短的距离的时候连线
CLLocationCoordinate2D coors[2] = {0};
coors[0].latitude = userLocation.location.coordinate.latitude;
coors[0].longitude = userLocation.location.coordinate.longitude;
coors[1].latitude = mincoordinate.latitude;
coors[1].longitude = mincoordinate.longitude;
BMKPolyline* polyline = [BMKPolyline polylineWithCoordinates:coors count:2];
[_mapView addOverlay:polyline];
}
//反地理编码
BMKReverseGeoCodeOption *reverseOption=[[BMKReverseGeoCodeOption alloc]init];
//2.给反向地理编码选项对象的坐标点赋值
reverseOption.reverseGeoPoint=userLocation.location.coordinate;
//3.执行反地理编码
BOOL flag = [self.geocodesearch reverseGeoCode:reverseOption];
if(flag)
{
NSLog(@"反geo检索发送成功");
}
else
{
NSLog(@"反geo检索发送失败");
}
}
计算距离,更新显示--
#pragma mark---获取反编码的数据---
-(void)onGetReverseGeoCodeResult:(BMKGeoCodeSearch *)searcher result:(BMKReverseGeoCodeResult *)result errorCode:(BMKSearchErrorCode)error
{
// BMKAddressComponent *component=[[BMKAddressComponent alloc]init];
// component=result.addressDetail;
self.geoLabel.text= result.address;
}
5.点击其他位置时更新连线(我的位置到点击的大头针的连线, 以及计算距离)
#pragma mark---点击位置的方法 可屏蔽掉我的位置的气泡--
- (void)mapView:(BMKMapView *)mapView didSelectAnnotationView:(BMKAnnotationView *)view{
// NSLog(@"%@",view);
if (![view isKindOfClass:NSClassFromString(@"LocationView")]) {
view.canShowCallout = YES;
[mapView bringSubviewToFront:view];
//下面的是添加折线,(覆盖物)
NSArray * array = [NSArray arrayWithArray:_mapView.overlays];
[mapView removeOverlays:array];
BMKPointAnnotation *animation = view.annotation;
//计算最短的距离的时候连线
CLLocationCoordinate2D coors[2] = {0};
coors[0].latitude = self.userLocation.location.coordinate.latitude;
coors[0].longitude = self.userLocation.location.coordinate.longitude;
coors[1].latitude = animation.coordinate.latitude;
coors[1].longitude = animation.coordinate.longitude;
BMKPolyline* polyline = [BMKPolyline polylineWithCoordinates:coors count:2];
[_mapView addOverlay:polyline];
BMKMapPoint point1 = BMKMapPointForCoordinate(self.userLocation.location.coordinate);
BMKMapPoint point2 = BMKMapPointForCoordinate(animation.coordinate);
CLLocationDistance distance = BMKMetersBetweenMapPoints(point1,point2);
//距离
self.ditanceLabel.text = [NSString stringWithFormat:@"离我距离%.f 米",distance];
[mapView setNeedsDisplay];
}else{
view.canShowCallout = NO;
}
}
代码需要在真机下运行。
demo 地址:百度地图testDemo
网友评论