7

これは少し詳細な質問ですので、まず状況を説明してから実装してください。大きすぎる経路を分割するときに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にまたがることがあります。

elevation data not following the overview_path it was told to follow

は、私は約束を使用して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(); 
      } 
     }); 
    }); 
} 

答えて

0

最後の残りの問題は、このSOの質問の助けを借りて解決されました:How to re-run a javascript promise when failed?。だからもしjfriend00がこの質問に返答すれば、私は彼に賞金を授与することができます。それは私を最後まで助けてくれるトリックだからです。

function getRouteElevationChartDataBatchPromise(batch, batchSize) { 
    return new Promise(function(resolve, reject) { 
     function run(batch, batchSize) { 
      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) { 
        routeElevations = routeElevations.concat(elevations); 
        resolve(); 
       } else if (status == google.maps.ElevationStatus.OVER_QUERY_LIMIT) {       
        setTimeout(function() { 
         run(batch, batchSize); 
        }, 200); 
       } else { 
        reject(status); 
       } 
      }); 
     } 

     run(batch, batchSize); 
    }); 
} 

機能ステータスOKを解決する確かに、リトライOVER_QUERY_LIMITany other statusを拒否私はそうのように、関数内でプロミスロジックを入れて、その関数を呼び出す必要がありました

0

実装部分、サイドノートに懸念や問題点は、すべてのGoogle Maps Elevation APIで覆われています。完全なドキュメントは、標高データの地球上の場所を照会する簡単なインターフェースを提供し、標高要求、パラメーター使用法、位置、経路、標高応答の指定など、遭遇したすべての問題に対処します。

はじめにで説明したように、Google Maps Elevation APIには、標準とプレミアムの使用制限があります。これらの制限は、Google Maps Elevation APIの悪用を防ぐために適用されます。 Google Maps Elevation API Usage Limitsには、利用制限とクォータを増やすオプションに関する詳細が記載されています。

あなたの懸念に対処することができるドキュメントから

その他の注意事項:

  1. 注複数のポイントが渡されたときに標高データをより粗くなること。点の最も正確な仰角値を得るには、それを独立して照会する必要があります。
  2. Googleが要求した正確な場所で正確な標高測定値を持っていない場合、サービスは補間し、最も近い4つの場所を使用して平均値を返します。
  3. 位置リクエストと同様に、pathパラメータは緯度と経度の値のセットを指定します。ただし、位置要求とは異なり、パスは順序付けられた頂点のセットを指定します。頂点で標高データを返すのではなく、パスの長さに沿ってパス要求がサンプリングされます。各サンプルは互いに等距離にあります。
  4. Google Maps Elevation APIは、可能な限り高い精度の1点クエリのデータを返します。複数の場所を含むバッチクエリは、精度の低いデータを返す可能性があります。
+0

お返事ありがとうございます。しかし、私は(完全に)あなたに同意しません。 Google Maps APIの境界内では、ルートに沿って優れた標高データが提供されます。そう;特定の境界内でコールを実行するためにこれらの要求をバッチすると、高度サービス応答が期待されます。結果を連結して複数の回答をグラフに表示するだけです。私の意見では、これは達成できるはずです。 – Ben

0

あなたは何点を処理する必要がありますか。パスを公開することができますか?他のアプリでアプリをテストできますか? Douglas-Peukerまたは同等の方法でパスポイントを減らそうとしましたか? 無料の "Routeconverter"(HGTと連携する)のような他のアプリを試してみましたか?エレベーションポイントがダイレクトに/オンザフライで必要ですか?他の無料標高サービスを使用することはオプションになりますか?おそらく、あなたはあなたのルートポイントに戻って仰角のポイントを読んで、不要なポイントを並べ替えることができます。

いくつかの考えだけ、悪い英語で - 私は恐れています。 幸運Reinhard

+0

ご返信ありがとうございますが、私はすでに問題を原因に絞り込んでいます。しかし、私はRamer Douglas Peuckerの言葉が好きです。私はそれを以前は聞いていませんでした;) – Ben

関連する問題