iOS-BMK标注&覆盖物
阅读原文时间:2023年07月16日阅读:1

在iOS开发中,地图算是一个比较重要的模块。我们常用的地图有高德地图,百度地图,谷歌地图,对于中国而言,苹果公司已经不再使用谷歌地图,官方使用的是高德地图。下面将讲述一下百度地图开发过程中的一些小的知识点。

对于如何配置百度地图的开发环境,在此不再讲述,具体可以参考:http://developer.baidu.com/map/index.php?title=iossdk/guide/buildproject

百度地图iOS的API下载地址:http://developer.baidu.com/map/index.php?title=iossdk/sdkiosdev-download

关于百度地图的基本使用,我们可以参考百度地图的开发文档,在此主要总结一下开发文档中一些重要的知识点和延伸点。(地图版本IOS SDK 2.9.0)

首先说明一下百度地图开发中可能遇到的问题:

如何添加标注(系统标注和自定义标注)

//添加标记
-(void)viewDidAppear:(BOOL)animated
{
/*
for (int i = 0; i < 3; i++) {
BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init];
CLLocationCoordinate2D coor;
coor.latitude = 39.915 + i*2;
coor.longitude = 116.404 + i*2;
annotation.coordinate = coor;
annotation.title = @"这里是北京";
[myMapView addAnnotation:annotation];
}
*/
BMKPointAnnotation* annotation = [[BMKPointAnnotation alloc]init];
CLLocationCoordinate2D coor;
coor.latitude = 39.915;
coor.longitude = 116.404;
annotation.coordinate = coor;
annotation.title = @"这里是北京";
annotation.subtitle = @"";
//[myMapView addAnnotation:annotation];

 BMKPointAnnotation\* annotation1 = \[\[BMKPointAnnotation alloc\]init\];  
 CLLocationCoordinate2D coor1;  
 coor1.latitude = 38.915;  
 coor1.longitude = 113.404 + ;  
 annotation1.coordinate = coor1;  
 annotation1.title = @"这里也是北京";  
 annotation1.subtitle = @"";  
 //\[myMapView addAnnotation:annotation1\];

 BMKPointAnnotation\* annotation2 = \[\[BMKPointAnnotation alloc\]init\];  
 CLLocationCoordinate2D coor2;  
 coor2.latitude = 38.915;  
 coor2.longitude = 119.404 + ;  
 annotation2.coordinate = coor2;  
 annotation2.title = @"这里同样是北京";  
 annotation2.subtitle = @"";  
 //\[myMapView addAnnotation:annotation2\];

 NSArray \*arr = \[NSArray arrayWithObjects:annotation,annotation1,annotation2, nil\];  
 \[myMapView addAnnotations:arr\];  

}

-(BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id)annotation
{
if ([annotation isKindOfClass:[BMKPointAnnotation class]])
{
BMKPinAnnotationView *newAnnotationView = (BMKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"AnnotationView"];
newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"AnnotationView"];
newAnnotationView.pinColor = BMKPinAnnotationColorPurple;
newAnnotationView.animatesDrop = YES;// 设置该标注点动画显示
return newAnnotationView;
}
return nil;
}

系统标记

如何自定义大头针

自定义大头针就是改变大头针的样式,如你想使用自己的图片代替上面显示的样式,代码实现跟上面的代码基本一样。只是在上面代理实现的代码中加入下面的代码即可。

  newAnnotationView.image = [UIImage imageNamed:@""]; (图片显示的大小,可以通过newAnnotationView的frame设定)

如何修改气泡样式

在气泡上默认是可以显示两行信息,一个title,一个subtitle,在此仅修改气泡的样式,如边框大小,字体,等基本信息,没有改变总体布局。

-(BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id)annotation
{
if ([annotation isKindOfClass:[BMKPointAnnotation class]])
{
BMKPinAnnotationView *newAnnotationView = (BMKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"AnnotationView"];
newAnnotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"AnnotationView"];
newAnnotationView.pinColor = BMKPinAnnotationColorPurple;
newAnnotationView.animatesDrop = YES;// 设置该标注点动画显示

     UIView \*view = \[\[UIView alloc\]init\];  
     view.frame = CGRectMake(, , , );  
     view.backgroundColor = \[UIColor greenColor\];  
     \[view.layer setMasksToBounds:YES\];  
     \[view.layer setCornerRadius:\];  
     view.alpha = 0.9;

     UILabel \*label1 = \[\[UILabel alloc\]init\];  
     label1.frame = CGRectMake(, , , );  
     label1.text = annotation.title;  
     label1.numberOfLines = ;  
     label1.font = \[UIFont systemFontOfSize:\];  
     label1.textColor = \[UIColor blackColor\];  
     \[view addSubview:label1\];

     UILabel \*label2 = \[\[UILabel alloc\]init\];  
     label2.frame = CGRectMake(, , , );  
     label2.text = annotation.subtitle;  
     label2.numberOfLines = ;  
     label2.font = \[UIFont systemFontOfSize:\];  
     label2.textColor = \[UIColor lightGrayColor\];  
     \[view addSubview:label2\];

     BMKActionPaopaoView \*pView = \[\[BMKActionPaopaoView alloc\]initWithCustomView:view\];  
     pView.frame = CGRectMake(, , , );  
     ((BMKPinAnnotationView \*)newAnnotationView).paopaoView = pView;  
     return newAnnotationView;  
 }  
 return nil;  

}

简单定义气泡样式

如果我们想要修改气泡的布局怎样处理呢?

因为系统默认的一个是坐标,一个标题,一个子标题,我们想要按照自己的方式布局弹出的气泡,我们需要做什么工作呢?

首先系统提供BMKPointAnnotation的方法不够我们使用,我们需要继承这个类,假如新类为myPoint,添加一些新的属性。比如这个类,我们需要添加三个属性。

分别是NSString *imgName ; NSString *placeName; NSString *idNum;

接下来我们我们需要自定义气泡,气泡本身是一个UIView,我们可以在继承于UIView,创建一个子类myPaopao;在myPaopao里面要添加三个控件,显示上面定义的三个属性。

#import

@interface myPaopao : UIView
@property(nonatomic,retain)UIImageView *imgView;
@property(nonatomic,retain) UILabel *placeName;
@property(nonatomic,retain) UILabel *idNum;

@end

myPaopao.h

#import "myPaopao.h"

@implementation myPaopao

-(instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.frame = CGRectMake(, , , );
self.backgroundColor = [UIColor whiteColor];

     \_imgView = \[\[UIImageView alloc\]init\];  
     \_imgView.frame = CGRectMake(, , , );  
     \[self addSubview:\_imgView\];

     \_placeName = \[\[UILabel alloc\]init\];  
     \_placeName.frame = CGRectMake(, , , );  
     \_placeName.font = \[UIFont systemFontOfSize:\];  
     \[self addSubview:\_placeName\];

     \_idNum = \[\[UILabel alloc\]init\];  
     \_idNum.frame = CGRectMake(, , , );  
     \[self addSubview:\_idNum\];

 }  
 return self;  

}
@end

myPaopao.m

//添加标记
-(void)viewDidAppear:(BOOL)animated
{
myPoint* annotation = [[myPoint alloc]init];
CLLocationCoordinate2D coor;
coor.latitude = 39.915;
coor.longitude = 116.404;
annotation.coordinate = coor;
annotation.imgName = @"1.jpg";
annotation.placeName = @"这里是北京";
annotation.idNum = @"";
[myMapView addAnnotation:annotation];

 myPoint\* annotation1 = \[\[myPoint alloc\]init\];  
 CLLocationCoordinate2D coor1;  
 coor1.latitude = 38.915;  
 coor1.longitude = 113.404 + ;  
 annotation1.coordinate = coor1;  
 annotation1.imgName = @"2.jpg";  
 annotation1.placeName = @"这里也是北京";  
 annotation1.idNum = @"";  
 \[myMapView addAnnotation:annotation1\];

}
-(BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id)annotation
{
if ([annotation isKindOfClass:[myPoint class]])
{
myPoint *myAnnotation = (myPoint *)annotation;

     BMKPinAnnotationView \*newAnnotationView = (BMKPinAnnotationView \*)\[mapView dequeueReusableAnnotationViewWithIdentifier:@"AnnotationView"\];  
     newAnnotationView = \[\[BMKPinAnnotationView alloc\] initWithAnnotation:annotation reuseIdentifier:@"AnnotationView"\];  
     newAnnotationView.pinColor = BMKPinAnnotationColorPurple;  
     newAnnotationView.animatesDrop = YES;// 设置该标注点动画显示  
     myPaopao \*paopapo = \[\[myPaopao alloc\]init\];

     paopapo.imgView.image = \[UIImage imageNamed:myAnnotation.imgName\];  
     paopapo.placeName.text = myAnnotation.placeName;  
     paopapo.idNum.text = myAnnotation.idNum;  
     BMKActionPaopaoView \*pView = \[\[BMKActionPaopaoView alloc\]initWithCustomView:paopapo\];  
     ((BMKPinAnnotationView \*)newAnnotationView).paopaoView = pView;  
     return newAnnotationView;  
 }  
 return nil;  

}

实现代码

如果有需要,我们还可以添加一个按钮,跳转到详情界面,添加按钮的方法,与上面的方法相同,在此

点聚合功能

点聚合功能是v2.9.0新增加的一个功能,如果在一个区域有大量的点,会产生覆盖现象,点聚合功能可以实现将很多点聚合到一个点上,通过缩放比例,可以显示更多点或聚合点。我们在下载SDK的时候,会带有一个Demo,从Demo中我们可以找到相应的实现代码。在开发文档中给出了我们核心代码:

折线(从一位置到另一位置的线段)

 代码段:

//添加标记
-(void)viewDidAppear:(BOOL)animated
{
CLLocationCoordinate2D coors[] = {};
coors[].latitude = 39.315;
coors[].longitude = 116.304;
coors[].latitude = 30.515;
coors[].longitude = 116.504;
BMKPolyline *polyline = [BMKPolyline polylineWithCoordinates:coors count:];
[myMapView addOverlay:polyline];
}
-(BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id)overlay
{
NSLog(@"sdf");
if ([overlay isKindOfClass:[BMKPolyline class]])
{
BMKPolylineView *polylineView = [[BMKPolylineView alloc]initWithPolyline:overlay];
polylineView.strokeColor = [[UIColor greenColor]colorWithAlphaComponent:];
polylineView.lineWidth = 5.0;
return polylineView;
}
return nil;
}

折线

分段纹理分段折线

代码段:

//添加标记
-(void)viewDidAppear:(BOOL)animated
{
CLLocationCoordinate2D coords[] = {};
coords[].latitude = 39.965;
coords[].longitude = 116.404;
coords[].latitude = 39.925;
coords[].longitude = 116.454;
coords[].latitude = 39.955;
coords[].longitude = 116.494;
coords[].latitude = 39.905;
coords[].longitude = 116.654;
coords[].latitude = 39.965;
coords[].longitude = 116.704;
//构建分段文理索引数组
NSArray *textureIndex = [NSArray arrayWithObjects:
[NSNumber numberWithInt:],
[NSNumber numberWithInt:],
[NSNumber numberWithInt:],
[NSNumber numberWithInt:], nil];
BMKPolyline *polyline = [BMKPolyline polylineWithCoordinates:coords count: textureIndex:textureIndex];
[myMapView addOverlay:polyline];
}
-(BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id)overlay
{
if ([overlay isKindOfClass:[BMKPolyline class]])
{
BMKPolylineView* polylineView = [[BMKPolylineView alloc] initWithOverlay:overlay];
polylineView.lineWidth = ;
polylineView.isFocus = YES;// 是否分段纹理绘制(突出显示),默认YES
//加载分段纹理图片,必须否则不能进行分段纹理绘制
[polylineView loadStrokeTextureImages:
[NSArray arrayWithObjects:[UIImage imageNamed:@"1.jpg"],
[UIImage imageNamed:@"2.jpg"],
[UIImage imageNamed:@"3.jpg"],nil]];
return polylineView;
}
return nil;
}

纹理折线

分段颜色分段折线

代码段:

-(void)viewDidAppear:(BOOL)animated
{
CLLocationCoordinate2D coords[] = {};
coords[].latitude = 39.965;
coords[].longitude = 116.404;
coords[].latitude = 39.925;
coords[].longitude = 116.454;
coords[].latitude = 39.955;
coords[].longitude = 116.494;
coords[].latitude = 39.905;
coords[].longitude = 116.654;
coords[].latitude = 39.965;
coords[].longitude = 116.704;
//构建分段文理索引数组
NSArray *colorIndexs = [NSArray arrayWithObjects:
[NSNumber numberWithInt:],
[NSNumber numberWithInt:],
[NSNumber numberWithInt:],
[NSNumber numberWithInt:], nil];
BMKPolyline *polyline = [BMKPolyline polylineWithCoordinates:coords count: textureIndex:colorIndexs];
[myMapView addOverlay:polyline];
}
-(BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id)overlay
{
if ([overlay isKindOfClass:[BMKPolyline class]])
{
BMKPolylineView* polylineView = [[BMKPolylineView alloc] initWithOverlay:overlay];
polylineView.lineWidth = ;
// 使用分段颜色绘制时,必须设置(内容必须为UIColor)
polylineView.colors = [NSArray arrayWithObjects:[UIColor greenColor], [UIColor redColor], [UIColor yellowColor], nil];
return polylineView;
}
return nil;
}

颜色分段

弧线(起点,途经点,终点)

代码段:

-(void)viewDidAppear:(BOOL)animated
{
CLLocationCoordinate2D coords[] = {};
coords[].latitude = 39.9374;
coords[].longitude = 116.350;
coords[].latitude = 39.9170;
coords[].longitude = 116.360;
coords[].latitude = 39.9479;
coords[].longitude = 116.373;
BMKArcline *arcline = [BMKArcline arclineWithCoordinates:coords];
[myMapView addOverlay:arcline];
}
-(BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id)overlay
{
if ([overlay isKindOfClass:[BMKArcline class]])
{
NSLog(@"adf");
BMKArclineView* arclineView = [[BMKArclineView alloc] initWithOverlay:overlay];
arclineView.strokeColor = [[UIColor blackColor]colorWithAlphaComponent:0.5];
arclineView.lineWidth = 5.0;
return arclineView;
}
return nil;
}

弧线

多边形

代码段:

-(void)viewDidAppear:(BOOL)animated
{
CLLocationCoordinate2D coords[] = {};
coords[].latitude = ;
coords[].longitude = ;
coords[].latitude = ;
coords[].longitude = ;
coords[].latitude = ;
coords[].longitude = ;
BMKPolygon *ploygon = [BMKPolygon polygonWithCoordinates:coords count:];
[myMapView addOverlay:ploygon];
}
-(BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id)overlay
{
if ([overlay isKindOfClass:[BMKPolygon class]])
{
BMKPolygonView* polygonView = [[BMKPolygonView alloc] initWithOverlay:overlay];
polygonView.strokeColor = [[UIColor purpleColor] colorWithAlphaComponent:];
polygonView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.2];
polygonView.lineWidth = 5.0;

     return polygonView;  
 }  
 return nil;  

}

多边形

代码段:

-(void)viewDidAppear:(BOOL)animated
{
CLLocationCoordinate2D coor;
coor.latitude = 39.915;
coor.longitude = 116.404;
BMKCircle* circle = [BMKCircle circleWithCenterCoordinate:coor radius:];
[myMapView addOverlay:circle];
}
-(BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id)overlay
{
if ([overlay isKindOfClass:[BMKCircle class]])
{
BMKCircleView* circleView = [[BMKCircleView alloc] initWithOverlay:overlay];
circleView.fillColor = [[UIColor cyanColor] colorWithAlphaComponent:0.5];
circleView.strokeColor = [[UIColor orangeColor] colorWithAlphaComponent:0.5];
circleView.lineWidth = 10.0;

     return circleView;  
 }  
 return nil;  

}

图片图层

第一种方法根据坐标,缩放尺度确定

代码段:

-(void)viewDidAppear:(BOOL)animated
{
CLLocationCoordinate2D coors;
coors.latitude = 39.800;
coors.longitude = 116.404;
BMKGroundOverlay* ground = [BMKGroundOverlay groundOverlayWithPosition:coors
zoomLevel: anchor:CGPointMake(0.0f,0.0f)
icon:[UIImage imageNamed:@"1.jpg"]];
[myMapView addOverlay:ground];
}
-(BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id)overlay
{
if ([overlay isKindOfClass:[BMKGroundOverlay class]]){
BMKGroundOverlayView* groundView = [[BMKGroundOverlayView alloc] initWithOverlay:overlay];
return groundView;
}
return nil;
}

图片图层一

第二种方法根据指定区域生成

代码段:

-(void)viewDidAppear:(BOOL)animated
{
CLLocationCoordinate2D coords[] = {};
coords[].latitude = 39.815;
coords[].longitude = 116.404;
coords[].latitude = 39.915;
coords[].longitude = 116.504;
BMKCoordinateBounds bound;
bound.southWest = coords[];
bound.northEast = coords[];
BMKGroundOverlay* ground = [BMKGroundOverlay groundOverlayWithBounds: bound
icon:[UIImage imageNamed:@"2.jpg"]];
[myMapView addOverlay:ground];
}
-(BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id)overlay
{
if ([overlay isKindOfClass:[BMKGroundOverlay class]]){
BMKGroundOverlayView* groundView = [[BMKGroundOverlayView alloc] initWithOverlay:overlay];
return groundView;
}
return nil;
}

图片图层二