简体   繁体   中英

How to fetch duration_in_traffic from distance matrix API

I want to fetch duration_in_traffic from distance matrix API.

It works fine when I access the API Directly through URL

https://maps.googleapis.com/maps/api/distancematrix/json?origins=Boston,MA&destinations=Lexington,MA&departure_time=now&key=MY_KEY

But It does not work from code. here are the things that I tried.

1) Tried to call the API through AJAX from client side JS. getting CORS issue in response

2) Tried to use JS client library

        var base = "https://maps.googleapis.com/maps/api/distancematrix/json?units=metric";
        var source = "&origins=" + element["Origin Name"] + " , " + element["Origin Street"] + " , " + element["Origin City"] + " , " + element["Origin State"] + " , " + element["Origin County"] + " , " + element["Origin Postal"];
        var destination = "&destinations=" + element["Destination Name"] + " , " + element["Destination Street"] + " , " + element["Destination City"] + " , " + element["Destination State"] + " , " + element["Destination County"] + " , " + element["Destination Postal"];
        var key = "&key=MY_KEY";
        var time = "&departure_time=";
        try {
            time += new Date().setHours(24 + parseInt(element["Pickup Time"].split(":")[0]), parseInt(element["Pickup Time"].split(":")[1]), 0, 0);
        }
        catch{
            time += new Date().setHours(0, 0, 0, 0);
        }
        console.log(time);
        var url = base + time + source + destination + key + "&transit_mode=driving";

        var service = new google.maps.DistanceMatrixService();
        service.getDistanceMatrix(
            {
                origins: [source],
                destinations: [destination],
                travelMode: 'DRIVING',
            }, callback);

        if (lastSource != "empty") {
            service.getDistanceMatrix(
                {
                    origins: [lastSource],
                    destinations: [source],
                    travelMode: 'DRIVING',
                }, callback2);
        }

        lastSource = source;

        function callback(response, status) {
            try {
                element["TRIP DISTANCE"] = (parseFloat(response.rows["0"].elements["0"].distance.text.replace(/ km/g, '')) / 1.609).toFixed(2) + " Miles";
                console.log(response.rows["0"].elements["0"].distance.text);
                console.log(element["TRIP DISTANCE"]);
                element["TRIP TRAVEL TIME "] = response.rows["0"].elements["0"].duration.text;
            }
            catch (e) {
                console.log(e);
            }
        }
        function callback2(response, status) {
            try {
                element["ROUTE DISTANCE"] = (parseFloat(response.rows["0"].elements["0"].distance.text.replace(/ km/g, '')) / 1.609).toFixed(2) + " Miles";
                console.log(response.rows["0"].elements["0"].distance.text);
                console.log(element["TRIP DISTANCE"]);
                element["ROUTE TRAVEL TIME"] = response.rows["0"].elements["0"].duration.text;
            }
            catch (e) {
                console.log(e);
            }
        }

It does not return duration_in_traffic. I searched about it and found two different reasons, I donno which one is correct.

First is that duration_in_traffic is not supported by javascript client library, it is only returned if the request is made from server.

Second is that this response is only sent to accounts with premium plan only. I tried to see the procedure to enrolling for premium plan but its not clear. this site here says "The Google Maps Platform Premium Plan is no longer available for sign up or new customers.". what is that supposed to mean. I am currently using google cloud platform free 1 year and 300 dollars trial version.

3) I tried using nodeJS library

 const googleMapsClient = require('@google/maps').createClient({
  key: 'MY_KEY',
  Promise: Promise
});

googleMapsClient.geocode({address: '1600 Amphitheatre Parkway, Mountain View, CA'})
  .asPromise()
  .then((response) => {
    console.log(response.json.results);
  })
  .catch((err) => {
    console.log(err);
  });

and got this response.

    { status: 200,
  headers:
   { 'content-type': 'application/json; charset=UTF-8',
     date: 'Sat, 07 Dec 2019 11:03:05 GMT',
     pragma: 'no-cache',
     expires: 'Fri, 01 Jan 1990 00:00:00 GMT',
     'cache-control': 'no-cache, must-revalidate',
     'access-control-allow-origin': '*',
     server: 'mafe',
     'x-xss-protection': '0',
     'x-frame-options': 'SAMEORIGIN',
     'server-timing': 'gfet4t7; dur=19',
     'alt-svc':
      'quic=":443"; ma=2592000; v="46,43",h3-Q050=":443"; ma=2592000,h3-Q049=":443"; ma=2592000,h3-Q048=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000',
     'accept-ranges': 'none',
     vary: 'Accept-Language,Accept-Encoding',
     connection: 'close' },
  json:
   { error_message: 'This API project is not authorized to use this API.',
     results: [],
     status: 'REQUEST_DENIED' },
  requestUrl:
   'https://maps.googleapis.com/maps/api/geocode/json?address=1600%20Amphitheatre%20Parkway%2C%20Mountain%20View%2C%20CA&key=MY_KEY',
  query:
   { address: '1600 Amphitheatre Parkway, Mountain View, CA',
     key: 'MY_KEY' } }

I tried looking for the documentation for this nod library but could not find it.

I am okay with all 3 methods or even if there is any other. would you please help me figure out where am I going wrong.

If you want to query the Distance Matrix client side, you should use the Distance Matrix Service which is part of the Javascript API.

That said, the documentation says:

The duration_in_traffic is only returned to Google Maps Platform Premium Plan customers where traffic data is available, the mode is set to driving , and departureTime is included as part of the distanceMatrixOptions field in the request.

So you should use the web service which mentions that all of the below must be true to get the duration_in_traffic :

  • The request includes a departure_time parameter.
  • The request includes a valid API key, or a valid Google Maps Platform Premium Plan client ID and signature.
  • Traffic conditions are available for the requested route.
  • The mode parameter is set to driving .

Given what you posted, it doesn't seem you have provided all of these in your requests.

You mentioned you tried the node JS library but what you posted is a call to the Geocoder service which is a different API and which requires to be enabled for your key, hence the error in the response This API project is not authorized to use this API .

To make this work and return the duration_in_traffic , please add the drivingOptions object [1] with the fields:

{
  departureTime: Date,
  trafficModel: TrafficModel
}

It will look similar to this example:

{
  origins: [{lat: 55.93, lng: -3.118}, 'Greenwich, England'],
  destinations: ['Stockholm, Sweden', {lat: 50.087, lng: 14.421}],
  travelMode: 'DRIVING',
  drivingOptions: {
    departureTime: new Date(),
    trafficModel: 'optimistic'
  }
}

[1] https://developers.google.com/maps/documentation/javascript/distancematrix#DrivingOptions

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM