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