简体   繁体   中英

Removing directions overlay using angular-google-maps and angular2

Im using an api to populate a map with several markers, my desired functionality is for a user to click a button associated with a marker and it would plot directions from their current location. On the first instance it works perfectly but the current directions plotted just remain when trying to change the coordinates

Im using angular2-google-maps to plot the markers but I had to find a custom directive for directions. I think the problem is that I need to destroy the instance of the directions but using ngIf didnt help. I also tried resetting the instance of the direction in my directive using directionsDisplay.set('directions', null); but that didnt work either

      /* directions.directive.ts */

      import {GoogleMapsAPIWrapper} from '@agm/core/services/google-maps-api-wrapper';
      import { Directive,  Input} from '@angular/core';
      declare var google: any;

      @Directive({
        selector: '<agm-map-directions  [origin]="origin" [destination]="destination" #test></agm-map-directions>'
      })
      export class DirectionsMapDirective {
        @Input() origin;
        @Input() destination;
        constructor (private gmapsApi: GoogleMapsAPIWrapper) {}
        ngOnInit(){
          this.gmapsApi.getNativeMap().then(map => {

                    var directionsService = new google.maps.DirectionsService;
                    var directionsDisplay = new google.maps.DirectionsRenderer;

                      console.log("test");
                    directionsDisplay.setMap(map);
                    directionsService.route({
                            origin: {lat: this.origin.latitude, lng: this.origin.longitude},
                            destination: {lat: this.destination.latitude, lng: this.destination.longitude},
                            waypoints: [],
                            optimizeWaypoints: true,
                            travelMode: 'DRIVING'
                          }, function(response, status) {
                                      if (status === 'OK') {


                                        directionsDisplay.setDirections(response);
                                      } else {
                                        window.alert('Directions request failed due to ' + status);
                                      }
                    });

          });
        }
      }

Here is the html associated with it

    <agm-map [zoom]="13" [latitude]="currentLocation.result.latitude" [longitude]="currentLocation.result.longitude">
        <agm-marker [latitude]="currentLocation.result.latitude" [longitude]="currentLocation.result.latitude"></agm-marker>

        <agm-marker *ngFor="let device of location.ChargeDevice; let i = index" 
                    ngShow="device.SubscriptionRequiredFlag" 
                    [latitude]="convertStringToNumber(device.ChargeDeviceLocation.Latitude)" 
                    [longitude]="convertStringToNumber(device.ChargeDeviceLocation.Longitude)"
                    (markerClick)="clickedMarker(device)">
        </agm-marker>


        <div *ngIf="showDirections" >
            <agm-map-directions  [origin]="origin" [destination]="destination" #test></agm-map-directions>
        </div>
    </agm-map>

I had the same problem as you.

I solved it by creating a global object that holds the instantiation of directionsService and directionsDisplay, to be able to pass those as reference later. ( See javascript pass by reference )

  public directions: any = {
    directionsService: null,
    directionsDisplay: null
  }

Then, I created a function that initialize the map once and I called it within ngOnInit() function:

 constructor(private _gmapsApi: GoogleMapsAPIWrapper) { }

 ngOnInit() {
    this.initalizeMap(this.directions);
  }

  initalizeMap(directions): void {
    this._gmapsApi.getNativeMap().then(map => {
      directions.directionsService = new google.maps.DirectionsService;
      directions.directionsDisplay = new google.maps.DirectionsRenderer;
      directions.directionsDisplay.setMap(map);
      directions.directionsDisplay.addListener('directions_changed', function() {
          this.displayRoute(this.origin, this.destination, directions.directionsService, directions.directionsDisplay);
      });

      this.displayRoute(this.origin, this.destination, directions.directionsService, directions.directionsDisplay);
    })
  }

I added a listener to directionsDisplay to displayRoute whenever a change is made in the directions. The function displayRoute take as parameters origin and destination passed through @Input and references to directionsService and directionsDisplay whose instances I saved in directions object. The waypoints I took are also through @Input.

displayRoute(origin, destination, service, display): void {
  var myWaypoints = [];

  for (var i = 0; i < this.waypoints.length; i++) {
    console.log(this.waypoints[i].markerID);
    console.log(this.waypoints[i].location);
  }

  for (var i = 0; i < this.waypoints.length; i++) {
    myWaypoints.push({
      location: new google.maps.LatLng(this.waypoints[i].location),
      stopover: true
    })
  }

  service.route({
    origin: origin,
    destination: destination,
    waypoints: myWaypoints,
    travelMode: 'WALKING',
    avoidTolls: true
  }, function(response, status) {
    if (status === 'OK') {
      console.log("Route OK.");
      display.setDirections(response);
    } else {
      alert('Could not display directions due to: ' + status);
    }
  });
 }

The last function and the most important is calculateRoute, which I call from the component I injected the service ( Map Component in my case ) whenever I want it to recalculate the route.

  calculateRoute(): void {
    this._gmapsApi.getNativeMap().then(map => {
      this.displayRoute(this.origin, this.destination, this.directions.directionsService, this.directions.directionsDisplay);
    });
  }

Hope it helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM