在Google地图上触发折线点击时更改折线颜色

时间:2019-01-22 10:01:13

标签: google-maps google-maps-api-3 ionic3

我在Google Map上有多条折线,并为每条折线添加了“ click”事件处理程序。当我单击地图上的任何折线时,我需要更改特定的折线颜色。

enter image description here

screenshot of map-我为steppolyline设置的颜色是只得到一个彩色的点。附件图片供您参考。

enter image description here-更新的图像。

我尝试了以下代码,但这没有帮助。

// TypeScript

import { Component, ViewChild, ElementRef, NgZone } from '@angular/core';
import { IonicPage } from 'ionic-angular';
import { NavController } from 'ionic-angular';
import { WeatherProvider } from '../../providers/weather/weather';
import { Observable } from 'rxjs/Observable';
import { Geolocation } from '@ionic-native/geolocation';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';

declare var google;

@Component({
  selector: 'page-home',
  templateUrl: 'home.html',
  providers: [WeatherProvider]
})
export class HomePage {
  sourceLocSeleted: boolean;
  destLocSeleted: boolean;
  estimatedDistance: any;
  estimatedTime: any;
  autocompleteItems: any = [];
  autocompleteDestItems: any = [];
  autocomplete: any = {
    query: ''
  };
  destautocomplete: any = {
    destloc: ''
  };

  longitudewatch: any;
  latitudewatch: any;

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

  DataMarker: any;
  mapData: any;
  markerArray: any[];
  stepDisplay: any;
  directionsDisplay: any;

  public weatherList: any = [];
  public weatherData: any = [];

  /*   @ViewChild('map') mapElement: ElementRef;
    map: any; */
  start: any;
  end: any;
  /* res: any;
  directionsService: any; */

  latitude: any;
  longitude: any;

  constructor(public navCtrl: NavController, public weather: WeatherProvider, private geolocation: Geolocation, public zone: NgZone) {
    this.sourceLocSeleted = false;
    this.destLocSeleted = false;
    this.geolocation.getCurrentPosition().then((resp) => {
      this.latitude = resp.coords.latitude;
      this.longitude = resp.coords.longitude;
      console.log("lat ---- " + this.latitude + "log ----- " + this.longitude);

      this.loadMap(this.latitude, this.longitude);
    }).catch((error) => {
      console.log('Error getting location', error);
    });

  }



  loadMap(latitude, longitude) {

    let latLng = new google.maps.LatLng(latitude, longitude);
    console.log("latlng value --" + latLng);

    let mapOptions = {
      center: latLng,
      zoom: 15,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    var geocoder = new google.maps.Geocoder();
    this.map = new google.maps.Map(this.mapElement.nativeElement, mapOptions);

    if (this.autocomplete.query != "" && this.destautocomplete.destloc != "") {
      this.geocodeAddress(geocoder).then(res => {
        /* this.startNavigating(res[0], res[1]); */
        let sourcelat = res[0];
        let sourcelon = res[1];
        this.geocodeDestAddress(geocoder).then(res => {
          this.startNavigating(sourcelat, sourcelon, res[0], res[1]);
        });
      });

    }
  }

  setMarker(posLatLng, address) {
    var marker;
    console.log("orginLatLng -- " + posLatLng);
    marker = new google.maps.Marker({
      position: posLatLng,
      map: this.map
    });

    var infoWindow = new google.maps.InfoWindow({
      content: address
    });

    google.maps.event.addListener(marker, 'click', function () {
      infoWindow.open(this.map, marker);
    });

    console.log("markerlatLng ..... " + posLatLng);
    marker.setPosition(parseFloat(posLatLng));

  }

  sourceLocationSearch(event) {
    this.sourceLocSeleted = true;
    if (this.autocomplete.query == '') {
      this.autocompleteItems = [];
      return;
    }
    try {
      const service = new google.maps.places.AutocompleteService();
      let me = this;
      service.getPlacePredictions({ input: this.autocomplete.query }, function (predictions, status) {

        if (status != google.maps.places.PlacesServiceStatus.OK) {
          console.log("no matches");
          return;
        }

        me.autocompleteItems = [];
        me.zone.run(function () {
          predictions.forEach(function (prediction) {
            me.autocompleteItems.push(prediction.description);
          });
        });
      });
    } catch (e) {
      console.log("e" + e);
    }
  }

  chooseSourceItem(item: any) {
    this.autocomplete.query = item;
    this.sourceLocSeleted = false;
    this.loadMap(this.latitude, this.longitude);
  }


  destinationLocationSearch(event) {
    this.destLocSeleted = true;
    if (this.destautocomplete.destloc == '') {
      this.autocompleteDestItems = [];
      return;
    }
    try {
      const service = new google.maps.places.AutocompleteService();
      let me = this;
      service.getPlacePredictions({ input: this.destautocomplete.destloc }, function (predictions, status) {

        if (status != google.maps.places.PlacesServiceStatus.OK) {
          console.log("no matches");
          return;
        }

        me.autocompleteDestItems = [];
        me.zone.run(function () {
          predictions.forEach(function (prediction) {
            me.autocompleteDestItems.push(prediction.description);
          });
        });
      });
    } catch (e) {
      console.log("e" + e);
    }
  }

  chooseDestItem(item: any) {
    this.destautocomplete.destloc = item;
    this.destLocSeleted = false;
    this.loadMap(this.latitude, this.longitude);
  }



  geocodeAddress(geocoder): Promise<any> {
    return new Promise((resolve, reject) => {
      var address = this.autocomplete.query;
      console.log("address    " + this.autocomplete.query);
      geocoder.geocode({ 'address': address }, function (results, status) {
        if (status === 'OK') {
          console.log("results[0].geometry.location   " + results[0].geometry.location);
          let geometryLat = results[0].geometry.location.lat();
          let geometryLon = results[0].geometry.location.lng();
          resolve([geometryLat, geometryLon]);
          reject("error");
        } else {
          alert('Geocode was not successful for the following reason: ' + status);
        }
      });
    });
  }

  geocodeDestAddress(geocoder): Promise<any> {
    return new Promise((resolve, reject) => {
      var address = this.destautocomplete.destloc;
      console.log("address    " + this.destautocomplete.destloc);
      geocoder.geocode({ 'address': address }, function (results, status) {
        if (status === 'OK') {
          console.log("results[0].geometry.location   " + results[0].geometry.location);
          let geometryDestLat = results[0].geometry.location.lat();
          let geometryDestLon = results[0].geometry.location.lng();
          resolve([geometryDestLat, geometryDestLon]);
          reject("error..");
        } else {
          alert('Geocode was not successful for the following reason: ' + status);
        }
      });
    });
  }


  startNavigating(geometrySourceLat, geometrySourceLon, geometryLat, geometryLon) {

    let directionsService = new google.maps.DirectionsService;
    let directionsDisplay;
    directionsDisplay = new google.maps.DirectionsRenderer({
      suppressPolylines: true,
      suppressMarkers: true
    });


    directionsService.route({

      origin: { lat: geometrySourceLat, lng: geometrySourceLon },
      destination: { lat: geometryLat, lng: geometryLon },
      provideRouteAlternatives: true,
      travelMode: google.maps.TravelMode['DRIVING']
    }, (res, status) => {
      var routeIndexVal;
      if (status == google.maps.DirectionsStatus.OK) {

        directionsDisplay.setDirections(res);
        directionsDisplay.setMap(this.map);
        directionsDisplay.setPanel(this.directionsPanel.nativeElement);
        this.renderDirectionsPolylines(res);

var leg = res.routes[0].legs[0];

        this.setMarker(leg.start_location, leg.start_address);
        this.setMarker(leg.end_location, leg.end_address);

      } else {
        console.warn(status);
      }

    });
  }

  renderDirectionsPolylines(response) {

    let infowindow = new google.maps.InfoWindow();

    let polylineOptions = {
      strokeColor: 'darkgrey',
      strokeOpacity: 1.0,
      strokeWeight: 7
    };
    var polylines = [];

    for (let i = 0; i < polylines.length; i++) {
      polylines[i].setMap(null);
    }

    for (let m = 0, len = response.routes.length; m < len; m++) {
      let count = m;
      var legs = response.routes[m].legs;

      for (let i = 0; i < legs.length; i++) {

        var steps = legs[i].steps;

        for (let j = 0; j < steps.length; j++) {
          var nextSegment = steps[j].path;

          var stepPolyline = new google.maps.Polyline(polylineOptions);
          for (let k = 0; k < nextSegment.length; k++) {
            stepPolyline.getPath().push(nextSegment[k]);
          }

          polylines.push(stepPolyline);

          google.maps.event.addListener(stepPolyline, 'click', function (evt) {

              stepPolyline.setOptions({
                strokeColor: '#0000FF'
              });

          });


          stepPolyline.setMap(this.map);
        }

      }

    }

  }

}


    // HTML 
    <ion-header>
      <ion-navbar>
        <ion-title> Google Maps </ion-title>
      </ion-navbar>
    </ion-header>

    <ion-content no-padding>

      <ion-item>
        <ion-searchbar mode="md" id="sourceId" [(ngModel)]="autocomplete.query" [showCancelButton]="true" placeholder="Enter source Location"
          (ionInput)="sourceLocationSearch()"></ion-searchbar>
      </ion-item>
      <ion-item *ngIf= "sourceLocSeleted">
        <ion-list class="autosuggestion-list">
          <ion-item *ngFor="let sourceitem of autocompleteItems" tappable (click)="chooseSourceItem(sourceitem)">
            <ion-icon item-content name="pin" item-left></ion-icon>{{ sourceitem }}
          </ion-item>
        </ion-list>
      </ion-item>

        <ion-item>
          <ion-searchbar mode="md" id="destId" [(ngModel)]="destautocomplete.destloc" [showCancelButton]="true" placeholder="Enter destination Location"
            (ionInput)="destinationLocationSearch()"></ion-searchbar>
        </ion-item>
        <ion-item *ngIf= "destLocSeleted">
          <ion-list class="autosuggestion-list">
            <ion-item *ngFor="let destitem of autocompleteDestItems" tappable (click)="chooseDestItem(destitem)">
              <ion-icon item-content name="pin" item-left></ion-icon>{{ destitem }}
            </ion-item>
          </ion-list>
        </ion-item>

        <ion-item>
          <ion-label> <b>Estimated Distance </b> <p> {{ estimatedDistance }} </p> </ion-label>
          <ion-label> <b>Estimated Time </b> <p> {{ estimatedTime }} </p> </ion-label>
        </ion-item>

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

      <div #map id="map"></div>
    </ion-content>

2 个答案:

答案 0 :(得分:0)

您可以使用闭包将侦听器添加到每条折线

  var addListenerOnPolyline = function(actLine){

      actLine.addListener('click', function() {
          actLine.setOptions({ strokeColor: '#0000FF' });
      });

   }


  for (let m = 0, len = response.routes.length; m < len; m++) {
    var legs = response.routes[m].legs;

    for (let i = 0; i < legs.length; i++) {

      var steps = legs[i].steps;

      for (let j = 0; j < steps.length; j++) {
        var nextSegment = steps[j].path;

        var stepPolyline = new google.maps.Polyline(polylineOptions);
        for (let k = 0; k < nextSegment.length; k++) {
          stepPolyline.getPath().push(nextSegment[k]);
        }

        polylines.push(stepPolyline);

        addListenerOnPolyline(stepPolyline);

        stepPolyline.setMap(this.map);
      }

    }
  }

答案 1 :(得分:0)

一种选择是在点击侦听器中使用this(指被点击的折线):

google.maps.event.addListener(stepPolyline, 'click', function(evt) {
  this.setOptions({
    strokeColor: '#0000FF'
  });
});

proof of concept fiddle

screenshot of resulting map after clicking polyline

代码段:

function renderDirectionsPolylines(response) {
  let infowindow = new google.maps.InfoWindow();
  let polylineOptions = {
    strokeColor: 'darkgrey',
    strokeOpacity: 1.0,
    strokeWeight: 7
  };
  var polylines = [];
  for (let i = 0; i < polylines.length; i++) {
    polylines[i].setMap(null);
  }
  for (let m = 0, len = response.routes.length; m < len; m++) {
    var legs = response.routes[m].legs;
    for (let i = 0; i < legs.length; i++) {
      var steps = legs[i].steps;
      for (let j = 0; j < steps.length; j++) {
        var nextSegment = steps[j].path;
        var stepPolyline = new google.maps.Polyline(polylineOptions);
        for (let k = 0; k < nextSegment.length; k++) {
          stepPolyline.getPath().push(nextSegment[k]);
        }
        polylines.push(stepPolyline);
        google.maps.event.addListener(stepPolyline, 'click', function(evt) {
          this.setOptions({
            strokeColor: '#0000FF'
          });
        });
        stepPolyline.setMap(this.map);
      }
    }
  }
}
var map;

function initMap() {
  var directionsService = new google.maps.DirectionsService;
  var directionsDisplay = new google.maps.DirectionsRenderer;
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 7,
    center: {
      lat: 41.85,
      lng: -87.65
    }
  });
  directionsDisplay.setMap(map);

  var onChangeHandler = function() {
    calculateAndDisplayRoute(directionsService, directionsDisplay);
  };
  document.getElementById('start').addEventListener('change', onChangeHandler);
  document.getElementById('end').addEventListener('change', onChangeHandler);
  calculateAndDisplayRoute(directionsService, directionsDisplay);
}

function calculateAndDisplayRoute(directionsService, directionsDisplay) {
  directionsService.route({
    origin: document.getElementById('start').value,
    destination: document.getElementById('end').value,
    travelMode: 'DRIVING'
  }, function(response, status) {
    if (status === 'OK') {
      renderDirectionsPolylines(response);
    } else {
      window.alert('Directions request failed due to ' + status);
    }
  });
}
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#map {
  height: 90%;
}
<div id="floating-panel">
  <b>Start: </b>
  <input id="start" value="chicago, il" />
  <b>End: </b>
  <input id="end" value="joplin, mo">
</div>
<div id="map"></div>
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap"></script>