javascriptreactjsgoogle-mapsnext.jsgoogle-maps-react

How to update google-maps-react direction route?


I have array of coordinates, if i add another coordinate in array the route direction of the map should be updated.

this is my code in 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);

Im kinda new in this plugin, because im using react-google-maps in the past few days but its not being maintained anymore thats why im using this plugin for now.


Solution

  • If you have an array of coordinates and would like to show the directions in the map that shows these coordinates, you need to set the first coordinate as your start , the last coordinate as the destination and the coordinates in between to be your waypoints.

    Then once you will add a new coordinate in the array, you need to include the previous last coordinate in your waypoint and make the newly added coordinate as the destination.

    Here is a sample code that shows this where I use Google Place Autocomplete where you can input a place and it will provide suggestion then once you choose a place from the suggestion it will get it's coordinate andpush the coordinate in the array.

    Please see the code snippet below:

    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);