全部服务产品
开发者频道
定价
登录
绘制Marker
下载开发文档
一、Marker简介

Marker用来在地图上标记任何位置,例如用户位置、车辆位置、店铺位置等一切带有位置属性的事物。 iOS地图 SDK 提供的Marker包含:图标Marker(BMKIconMarker)和文本Marker(BMKTextMarker),支持Marker动画和点击回调,支持碰撞检测。同时支持RichView(等同于paopaoview)及RichView上子元素的点击事件。 开发者可以根据自己实际的业务需求,利用Marker覆盖物绘制,在地图指定的位置上添加标注信息。

二、绘制Marker
1. 创建BMKMapView,并设置delegate
BMKMapView *mapView = [[BMKMapView alloc]initWithFrame:self.view.bounds];
mapView.delegate = self;
[self.view addSubView:mapView];
2. 创建Marker并添加到地图上

使用BMKIconMarker创建一个带有图片的Marker,使用BMKTextMarker创建一个带有文本的Marker,调用BMKMapView的addOverlay和addOverlays方法添加Marker到地图上。

// 创建图片Marker
BMKIconMarker *iconMarker = [[BMKIconMarker alloc] init];
iconMarker.coordinate = CLLocationCoordinate2DMake(40.015, 116.564);
iconMarker.icon = [UIImage imageNamed:@"sportArrow"];
//_iconMarker.color = [UIColor redColor];
iconMarker.size = CGSizeMake(100, 30);
iconMarker.rotate = 90;
iconMarker.anchorX = 0.5;
iconMarker.anchorY = 0.5;
// 创建文本Marker
BMKTextMarker *textMarker = [[BMKTextMarker alloc] init];
// 设置marker位置
textMarker.coordinate = CLLocationCoordinate2DMake(40.015, 116.554);
// 设置marker文本
textMarker.text = @"小车";
// 设置marker宽高
textMarker.size = CGSizeMake(100, 30);
// 设置文本字体样式
BMKTextStyle *style = [[BMKTextStyle alloc] init];
// 字体大小
style.fontSize = 20;
// 文本样式
style.fontOption = BMKFontBold;
// 描边宽度
style.borderWidth = 2;
// 描边颜色
style.borderColor = [UIColor blackColor];
// 文本颜色
style.textColor = [UIColor redColor];
textMarker.style = style;
[self.mapView addOverlays:@[textMarker, iconMarker]];
3. 实现代理方法
#pragma mark - BMKMapViewDelegate
- (__kindof BMKOverlayView *)mapView:(BMKMapView *)mapView viewForOverlay:(id<BMKOverlay>)overlay {
if ([overlay isEqual:self.textMarker]) {
BMKTextMarkerView *makerView = [[BMKTextMarkerView alloc] initWithMarker:self.textMarker];
// 设置可点击后,marker被点击后会触发overlay点击回调
makerView.isClickable = YES;
return makerView;
} else if ([overlay isEqual:self.iconMarker]) {
BMKIconMarkerView *makerView = [[BMKIconMarkerView alloc] initWithMarker:self.iconMarker];
makerView.isClickable = YES;
return makerView;
}
return nil;
}
4. 实现overlay点击代理回调
#pragma mark - BMKMapViewDelegate
- (void)mapView:(BMKMapView *)mapView onClickedBMKOverlayView:(BMKOverlayView *)overlayView {
if ([overlayView isKindOfClass:[BMKTextMarkerView class]]) {
NSLog(@"TextMarkerView 点击-%@", ((BMKTextMarker *)((BMKTextMarkerView *)overlayView).marker).text);
}
if ([overlayView isKindOfClass:[BMKIconMarkerView class]]) {
NSLog(@"BMKIconMarkerView 点击-%@", ((BMKIconMarkerView *)((BMKIconMarkerView *)overlayView).marker));
}
}

运行效果如下:

IMG_1880.png
三、添加RichView

RichView(等同于paopaoview),开发者可以使用SDK提供的UI控件和布局进行丰富的UI自定义。同时支持RichView的碰撞避让检测及上子元素的点击事件。

// Notes:RichView没有坐标,必须挂接到marker或3D模型上
[_iconMarker addRichView:self.richView];
- (BMKRichView *)richView {
if (!_richView) {
// 准备挂接的RichVieW
BMKImageUIView *imageUI = [[BMKImageUIView alloc] init];
imageUI.image = [UIImage imageNamed:@"trump_256x256"];
// 设置宽高,不设置按图片尺寸。如只设置width,height按图片尺寸显示
imageUI.width = 50;
imageUI.height = 50;
// 设置背景,使用白色图片+混合颜色的方式
imageUI.background = [UIImage imageNamed:@"backgroundImage_white"];
imageUI.backgroundColor = [UIColor redColor];
// 内边距
//imageUI.padding = UIEdgeInsetsMake(5, 5, 5, 5);
// 外边距
imageUI.margin = UIEdgeInsetsMake(5, 10, 5, 5);
imageUI.clickable = YES;
// 添加点击事件
[imageUI setTarget:self action:@selector(imageUIClick)];
BMKLabelUIView *labelUI = [[BMKLabelUIView alloc] init];
labelUI.text = @"特师傅";
BMKTextStyle *style = [[BMKTextStyle alloc] init];
style.fontSize = 20;
style.fontOption = BMKFontBold;
style.borderWidth = 2;
style.textColor = [UIColor blackColor];
style.borderColor = [UIColor yellowColor];
labelUI.style = style;
// 设置宽高,不设置按字体自适应;也可以只设置width,代表按这个最大宽度适配多行文字,默认最多20行
labelUI.width = 90;
labelUI.height = 30;
// 可通过maxLines设置最大行数
// labelUI.maxLines = 2;
// 设置背景,使用白色图片+混合颜色的方式
labelUI.background = [UIImage imageNamed:@"backgroundImage_white"];
labelUI.backgroundColor = [UIColor whiteColor];
// 外边距
labelUI.margin = UIEdgeInsetsMake(15, 5, 15, 10);
labelUI.gravity = BMKGravityCenter;
// 添加点击事件
labelUI.clickable = YES;
[labelUI setTarget:self action:@selector(labelUIClick)];
// 垂直布局
BMKVerticalLayout *verLayout = [[BMKVerticalLayout alloc] init];
// 水平布局
BMKHorizontalLayout *horLayout = [[BMKHorizontalLayout alloc] init];
[horLayout addView:imageUI];
[horLayout addView:labelUI];
horLayout.backgroundColor = [UIColor blackColor];
[verLayout addView:horLayout];
verLayout.gravity = BMKGravityCenter;
// 使用白色图片+混合颜色的方式实现灰色背景
verLayout.background = [UIImage imageNamed:@"backgroundImage_white"];
verLayout.backgroundColor = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];
_richView = [[BMKRichView alloc] init];
// Notes:RichView可以挂接BMKHorizontalLayout, BMKVerticalLayout, BMKImageUI或者BMapLabelUI
// Notes:RichView相对于marker的位置
_richView.rootView = verLayout;
_richView.locate = BMKLocateTop;
// richView.offsetY = 40;
// 碰撞检测类型
_richView.collisionBehavior = BMKCollisionWithAllLayersByPriority;
// 碰撞检测优先级
_richView.collisionPriority = 100;
// 设置可选位置,用于碰撞避让
// BMKRichUIOption *richUIOption1 = [[BMKRichUIOption alloc] initWithLocate:BMKLocateBottom andBaseUI:horLayout];
// [_richView addRichUIOption:richUIOption1];
// BMKRichUIOption *richUIOption2 = [[BMKRichUIOption alloc] initWithLocate:BMKLocateTop andBaseUI:horLayout];
// [_richView addRichUIOption:richUIOption2];
// BMKRichUIOption *richUIOption3 = [[BMKRichUIOption alloc] initWithLocate:BMKLocateLeft andBaseUI:horLayout];
// [_richView addRichUIOption:richUIOption3];
// BMKRichUIOption *richUIOption4 = [[BMKRichUIOption alloc] initWithLocate:BMKLocateRight andBaseUI:horLayout];
// [_richView addRichUIOption:richUIOption4];
// richView.offsetY = 40;
}
return _richView;
}
- (void)labelUIClick {
NSLog(@"label click");
}
- (void)imageUIClick {
NSLog(@"image click");
}

运行效果如下:

IMG_1881.png
四、Marker动画

Marker支持透明度动画,平移动画、旋转动画、缩放动画、Track动画及动画组。BMKIconMarker还支持帧动画。

// 缩放动画
BMKMapScaleAnimation *scaleAnimation = [[BMKMapScaleAnimation alloc] initWithFromSizeScale:CGSizeMake(1, 1) to:CGSizeMake(0.5, 0.5)];
scaleAnimation.duration = 3000;
scaleAnimation.repeatCount = 3;
scaleAnimation.repeatMode = BMKAnimationReleatReserse;
// 旋转动画
BMKMapRotateAnimation *rotateAnimation = [[BMKMapRotateAnimation alloc] initWithFromDegrees:0 to:360];
rotateAnimation.duration = 3000;
rotateAnimation.repeatCount = 3;
rotateAnimation.repeatMode = BMKAnimationRepeatRestart;
// 透明度动画
BMKMapAlphaAnimation *alphaAnimation = [[BMKMapAlphaAnimation alloc] initWithFromAlpha:0 to:1.0];
alphaAnimation.duration = 3000;
alphaAnimation.repeatCount = 4;
alphaAnimation.repeatMode = BMKAnimationReleatReserse;
// 动画组
BMKMapAnimationSet *animationSet = [[BMKMapAnimationSet alloc] init];
[animationSet addAnimation:scaleAnimation addAnimationSetOrderType:BMKAnimationSetOrderTypeWith];
[animationSet addAnimation:rotateAnimation addAnimationSetOrderType:BMKAnimationSetOrderTypeWith];
[animationSet addAnimation:alphaAnimation addAnimationSetOrderType:BMKAnimationSetOrderTypeThen];
_textMarker.animation = animationSet;

运行效果如下:

使用polyline的Track动画实现小车平滑移动:

// polyline的Track动画
BMKMultiPolyline *polyline = [BMKMultiPolyline multiPolylineWithPoints:points count:pointCount drawIndexs:textIndexs];
polyline.animation = self.trackAnimation;
[_mapView addOverlay:polyline];
// iconMarker的Track动画
self.iconMarker.animation = self.trackAnimation;
[self.mapView addOverlay:self.iconMarker];
- (BMKIconMarker *)iconMarker {
if (!_iconMarker) {
_iconMarker = [[BMKIconMarker alloc] init];
_iconMarker.coordinate = CLLocationCoordinate2DMake(40.015, 116.564);
// 因为rotateFeature为默认BMKRotateFreeze,所以单独设置rotate不会生效,需要设置rotateFeature中包含BMKRotateItem才会生效,注意:BMKRotateItem和BMKRotateAnmination只能二选一
// _iconMarker.rotate = 90; //此场景不支持设置外部旋转角度,请按图片要求传入图片:车头朝向右为正(0度)
// 因为当前场景时需要小车动画,需要包含BMKRotateAnmination,所以使用默认rotateFeature即可,可以更改下边的值看发声的变化
_iconMarker.rotateFeature = BMKRotateAnmination | BMKRotateScreenUpper | BMKRotateFlipNo;
// 因为旋转动画对图片的要求,需要车头朝向右为正(0度),可以参考demo的trace_car图片
_iconMarker.icon = [UIImage imageNamed:@"trace_car"];
// 因为SDK是根据图片资源尺寸绘制的,demo中图片尺寸较大中,这里做缩小处理
_iconMarker.scaleX = 0.8;
_iconMarker.scaleY = 0.8;
// 默认0.5 1.0,这里设置为锚点局中0.5 0.5
_iconMarker.anchorX = 0.5;
_iconMarker.anchorY = 0.5;
// 动画跟随模式,默认BMKAnimationTrackXY
_iconMarker.trackBy = BMKAnimationTrackXY;
// 远小近大效果,默认为NO,可以设置为YES,在地图有一定俯仰角时看下效果
_iconMarker.perspective = YES;
// 是否跟随地图的旋转轴旋转,默认都不跟随,这里需要根据业务需要设置,此demo需要
_iconMarker.followMapRotateAxis = BMKFollowMapRotateAxisPitch | BMKFollowMapRotateAxisYaw;
}
return _iconMarker;
}
- (BMKMapTrackAnimation *)trackAnimation {
if (!_trackAnimation) {
_trackAnimation = [[BMKMapTrackAnimation alloc] init];
_trackAnimation.duration = 20000;
_trackAnimation.startDelay = 0;
_trackAnimation.repeatCount = 2;
_trackAnimation.repeatMode = BMKAnimationRepeatRestart;
_trackAnimation.delegate = self;
_trackAnimation.trackDelegate = self;
// 创建动画差值器,可根据需求按类型或具体差值算法参数创建,参考BMKInterpolator类
BMKInterpolator *interpolator = [[BMKInterpolator alloc] init];
_trackAnimation.interpolator = interpolator;
[_trackAnimation setTrackPosRadio:0.0 to:1.0];
}
return _trackAnimation;
}

效果如下:

上一篇

覆盖物交互

下一篇

绘制点标记

本篇文章对您是否有帮助?