Udara

Software Application

Blog Post

How To Draw Directions Between 2 Points In The Google Maps Using React Js

Google Map Directions
In This tutorial we are going to create an app for drawing directions between two points in google map using react with autocomplete google place suggestions.
What we build Today  :- https://asg.udarax.me/gmapstest/

What is Google Map API?

In simple terms the google map API is a set of package pieces of code that let you quickly and easily include maps on your websites or in your mobile apps. There are so many awesome libraries services included.
Without a doubt, there are various justifications for why you might decide to incorporate Google Maps into your React application, and we’ll be investigating perhaps the most well known one: showing your address.
Topics
  1. Map Integration
  2. Markers
  3. Directions service

Let's Build Google Map App

Step 1 : Create New React app

npx create-react-app my-app
Then
cd my-app

Step 2 : Install Google maps library

npm i @react-google-maps/api
Here is the official documentation for the @react-google-maps/api . you can also check this out. https://react-google-maps-api-docs.netlify.app

Step 3 : Generate google map API key form google

Now we need to create a google maps API key. To do that you have to go to google cloud console. Here is the URL https://console.cloud.google.com/
Follow below video to get the API key from Google.

Steps :

  • Create a new project 
  • Navigate to the credentials page and create new API key
  • Then move to the API services and Enable below services
      1. Maps SDk Javascript
      2. Direction API
      3. Places API
Then navigate to the billings page and create a billing account. This step is essential for getting the API key work. Without the billing step you cant use your API key as expected.

Step 4

Open your project in a code editor. In my case I used vs code. Then select your App.js file from your project’s src folder.

01. Import Libraries

import {
  useJsApiLoader,
  GoogleMap,
  Marker,
  Autocomplete,
  DirectionsRenderer,
} from "@react-google-maps/api";

02. Map Center

Now we have to define a center point for our map. You can use any latitude and longitude values for that. I used my country location for this case.
const center = {
  lat: 7.8731,
  lng: 80.7718,
};

03. Configure the map

Follow the below code snippet to configure the google map in App() function.
const { isLoaded } = useJsApiLoader({
    id: "google-map-script",
    googleMapsApiKey:"YOUR-API-KEY",
});

04. Define some states and Refs

import React,{ useRef, useState } from "react";
const [map, setMap] = useState(null);
const [directionsResponse, setDirectionsResponse] = useState(null);
const originRef = useRef();
const destiantionRef = useRef();

05. Render Map with marker

<GoogleMap
    center={center}
    zoom={5}
    mapContainerStyle={{ width: "100%", height: "100vh" }}
    options={{
      zoomControl: false,
      streetViewControl: false,
      mapTypeControl: false,
      fullscreenControl: false,
    }}
    onLoad={(map) => setMap(map)}
>
    <Marker position={center} />
</GoogleMap>

06. Create Option View

Google Map Directions
You can follow the code below to create an option view. I also used bootstrap for styling the view ( here is the official documentation for the bootstrap https://getbootstrap.com/)
Put the CDN scripts into head tag in index.html file ( Located in the public folder)
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<!-- JavaScript Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
<div className="searchbox">
    <div className="row">
      <div className="col-lg-4">
        <Autocomplete>
          <input
            type="text"
            name="Origin"
            className="form-control"
            placeholder="Origin"
            ref={originRef}
          />
        </Autocomplete>
      </div>
      <div className="col-lg-4">
        <Autocomplete>
          <input
            type="text"
            name="Destication"
            className="form-control"
            placeholder="Destication"
            ref={destiantionRef}
          />
        </Autocomplete>
      </div>
      <div className="col-lg-2">
        <button
          type="submit"
          name="submit"
          className="btn btn-primary"
          onClick={calculateRoute}
        >
          Search
        </button>
      </div>
      <div className="col-lg-2">
        <button
          type="submit"
          name="clear"
          className="btn btn-danger"
          onClick={clearRoute}
        >
          Clear
        </button>
      </div>
    </div>
</div>

App.css

.searchbox{
  width: 50%;
  height: 75px;
  background-color: #fff;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: 50px;
  z-index: 1;
  border-radius: 50px;
  border: 1px solid #000;
  display: grid;
  align-items: center;
  padding: 10px 20px;
}

.locationbox{
  position: absolute;
  right: 50px;
  bottom: 50px;
  z-index: 1;
}
.form-control{
  border-radius: 20px;
}

.roundbox{
  width: 50px;
  height: 50px;
  border-radius: 100%;
  background-color: #fa0;
}

.makethiscenter{
  display: grid;
  align-items: center;
  justify-content: center;
}

.btn{
  width: 100%;
  border-radius: 20px;
}

07. Create Route drawer function

async function calculateRoute() {
    if (originRef.current.value === "" || destiantionRef.current.value === "") {
      return;
    }
    const directionsService = new window.google.maps.DirectionsService();
    const results = await directionsService.route({
      origin: originRef.current.value,
      destination: destiantionRef.current.value,
      travelMode: window.google.maps.TravelMode.DRIVING,
    });
    setDirectionsResponse(results);
}
Now we can render the Route on the map. To do that simply put below snippet into <GoogleMap></GoogleMap> Tag.
{directionsResponse && (
  <DirectionsRenderer directions={directionsResponse} />
)}

08. Clear Route function

function clearRoute() {
    setDirectionsResponse(null);
    originRef.current.value = "";
    destiantionRef.current.value = "";
}
If you followed all the steps, You have a working google maps Route app. Great!. I also Attached the full app.js file and app.css file below.
import { useRef, useState } from "react";
import "./App.css";
import {
  useJsApiLoader,
  GoogleMap,
  Marker,
  Autocomplete,
  DirectionsRenderer,
} from "@react-google-maps/api";

const center = {
  lat: 7.8731,
  lng: 80.7718,
};

function App() {
  const { isLoaded } = useJsApiLoader({
    id: "google-map-script",
    googleMapsApiKey: "YOUR-API-KEY",
  });

  const [map, setMap] = useState(null);
  const [directionsResponse, setDirectionsResponse] = useState(null);

  const originRef = useRef();
  const destiantionRef = useRef();

  async function calculateRoute() {
    if (originRef.current.value === "" || destiantionRef.current.value === "") {
      return;
    }
    const directionsService = new window.google.maps.DirectionsService();
    const results = await directionsService.route({
      origin: originRef.current.value,
      destination: destiantionRef.current.value,
      travelMode: window.google.maps.TravelMode.DRIVING,
    });
    setDirectionsResponse(results);
  }

  function clearRoute() {
    setDirectionsResponse(null);
    originRef.current.value = "";
    destiantionRef.current.value = "";
  }

  return isLoaded ? (
    <>
      <div className="searchbox">
        <div className="row">
          <div className="col-lg-4">
            <Autocomplete>
              <input
                type="text"
                name="Origin"
                className="form-control"
                placeholder="Origin"
                ref={originRef}
              />
            </Autocomplete>
          </div>
          <div className="col-lg-4">
            <Autocomplete>
              <input
                type="text"
                name="Destication"
                className="form-control"
                placeholder="Destication"
                ref={destiantionRef}
              />
            </Autocomplete>
          </div>
          <div className="col-lg-2">
            <button
              type="submit"
              name="submit"
              className="btn btn-primary"
              onClick={calculateRoute}
            >
              Search
            </button>
          </div>
          <div className="col-lg-2">
            <button
              type="submit"
              name="clear"
              className="btn btn-danger"
              onClick={clearRoute}
            >
              Clear
            </button>
          </div>
        </div>
      </div>
      <GoogleMap
        center={center}
        zoom={5}
        mapContainerStyle={{ width: "100%", height: "100vh" }}
        options={{
          zoomControl: false,
          streetViewControl: false,
          mapTypeControl: false,
          fullscreenControl: false,
        }}
        onLoad={(map) => setMap(map)}
      >
        <Marker position={center} />
        {directionsResponse && (
          <DirectionsRenderer directions={directionsResponse} />
        )}
      </GoogleMap>
    </>
  ) : (
    <></>
  );
}

export default App;
.searchbox{
  width: 50%;
  height: 75px;
  background-color: #fff;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: 50px;
  z-index: 1;
  border-radius: 50px;
  border: 1px solid #000;
  display: grid;
  align-items: center;
  padding: 10px 20px;
}

.locationbox{
  position: absolute;
  right: 50px;
  bottom: 50px;
  z-index: 1;
}
.form-control{
  border-radius: 20px;
}

.roundbox{
  width: 50px;
  height: 50px;
  border-radius: 100%;
  background-color: #fa0;
}

.makethiscenter{
  display: grid;
  align-items: center;
  justify-content: center;
}

.btn{
  width: 100%;
  border-radius: 20px;
}
Ask any question that you have in the contact section. Thank you!