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

【HarmonyOS实战】 MapKit地图接入:从初始化到显示完整地图

文章目录

    • 前言
    • 一、MapKit 的核心类
    • 二、声明相关变量
    • 三、初始化 mapOptions
      • 3.1 zoom 缩放级别
      • 3.2 mapType 地图类型
      • 3.3 myLocationControlsEnabled
    • 四、初始化回调(Callback)
    • 五、在 build() 里放置 MapComponent
    • 六、setMyLocationEnabled:显示当前位置
    • 七、地图事件监听
      • 7.1 监听"我的位置"按钮点击
      • 7.2 监听 Marker 点击
    • 八、MapKit 事件类型
    • 九、完整流程图
    • 总结

前言

"附近加油站"的核心功能是地图,地图来自华为MapKit。MapKit 是华为提供的地图能力套件,类似高德地图 SDK 或 Google Maps SDK,但深度集成在 HarmonyOS 里。

这篇文章从头讲 MapKit 的接入流程,把GasStationPage.ets里地图相关的代码全部讲清楚。

项目预览

一、MapKit 的核心类

使用 MapKit 需要了解三个核心对象:

对象作用
MapComponent地图 UI 组件,嵌入到build()里显示地图
mapCommon.MapOptions地图初始化配置(中心点、缩放级别、地图类型等)
map.MapComponentController地图控制器,控制地图行为(移动、添加标记、监听事件)

三者的关系:

MapOptions(配置参数) ↓ 传给 MapComponent(UI显示) ↓ 通过 callback 返回 MapComponentController(控制器) ↓ 用于 添加标记、移动镜头、监听点击...

二、声明相关变量

// GasStationPage.ets@Componentstruct GasStationPage{privatemapOptions?:mapCommon.MapOptions;// 地图配置(可选,初始为空)privatemapController?:map.MapComponentController;// 地图控制器(回调里赋值)privatecallback?:AsyncCallback<map.MapComponentController>;// 初始化回调}

这三个属性都是private(私有的),只在组件内部使用。都带?表示可选,初始值为undefined,在init()方法里初始化。

三、初始化 mapOptions

asyncinit():Promise<void>{// 配置地图初始化选项this.mapOptions={position:{target:{latitude:this.latitude,// 初始中心点纬度(初始为0)longitude:this.longitude,// 初始中心点经度(初始为0)},zoom:16,// 初始缩放级别(1-20,16约等于街道级别)},myLocationControlsEnabled:true,// 显示"我的位置"按钮mapType:mapCommon.MapType.STANDARD,// 地图类型:标准地图};}

3.1 zoom 缩放级别

zoom 值显示范围
1全球视图
5国家/大陆
10城市
15街区
16街道(本项目使用)
20建筑物

3.2 mapType 地图类型

类型说明
STANDARD标准矢量地图(本项目使用)
SATELLITE卫星图
TERRAIN地形图
NONE空白底图

3.3 myLocationControlsEnabled

设为true会在地图右下角显示一个"定位到我的位置"按钮(蓝色圆点按钮),用户点击后地图自动跳到当前位置。

四、初始化回调(Callback)

这是 MapKit 最关键的部分。当地图组件创建完成后,通过回调函数返回MapComponentController

// 定义回调this.callback=async(err,mapController):Promise<void>=>{// 错误处理if(err){Logger.error('testTag',`init fail, code:${err.code}, message:${err.message}`);return;}// 获取到控制器,保存下来this.mapController=mapController;// 从这里开始,可以操作地图了// 1. 开启"我的位置"图层(蓝色小点显示当前位置)this.mapController.setMyLocationEnabled(true);// 2. 监听"我的位置"按钮点击this.mapController.on('myLocationButtonClick',()=>{Logger.info('testTag','Jump to my location');mapUtil.moveToMyLocation(mapController).then(()=>{this.isShow=true;});});// 3. 监听地图标记(Marker)点击this.mapController.on('markerClick',(marker)=>{this.isShow=true;marker.setInfoWindowVisible(true);this.curMarker=marker;this.imageScale=1.5;mapUtil.imageAnimation(marker,this.imageScale);mapUtil.moveToCurrentPosition(marker.getPosition().latitude,marker.getPosition().longitude,mapController);});// 4. 初始化时移动到当前位置mapUtil.moveToMyLocation(mapController);// 5. 获取当前位置坐标this.currentLatitude=(awaitmapUtil.getMyLocation()).latitude;this.currentLongitude=(awaitmapUtil.getMyLocation()).longitude;this.latitude=this.currentLatitude;this.longitude=this.currentLongitude;// 6. 给每个加油站添加地图标记this.stationInfoList.forEach(async(stationItem:StationData)=>{awaitmapUtil.addMapMaker(stationItem.latitude,stationItem.longitude,this.mapControllerasmap.MapComponentController);});};

提示:所有对地图的操作(移动镜头、添加标记、监听事件)都必须在 callback 被调用之后进行,因为此时mapController才准备好了。这是最常见的初学者踩坑点。

五、在 build() 里放置 MapComponent

build(){NavDestination(){Stack(){// 地图组件:占满全屏MapComponent({mapOptions:this.mapOptions,// 传入配置mapCallback:this.callback,// 传入回调(地图就绪时被调用)});// 叠加在地图上的标题栏this.titleBuilder();}.width(Constants.FULL_PERCENT).height(Constants.FULL_PERCENT)// ...}}

MapComponent接受两个参数:

  • mapOptions:地图初始配置
  • mapCallback:地图就绪回调

地图组件渲染完成后,会调用mapCallback,把MapComponentController传给你,你就可以开始操控地图了。

六、setMyLocationEnabled:显示当前位置

this.mapController.setMyLocationEnabled(true);

调用这个方法后,地图上会在用户当前位置显示一个蓝色光晕圆点,实时更新用户位置。

这个功能需要定位权限,所以必须在权限申请成功后才有效(项目在主页进入时就申请了权限,所以这里通常已经有权限了)。

七、地图事件监听

7.1 监听"我的位置"按钮点击

this.mapController.on('myLocationButtonClick',()=>{Logger.info('testTag','Jump to my location');mapUtil.moveToMyLocation(mapController).then(()=>{this.isShow=true;// 显示底部加油站列表});});

用户点击地图右下角的定位按钮,地图镜头自动跳到用户位置,同时显示底部列表。

7.2 监听 Marker 点击

this.mapController.on('markerClick',(marker)=>{this.isShow=true;marker.setInfoWindowVisible(true);// 显示标记的信息窗口this.curMarker=marker;// 记录当前点击的标记this.imageScale=1.5;// 放大比例mapUtil.imageAnimation(marker,this.imageScale);// 播放放大动画mapUtil.moveToCurrentPosition(marker.getPosition().latitude,marker.getPosition().longitude,mapController);});

用户点击地图上的加油站标记时:

  1. 显示底部列表(isShow = true
  2. 显示标记的信息窗口
  3. 记录当前标记(用于后续取消动画)
  4. 播放标记放大动画(视觉反馈)
  5. 地图镜头移动到该标记位置

八、MapKit 事件类型

mapController.on(event, callback)支持的常用事件:

事件触发时机
markerClick点击 Marker 标记
mapClick点击地图空白区域
myLocationButtonClick点击"我的位置"按钮
cameraChange地图镜头位置改变
cameraChangeFinish地图镜头停止移动
mapLoad地图底图加载完成

九、完整流程图

onWillAppear() └─> init() ├─> STATION_LIST → stationInfoList ├─> 创建 mapOptions(初始配置) └─> 创建 callback(等待地图就绪) MapComponent 渲染 └─> 地图就绪,调用 callback(null, mapController) ├─> 保存 mapController ├─> setMyLocationEnabled(true) // 显示位置蓝点 ├─> on('myLocationButtonClick') // 监听定位按钮 ├─> on('markerClick') // 监听标记点击 ├─> moveToMyLocation() // 定位到当前位置 ├─> getMyLocation() // 获取坐标(用于距离计算) └─> forEach → addMapMaker() // 为每个加油站添加标记

总结

MapKit 接入的核心流程:

  1. 声明变量mapOptionsmapControllercallback
  2. 配置 mapOptions:设置初始位置、缩放级别、地图类型
  3. 定义 callback:地图就绪后获取 controller,做所有初始化操作
  4. 放置 MapComponent:传入 options 和 callback
  5. 在 callback 里操控地图:监听事件、移动镜头、添加标记

下一篇讲坐标系转换——WGS84(GPS坐标)和 GCJ02(国内地图坐标)有什么区别,为什么需要转换。

http://www.zskr.cn/news/1468620.html

相关文章:

  • 2026北京名表回收推荐|五大商家综合测评,禹竞名奢汇稳居行业榜首 - 奢侈品交易观察员
  • 告别JConsole连接烦恼:手把手教你用代码和Zabbix/Grafana集成TongWeb7的JMX监控数据
  • 2026地坪漆厂家深度解析:耐迪斯与9大主流品牌选型指南 - 温茶叙旧
  • VMware Workstation Pro磁盘空间救星:手把手教你用克隆和OVF导出‘重置’臃肿虚拟机
  • 隔壁的美艳人妻 下载2026最新 无马赛克纯绿版
  • FPGA图像采集显示系统:Verilog实现与SDRAM控制器设计
  • 哪些 AI 工具真的能帮你写好毕业论文?【亲测 9 款】低查重与写作效率如何兼得?
  • 2026年黑龙江省CPPM考试最新全攻略:科目题型、通过率、备考重点及官方双认证报考机构推荐 - 众智商学院课程中心
  • 炉石传说HsMod:55个隐藏功能全面解锁,彻底改变你的游戏体验
  • 2026年企业级智能体自动化选型与技术路径全景盘点
  • NoFences桌面分区管理工具:免费开源的高效桌面整理方案
  • 避坑指南:用Blastp/Hmmer找结构域时,为什么你的结果和文献对不上?聊聊Pfam在线验证的那些事儿
  • 宁波钻戒旧饰回收靠谱之选|正规资质齐全,快速结算不拖沓 - 奢侈品回收测评
  • 2026跨平台多模态监测技术全景深度解析
  • 酵母单杂交与双杂交:技术原理与核心区别
  • 2026年辽宁省CPPM考试最新全攻略:科目题型、通过率、备考重点及官方双认证报考机构推荐 - 众智商学院课程中心
  • 告别龟速下载!手把手教你用官方命令制作VS2019企业版离线安装包(附完整功能清单)
  • 大连市有哪些官方授权的CPPM注册职业采购经理培训机构? - 众智商学院课程中心
  • 2026年 工业冷风机厂家推荐排行榜:车间降温/厂房通风/环保空调源头厂商深度解析与选购指南 - 品牌企业推荐师(官方)
  • ICC II库管理进阶:如何用Library Manager高效构建和管理你的CLIBs(含PVT聚合与更新技巧)
  • WorkshopDL:无需Steam客户端,轻松下载1000+游戏创意工坊模组
  • 计算机小程序毕设实战-基于Java+SpringBoot+Vue医疗器械管理系统基于springboot+微信小程序的医疗器械预定小程序【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 如何在Windows上直接安装安卓应用:APK安装器完整指南
  • 告别微信网页版访问限制:wechat-need-web浏览器插件全攻略
  • 别再乱铺铜了!AD2019实心区域开窗与阻焊设置详解(附3D视图对比)
  • 别再被‘奇葩函数’吓到了!用Matlab的dirac函数,5分钟搞懂狄利克雷函数的本质
  • DDrawCompat完整指南:三步让经典Windows游戏在现代系统重生
  • Anthropic Layer Zero:大模型服务架构的去中间层革命
  • 毕业论文是你的“产品”,答辩PPT就是它的“发布会”
  • Arduino简易纸灯制作:从电路原理到创意实践