Ionic 3中如何利用Google Distance Matrix API计算分店距离与时长
我来帮你搞定这个需求!结合你的Ionic项目结构,我们可以分三步实现:先在Provider里封装Google Distance Matrix API的调用逻辑,然后在Branches页面获取用户当前位置并请求行程数据,最后把计算好的距离和时长渲染到页面上。具体代码和步骤如下:
解决方案:计算并展示分店距离与行程时长
1. 完善TravelDetailsProvider的API调用逻辑
把Google Distance Matrix API的请求逻辑封装在Provider里,方便页面调用和复用:
// travel-details.ts import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { map } from 'rxjs/operators'; @Injectable() export class TravelDetailsProvider { // 替换成你自己的Google Distance Matrix API密钥 private apiKey = 'YOUR_GOOGLE_API_KEY'; private apiUrl = 'https://maps.googleapis.com/maps/api/distancematrix/json'; constructor(public http: HttpClient) {} /** * 获取当前位置到所有分店的行程详情 * @param currentLat 当前位置纬度 * @param currentLng 当前位置经度 * @param branches 分店列表(每个分店需包含lat、lng属性) */ getTravelDetails(currentLat: number, currentLng: number, branches: any[]) { // 拼接所有分店经纬度为API要求的格式:"lat1,lng1|lat2,lng2|..." const destinations = branches.map(branch => `${branch.lat},${branch.lng}`).join('|'); const origins = `${currentLat},${currentLng}`; // 构建请求参数,支持driving/walking/bicycling/transit等出行模式 const params = { origins, destinations, mode: 'driving', key: this.apiKey }; return this.http.get(this.apiUrl, { params }).pipe( map((response: any) => { if (response.status !== 'OK') { throw new Error(`API请求失败:${response.status}`); } // 将行程数据与原分店数据合并 return branches.map((branch, index) => { const element = response.rows[0].elements[index]; return { ...branch, distance: element.distance, // 包含text(如"5 km")和value(米数) duration: element.duration // 包含text(如"10 mins")和value(秒数) }; }); }) ); } }
2. 在Branches页面集成数据获取逻辑
页面里先获取用户当前位置,再调用Provider获取行程数据:
// Branches.ts import { Component } from '@angular/core'; import { IonicPage, NavController, LoadingController, Platform } from 'ionic-angular'; import { TravelDetailsProvider } from '../../providers/travel-details/travel-details'; import { Geolocation } from '@ionic-native/geolocation'; import { ToastController } from 'ionic-angular'; @IonicPage() @Component({ selector: 'page-branches', templateUrl: 'branches.html', }) export class BranchesPage { // 替换成你的原始分店列表(需包含lat、lng属性) branches: any[] = [ { name: '分店A', address: 'XX路XX号', lat: 31.2304, lng: 121.4737 }, { name: '分店B', address: 'YY路YY号', lat: 31.2165, lng: 121.4365 } ]; branchesWithTravelDetails: any[] = []; isLoading = false; constructor( public navCtrl: NavController, private travelDetailsProvider: TravelDetailsProvider, private geolocation: Geolocation, private loadingCtrl: LoadingController, private platform: Platform, private toastCtrl: ToastController ) {} ionViewDidEnter() { this.loadTravelDetails(); } async loadTravelDetails(refresher?: any) { this.isLoading = true; const loader = this.loadingCtrl.create({ content: '正在计算距离...' }); await loader.present(); try { // 等待平台就绪后获取当前位置 await this.platform.ready(); const position = await this.geolocation.getCurrentPosition({ enableHighAccuracy: true, timeout: 10000 }); // 调用Provider获取行程数据 this.travelDetailsProvider.getTravelDetails( position.coords.latitude, position.coords.longitude, this.branches ).subscribe( (data) => { this.branchesWithTravelDetails = data; loader.dismiss(); this.isLoading = false; refresher?.complete(); }, (error) => { this.showToast('获取行程信息失败,请稍后重试'); console.error('API请求错误:', error); loader.dismiss(); this.isLoading = false; refresher?.complete(); } ); } catch (error) { this.showToast('无法获取当前位置,请检查权限设置'); console.error('位置获取错误:', error); loader.dismiss(); this.isLoading = false; refresher?.complete(); } } private showToast(message: string) { const toast = this.toastCtrl.create({ message, duration: 2000, position: 'bottom' }); toast.present(); } }
3. 模板渲染距离与时长
在Branches页面的HTML模板里,把行程数据渲染出来:
<!-- branches.html --> <ion-header> <ion-navbar> <ion-title>分店列表</ion-title> </ion-navbar> </ion-header> <ion-content> <!-- 下拉刷新 --> <ion-refresher (ionRefresh)="loadTravelDetails($event)"> <ion-refresher-content></ion-refresher-content> </ion-refresher> <!-- 加载状态 --> <div *ngIf="isLoading" class="loading-wrap"> <ion-spinner></ion-spinner> <p>正在计算距离...</p> </div> <!-- 分店列表 --> <ion-list *ngIf="!isLoading && branchesWithTravelDetails.length > 0"> <ion-item *ngFor="let branch of branchesWithTravelDetails"> <h2>{{branch.name}}</h2> <p>{{branch.address}}</p> <ion-note item-end> <p>距离: {{branch.distance?.text}}</p> <p>预计时长: {{branch.duration?.text}}</p> </ion-note> </ion-item> </ion-list> <!-- 空状态 --> <div *ngIf="!isLoading && branchesWithTravelDetails.length === 0" class="empty-wrap"> <p>暂无分店数据</p> </div> </ion-content>
关键注意事项
- API密钥配置:一定要替换代码中的
YOUR_GOOGLE_API_KEY为你在Google Cloud平台申请的Distance Matrix API密钥,并确保该API已启用,同时配置好使用限制(如HTTP referrers)保障安全。 - 位置权限:需在项目
config.xml中添加位置权限配置:<plugin name="cordova-plugin-geolocation" spec="^4.1.0" /> - 计费说明:Google Distance Matrix API为付费服务,记得在Google Cloud平台监控使用量,避免超出预算。
内容的提问来源于stack exchange,提问作者user538578964
相关产品推荐
相关产品推荐

