如何更新谷歌地图反应路线?

时间:2020-09-22 03:27:03

标签: javascript reactjs google-maps next.js google-maps-react

我有一个坐标数组,如果我在数组中添加另一个坐标,则应该更新地图的路线方向。

这是我在googlemap.js中的代码

/* global google */
import React, { Component } from "react";
import { Map, GoogleApiWrapper } from "google-maps-react";
import "./config";
import Router from 'next/router';


class MapContainer extends React.Component {


  constructor(props) {
    super(props);
    this.handleMapReady = this.handleMapReady.bind(this);
  }

  handleMapReady(mapProps, map) {
    this.calculateAndDisplayRoute(map);
  }
  

calculateAndDisplayRoute(map) {
  const directionsService = new google.maps.DirectionsService();
  const directionsDisplay = new google.maps.DirectionsRenderer();
  directionsDisplay.setMap(map);

  const waypoints = this.props.data.map((item) => {
    return {
      location: { lat: item.lat, lng: item.lng },
      stopover: true,
    };
  });
  const origin = waypoints.shift().location;
  const destination = waypoints.pop().location;

  directionsService.route(
    {
      origin: origin,
      destination: destination,
      waypoints: waypoints,
      travelMode: "DRIVING",
    },
    (response, status) => {
      if (status === "OK") {
        directionsDisplay.setDirections(response);
      } else {
        window.alert("Directions request failed due to " + status);
      }
    }
  );
}
  render() {
   
    return (
      <div className="map-container"  >
        <Map
          google={this.props.google}
          className={"map"}
          zoom={14}
          initialCenter={{
            lat: 14.5995,
            lng: 120.9842,
          }}
          onClick={this.handleMapClick}
          onReady={this.handleMapReady}
        />
      </div>
    );
  }
}

export default GoogleApiWrapper({
  apiKey: "",
  libraries: [],
})(MapContainer);

我有点喜欢这个插件,因为我过去几天都在使用react-google-maps,但是现在不再维护了,这就是为什么我现在使用这个插件。

1 个答案:

答案 0 :(得分:1)

如果您有一个坐标数组,并且想在显示这些坐标的地图中显示方向,则需要将first coordinate设置为start,将last coordinate设置为destinationcoordinates in between成为您的waypoints

然后,一旦在数组中添加了新坐标,就需要在航路点中包含前一个最后一个坐标,并使新添加的坐标成为目的地。

这里是sample code,它显示了我在其中使用Google Place Autocomplete的位置,您可以在其中输入位置,它会提供建议,然后从建议中选择位置后,它将获得其坐标并将坐标推入数组。

请参见下面的代码段:

import React, { Component } from "react";
import { Map, InfoWindow, Marker, GoogleApiWrapper } from "google-maps-react";
import "./style.css";
import "./config";
export class MapContainer extends Component {

  onMapReady = (mapProps, map) => {
    let coords = [];
    let waypoints = [];
    //put data from config file in an array
    {
      places.map((place) => coords.push({ lat: place.lat, lng: place.lng }));
    }

    //instantiate directions service and directions renderer
    const directionsService = new google.maps.DirectionsService();
    const directionsDisplay = new google.maps.DirectionsRenderer();
    //put directions renderer to render in the map
    directionsDisplay.setMap(map);
    //Getting the first coordinate in the array as the start/origin
    let start = { lat: coords[0].lat, lng: coords[0].lng };
    //Getting the last coordinate in the array as the end/destination
    let end = {
      lat: coords[coords.length - 1].lat,
      lng: coords[coords.length - 1].lng,
    };
    
    //putting all the coordinates between the first and last coordinate from the array as the waypoints
    for (let i = 1; i < coords.length - 1; i++) {
      waypoints.push({
        location: { lat: coords[i].lat, lng: coords[i].lng },
        stopover: true,
      });
    }

    // directions requests

    let request = {
      origin: start,
      waypoints: waypoints,
      destination: end,
      travelMode: "DRIVING",
    };
    //show results in the directionsrenderer
    directionsService.route(request, function (result, status) {
      if (status == "OK") {
        directionsDisplay.setDirections(result);
      }
    });

    //setting the autocomplete input
    let card = document.getElementById("pac-card");
    let input = document.getElementById("pac-input");
    map.controls[google.maps.ControlPosition.TOP_RIGHT].push(card);
    let autocomplete = new google.maps.places.Autocomplete(input);

    // Bind the map's bounds (viewport) property to the autocomplete object,
    // so that the autocomplete requests use the current map bounds for the
    // bounds option in the request.
    autocomplete.bindTo("bounds", map);

    // Set the data fields to return when the user selects a place.
    autocomplete.setFields(["address_components", "geometry", "icon", "name"]);

    //listener for the places input
    autocomplete.addListener("place_changed", function () {
      console.log(waypoints);
      let place = autocomplete.getPlace();
      if (!place.geometry) {
        // User entered the name of a Place that was not suggested and
        // pressed the Enter key, or the Place Details request failed.
        window.alert("No details available for input: '" + place.name + "'");
        return;
      }
      
      //Putting the previous last coordinate in the array to be part of the waypoint
      waypoints.push({
        location: {
          lat: coords[coords.length - 1].lat,
          lng: coords[coords.length - 1].lng,
        },
        stopover: true,
      });

      //putting the Place Autocomplete coordinate result in the coords array
      coords.push({
        lat: place.geometry.location.lat(),
        lng: place.geometry.location.lng(),
      });
      //putting the Place Autocomplete coordinate result the value of the end/destination
      end = place.geometry.location;
      
      //changing  request
      request = {
        origin: start,
        waypoints: waypoints,
        destination: end,
        travelMode: "DRIVING",
      };
      //creating new directions request
      directionsService.route(request, function (result, status) {
        if (status == "OK") {
          directionsDisplay.setDirections(result);
        }
      });
    });
  };


  render() {
    //if (!this.props.loaded) return <div>Loading...</div>;

    return (
      <div>
        <Map
          className="map"
          initialCenter={{ lat: 14.6091, lng: 121.0223 }}
          google={this.props.google}
          onClick={this.onMapClicked}
          onReady={this.onMapReady}
          style={{ height: "100%", position: "relative", width: "100%" }}
          zoom={8}
        ></Map>
        <div className="pac-card" id="pac-card">
          <div>
            <div id="title">Add new point</div>

            <div id="pac-container">
              <input
                id="pac-input"
                type="text"
                placeholder="Enter a location"
              />
            </div>
          </div>
        </div>
        <div style={{ width: 500, height: 500 }} id={this.props.id} />
        <div id="infowindow-content">
          <img src="" width="16" height="16" id="place-icon" />
          <span id="place-name" className="title"></span>
          <br />
          <span id="place-address"></span>
          <br />
          <span id="place-coord"></span>
        </div>
      </div>
    );
  }
}
export default GoogleApiWrapper({
  apiKey: "YOUR_API_KEY",
  version: "3.40",
})(MapContainer);