目录

Map Kit地图服务如何设置我的位置图标实时指向当前设备移动方向

问题现象

Map Kit地图中,我的位置当前可以通过设置mapCommon.MyLocationDisplayType.FOLLOW_ROTATE,实现我的位置图标实时指向设备旋转方向。

如何实现我的位置图标实时指向设备的移动方向,比如在跑步场景,我的位置实时指向跑步的方向。

背景知识

解决方案

前提条件:

  1. 设置我的位置图标自定义样式和移动效果,此方案场景,需设置displayType参数为mapCommon.MyLocationDisplayType.FOLLOW(我的位置图标不跟随或设备方向旋转)。
    let style: mapCommon.MyLocationStyle = {
      anchorU: 0.5,
      anchorV: 0.5,
      icon: $r('app.media.startIcon'), // 此处替换为自定义的我的位置图标
      displayType: mapCommon.MyLocationDisplayType.FOLLOW
    };
    await this.mapController.setMyLocationStyle(style);
    this.mapController.setMyLocationEnabled(true);
  2. 通过geoLocationManager.on('locationChange')监听当前设备的位置信息Location,其中包括设备的移动方向信息(direction)。在监听回调中通过setMyLocation接口设置地图上我的位置图标的位置信息,其中包括显示我的位置图标方向为direction设备移动方向。
    let requestInfo: geoLocationManager.LocationRequest = {
      'priority': geoLocationManager.LocationRequestPriority.FIRST_FIX,
      'scenario': geoLocationManager.LocationRequestScenario.UNSET,
      'timeInterval': 1,
      'distanceInterval': 0,
      'maxAccuracy': 0
    };
    let locationChange = (location: geoLocationManager.Location): void => {
      location.accuracy = 0;
      this.mapController?.setMyLocation(location);
    };
    try {
      geoLocationManager.on('locationChange', requestInfo, locationChange);
    } catch (err) {
      console.error("errCode:" + err.code + ", message:" + err.message);
    }

direction设备移动方向只有在使用GPS定位时才返回有效值,请在空旷的室外进行测试验证。

完整示例参考如下:

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

@Entry
@Component
struct MyLocationDirection {
  private mapOptions?: mapCommon.MapOptions;
  private callback?: AsyncCallback<map.MapComponentController>;
  private mapController?: map.MapComponentController;

  aboutToAppear(): void {
    // 地图初始化参数,设置地图中心点坐标及层级
    this.mapOptions = {
      position: {
        target: {
          latitude: 39.9,
          longitude: 116.4
        },
        zoom: 10
      }
    };

    // 地图初始化的回调
    this.callback = async (err, mapController) => {
      if (!err) {
        // 获取地图的控制器类,用来操作地图
        this.mapController = mapController;
        let style: mapCommon.MyLocationStyle = {
          anchorU: 0.5,
          anchorV: 0.5,
          icon: $r('app.media.startIcon'), // 此处替换为自定义的我的位置图标
          displayType: mapCommon.MyLocationDisplayType.FOLLOW
        };
        await this.mapController.setMyLocationStyle(style);
        this.mapController.setMyLocationEnabled(true);

        let requestInfo: geoLocationManager.LocationRequest = {
          'priority': geoLocationManager.LocationRequestPriority.FIRST_FIX,
          'scenario': geoLocationManager.LocationRequestScenario.UNSET,
          'timeInterval': 1,
          'distanceInterval': 0,
          'maxAccuracy': 0
        };
        let locationChange = (location: geoLocationManager.Location): void => {
          location.accuracy = 0;
          this.mapController?.setMyLocation(location);
        };
        try {
          geoLocationManager.on('locationChange', requestInfo, locationChange);
        } catch (err) {
          console.error("errCode:" + err.code + ", message:" + err.message);
        }
      }
    };
  }

  build() {
    Stack() {
      // 调用MapComponent组件初始化地图
      MapComponent({
        mapOptions: this.mapOptions,
        mapCallback: this.callback,
      })
        .width('100%')
        .height('100%');
    }.height('100%')
  }
}