如何用@capacitor实现类似Ola/Uber的实时追踪导航地图
实现基于@capacitor/google-maps的实时位置追踪(仿Ola/Uber)
以下是完整的实现步骤与代码,帮你完成从当前位置到目的地的地图显示与实时追踪功能:
1. 依赖确认
确保已安装必要依赖:
@capacitor/geolocation@capacitor/google-maps
2. 核心实现代码
组件属性定义
先在组件类中声明必要的属性:
import { Component, ElementRef, ViewChild, OnDestroy } from '@angular/core'; import { Geolocation, Position } from '@capacitor/geolocation'; import { GoogleMap, Marker } from '@capacitor/google-maps'; @Component({ selector: 'app-map-tracker', templateUrl: './map-tracker.component.html', styleUrls: ['./map-tracker.component.scss'], }) export class MapTrackerComponent implements OnDestroy { @ViewChild('map') mapRef!: ElementRef<HTMLElement>; newMap!: GoogleMap; userMarker!: Marker; watchId?: string; destination = { lat: 33.7, lng: -118.0 }; // 替换为实际目的地坐标 APIkey = '你的Google Maps API密钥';
初始化地图并定位当前位置
修改createMap方法,初始化时直接定位到用户当前位置并添加标记:
async createMap() { // 获取当前位置 const currentPosition = await Geolocation.getCurrentPosition(); const userCoords = { lat: currentPosition.coords.latitude, lng: currentPosition.coords.longitude }; // 创建地图,以用户当前位置为中心 this.newMap = await GoogleMap.create({ id: 'my-cool-map', element: this.mapRef.nativeElement, apiKey: this.APIkey, config: { center: userCoords, zoom: 15, // 放大到适合查看的级别 }, }); // 添加用户位置标记 this.userMarker = await this.newMap.addMarker({ position: userCoords, title: '你的位置', iconUrl: 'https://cdn-icons-png.flaticon.com/512/1005/1005141.png' // 可选:自定义用户标记图标 }); // 添加目的地标记 await this.newMap.addMarker({ position: this.destination, title: '目的地', iconUrl: 'https://cdn-icons-png.flaticon.com/512/1005/1005142.png' // 可选:自定义目的地标记图标 }); // 启动实时位置监听 this.startLocationTracking(); }
实时位置追踪逻辑
实现startLocationTracking方法,监听位置变化并更新地图与标记:
startLocationTracking() { this.watchId = Geolocation.watchPosition( { enableHighAccuracy: true, // 开启高精度定位 timeout: 10000, maximumAge: 0 }, async (position, err) => { if (err) { console.error('位置监听错误:', err); return; } const newCoords = { lat: position.coords.latitude, lng: position.coords.longitude }; // 更新用户标记位置 await this.userMarker.setPosition(newCoords); // 平滑移动地图中心到新位置 await this.newMap.setCamera({ center: newCoords, zoom: 15, animate: true // 开启动画提升体验 }); // 可选:更新当前位置到目的地的路线 await this.updateRoute(newCoords, this.destination); } ); }
(可选)绘制实时路线
如果需要显示当前位置到目的地的路线,添加updateRoute方法:
async updateRoute(origin: { lat: number; lng: number }, destination: { lat: number; lng: number }) { // 清除之前的路线 await this.newMap.clear(); // 重新添加用户和目的地标记 this.userMarker = await this.newMap.addMarker({ position: origin, title: '你的位置', iconUrl: 'https://cdn-icons-png.flaticon.com/512/1005/1005141.png' }); await this.newMap.addMarker({ position: destination, title: '目的地', iconUrl: 'https://cdn-icons-png.flaticon.com/512/1005/1005142.png' }); // 请求路线数据 const response = await fetch( `https://maps.googleapis.com/maps/api/directions/json?origin=${origin.lat},${origin.lng}&destination=${destination.lat},${destination.lng}&key=${this.APIkey}` ); const data = await response.json(); if (data.routes.length > 0) { // 解析路线坐标(需安装@mapbox/polyline库:npm install @mapbox/polyline) import('@mapbox/polyline').then(polyline => { const decodedCoords = polyline.default.decode(data.routes[0].overview_polyline.points).map(coord => ({ lat: coord[0], lng: coord[1] })); // 在地图上绘制路线 this.newMap.addPolyline({ points: decodedCoords, color: '#2196F3', // 路线颜色 width: 5 // 路线宽度 }); }); } }
清理资源
页面销毁时停止位置监听,避免内存泄漏:
ngOnDestroy() { if (this.watchId) { Geolocation.clearWatch({ id: this.watchId }); } }
模板代码
在组件模板中添加地图容器:
<div #map style="width: 100%; height: 100vh;"></div>
3. 关键注意事项
- API权限:确保Google Maps API密钥已启用
Maps JavaScript API、Geocoding API和Directions API(若使用路线功能)。 - 定位权限:在
capacitor.config.ts中配置定位权限说明,确保用户授权:import { CapacitorConfig } from '@capacitor/cli'; const config: CapacitorConfig = { appId: 'com.your.app', appName: 'Your App', webDir: 'www', bundledWebRuntime: false, plugins: { Geolocation: { enableHighAccuracy: true, androidBackgroundLocationPermission: '需要访问你的位置以提供实时导航服务', }, }, }; export default config; - 性能优化:若无需实时更新路线,可降低位置监听频率,减少API请求次数。
内容的提问来源于stack exchange,提问作者Calvin Care
相关产品推荐
相关产品推荐

