javascript – 分割太大路径时,Google Maps Elevation Service响应不准确

前端之家收集整理的这篇文章主要介绍了javascript – 分割太大路径时,Google Maps Elevation Service响应不准确前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是一个有一定程度细节的问题,所以让我首先解释一下情况,然后我的实现和最后的问题让你最了解.

截至4月4日,已添加更新,问题范围缩小为一个待处理问题,请参阅此问题的底部获取最新信息.

TLDR;

我有一条很长的路线从谷歌地图方向API返回,并希望该路线的高程图表.太糟糕了它不起作用,因为它是通过GET请求的,并且URL最大长度是超过2.048个字符.我分开了请求;使用Promises保证正确的处理顺序;但是,对于完整路线,Evelation数据并不总是完整的,并不总是按照正确的顺序显示,并不总是遵循给定的路径,并且有时会跨越几公里的高程间隔.

介绍;

尝试为Google Maps DirectionsService响应创建高程图我遇到了路线太长的问题(这似乎与距离无关,而不是每个overview_path的LatLng数量).这是因为通过GET请求ElevationService并且URL的最大长度为2048个字符.这个问题是described on SO here as well.

实施;

我认为我会比谷歌聪明(不是真的,但至少试图找到一种方法解决它),将DirectionsService(overview_path属性)返回的路径分成批并连接结果(ElevationService返回的高程)方法getElevationsAlongPath).

>为了获得最佳细节级别,我使用512查询ElevationService
每批样品;
>并且因为ElevationService在整个长度上传播样本
路径我设置每批最大LatLng数并检查
处理完整路径需要多少批次(totalBatches
= overview_path.length / maxBatchSize);
>并最终得到一个均匀的传播我的方向导致尝试
获得完整路线的相同详细程度(batchSize =
Math.ceil(overview_path.length / totalBatches)).

当ElevationService异步工作时,我确保在其他SO用户的帮助下,首先使用setTimout并使用Promises,以正确的顺序处理所有请求.

我的代码

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);
    });
}

边注;

我也正在批准DirectionService的请求,以解决该服务所具有的8个航点限制,但我可以确认这不是问题,因为我也遇到了8个或更少航路点的问题.

问题;

我面临的问题是:

>高程数据并不总是遵循路径的完整路径,这意味着图表中的最后一个高程点距路径末端(远);
>高程数据有时会以随机顺序显示,就好像承诺仍未等待下一个任务执行一样;
>高程数据并不总是遵循给定的LatLng
给定批次中提供的overview_path(参见屏幕截图);
>海拔高度距离数据很多.有时跨越多公里,同时请求512个样品以获得均匀匹配的批量大小,每批最多200个LatLng.

我想使用Promise批量处理ElevationService(在使用setTimtout计时之前)将解决我的所有问题,但我解决的唯一问题是不超过2.048字符请求URL并面临上述新问题.

非常感谢帮助

另外我想说250代表.关于这个问题的赏金,但是现在这是不可能的.所以请随时回复,因为我可以稍后添加赏金并将其奖励给解决所述问题的答案. 250代表.赏金已被授予我感谢你指出我正确的方向.

感谢阅读和回复

4月4日更新,留下1个未决问题(据我现在所知)

解决随机顺序升高的问题

当我注意到路线结果中的不一致行为时,我已经能够解决一些问题.这是由于一个显而易见的原因造成的:异步调用没有“承诺”被安排,所以有些时候订单是正确的,大部分时间都没有.起初我没有注意到这一点,因为标记显示正确(缓存).

海拔高度距离问题被解决

显示高程数据的div只有300px宽,包含许多数据点.通过如此小的宽度,我根本无法悬停在足够的点上,从而触发彼此远离的高程点.

高程数据未沿路线显示的问题

在某种程度上,我已经解决了这个问题,但我不确定更大的宽度或“有希望”的方向顺序是否解决了这个问题.

待定问题:高程数据并不总是完整的

唯一剩下的问题是高程数据并不总是覆盖整个路径.我相信这是因为Promising逻辑中的一个错误,因为在控制台中记录一些消息告诉我高程图是在不是所有Promise-then已经完成的点上绘制的,我认为这是由于当一个Over时重新启动一个批量调用Google Maps API会返回“查询限制”错误.

当返回Over Query Limit错误时,如何重新连接相同的链?我已经尝试过不再解析相同的函数,但只是触发了setTimeout(…),但是当它不再获得Over Query Limit时,Promise似乎无法解析已批准的批处理.目前这是我设置它的方式(方向和高程):

function getRouteElevationChartDataBatchPromise(batch,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,200));
                } else {
                    reject(status);
                }
            } else {
                console.log('Elevations Count: ' + elevations.length);
                routeElevations = routeElevations.concat(elevations);
                resolve();
            }
        });
    });
}

解决方法

在实施部分,附注和所列举的问题中提出的问题都在 Google Maps Elevation API中介绍.完整的文档提供了一个简单的界面来查询地球上的高程数据位置,并将解决您遇到的所有问题,如高程请求,参数用法,指定位置,路径和高程响应.

对于您的简介中讨论的问题,Google Maps Elevation API具有标准和高级使用限制.强制执行这些限制是为了防止滥用Google Maps Elevation API. Google Maps Elevation API Usage Limits为您提供有关使用限制的详细信息以及增加配额的选项.

文档中可能解决您的问题的其他说明:

  1. Note that elevation data becomes more coarse when multiple points are passed. To obtain the most accurate elevation value for a point,it should be queried independently.
  2. In those cases where Google does not possess exact elevation measurements at the precise location you request,the service will interpolate and return an averaged value using the four nearest locations.
  3. As with positional requests,the path parameter specifies a set of latitude and longitude values. Unlike a positional request,however,the path specifies an ordered set of vertices. Rather than return elevation data at the vertices,path requests are sampled along the length of the path,where each sample is equidistant from each other.
  4. The Google Maps Elevation API returns data for single point queries of the highest accuracy possible. Batch queries involving multiple locations may return data with less accuracy.

猜你在找的JavaScript相关文章