Eduardo Luis Santos
Eduardo Luis Santos

Reputation: 496

How to display the route on ReactGoogleMap?

Describe the bug 🐛

Using the Google Maps API I'm getting the directions and I'm creating DirectionsRenderer all looks correct, the map is displayed but the route is not displayed, not sure if this option is not available on GoogleMapReact

To Reproduce 🔍

Steps to reproduce the behavior:

  1. Add the request to get the directions in the constructor
constructor(props: any){
    super(props)
    const DirectionsService = new google.maps.DirectionsService();
    this.state = {};

    DirectionsService.route(
      {
        origin: new google.maps.LatLng(19.5682414, -99.0436029),
        destination: new google.maps.LatLng(19.7682414, -99.0436029),
        travelMode: window.google.maps.TravelMode.DRIVING,
      },
      (result, status) => {
        // console.log("status", status);
        if (status === window.google.maps.DirectionsStatus.OK) {
          this.setState({
            directions: result,
          });
          console.log(result);
        } else {
          console.error(`error fetching directions ${result}`);
        }
      }
    );

image

At this point, the directions are set in the state so let's try to render it.

render() {
    return (
      // Important! Always set the container height explicitly
      <div id="BrainMap" className="schedulerMap  justify-content-md-left">
        <GoogleMapReact
          bootstrapURLKeys={{ key: process.env.REACT_APP_MAPS_API_KEY }}
          defaultCenter={this.initialPosition.center}
          defaultZoom={this.initialPosition.zoom}
        >

          {this.state.directions && (
            <DirectionsRenderer
              directions={this.state.directions}
              options={{
                polylineOptions: {
                  strokeOpacity: 0.4,
                  strokeWeight: 4,
                },
                preserveViewport: true,
                suppressMarkers: true,
              }}
            />
          )}
        </GoogleMapReact>
      </div>
    );
  }

Expected behavior 💭

I expect to see the route displayed on the map.

Other Context

In other examples looks like they are using other GoogleMap Component and other functions with composing, I will like to avoid this.

Code

import React, { Component } from "react";

import GoogleMapReact from "google-map-react";
import { DirectionsRenderer  } from "react-google-maps";

import MapCard from "../commons/MapCard";

import "./Scheduler.css";

type BrainMapState = {
  directions?: any;
}

class BrainMap extends Component {
  state: BrainMapState;
  initialPosition = {
    center: {
      lat: 19.4978,
      lng: -99.1269,
    },
    zoom: 12,
  };

  constructor(props: any){
    super(props)
    const DirectionsService = new google.maps.DirectionsService();
    this.state = {};

    DirectionsService.route(
      {
        origin: new google.maps.LatLng(19.5682414, -99.0436029),
        destination: new google.maps.LatLng(19.7682414, -99.0436029),
        travelMode: window.google.maps.TravelMode.DRIVING,
      },
      (result, status) => {
        // console.log("status", status);
        if (status === window.google.maps.DirectionsStatus.OK) {
          this.setState({
            directions: result,
          });
          console.log(result);
        } else {
          console.error(`error fetching directions ${result}`);
        }
      }
    );

    //const directionsRenderer = new google.maps.DirectionsRenderer();
}

  render() {
    return (
      // Important! Always set the container height explicitly
      <div id="BrainMap" className="schedulerMap  justify-content-md-left">
        <GoogleMapReact
          bootstrapURLKeys={{ key: process.env.REACT_APP_MAPS_API_KEY }}
          defaultCenter={this.initialPosition.center}
          defaultZoom={this.initialPosition.zoom}
        >
          {this.state.directions && (
            <DirectionsRenderer
              directions={this.state.directions}
              options={{
                polylineOptions: {
                  strokeOpacity: 0.4,
                  strokeWeight: 4,
                },
                preserveViewport: true,
                suppressMarkers: true,
              }}
            />
          )}
        </GoogleMapReact>
      </div>
    );
  }
}

export default BrainMap;

Upvotes: 0

Views: 866

Answers (1)

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59328

Since GoogleMapReact library does not support Directions Service API, the following component could be introduced to render directions:

 function DirectionsRenderer(props: {
  map: google.maps.Map | null;
  origin: google.maps.LatLngLiteral;
  destination: google.maps.LatLngLiteral;
}) {
  async function getRoute(
    origin: google.maps.LatLngLiteral,
    destination: google.maps.LatLngLiteral
  ): Promise<google.maps.DirectionsResult> {
    const directionsService = new google.maps.DirectionsService();
    return new Promise(function (resolve, reject) {
      directionsService.route(
        {
          origin: origin,
          destination: destination,
          travelMode: google.maps.TravelMode.DRIVING,
        },
        (result: any, status: google.maps.DirectionsStatus) => {
          if (status === google.maps.DirectionsStatus.OK) {
            resolve(result);
          } else {
            reject(result);
          }
        }
      );
    });
  }

  async function renderRoute() {
    const directions = await getRoute(props.origin, props.destination);
    const directionsRenderer = new google.maps.DirectionsRenderer();
    directionsRenderer.setMap(props.map);
    directionsRenderer.setDirections(directions);
  }

  useEffect(() => {
    renderRoute().catch((err) => {
      console.log(err);
    });
  }, []);

  return null;
}

Usage

function MapWithADirectionsRenderer(props: {
  center: google.maps.LatLngLiteral;
  zoom: number;
}) {
  const [map, setMap] = useState<google.maps.Map | null>(null);

  function handleApiLoaded(mapInstance: google.maps.Map, google: any) {
    setMap(mapInstance);
  }

  return (
    <div style={{ height: "100vh", width: "100%" }}>
      <GoogleMapReact
        bootstrapURLKeys={{ key: "--Google Maps Key goes here--" }}
        defaultCenter={props.center}
        defaultZoom={props.zoom}
        onGoogleApiLoaded={({ map, maps }) => handleApiLoaded(map, maps)}
      >
        {map && (
          <DirectionsRenderer
            map={map}
            origin={{ lat: 40.756795, lng: -73.954298 }}
            destination={{ lat: 41.756795, lng: -78.954298 }}
          />
        )}
      </GoogleMapReact>
    </div>
  );
}

Demo

Note: Google Maps Key needs to be specified

Result

enter image description here

Upvotes: 1

Related Questions