当前位置: 首页 > news >正文

鸿蒙 地图开发:标记(Marker)增加

开发中,标记(Marker)是最常用的功能之一。点标记用来在地图上标记任何位置,例如用户位置、车辆位置、店铺位置等一切带有位置属性的事物。

本文介绍如下:

  • 标记的基本使用:添加标记、修改属性

  • 自定义标记:自定义图标

  • 标记文字控制:文字显隐、文字内容

  • 事件监听:点击、拖拽、长按事件

  • 标记动画:旋转、缩放、平移、透明、图片动画播放

一、标记

Map Kit提供的点标记功能(Marker)封装了大量的触发事件:点击事件、长按事件、拖拽事件。

版本说明

版本新增功能
5.1.1(19)支持控制Marker文字显隐功能
6.0.0(20)支持自定义组件实现Marker图标功能
6.1.1(24)支持监听Marker长按事件

二、核心接口

接口描述
MarkerOptions标记参数
addMarker(options)在地图上添加标记
Marker标记,支持更新和查询相关属性

三、开发步骤

3.1 导入模块

import { MapComponent, mapCommon, map } from '@kit.MapKit'; import { AsyncCallback } from '@kit.BasicServicesKit';

3.2 添加标记

@Entry @Component struct MarkerDemo { private mapOptions?: mapCommon.MapOptions; private mapController?: 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; 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 }; this.marker = await this.mapController.addMarker(markerOptions); } }; } build() { Stack() { MapComponent({ mapOptions: this.mapOptions, mapCallback: this.callback }) }.height('100%') } }

3.3 MarkerOptions参数

参数类型说明
positionLatLng标记位置(纬度、经度)
rotationnumber旋转角度
visibleboolean是否可见
zIndexnumber层级
alphanumber透明度
anchorUnumber锚点U坐标
anchorVnumber锚点V坐标
clickableboolean是否可点击
draggableboolean是否可拖拽
flatboolean是否平贴地图
iconstring自定义图标(rawfile相对路径)
annotationsArray文字标注配置
collisionRuleCollisionRule碰撞规则
titlestring信息窗标题
snippetstring信息窗子标题

3.4 修改标记属性

// 设置标记可拖拽 this.marker.setDraggable(true); // 设置标记锚点 this.marker.setMarkerAnchor(1.0, 1.0);

四、自定义标记

MarkerOptions中将icon属性设置为自定义图标的资源。

let markerOptions: mapCommon.MarkerOptions = { position: { latitude: 31.984410259206815, longitude: 118.76625379397866 }, icon: 'test.png' // 图标存放在resources/rawfile }; this.marker = await this.mapController.addMarker(markerOptions);

五、控制Marker文字显隐

let markerOptions: mapCommon.MarkerOptions = { position: { latitude: 31.984410259206815, longitude: 118.76625379397866 }, annotations: [{ content: "text", // 定义标题内容 fontStyle: 1, strokeWidth: 3, fontSize: 15 }] }; this.marker = await this.mapController.addMarker(markerOptions); // 设置文字隐藏 this.marker.setAnnotationVisible(false); // 查询当前显隐状态 let isAnnotationVisible = this.marker.isAnnotationVisible();

六、碰撞检测

通过设置collisionRule属性,可以设置标记的冲突处理规则。

let markerOptions: mapCommon.MarkerOptions = { position: { latitude: 31.984410259206815, longitude: 118.76625379397866 }, icon: 'icon.png', annotations: [{ content: "Test", fontStyle: 1, strokeWidth: 3, fontSize: 15 }], // 设置碰撞规则为图标和名称都参与碰撞 collisionRule: mapCommon.CollisionRule.ALL, annotationPosition: mapCommon.TextPosition.TOP };

七、事件监听

7.1 标记点击事件

let callback = (marker: map.Marker) => { console.info(`markerClick: ${marker.getId()}`); }; this.mapEventManager.on("markerClick", callback);

7.2 标记拖拽事件

需要先设置标记可拖拽,然后监听拖拽事件。

// 设置标记可拖拽 this.marker.setDraggable(true); // 监听标记开始拖拽 this.mapEventManager.on("markerDragStart", (marker: map.Marker) => { console.info(`markerDragStart: ${marker.getId()}`); }); // 监听标记拖拽过程 this.mapEventManager.on("markerDrag", (marker: map.Marker) => { console.info(`markerDrag: ${marker.getId()}`); }); // 监听标记拖拽结束 this.mapEventManager.on("markerDragEnd", (marker: map.Marker) => { console.info(`markerDragEnd: ${marker.getId()}`); });

7.3 标记长按事件(6.1.1+)

let callback = (markerLong: map.Marker) => { console.info(`markerLongClick: ${markerLong.getId()}`); }; this.mapEventManager.onMarkerLongClick(callback);

八、信息窗

8.1 基础信息窗

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

8.2 自定义信息窗

@Entry @Component struct MarkerDemo { private mapOptions?: mapCommon.MapOptions; private mapController?: map.MapComponentController; aboutToAppear(): void { this.mapOptions = { 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); } }; } @BuilderParam customInfoWindow: ($$: map.MarkerDelegate) => void = this.customInfoWindowBuilder; @Builder customInfoWindowBuilder($$: map.MarkerDelegate) { if ($$.marker) { Text($$.marker.getTitle()) .width("50%") .height(50) .backgroundColor(Color.Green) .textAlign(TextAlign.Center) .fontColor(Color.Black) } } build() { MapComponent({ mapOptions: this.mapOptions, mapCallback: this.callback, customInfoWindow: this.customInfoWindow }) } }

九、标记动画

9.1 动画类型

动画类说明
AlphaAnimation控制透明度的动画
RotateAnimation控制旋转的动画
ScaleAnimation控制缩放的动画
TranslateAnimation控制平移的动画
PlayImageAnimation控制多张图片的动画
AnimationSet动画集合

9.2 旋转动画示例

let markerOptions: mapCommon.MarkerOptions = { position: { latitude: 32.020750, longitude: 118.788765 } }; let marker: map.Marker = await mapController.addMarker(markerOptions); // 构造RotateAnimation对象(0度到270度) 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("animationStart", () => console.info("动画开始")); animation.on("animationEnd", () => console.info("动画结束")); // 设置动画并启动 marker.setAnimation(animation); marker.startAnimation();

9.3 图片动画播放

let images: Array<ResourceStr | image.PixelMap> = [ 'icon/avocado.png', // rawfile目录 'icon/20231027.png', $r('app.media.maps_blue_dot') // base/media目录 ]; 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); marker.setAnimation(animation); marker.startAnimation();

十、自定义组件实现Marker图标(6.0.0+)

@Entry @Component struct MarkerDemo { aboutToAppear(): void { this.callback = async (err, mapController) => { if (!err) { let markerOptions: mapCommon.MarkerOptions = { position: { latitude: 32.120750, longitude: 118.788765 }, iconBuilder: () => { this.renderBuilder(); } // 自定义组件 }; this.marker = await this.mapController?.addMarker(markerOptions); } }; } @Builder renderBuilder() { Stack({ alignContent: Alignment.Center }) { Image($r('app.media.iconbuilder')).syncLoad(true) } .height(50) .width(50) } }
http://www.jsqmd.com/news/927696/

相关文章:

  • BiomedVLP-CXR-BERT-specialized完整指南:从安装到实战应用
  • 2026年悦麓居深度剖析:城区CCRC场景下养老成本与医疗衔接痛点 - 品牌推荐
  • 如何永久保存微信聊天记录?开源工具WeChatMsg的终极备份指南
  • 如何快速部署Dmeta-embedding-zh:免费商用的中文文本嵌入模型完整指南 [特殊字符]
  • 面试官追问的Python‘八股文’,我用一个爬虫项目全讲清楚了(附避坑指南)
  • SY_AICC/gpt2-conversational-retrain模型微调进阶:如何定制化训练行业专用对话模型 [特殊字符]
  • 避坑指南:Matlab双目标定中那些容易出错的细节(棋盘格检测、坐标转换、参数解读)
  • 边缘计算实战:从云边协同到51个场景的落地解析
  • ChatGPT在国际私法实务中的应用场景与风险规避指南
  • JavaEE之多线程
  • Python金融数据分析终极指南:5分钟掌握mootdx通达信接口实战
  • 避开建模‘深坑’:LCL滤波器参数对并网稳定性的影响到底该怎么分析?
  • stsb-xlm-r-multilingual优化策略:提升多语言语义理解性能
  • AI文档管理:从智能分类到自动化提取的7大核心优势
  • 不只是转图片:深入理解BraTs2020的.nii文件结构与Python可视化技巧
  • 从无人机到扫地机:手把手教你为不同移动平台配置ROS REP-105坐标系
  • Granite-3B-Code-Base-2K社区贡献指南:如何参与开源代码模型的发展
  • ALMA-13B-R参数配置详解:如何优化hidden_size与attention_heads提升翻译质量
  • 量子计算模块化架构中的耦合器布局优化技术
  • Instant-NGP 实战:用多分辨率哈希编码,5分钟让你的NeRF训练快100倍
  • 【教学类-160-43】20260524 AI视频培训-练习043“豆包AI视频《三字经》片段(演唱:04ZXY)+豆包图片风格:卡通
  • TRT-LLM深入理解之GPU基础/CTA/Kernel/Tile/算子/Cubin)
  • FOC 电流环PI 速度环PI
  • 数据预处理全流程解析:从EDA到特征工程的系统性方法
  • 一、Java程序的开发步骤
  • Snowflake Arctic-Embed-L OpenMind vs BGE-Large:谁才是检索任务的王者?
  • 如何永久保存微信聊天记录:WeChatMsg完整实战指南与深度解析
  • 基于边缘计算与Cloudflare Workers构建个人新闻聚合系统
  • TSL2591光传感器数据飘忽不定?可能是你的Arduino代码没调好增益和积分时间
  • M1/M2 MacBook 新手避坑指南:从JDK 1.8到MySQL 8.0,一次配好Java开发环境