场景介绍
本章节将向您介绍如何在地图的指定位置添加标记以标识位置、商家、建筑等。
点标记用来在地图上标记任何位置,例如用户位置、车辆位置、店铺位置等一切带有位置属性的事物。Map Kit提供的点标记功能(又称 Marker)封装了大量的触发事件,例如点击事件、长按事件、拖拽事件。
Marker有默认风格,同时也支持自定义。由于内容丰富,以下只能展示一些基础功能的使用,详细内容可参见接口文档。
接口说明
添加标记功能主要由MarkerOptions、addMarker和Marker提供,更多接口及使用方法请参见接口文档。
接口名 | 描述 |
---|---|
MarkerOptions | Marker相关属性。 |
addMarker(options: mapCommon.MarkerOptions): Promise<Marker> | 在地图上添加标记。 |
Marker | 标记,支持更新和查询标记。 |
开发步骤
添加标记
-
导入相关模块。
TypeScriptimport { MapComponent, mapCommon, map } from '@kit.MapKit'; import { AsyncCallback } from '@kit.BasicServicesKit';
-
添加标记,在Callback方法中创建初始化参数并新建Marker。
TypeScript@Entry @Component struct MarkerDemo { private mapOptions?: mapCommon.MapOptions; private mapController?: map.MapComponentController; private callback?: AsyncCallback<map.MapComponentController>; private marker?: map.Marker; aboutToAppear(): void { // 地图初始化参数 this.mapOptions = { position: { target: { latitude: 31.984410259206815, longitude: 118.76625379397866 }, zoom: 15 } }; this.callback = async (err, mapController) => { if (!err) { this.mapController = mapController; // Marker初始化参数 let markerOptions: mapCommon.MarkerOptions = { position: { latitude: 31.984410259206815, longitude: 118.76625379397866 }, rotation: 0, visible: true, zIndex: 0, alpha: 1, anchorU: 0.5, anchorV: 1, clickable: true, draggable: true, flat: false }; // 创建Marker this.marker = await this.mapController.addMarker(markerOptions); } }; } build() { Stack() { Column() { MapComponent({ mapOptions: this.mapOptions, mapCallback: this.callback }); }.width('100%') }.height('100%') } }
-
在添加标记之后,修改已经设置的标记属性。
TypeScript// 设置标记可拖拽 this.marker.setDraggable(true); // 设置标记锚点 this.marker.setMarkerAnchor(1.0, 1.0);
自定义标记
通过在MarkerOptions中将icon属性设置为自定义图标的资源,可将默认标记图标修改成自定义图标。
TypeScript
let markerOptions: mapCommon.MarkerOptions = {
position: {
latitude: 31.984410259206815,
longitude: 118.76625379397866
},
rotation: 0,
visible: true,
zIndex: 0,
alpha: 1,
anchorU: 0.5,
anchorV: 1,
clickable: true,
draggable: true,
flat: false,
// 图标存放在resources/rawfile,icon参数传入rawfile文件夹下的相对路径
icon: 'test.png'
};
this.marker = await this.mapController.addMarker(markerOptions);
设置监听标记点击事件
TypeScript
this.mapController.on("markerClick", (marker) => {
console.info(`on-markerClick marker = ${marker.getId()}`);
});
设置监听标记拖动事件
将Marker的拖拽属性设置为true,然后调用on(type: 'markerDragStart' , callback: Callback<Marker>)方法监听标记是否开始拖拽。
调用on(type: 'markerDrag' , callback: Callback<Marker>),监听标记拖动过程。
调用on(type: 'markerDragEnd' , callback: Callback<Marker>),监听标记拖动结束事件。
TypeScript
// 设置标记可拖拽
this.marker.setDraggable(true);
// 监听标记开始拖拽
this.mapController.on("markerDragStart", (marker) => {
console.info(`on-markerDragStart marker = ${marker.getId()}`);
});
// 监听标记拖拽事件
this.mapController.on("markerDrag", (marker) => {
console.info(`on-markerDrag marker = ${marker.getId()}`);
});
// 监听标记拖拽结束
this.mapController.on("markerDragEnd", (marker) => {
console.info(`on-markerDragEnd marker = ${marker.getId()}`);
});
信息窗
TypeScript
// 添加信息窗
let markerOptions: mapCommon.MarkerOptions = {
position: {
latitude: 31.984410259206815,
longitude: 118.76625379397866
}
};
this.marker = await this.mapController?.addMarker(markerOptions);
// 设置信息窗的标题
this.marker.setTitle('南京');
// 设置信息窗的子标题
this.marker.setSnippet('华东地区');
// 设置信息窗可点击
this.marker.setClickable(true);
// 设置信息窗的锚点位置
this.marker.setInfoWindowAnchor(1, 1);
// 设置信息窗可见
this.marker.setInfoWindowVisible(true);
自定义信息窗
TypeScript
import { map, mapCommon, MapComponent } from '@kit.MapKit'
import { AsyncCallback } from '@kit.BasicServicesKit'
@Entry
@Component
struct MarkerDemo {
private TAG = "OHMapSDK_MarkerDemo";
private mapOption?: mapCommon.MapOptions;
private mapController?: map.MapComponentController;
private callback?: AsyncCallback<map.MapComponentController>;
aboutToAppear(): void {
this.mapOption = {
position: {
target: {
latitude: 32.120750,
longitude: 118.788765
},
zoom: 15
}
}
this.callback = async (err, mapController) => {
if (!err) {
this.mapController = mapController;
let markerOptions: mapCommon.MarkerOptions = {
position: {
latitude: 32.120750,
longitude: 118.788765
},
clickable: true,
// 设置信息窗标题
title: "自定义信息窗",
};
await this.mapController?.addMarker(markerOptions);
}
}
}
build() {
Stack() {
Column() {
MapComponent({
mapOptions: this.mapOption,
mapCallback: this.callback,
// 自定义信息窗
customInfoWindow: this.customInfoWindow
})
.width('100%')
.height('100%');
}.width('100%')
}.height('100%')
}
// 自定义信息窗BuilderParam
@BuilderParam customInfoWindow: ($$: map.MarkerDelegate) => void = this.customInfoWindowBuilder;
// 自定义信息窗Builder
@Builder
customInfoWindowBuilder($$: map.MarkerDelegate) {
if ($$.marker) {
Text($$.marker.getTitle())
.width("50%")
.height(50)
.backgroundColor(Color.Green)
.textAlign(TextAlign.Center)
.fontColor(Color.Black)
.font({ size: 25, weight: 10, style: FontStyle.Italic })
.border({ width: 3, color: Color.Black, radius: 25, style: BorderStyle.Dashed })
}
}
}
标记动画
Marker支持设置旋转、缩放、平移、透明、图片动画播放和组合动画效果。
接口名 | 描述 |
---|---|
AlphaAnimation | 控制透明度的动画类。 |
RotateAnimation | 控制旋转的动画类。 |
ScaleAnimation | 控制缩放的动画类。 |
TranslateAnimation | 控制平移的动画类。 |
PlayImageAnimation | 控制多张图片的动画类。 |
AnimationSet | 动画集合。 |
旋转动画效果的示例代码如下:
TypeScript
import { map, mapCommon, MapComponent } from '@kit.MapKit';
import { AsyncCallback } from '@kit.BasicServicesKit';
@Entry
@Component
struct MarkerDemo {
private mapOption?: mapCommon.MapOptions;
private callback?: AsyncCallback<map.MapComponentController>;
aboutToAppear(): void {
this.mapOption = {
position: {
target: {
latitude: 32.020750,
longitude: 118.788765
},
zoom: 11
}
}
this.callback = async (err, mapController) => {
if (!err) {
// 构造MarkerOptions对象
let markerOptions: mapCommon.MarkerOptions = {
position: {
latitude: 32.020750,
longitude: 118.788765
},
};
// 新建marker
let marker: map.Marker = await mapController.addMarker(markerOptions);
// 构造RotateAnimation对象
let animation = new map.RotateAnimation(0, 270);
// 动画执行时间
animation.setDuration(2000);
// 动画结束状态
animation.setFillMode(map.AnimationFillMode.BACKWARDS);
// 动画重复模式
animation.setRepeatMode(map.AnimationRepeatMode.REVERSE);
// 动画重复次数
animation.setRepeatCount(100);
// 根据开发需要设置动画监听
animation.on("start", () => {
console.info('start RotateAnimation');
})
animation.on("end", () => {
console.info('end RotateAnimation');
})
// 设置动画
marker.setAnimation(animation);
// 开启动画
marker.startAnimation();
}
}
}
build() {
Stack() {
Column() {
MapComponent({ mapOptions: this.mapOption, mapCallback: this.callback })
}.width('100%')
}.height('100%')
}
}
展示效果如图:
图片动画播放
TypeScript
import { map, mapCommon, MapComponent } from '@kit.MapKit';
import { AsyncCallback } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';
@Entry
@Component
struct MarkerDemo {
private mapOption?: mapCommon.MapOptions;
private callback?: AsyncCallback<map.MapComponentController>;
aboutToAppear(): void {
this.mapOption = {
position: {
target: {
latitude: 32.020750,
longitude: 118.788765
},
zoom: 11
}
}
this.callback = async (err, mapController) => {
if (!err) {
// 构造MarkerOptions对象
let markerOptions: mapCommon.MarkerOptions = {
position: {
latitude: 32.020750,
longitude: 118.788765
},
};
let mContext = getContext();
const fileData: Uint8Array = await mContext?.resourceManager?.getRawFileContent('icon/icon.png');
let imageSource: image.ImageSource = image.createImageSource(fileData.buffer.slice(0, fileData.buffer.byteLength));
let pixelMap: PixelMap = await imageSource.createPixelMap();
let images: Array<ResourceStr | image.PixelMap> = [
// 图标需存放在resources/rawfile
'icon/avocado.png',
'icon/20231027.png',
pixelMap,
$r('app.media.maps_blue_dot')
]
// 新建marker
let marker: map.Marker = await mapController.addMarker(markerOptions);
// 构造RotateAnimation对象
let animation: map.PlayImageAnimation = new map.PlayImageAnimation();
// 添加图片
await animation.addImages(images)
// 动画执行时间
animation.setDuration(3000);
// 动画结束状态
animation.setFillMode(map.AnimationFillMode.BACKWARDS);
// 动画重复模式
animation.setRepeatMode(map.AnimationRepeatMode.REVERSE);
// 动画重复次数
animation.setRepeatCount(100);
// 根据开发需要设置动画监听
animation.on("start", () => {
console.info('start RotateAnimation');
})
animation.on("end", () => {
console.info('end RotateAnimation');
})
// 设置动画
marker.setAnimation(animation);
// 开启动画
marker.startAnimation();
}
}
}
build() {
Stack() {
Column() {
MapComponent({ mapOptions: this.mapOption, mapCallback: this.callback })
}.width('100%')
}.height('100%')
}
}
展示效果如图: