如何在原生 Google 地图上以英里和公里显示两个标记之间的距离? (科尔多瓦,离子 3)

How can I display distance between two markers in miles and km on native Google Maps? (Cordova, Ionic 3)

如何在 Ionic 原生 google 地图上以英里和公里显示两个标记之间的距离? 我想使用 h3 标签在地图右上角显示数字。

有没有办法显示估计的旅行时间?我需要估计走路和开车的时间。

任何示例代码将不胜感激。

谢谢,

我使用 Google 地图 路线服务 API 来显示两地之间的距离。

首先,安装 Google 地图库:

npm install @types/googlemaps --save-dev

现在转到 node_modules,然后转到 @types,然后在 Google 地图文件夹中添加以下行:

declare module 'googlemaps';

现在我们将使用 Google 地图 JavaScript 库来获取有关地点的信息。所以在 index.html 文件中包含 Google Maps js 文件:

<script src="http://maps.google.com/maps/api/js?key=XXXXX=places"></script>
  • 上面的脚本需要 Google 地图 API 键。按着这些次序:
    • 转到https://console.developers.google.com
    • 创建一个新的 Google 项目并为您的项目取一个合适的名称
    • 创建新项目后,它会将您重定向到 API 部分并单击 Google 地图 JavaScript API
    • 点击启用API。然后单击创建凭据并单击我需要什么凭据?
    • 就是这样。它会给你 Google 地图 API 键

然后安装地理定位插件以访问用户位置:

ionic cordova plugin add cordova-plugin-geolocation
npm install --save @ionic-native/geolocation

现在要在 app.module.ts 文件中导入地理定位插件:

import { Geolocation } from '@ionic-native/geolocation';      
@NgModule({    
     ...   
     providers: [  Geolocation   ]  
     ... })

然后将 Google 地图 class 和地理定位插件导入 home.ts 文件:

import { Geolocation ,GeolocationOptions } from '@ionic-native/geolocation';

import { googlemaps } from 'googlemaps';

现在将以下代码添加到您的 home.ts 文件中:

import { Component, ElementRef, ViewChild } from '@angular/core';
import { NavController, Platform } from 'ionic-angular';
import { Geolocation ,GeolocationOptions ,Geoposition ,PositionError } from '@ionic-native/geolocation';
import { googlemaps } from 'googlemaps';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})


export class HomePage {

  @ViewChild('map') mapElement: ElementRef;
  @ViewChild('directionsPanel') directionsPanel: ElementRef;

  map:any;
  latLng:any;
  markers:any;
  mapOptions:any;

  startService:any;
  autocompleteStart:any;

  endService:any;
  autocompleteEnd:any;

  directionsService = new google.maps.DirectionsService;
  directionsDisplay = new google.maps.DirectionsRenderer;
  start:any;
  end:any;
  travelType:any = 'DRIVING';

  //distance and duration
  distance:any='';
  duration:any='';

  constructor(private geolocation : Geolocation) { }

  ionViewDidLoad() {
    this.loadMap();
    this.startService = new google.maps.places.AutocompleteService();        
    this.autocompleteStart = [];
    this.endService = new google.maps.places.AutocompleteService();        
    this.autocompleteEnd = [];      
    this.start = '';
    this.end = '';
  }

  loadMap(){

    this.geolocation.getCurrentPosition().then((position) => {

      this.latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

      console.log('latLng',this.latLng);

      this.mapOptions = {
        center: this.latLng,
        zoom: 14,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      }   

      this.map = new google.maps.Map(this.mapElement.nativeElement, this.mapOptions);

    }, (err) => {
      alert('err '+err);
    });

  }

/*-----------------------Search Direction--------------------*/

  startSearch() {

    if (this.start == '') {
      this.autocompleteStart = [];
      return;
    }

    let self = this; 

    let config = { 
      input: this.start, 
      componentRestrictions: {  } 
    }

    this.startService.getPlacePredictions(config, function (predictions, status) {
      console.log('modal > getPlacePredictions > status > ', status);
      self.autocompleteStart = [];            
      predictions.forEach(function (prediction) {              
      self.autocompleteStart.push(prediction);
      });
    });

  }

  endSearch() {

    if (this.end == '') {
      this.autocompleteEnd = [];
      return;
    }

    let self = this; 

    let config = { 
      input: this.end, 
      componentRestrictions: {  } 
    }

    this.endService.getPlacePredictions(config, function (predictions, status) {
      console.log('modal > getPlacePredictions > status > ', status);
      self.autocompleteEnd = [];            
      predictions.forEach(function (prediction) {              
        self.autocompleteEnd.push(prediction);
      });
    });
  }

  chooseStart(item){
    console.log('item',item);
    this.start = item.description; 
    this.autocompleteStart = [];
  }

  chooseEnd(item){
    console.log('item',item);
    this.end = item.description;
    this.autocompleteEnd = [];
  }

/*--------------------Get Direction beteen to places-----------------------*/

  getDirections(){

    this.directionsDisplay.setMap(this.map);
    this.directionsDisplay.setPanel(this.directionsPanel.nativeElement);

    this.directionsService.route({
      origin : this.start,
      destination : this.end,
      waypoints: this.wayPoints,
      optimizeWaypoints: true,
      travelMode : this.travelType,
      provideRouteAlternatives: true,
    }, (response, status) => {
        if (status == google.maps.DirectionsStatus.OK) {
         this.directionsDisplay.setDirections(response);
          // Create a new DirectionsRenderer for each route
        for (var i = 0; i < response.routes.length; i++) {
            var dr = new google.maps.DirectionsRenderer();
            dr.setDirections(response);
            // Tell the DirectionsRenderer which route to display
            dr.setRouteIndex(i);
            dr.setMap(this.map);

            // Code ommited to display distance and duration
           let x = i+1;
            // Display the distance:
             this.distance += x +') '+ response.routes[i].legs[0].distance.text +', ' ;
             console.log('distance',this.distance);
            // Display the duration:
            this.duration += x +') '+ response.routes[i].legs[0].duration.text +', ' ;
            console.log('duration',this.duration);
        }

       // this.directionsDisplay.setDirections(response);
        console.log('response:-',response);
      } else {
        alert('Directions request failed due to ' + status);
      }
    });
  }

}

现在将以下代码添加到您的 home.html 文件中:

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Map
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>

<!--====================== For Get Direction ==========================-->

<form align="center">

    <ion-searchbar 
    [(ngModel)]="start" 
    name="start"
    [showCancelButton]="shouldShowCancel" 
    (ionInput)="startSearch()" 
    (ionCancel)="dismiss()"
    placeholder="Starting Places">
    </ion-searchbar>
    <ion-list>
        <ion-item *ngFor="let item of autocompleteStart" (click)="chooseStart(item)">
            {{ item.description }}
        </ion-item>
    </ion-list>


    <ion-searchbar 
    [(ngModel)]="end" 
    name="end"
    [showCancelButton]="shouldShowCancel" 
    (ionInput)="endSearch()" 
    (ionCancel)="dismiss()"
    placeholder="Ending Places">
    </ion-searchbar>
    <ion-list>
        <ion-item *ngFor="let item of autocompleteEnd" (click)="chooseEnd(item)">
            {{ item.description }}
        </ion-item>
    </ion-list>

    <button ion-button round (click)="getDirections()">GO</button>

</form>

<br>
  <div *ngIf="distance && duration">
    <b>Distance :- {{distance}}</b><br>
    <b>Duration :- {{duration}}</b>
  </div>

<br>
    <div #map id="map"></div>

    <ion-card>
        <ion-card-content>
            <div #directionsPanel></div>
        </ion-card-content>
    </ion-card>

</ion-content>