DEV Community

Arif Nurdian
Arif Nurdian

Posted on

How to find the closest destination from one origin to multiple destination options using Google Maps

To find the closest destination from one origin to multiple destination options using Google Maps, you should use the Google Distance Matrix API.

Here’s a complete guide using Next.js + @react-google-maps/api to find the nearest destination:

Overview:

  • Use the Distance Matrix API to get travel distances between one origin and multiple destinations.
  • Compare the distances and pick the closest one.

Step-by-step Implementation:

1. Enable Distance Matrix API

Go to: https://console.cloud.google.com/apis/library
Search for Distance Matrix API, and click Enable.

2. Add destinations list

For example:

const destinations = [
  { name: 'Location A', address: 'Jl. Sudirman, Jakarta' },
  { name: 'Location B', address: 'Jl. Thamrin, Jakarta' },
  { name: 'Location C', address: 'Jl. Merdeka, Jakarta' },
];
Enter fullscreen mode Exit fullscreen mode

3. Code Sample in React (with Next.js)

'use client';

import React, { useRef, useState } from 'react';
import { useJsApiLoader, Autocomplete } from '@react-google-maps/api';

const libraries = ['places'];

export default function FindClosestLocation() {
  const { isLoaded } = useJsApiLoader({
    googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY,
    libraries,
  });

  const originRef = useRef();
  const [closest, setClosest] = useState(null);
  const [loading, setLoading] = useState(false);

  const destinations = [
    { name: 'Location A', address: 'Jl. Sudirman, Jakarta' },
    { name: 'Location B', address: 'Jl. Thamrin, Jakarta' },
    { name: 'Location C', address: 'Jl. Merdeka, Jakarta' },
  ];

  const findClosest = () => {
    const origin = originRef.current?.value;
    if (!origin) return alert('Please enter an origin');

    const service = new window.google.maps.DistanceMatrixService();

    setLoading(true);
    service.getDistanceMatrix(
      {
        origins: [origin],
        destinations: destinations.map((d) => d.address),
        travelMode: window.google.maps.TravelMode.DRIVING,
        unitSystem: window.google.maps.UnitSystem.METRIC,
      },
      (response, status) => {
        setLoading(false);
        if (status !== 'OK') return alert('Error: ' + status);

        const distances = response.rows[0].elements;

        let minIndex = 0;
        for (let i = 1; i < distances.length; i++) {
          if (distances[i].distance.value < distances[minIndex].distance.value) {
            minIndex = i;
          }
        }

        setClosest({
          destination: destinations[minIndex],
          distance: distances[minIndex].distance.text,
          duration: distances[minIndex].duration.text,
        });
      }
    );
  };

  if (!isLoaded) return <p>Loading...</p>;

  return (
    <div>
      <h2>Find Closest Location</h2>

      <Autocomplete>
        <input
          type="text"
          ref={originRef}
          placeholder="Enter your origin"
          style={{ width: '300px', padding: '0.5rem', marginRight: '1rem' }}
        />
      </Autocomplete>

      <button onClick={findClosest} disabled={loading} style={{ padding: '0.5rem 1rem' }}>
        {loading ? 'Finding...' : 'Find Closest'}
      </button>

      {closest && (
        <div style={{ marginTop: '1rem' }}>
          <h3>Closest: {closest.destination.name}</h3>
          <p>Address: {closest.destination.address}</p>
          <p>Distance: {closest.distance}</p>
          <p>Duration: {closest.duration}</p>
        </div>
      )}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)