Skip to main content

How to calculate the distance between 2 markers (coordinates) in Google Maps with JavaScript

One of the most recurrent needs of developers when working with Google Maps, is how to obtain the distance between 2 different points on the map, usually defined by Markers or just by plain coordinates, for example given the following code:

var map, markerA, markerB;

// Callback executed when Google Maps script has been loaded
function initMap() {
    // 1. Initialize map
    map = new google.maps.Map(document.getElementById('map'), {
        zoom: 10,
        center: {
            lat: 6.066385702972249, 
            lng: -74.07493328924413
        }
    });

    // 2. Put first marker in Bucaramanga
    markerA = new google.maps.Marker({
        position: {
            lat: 7.099473939079819, 
            lng: -73.10677064354888
        },
        map: map,
        icon: {
            url: 'http://maps.google.com/mapfiles/kml/pushpin/red-pushpin.png'
        },
        title: "Marker A"
    });

    // 3. Put second marker in Bogota
    markerB = new google.maps.Marker({
        position: {
            lat: 4.710993389138328, 
            lng: -74.07209873199463
        },
        map: map,
        icon: {
            url: 'http://maps.google.com/mapfiles/kml/pushpin/red-pushpin.png'
        },
        title: "Marker B"
    });
}   

This will place the 2 markers that appear on the picture of this article. According to Google, we can know that the flight distance from Bucaramanga to Bogota is about 280 Kilometers:

Bucaramanga - Bogota Flight Distance

So we will theorically expect an approximated value from our methods to obtain the distance between the 2 coordinates. In this article, we will show you 2 ways to obtain the distance between 2 markers or coordinates with JavaScript in Google Maps.

A. Using Google Geometry Module

By default, Google provides a custom way to obtain the distance between 2 points on the map using the Geometry library. You need to include this library by appending the &libraries get parameter to the request URL of the Google Maps JS API:

<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY&callback=initMap&libraries=geometry"></script>

Once you are sure that have loaded this library, you can now obtain the distance between 2 coordinates (LatLng object) from Google Maps through the google.maps.geometry.spherical.computeDistanceBetween method. For example, if you want to obtain the distance between 2 markers, you may simply run the following instruction:

// Obtain the distance in meters by the computeDistanceBetween method
// From the Google Maps extension
var distanceInMeters = google.maps.geometry.spherical.computeDistanceBetween(
    markerA.getPosition(),
    markerB.getPosition()
);

// Outputs: Distance in Meters:  286562.7470149898
console.log("Distance in Meters: ", distanceInMeters);

// Outputs: Distance in Kilometers:  286.5627470149898
console.log("Distance in Kilometers: ", (distanceInMeters * 0.001));

As you can see, the computeDistanceBetween method expects as first and second argument a LatLng object. It will compute the distance from those 2 parameters and return the value in meters. Is up to you to change the units mathematically to Miles or Kilometers. Alternatively if you are not using markers, you may provide the mentioned LatLng object as arguments with the direct coordinates:

// Obtain the distance in meters by the computeDistanceBetween method
// From the Google Maps extension using plain coordinates
var distanceInMeters = google.maps.geometry.spherical.computeDistanceBetween(
    new google.maps.LatLng({
        lat: 7.099473939079819, 
        lng: -73.10677064354888
    }),
    new google.maps.LatLng({
        lat: 4.710993389138328, 
        lng: -74.07209873199463
    })
);

// Outputs: Distance in Meters:  286562.7470149898
console.log("Distance in Meters: ", distanceInMeters);

// Outputs: Distance in Kilometers:  286.5627470149898
console.log("Distance in Kilometers: ", (distanceInMeters * 0.001));

B. Using the Haversine formula

If instead of relying on Google Maps, you can calculate the same distance based on the Haversine Formula, an important equation used in navigation, this provides great-circle distances between two points on a sphere from their longitudes and latitudes. It is a special case of a more general formula in spherical trigonometry, the law of haversines, relating the sides and angles of spherical "triangles".

To start, include the 2 following functions in your code:

/**
 * Converts degrees to radians.
 * 
 * @param degrees Number of degrees.
 */
function degreesToRadians(degrees){
    return degrees * Math.PI / 180;
}

/**
 * Returns the distance between 2 points of coordinates in Google Maps
 * 
 * @see https://stackoverflow.com/a/1502821/4241030
 * @param lat1 Latitude of the point A
 * @param lng1 Longitude of the point A
 * @param lat2 Latitude of the point B
 * @param lng2 Longitude of the point B
 */
function getDistanceBetweenPoints(lat1, lng1, lat2, lng2){
    // The radius of the planet earth in meters
    let R = 6378137;
    let dLat = degreesToRadians(lat2 - lat1);
    let dLong = degreesToRadians(lng2 - lng1);
    let a = Math.sin(dLat / 2)
            *
            Math.sin(dLat / 2) 
            +
            Math.cos(degreesToRadians(lat1)) 
            * 
            Math.cos(degreesToRadians(lat1)) 
            *
            Math.sin(dLong / 2) 
            * 
            Math.sin(dLong / 2);

    let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    let distance = R * c;

    return distance;
}

The first function allows you to convert a degree into radians, necessary in the function of interest, the getDistanceBetweenPoints method. In this case, with a slightly modification from the original snippet of RosettaCode. The function receives four arguments that correspond respectively to the latitude and longitude values of both points. This solution doesn't rely on Google Maps so it can be used in other projects as well:

// Obtain the distance in meters using the haversine formula
var distanceInMeters = getDistanceBetweenPoints(
    // LatA
    7.099473939079819,
    // LongA
    -73.10677064354888,
    // LatB
    4.710993389138328,
    // LongB
    -74.07209873199463
);

// Outputs: Distance in Meters:  286476.96153465303
console.log("Distance in Meters: ", distanceInMeters);

// Outputs: Distance in Kilometers:  286.476961534653
console.log("Distance in Kilometers: ", (distanceInMeters * 0.001));

Happy coding !

Comments

Popular posts from this blog

How to use Ngx-Charts in Angular ?

Charts helps us to visualize large amount of data in an easy to understand and interactive way. This helps businesses to grow more by taking important decisions from the data. For example, e-commerce can have charts or reports for product sales, with various categories like product type, year, etc. In angular, we have various charting libraries to create charts.  Ngx-charts  is one of them. Check out the list of  best angular chart libraries .  In this article, we will see data visualization with ngx-charts and how to use ngx-charts in angular application ? We will see, How to install ngx-charts in angular ? Create a vertical bar chart Create a pie chart, advanced pie chart and pie chart grid Introduction ngx-charts  is an open-source and declarative charting framework for angular2+. It is maintained by  Swimlane . It is using Angular to render and animate the SVG elements with all of its binding and speed goodness and uses d3 for the excellent math functio...

Understand Angular’s forRoot and forChild

  forRoot   /   forChild   is a pattern for singleton services that most of us know from routing. Routing is actually the main use case for it and as it is not commonly used outside of it, I wouldn’t be surprised if most Angular developers haven’t given it a second thought. However, as the official Angular documentation puts it: “Understanding how  forRoot()  works to make sure a service is a singleton will inform your development at a deeper level.” So let’s go. Providers & Injectors Angular comes with a dependency injection (DI) mechanism. When a component depends on a service, you don’t manually create an instance of the service. You  inject  the service and the dependency injection system takes care of providing an instance. import { Component, OnInit } from '@angular/core'; import { TestService } from 'src/app/services/test.service'; @Component({ selector: 'app-test', templateUrl: './test.component.html', styleUrls: ['./test.compon...

How to solve Puppeteer TimeoutError: Navigation timeout of 30000 ms exceeded

During the automation of multiple tasks on my job and personal projects, i decided to move on  Puppeteer  instead of the old school PhantomJS. One of the most usual problems with pages that contain a lot of content, because of the ads, images etc. is the load time, an exception is thrown (specifically the TimeoutError) after a page takes more than 30000ms (30 seconds) to load totally. To solve this problem, you will have 2 options, either to increase this timeout in the configuration or remove it at all. Personally, i prefer to remove the limit as i know that the pages that i work with will end up loading someday. In this article, i'll explain you briefly 2 ways to bypass this limitation. A. Globally on the tab The option that i prefer, as i browse multiple pages in the same tab, is to remove the timeout limit on the tab that i use to browse. For example, to remove the limit you should add: await page . setDefaultNavigationTimeout ( 0 ) ;  COPY SNIPPET The setDefaultNav...