Gmaps.js Route with Distance

10,102

Solution 1

Breaking this into parts you need to:

  1. Search your form entered addresses and geocode them using the geocoding API.
  2. Use the results from the geocoding to calculate the route.
  3. Pull required data from the route and plot/display

For Geocoding see this example: http://hpneo.github.io/gmaps/examples/geocoding.html

GMaps.geocode({
  address: $('#Start').val(),
  callback: function(results, status) {
    if (status == 'OK') {
      var latlng1 = results[0].geometry.location;
    }
  }
}); //Repeat for destination / end point

Now you have your lat/long points.

You can then take a few approaches to route, but just drawing it can be done like this example: http://hpneo.github.io/gmaps/examples/routes.html

map.drawRoute({
  origin: [latlng1.lat(), latlng1.lng()],
  destination: [latlng2.lat(), latlng2.lng()],
  travelMode: 'driving',
  strokeColor: '#131540',
  strokeOpacity: 0.6,
  strokeWeight: 6
});

If you call getRoutes instead of drawRoute you should get back a DirectionsResult object: https://developers.google.com/maps/documentation/javascript/directions#DirectionsResults . The TransitDetails object contains information on the travel time to the end location in the form of arrival time. Each leg will also contain a duration and distance which you can add up looping through them and access something like:

foreach($directions->routes[0]->legs as $leg) {
    $time+=$leg.duration.value
    $distance+=$leg.distance.value
}

Update:

Was playing with the API - and excuse the nested callbacks - but here is a working example: http://jsfiddle.net/mdares/82Dp2/

jQuery(document).ready(function () {
    var map;
    var latlng1;
    var latlng2;

    GMaps.geocode({
        address: $('#Start').val(),
        callback: function (results, status) {
            if (status == 'OK') {
                latlng1 = results[0].geometry.location;
                GMaps.geocode({
                    address: $('#End').val(),
                    callback: function (results, status) {
                        if (status == 'OK') {
                            latlng2 = results[0].geometry.location;
                            map = new GMaps({
                                div: '#map',
                                lat: latlng1.lat(),
                                lng: latlng1.lng(),
                                zoom: 12
                            });

                            map.drawRoute({
                                origin: [latlng1.lat(), latlng1.lng()],
                                destination: [latlng2.lat(), latlng2.lng()],
                                travelMode: 'driving',
                                strokeColor: '#131540',
                                strokeOpacity: 0.6,
                                strokeWeight: 6
                            });
                            map.getRoutes({
                                origin: [latlng1.lat(), latlng1.lng()],
                                destination: [latlng2.lat(), latlng2.lng()],
                                callback: function (e) {
                                    var time = 0;
                                    var distance = 0;
                                    for (var i=0; i<e[0].legs.length; i++) {
                                        time += e[0].legs[i].duration.value;
                                        distance += e[0].legs[i].distance.value;
                                    }
                                    alert(time + " " + distance);
                                }
                            });

                        }
                    }
                });
            }
        }
    });
});

Solution 2

Well, if you only care about distance between point A. and point B., and not turn-by-turn directions—It should be as simple as taking the coordinates of your two points and calculating the distance.

Example - calculate the distance from the center of New York City to the center of Philadelphia

JS

function distanceFrom(points) {
    var lat1 = points.lat1;
    var radianLat1 = lat1 * (Math.PI / 180);
    var lng1 = points.lng1;
    var radianLng1 = lng1 * (Math.PI / 180);
    var lat2 = points.lat2;
    var radianLat2 = lat2 * (Math.PI / 180);
    var lng2 = points.lng2;
    var radianLng2 = lng2 * (Math.PI / 180);
    var earth_radius = 3959; // or 6371 for kilometers
    var diffLat = (radianLat1 - radianLat2);
    var diffLng = (radianLng1 - radianLng2);
    var sinLat = Math.sin(diffLat / 2);
    var sinLng = Math.sin(diffLng / 2);
    var a = Math.pow(sinLat, 2.0) + Math.cos(radianLat1) * Math.cos(radianLat2) * Math.pow(sinLng, 2.0);
    var distance = earth_radius * 2 * Math.asin(Math.min(1, Math.sqrt(a)));
    return distance.toFixed(3);
}

var distance = distanceFrom({
    // NYC
    'lat1': 40.713955826286046,
    'lng1': -74.00665283203125,
    // Philly
    'lat2': 39.952335,
    'lng2': -75.163789
});

The result is 80.524 miles or 129.583 kilometers.

In the event that you want the user to be able to input city names, zip codes, etc. instead of coordinates, you could use the GMaps library to geocode the addresses first.


Related SO question here

Share:
10,102
Alexander Wigmore
Author by

Alexander Wigmore

Full stack Web developer, designer and digital marketer with skills in IT and most things tech related. Founder of guwii - a full stack design, development and digital marketing agency based in Cardiff, UK (South Wales). SOreadytohelp

Updated on June 14, 2022

Comments

  • Alexander Wigmore
    Alexander Wigmore almost 2 years

    I'm using Gmaps.js api in a little project I'm building.

    Basically to replicate Google Maps functionality I'm looking to get the route & distance from one address to another (can just be input/form fields). I notice this demo, but it requires clicking on the map, and also doesn't show the total distance or drive time?

    Any opinions on best way of parsing 2 addresses from a form, then calculating route and drive time using the gmaps.js api?