X
    Categories: Angularjs 2

google map directions display in angular 2

Google map directions display in angular 2

Goole map directions display using angular 2 with typescript. Normally google map providing Directions Service in javascript. We need to convert it to for angular 2.
Here you can see how to integrate google map in angular 2 with typescript. Lets see how to display google map directions in angular 2

Step 1 :

Integrate Google Map

Find a tutorial @ http://www.17educations.com/angularjs-2/google-map-api-angular-2-typescript/

Step 2 :

Add direction display tag inside sebm-google-map tag at your template

Eg :  <sebm-google-map-directions [origin]=”origin” [destination]=”destination”></sebm-google-map-directions>

Step 3 :

Create custom Directory to Display Direction.  Here my Directive Name is DirectionsMapDirective.

Step 4 :

Import your Directory and Merge it with declarations in your module file.

Step 5 :

Integrate your directive with components to display your google map directions.

 

Example Source Code:

Custom Directive => DirectionsMapDirective
My directive path is app/map/googlr-map.directive.ts

import {GoogleMapsAPIWrapper}  from 'angular2-google-maps/core';
import { Directive,  Input, Output } from '@angular/core';


declare var google: any;



@Directive({
  selector: 'sebm-google-map-directions'
})
export class DirectionsMapDirective {
  @Input() origin:any ;
  @Input() destination:any;
  @Input() originPlaceId:any;
  @Input() destinationPlaceId:any;
  @Input() waypoints:any;
  @Input() directionsDisplay:any;
  @Input() estimatedTime : any;
  @Input() estimatedDistance : any;
 
  constructor (private gmapsApi: GoogleMapsAPIWrapper) {}
  updateDirections(){
    this.gmapsApi.getNativeMap().then(map => {
              if(!this.originPlaceId || !this.destinationPlaceId ){
                return;
              }
              
              var directionsService = new google.maps.DirectionsService;
              var me = this;
              var latLngA = new google.maps.LatLng({lat: this.origin.latitude, lng: this.origin.longitude });
              var latLngB = new google.maps.LatLng({lat: this.destination.latitude, lng: this.destination.longitude });
              this.directionsDisplay.setMap(map);
              this.directionsDisplay.setOptions({
                polylineOptions: {
                            strokeWeight: 8,
                            strokeOpacity: 0.7,
                            strokeColor:  '#00468c' 
                        }
                });
              this.directionsDisplay.setDirections({routes: []});
              directionsService.route({
                      origin: {placeId : this.originPlaceId },
                      destination: {placeId : this.destinationPlaceId },
                      avoidHighways: true,
                      travelMode: google.maps.DirectionsTravelMode.DRIVING
                      //travelMode: 'DRIVING'
                    }, function(response: any, status: any) {
                                if (status === 'OK') {
                                  me.directionsDisplay.setDirections(response);
                                  map.setZoom(30);
                                  //console.log(me.getcomputeDistance (latLngA, latLngB));
                                  var point = response.routes[ 0 ].legs[ 0 ];
                                  me.estimatedTime = point.duration.text ;
                                  me.estimatedDistance = point.distance.text;
                                  console.log(me.estimatedTime);
                                  console.log( 'Estimated travel time: ' + point.duration.text + ' (' + point.distance.text + ')' );
 
                                } else {
                                  console.log('Directions request failed due to ' + status);
                                }
              });
    });

  }

  private getcomputeDistance(latLngA: any , latLngB: any ) 
  {
    return (google.maps.geometry.spherical.computeDistanceBetween(latLngA, latLngB) / 1000).toFixed(2);
  }
}

Import in your module. app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AgmCoreModule } from "angular2-google-maps/core";
import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms";

import { DirectionsMapDirective } from './map/google-map.directive';

import { AppComponent }  from './app.component';

@NgModule({
  imports:      [ 
  		AgmCoreModule.forRoot({
     		 	apiKey: "************************",
     		 	libraries: ["places"]
    			}),
  		BrowserModule,
  		FormsModule,
  		ReactiveFormsModule
  		],
  declarations: [ AppComponent, DirectionsMapDirective ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

Replace ******* with your map api key @apiKey field

My app.component.ts will be.

import { Component, NgModule, NgZone, OnInit, ViewChild, ElementRef, Directive, Input  } from '@angular/core';
import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms";
import { BrowserModule } from "@angular/platform-browser";
import { AgmCoreModule, MapsAPILoader, GoogleMapsAPIWrapper } from 'angular2-google-maps/core';
import { DirectionsMapDirective } from './map/google-map.directive';

declare var google:any;
declare var jQuery:any;

@Component({
  selector: 'my-app',
   styles: [`
    .sebm-google-map-container {
       height: 300px;
     },
     
  `],
template: `
    <div class="container">
      <h1>Angular 2 Google Map Direction Display</h1>
      <div class="form-group">
        <input placeholder="Enter source location" autocorrect="off" autocapitalize="off" spellcheck="off" type="text" class="form-control" #pickupInput [formControl]="destinationInput">
        <input placeholder="Enter destination" autocorrect="off" autocapitalize="off" spellcheck="off" type="text" class="form-control" #pickupOutput [formControl]="destinationOutput" >
      </div>
       <sebm-google-map [latitude]="latitude" [longitude]="longitude" [scrollwheel]="false" [zoom]="zoom" [styles]="mapCustomStyles">
                <!-- <sebm-google-map-marker [latitude]="latitude" [longitude]="longitude" [iconUrl]="iconurl">
                    <sebm-google-map-info-window>
                        <strong>InfoWindow content</strong>
                    </sebm-google-map-info-window>
                </sebm-google-map-marker> -->
                <sebm-google-map-directions [origin]="origin" [destination]="destination"></sebm-google-map-directions>
              </sebm-google-map>
    </div>
  `,
 providers : [ GoogleMapsAPIWrapper ]
})

export class AppComponent implements OnInit {
    public latitude: number;
    public longitude: number;
    public destinationInput: FormControl;
    public destinationOutput: FormControl;
    public zoom: number;
    public iconurl: string;
    public mapCustomStyles : any;
    public estimatedTime: any;
    public estimatedDistance: any;

    @ViewChild("pickupInput")
    public pickupInputElementRef: ElementRef;

     @ViewChild("pickupOutput")
    public pickupOutputElementRef: ElementRef;

     @ViewChild("scrollMe")
    private scrollContainer: ElementRef;

    @ViewChild(DirectionsMapDirective) vc: DirectionsMapDirective;

    public origin :any ; // its a example aleatory position
    public destination : any; // its a example aleatory position
    constructor(
      private mapsAPILoader: MapsAPILoader,
      private ngZone: NgZone,
      private gmapsApi: GoogleMapsAPIWrapper,
      private _elementRef : ElementRef
    ) {
    }
    
    ngOnInit() {
      //set google maps defaults
      this.zoom = 4;
      this.latitude = 39.8282;
      this.longitude = -98.5795;
      //this.iconurl = '../image/map-icon.png';
      this.iconurl = '../image/map-icon.png';

     // this.mapCustomStyles = this.getMapCusotmStyles();
      //create search FormControl
      this.destinationInput = new FormControl();
      this.destinationOutput = new FormControl();
      //set current position
      this.setCurrentPosition();
      
      //load Places Autocomplete
      this.mapsAPILoader.load().then(() => {
          let autocompleteInput = new google.maps.places.Autocomplete(this.pickupInputElementRef.nativeElement, {
            types: ["address"]
          });

          let autocompleteOutput = new google.maps.places.Autocomplete(this.pickupOutputElementRef.nativeElement, {
            types: ["address"]
          });
        
                 this.setupPlaceChangedListener(autocompleteInput, 'ORG');
                this.setupPlaceChangedListener(autocompleteOutput, 'DES');
      });
    }
    
    private setupPlaceChangedListener(autocomplete: any, mode: any ) {
      autocomplete.addListener("place_changed", () => {
            this.ngZone.run(() => {
              //get the place result
              let place: google.maps.places.PlaceResult = autocomplete.getPlace();
              //verify result
              if (place.geometry === undefined) {
                return;
              }
              if (mode === 'ORG') {
                  this.vc.origin = { longitude: place.geometry.location.lng(), latitude: place.geometry.location.lat() }; 
                  this.vc.originPlaceId = place.place_id;
              } else {
                  this.vc.destination = { longitude: place.geometry.location.lng(), latitude: place.geometry.location.lat() }; // its a example aleatory position
                  this.vc.destinationPlaceId = place.place_id;
              }
  
              if(this.vc.directionsDisplay === undefined){ this.mapsAPILoader.load().then(() => { 
                    this.vc.directionsDisplay = new google.maps.DirectionsRenderer;
                  }); 
            }
          
              //Update the directions
              this.vc.updateDirections();
              this.zoom = 12;
            });

         });

    }

    getDistanceAndDuration(){
      this.estimatedTime = this.vc.estimatedTime;
      this.estimatedDistance = this.vc.estimatedDistance;
    }

    scrollToBottom(): void {
      jQuery('html, body').animate({ scrollTop: jQuery(document).height() }, 3000);
    }
    private setPickUpLocation( place:any ) {
      //verify result
            if (place.geometry === undefined || place.geometry === null) {
              return;
            }
            //set latitude, longitude and zoom
            this.latitude = place.geometry.location.lat();
            this.longitude = place.geometry.location.lng();
            this.zoom = 12;
    }

    private setCurrentPosition() {
      if ("geolocation" in navigator) {
        navigator.geolocation.getCurrentPosition((position) => {
          this.latitude = position.coords.latitude;
          this.longitude = position.coords.longitude;
          this.zoom = 12;
        });
      }
    }

    private getMapCusotmStyles() {
      // Write your Google Map Custom Style Code Here.
    }

}

 

 

Hope it will Help someone also.

You can find more discussions about google map directions at https://github.com/SebastianM/angular2-google-maps/issues/495

Marimuthu:

View Comments

  • Hello, how could you modify the code so that you could also add the origin and destination marker directly from the map

  • Very helpful guide but for the life of me I cannot get my old map to clear when changing the directions. Any ideas?

  • I am facing some issue can you please help me out ?

    Can't bind to 'latitude' since it isn't a known property of 'sebm-google-map'.

  • Excellent guide managed to get this working but having problems getting the estimatedTime and estimatedDistance back from the directive it seems to be a timing issue as this is not calculated until after directionsService.route() but if I console.log the esstimatedTime in my parent component it is undefined. Any ideas

  • Hello. thanks for this tuguide. I just copied your code, but I get error on this code
    let place: google.maps.places.PlaceResult = autocomplete.getPlace();

    it says Cannot find namespace 'google'. is it OK for angular 5?
    i am using angular 5.