HarmonyOS Next 开发之地图定位功能详解

2025-06-18 14:39:21
110次阅读
0个评论

本文详细讲解如何在 HarmonyOS Next 中集成地图组件、获取设备定位信息、添加标记点及实现基础地图交互功能。教程基于 ArkUI 框架和 @ohos.geolocation 模块,提供代码示例。

首先添加权限 在 module.json5 中添加权限声明:

"requestPermissions": [
  { "name": "ohos.permission.LOCATION" }
]

1. 地图组件初始化

代码实现

// MapComponent.ets
import { Map, MapAttribute, MapContext } from '@ohos.geolocation';
import { Permissions } from '@ohos.abilityAccessCtrl';

@Component
struct MapComponent {
  @State private latitude: number = 39.90469; // 默认北京经纬度
  @State private longitude: number = 116.40717;
  private mapContext: MapContext | null = null;

  // 申请定位权限
  async requestLocationPermission() {
    try {
      const permissions: Array<string> = ['ohos.permission.LOCATION'];
      const result = await Permissions.requestPermissions(permissions);
      if (result.authResults[0] === 0) {
        console.info('定位权限已授权');
      }
    } catch (err) {
      console.error(`权限申请失败: ${err}`);
    }
  }

  // 初始化地图
  aboutToAppear() {
    this.requestLocationPermission();
    this.mapContext = new MapContext('mapId');
  }

  build() {
    Column() {
      Map({
        latitude: this.latitude,
        longitude: this.longitude,
        zoom: 15
      })
        .id('mapId')
        .width('100%')
        .height('80%')
        .onReady(() => {
          console.info('地图加载完成');
        })
    }
    .width('100%')
    .height('100%')
  }
}

2. 实时定位与位置更新

代码实现

// LocationService.ets
import { geolocation } from '@ohos.geolocation';

export class LocationService {
  static getLocation(): Promise<{ latitude: number, longitude: number }> {
    return new Promise((resolve, reject) => {
      geolocation.getCurrentLocation({
        priority: geolocation.LocationRequestPriority.FIRST_FIX,
        timeout: 5000
      }, (err, data) => {
        if (err) {
          reject(err);
          return;
        }
        resolve({
          latitude: data.latitude,
          longitude: data.longitude
        });
      });
    });
  }
}

// 在MapComponent中调用
@Component
struct MapComponent {
  // ... 其他代码 ...

  // 更新位置到地图
  private async updateLocation() {
    try {
      const { latitude, longitude } = await LocationService.getLocation();
      this.latitude = latitude;
      this.longitude = longitude;
      this.mapContext?.moveToLocation({ latitude, longitude });
    } catch (err) {
      console.error(`定位失败: ${err}`);
    }
  }

  build() {
    Column() {
      // ... 地图组件 ...
      Button('获取当前位置')
        .onClick(() => this.updateLocation())
    }
  }
}

3. 添加标记点与信息弹窗

代码实现

// 在MapComponent中添加标记
@Component
struct MapComponent {
  @State private markers: Array<MapAttribute.Marker> = [];

  private addMarker() {
    const marker: MapAttribute.Marker = {
      coordinate: { latitude: this.latitude, longitude: this.longitude },
      title: '当前位置',
      snippet: '设备实时定位点',
      icon: $r('app.media.marker_icon')
    };
    this.markers = [...this.markers, marker];
    this.mapContext?.addMarkers({ markers: [marker] });
  }

  build() {
    Column() {
      // ... 地图组件和按钮 ...
      Button('添加标记')
        .onClick(() => this.addMarker())
    }
  }
}

4. 路线规划(两点间路径绘制)

代码实现

// RouteService.ets
export class RouteService {
  static calculateRoute(start: { lat: number, lng: number }, end: { lat: number, lng: number }) {
    // 模拟路线坐标(实际需调用地图API)
    return [
      { latitude: start.lat, longitude: start.lng },
      { latitude: 39.9100, longitude: 116.4075 },
      { latitude: end.lat, longitude: end.lng }
    ];
  }
}

// 在MapComponent中绘制路径
@Component
struct MapComponent {
  @State private polyline: MapAttribute.Polyline | null = null;

  private drawRoute() {
    const points = RouteService.calculateRoute(
      { lat: 39.90469, lng: 116.40717 },
      { lat: 39.915, lng: 116.404 }
    );
    this.polyline = {
      points,
      color: '#FF0000',
      width: 5
    };
    this.mapContext?.addPolyline({ polyline: this.polyline });
  }

  build() {
    Column() {
      // ... 其他组件 ...
      Button('绘制路线')
        .onClick(() => this.drawRoute())
    }
  }
}

常见问题

  • 定位权限被拒绝:需引导用户在系统设置中手动开启权限。

  • 地图不显示:检查网络连接及地图SDK密钥配置。

  • 坐标偏移:确保使用WGS84坐标系,或调用地图API进行坐标转换。

收藏00

登录 后评论。没有帐号? 注册 一个。