华为HarmonyOS地图服务 7- 在地图上绘制标记

news/2024/11/17 5:34:30/

场景介绍

本章节将向您介绍如何在地图的指定位置添加标记以标识位置、商家、建筑等。

点标记用来在地图上标记任何位置,例如用户位置、车辆位置、店铺位置等一切带有位置属性的事物。Map Kit提供的点标记功能(又称 Marker)封装了大量的触发事件,例如点击事件、长按事件、拖拽事件。

Marker有默认风格,同时也支持自定义。由于内容丰富,以下只能展示一些基础功能的使用,详细内容可参见接口文档。

 

93a131ad8324d2b3ab14e08d5b22be20.png

接口说明

添加标记功能主要由MarkerOptions、addMarker和Marker提供,更多接口及使用方法请参见接口文档。

接口名

描述

MarkerOptions

Marker相关属性。

addMarker(options: mapCommon.MarkerOptions): Promise<Marker>

在地图上添加标记。

Marker

标记,支持更新和查询标记。

开发步骤

添加标记

  1. 导入相关模块。
    import { MapComponent, mapCommon, map } from '@kit.MapKit';
    import { AsyncCallback } from '@kit.BasicServicesKit';

     

  2. 添加标记,在Callback方法中创建初始化参数并新建Marker。
    @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%')
    }
    }

     

    caec6a4ac01a4979efcfb14cbcf4fe7b.png

  3. 在添加标记之后,修改已经设置的标记属性。
    
    // 设置标记可拖拽
    this.marker.setDraggable(true);
    // 设置标记锚点
    this.marker.setMarkerAnchor(1.0, 1.0);

自定义标记

通过在MarkerOptions中将icon属性设置为自定义图标的资源,可将默认标记图标修改成自定义图标。

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);

 

5cd1d79e041a5657583615e12da49089.png

设置监听标记点击事件

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>),监听标记拖动结束事件。

// 设置标记可拖拽
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()}`);
});

信息窗

// 添加信息窗
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);

 

e8ae51c004d8c5fbd7416ff664a26720.png

自定义信息窗

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 })
}
}
}

 

e56e0d79e8cfaa8825cc7966073f6989.png

标记动画

Marker支持设置旋转、缩放、平移、透明、图片动画播放和组合动画效果。

接口名

描述

AlphaAnimation

控制透明度的动画类。

RotateAnimation

控制旋转的动画类。

ScaleAnimation

控制缩放的动画类。

TranslateAnimation

控制平移的动画类。

PlayImageAnimation

控制多张图片的动画类。

AnimationSet

动画集合。

旋转动画效果的示例代码如下:

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%')
}
}

展示效果如图:

 

59e3d4fc0091d2c47130b1bb9eec81da.gif

图片动画播放

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%')
}
}

展示效果如图:

 

701455fce9a8953eeca954bed5609609.gif

 


http://www.ppmy.cn/news/1531346.html

相关文章

图为科技大模型一体机,智领未来社区服务

当AI与边缘计算相遇&#xff0c;一幅关于智慧生活的宏伟蓝图正缓缓展开。 今天&#xff0c;让我们一同探索&#xff0c;如何通过图为大模型一体机&#xff0c;为物业服务插上智能的翅膀。 通过整合采集物业数据&#xff0c;大模型一体机可全方位为物业行业赋能&#xff0c;实…

平行驾驶车端(客户端)模拟弱网策略步骤

概念 要进行弱网测试,通常需要同时模拟客户端和服务端的网络环境。因为弱网测试旨在模拟真实的网络条件,包括网络延迟、带宽限制、丢包率等。通过同时模拟客户端和服务端的网络环境,可以更准确地评估应用程序或系统在真实网络条件下的性能和鲁棒性。 在进行弱网测试时,确保…

傅里叶级数在机器人中的应用(动力学参数辨识)

B站首发&#xff01;草履虫都能看懂的【傅里叶变换】讲解&#xff0c;清华大学李永乐老师教你如何理解傅里叶变换&#xff0c;辨清美颜和变声原理&#xff0c;&#xff01;&#xff01;_哔哩哔哩_bilibiliB站首发&#xff01;草履虫都能看懂的【傅里叶变换】讲解&#xff0c;清…

卷轴模式商城APP开发指南

卷轴模式商城APP的开发是一项融合了技术创新、用户体验优化与商业策略实施的综合性工程。本文将从程序员的角度出发&#xff0c;详细介绍该类型应用的开发流程&#xff0c;涵盖从需求分析到后期维护的各个环节。 一、需求分析 首先&#xff0c;明确APP的核心功能需求&#xff…

AlphaFold3 | 详解 AlphaFold3 的模型结构及其在不同类型的预测实验中的表现

Jumper 本文将介绍 24 年 5 月发布的 Alaphafold3&#xff0c;其以“使用 AlphaFold 3 进行生物分子相互作用的精确结构预测”为标题发表在《nature》上&#xff0c;通讯作者为 Jumper。 Jumper 具有物理、化学、生物和计算方面的丰富背景。Jumper 本科学的是物理和数学&#…

【Linux实践】实验四:Shell实用功能及文件权限

【Linux实践】实验四&#xff1a;Shell实用功能及文件权限 实验目的实验内容实验步骤及结果1. 别名2. 输出和重定向3. 分页显示4. 权限&#xff08;续&#xff09;① 文件/目录管理② 用户管理③ 组管理 5. 链接 实验目的 1.掌握LINUX中Shell的实用功能&#xff0c;命令行自动…

【JavaEE精炼宝库】HTTP | HTTPS 协议详解

文章目录 一、HTTP 简介二、HTTP 协议格式&#xff1a;2.1 抓包工具的使用&#xff1a;2.2 HTTP 请求报文格式&#xff1a;2.3 HTTP 响应报文格式&#xff1a;2.4 HTTP 协议格式总结&#xff1a; 三、HTTP 请求详解&#xff1a;3.1 刨析 URL&#xff1a;3.2 方法(method)&#…