This is a bit of a question with some level of detail, so let me first explain the situation, then my implementation and the last question, so that you better understand.
As of April 4, an update is being added, and the problems narrow down to one incomplete problem, see the bottom of this question for current information.
TL; DR;
I have a long route returned from the Google Maps API, and you need an Elevation diagram for that route. Too bad that it does not work, because it is requested via GET, and the maximum URL length is 2.048 characters that exceed. I shared the requests; guaranteed the correct processing order using Promises; but Evelation data is not always complete for the full route, it does not always appear in the correct order, it does not always follow the given path, and intermediate intersections sometimes take several kilometers.
Introduction
Trying to create a height chart to respond to Google Maps DirectionsService. I ran into the problem of routes too long (this does not seem to be related to the distance, and not to the number of LatLngs per view_view). This is because the ElevationService is requested via GET and the maximum URL length is 2048 characters. This issue is described here as well here .
Implementation
I decided that I would be smarter than Google (not really, but at least trying to find a way around it), split the path returned by the DirectionsService ( overview_path ) property into packages and merge the results ( elevations returned by the ElevationService getElevationsAlongPath method).
- To get the best level of detail, I request an ElevationService with 512 samples per batch;
- and because the ElevationService distributes samples along the path, I set the maximum number of
LatLng per batch and checked how many packets are required to process the full path ( totalBatches = overview_path.length / maxBatchSize ); - and finally getting even distribution for my directions will result in an attempt to get an even level of detail for the entire route (
batchSize = Math.ceil(overview_path.length / totalBatches) ).
While the ElevationService works asynchronously, I am sure that all requests are processed in the correct order with the help of other SO users, first with setTimout and now work with Promises.
My code
var maxBatchSize = 200; var currentBatch = 0; var promise = Promise.resolve(); var totalElevationBatches = Math.ceil(directions.routes[0].overview_path.length / maxBatchSize); var batchSize = Math.ceil(directions.routes[0].overview_path.length / totalElevationBatches); while(currentBatch < totalElevationBatches) { promise = addToChain(promise, currentBatch, batchSize); currentBatch++; } promise.then(function() { drawRouteElevationChart(); // this uses the routeElevations to draw an AreaChart }); function getRouteElevationChartDataBatchPromise(batch, batchSize) { return new Promise(function(resolve, reject) { var elevator = new google.maps.ElevationService(); var thisBatchPath = []; for (var j = batch * batchSize; j < batch * batchSize + batchSize; j++) { if (j < directions.routes[0].overview_path.length) { thisBatchPath.push(directions.routes[0].overview_path[j]); } else { break; } } elevator.getElevationAlongPath({ path: thisBatchPath, samples: 512 }, function (elevations, status) { if (status != google.maps.ElevationStatus.OK) { if(status == google.maps.ElevationStatus.OVER_QUERY_LIMIT) { console.log('Over query limit, retrying in 250ms'); resolve(setTimeout(function() { getRouteElevationChartDataBatchPromise(batch, batchSize); }, 250)); } else { reject(status); } } else { routeElevations = routeElevations.concat(elevations); resolve(); } }); }); } function addToChain(chain, batch, batchSize){ return chain.then(function(){ console.log('Promise add to chain for batch: ' + batch); return getRouteElevationChartDataBatchPromise(batch, batchSize); }); }
Side note;
I also run a DirectionService request to solve the 8th route problem provided by the service, but I can confirm that this is not a problem, since I also ran into a problem with 8 or less waypoints.
Problem
I ran into problems:
- Altitude data does not always follow the full path of the route, that is, the last point in the graph (far) from the end of the route;
- Height data is sometimes displayed in random order, as if it seemed like promises were still not waiting for the next task;
- Altitude data does not always follow
LatLng data from overview_path in this batch (see screenshot); - Inter-distance between data is a lot. Sometimes it takes several kilometers, requesting 512 samples for a uniformly matching batch size with a maximum of 200
LatLng per batch.

I decided to dispense the ElevationService using promises (and before timing using setTimtout) it will solve all my problems, but the only problem I solved does not exceed the request URL 2.048 char and addresses the new problems described above.
Help is really appreciated
Also I would like to put 250 rep. generosity in this matter, but at this moment it is impossible. Therefore, please do not hesitate to answer, as I can add a reward later and give her an answer that solves the problems described. 250 rep. the award was awarded to express your appreciation for pointing me in the right direction.
Thanks for reading and responding!
Updated on April 4, leaving 1 incomplete problem (as far as I can tell at the moment)
Random elevation down issue
I managed to solve some problems when I noticed inconsistent behavior in the route results. This was caused for an obvious reason: asynchronous calls were not “promised” to be scheduled, so some of them were correct, in most cases this is not so. I did not notice this at first, because the markers were correctly displayed (cached).
The problem with the distance between the reliefs is overcome
The div, which displays height data, is only 300 pixels wide and contains many data points. With such a small width, I simply could not hover over a sufficient number of points, forcing me to launch elevation points that lie further apart.
Problem with altitude data not showing along the route
Somewhere somewhere along the line, I also solved this problem, but I'm not sure if this allowed a wider width or a "promise" of the order of directions.
Pending issue: height data not always complete
The only remaining problem is that the altitude data does not always cover the full path. I believe that this is due to the error in the Promising logic, since recording some messages in the console tells me that the height diagram is drawn at the point where not all the Promise is finished after that, and I think this is caused by repeating the batch call when Over Error request restriction is returned by the Google Maps API.
How can I restore the same chain when returning an error with a request exceeding? I tried not to allow the same function again, but just ran setTimeout(...) , but then Promise didn’t seem to be resolving the batch when it no longer gets the Over Over Query Limit. This is currently how I set it (for both directions and heights):
function getRouteElevationChartDataBatchPromise(batch, batchSize) { return new Promise(function(resolve, reject) { var elevator = new google.maps.ElevationService(); var thisBatchPath = []; for (var j = batch * batchSize; j < batch * batchSize + batchSize; j++) { if (j < directions.routes[0].overview_path.length) { thisBatchPath.push(directions.routes[0].overview_path[j]); } else { break; } } elevator.getElevationAlongPath({ path: thisBatchPath, samples: 512 }, function (elevations, status) { if (status != google.maps.ElevationStatus.OK) { if(status == google.maps.ElevationStatus.OVER_QUERY_LIMIT) { console.log('ElevationService: Over Query Limit, retrying in 200ms'); resolve(setTimeout(function() { getRouteElevationChartDataBatchPromise(batch, batchSize); }, 200)); } else { reject(status); } } else { console.log('Elevations Count: ' + elevations.length); routeElevations = routeElevations.concat(elevations); resolve(); } }); }); }