これは少し詳細な質問ですので、まず状況を説明してから実装してください。大きすぎる経路を分割するときにGoogle Maps Elevation Serviceの応答が正しくない
4月4日現在、更新が追加され、問題が保留中の問題に絞り込まれています。最新の情報については、この質問の下部を参照してください。
TLDR;
Google Maps Directions APIから長いルートが返されており、そのルートの標高チャートが必要です。 GET経由でリクエストされ、URLの最大長が2.048文字を超えているため、動作しません。私は要求を分割した。 Promisesを使用して正しい処理順序を保証しました。エヴェレーションのデータは完全なルートでは必ずしも完全ではなく、必ずしも正しい順序で表示されず、指定されたパスに沿っているとは限らず、時々数kmを越える緯度間の位置にまたがります。
序文;
Google Maps DirectionsServiceレスポンスの標高チャートを作成しようとしましたルートが長すぎます(overview_pathごとのLatLngの数ではなく、距離には関係していないようです)。これはElevationServiceがGET
で要求され、URLの最大長が2048文字であることが原因です。この問題はdescribed on SO here as wellです。
実装;
は、私が(バッチにDirectionsService(overview_path
プロパティ)によって返されたパスを分割し、結果を連結し、(本当に、しかし、少なくともそれを回避する方法を見つけようとして)私はグーグルより賢くなると考えましたElevationServiceメソッドgetElevationsAlongPath
によって返されたelevations
)。
- 私はバッチ当たり512個の サンプルでElevationServiceを照会ディテールの最高レベルを取得するには、
- とElevationService私はバッチ当たり
LatLng
との最大数を設定する経路の長さ にわたってサンプルを拡散するための完全なパス(totalBatches = overview_path.length/maxBatchSize
)を処理するために必要とされるどのように多くのバッチ をチェックします。 - 最終的に私の指示のために均一な広がりを得て、 の完全なルート(
batchSize = Math.ceil(overview_path.length/totalBatches)
)の詳細レベルを取得しようとします。
ElevationServiceは非同期に動作しますが、最初にsetTimoutを使用してPromisesを使用している他のSOユーザーの助けを借りて、リクエストがすべて正しい順序で処理されるようにします。
私のコード
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ポイント以下の問題に直面しているため、これは問題ではありません。
問題:私が直面してる
問題は、次のとおりです。
- 標高データは常にチャートの最後の標高ポイントは(はるか)ルートの終わりからある意味、ルートの完全なパスを、次のされていません。
- 高度データは、約束事が次のタスクの実行を待っていないように、ランダムな順序で表示されることがあります。
- 標高データは、特定のバッチで提供されている
overview_path
から常にLatLng
に従っていません(スクリーンショットを参照)。 - 桁間距離データは多くあります。バッチあたり最大200
LatLng
の均等に一致するバッチサイズの512サンプルを要求しながら、複数のkmにまたがることがあります。
は、私は約束を使用してElevationServiceをバッチ処理考え出し(およびsetTimtoutとのタイミングの前に)私のすべての問題を解決するだろうが、私は2.048 char型のリクエストURLを超えると向いていない解決唯一の問題は、上記の新しい説明しました問題。
ヘルプは本当にまた、私は250担当者を置くしたい
を高く評価しています。この問題についてすぐに恩恵を受けますが、現時点では不可能です。だから私は後で賞金を追加し、説明された問題を解決する答えにそれを授与することができるので、返信を自由に感じてください。
250人。あなたが正しい方向に私を指差してくれたことに対する感謝の念を示すために、賞金が授与されました。
読んでいただきありがとうございます。
は、私はいくつかに取り組むことができましたダウン取り組んでランダムな順序の上昇と
問題(私は現時点で言うことができる限りのために)1つの懸案を残して4月4日に更新しました私は方向の結果に一貫性のない行動に気づいていたときの問題のこれは明白な理由が原因で発生しました。非同期呼び出しは「約束されていません」とスケジュールされていたので、順序が正しく、時にはそうではありませんでした。マーカーが正しく表示された(キャッシュされている)ので、私は最初にこれに気付かなかった。標高データを表示するdiv要素のみ300個のピクセルの幅と含む多くのデータポイントだった
を下に取り組む間、昇降距離と
問題。このような小さな幅によって、私は単に、十分に離れた位置にマウスを置くことができず、互いからさらに離れた仰角点を引き起こしました。標高データは、ルートに沿って
どこかに大きな幅や「有望」方向の順序が解決した場合、私はまた、この問題を解決してきましたが、私はよく分からないラインダウンどういうわけかを示していないと
問題この。問題保留
:標高データは常に
ザ・唯一残っている問題で完全なものではありませんが、データが常に完全なパスをカバーしていないこと標高です。これは、有望なロジックのエラーは、コンソールにいくつかのメッセージを記録すると、Promiseが完了していない地点で標高チャートが表示されていることを示しています。これは、クエリ制限エラーはGoogle Maps APIから返されます。
オーバークエリー制限のエラーが返された場合、同じチェーンをリファイできますか?私は同じ機能をもう一度解決しないようにしようとしましたが、ちょうどsetTimeout(...)
を発射しましたが、プロミスは、もはやオーバークエリー制限を取得していない瞬間に消耗バッチを解決していないようです。現在、これは私が(両方の方向と仰角のために)それを設定した方法である:列挙
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();
}
});
});
}
お返事ありがとうございます。しかし、私は(完全に)あなたに同意しません。 Google Maps APIの境界内では、ルートに沿って優れた標高データが提供されます。そう;特定の境界内でコールを実行するためにこれらの要求をバッチすると、高度サービス応答が期待されます。結果を連結して複数の回答をグラフに表示するだけです。私の意見では、これは達成できるはずです。 – Ben