3

約200個のマーカーが付いたGoogleマップがあります。Google Distance Matrix Serviceを使用して、住所から地図上のすべてのマーカーまでの運転距離を見つけることができます。APIの制限により、呼び出しごとに送信できる宛先は25のみであるため、操作を距離行列サービスへの8つの個別の呼び出しに分割する必要があります。

私の問題は、呼び出しが非同期であるため、任意の順序で戻ってくる可能性があるため、返された結果を元のマーカーの配列と最もよく一致させる方法に少し困惑していることです。理想的には、コールバック関数にオフセットを渡して、元のマーカー配列のどの25要素がAPI呼び出しから返送された25の結果に対応するかを正確に把握したいのですが、これを実現する方法がわからないため、ヘルプが必要です。大変感謝しております。

var limit = 25;
var numMarkers = markers.length; // markers is an array of markers defined elsewhere
var numCallbacks = Math.ceil(numMarkers/limit);
var callbackCount = 0;

for(var i = 0; i < numMarkers; i += limit) {
    var destinations = [];

    // Get destination position in batches of 25 (API limit)
    for(var j = i; j < i + limit && j < numMarkers; j++) {
        destinations[j - i] = markers[j].getPosition();
    }

    // Calculate distances
    distMatrix.getDistanceMatrix(
    {
        origins: origin, // array containing single lat/lng
        destinations: destinations,
        travelMode: google.maps.TravelMode.DRIVING,
        unitSystem: google.maps.UnitSystem.IMPERIAL,
        avoidHighways: false,
        avoidTolls: false

    }, function(response, status) {

        if (status == google.maps.DistanceMatrixStatus.OK) {
            var distances = response.rows[0].elements;

            // This is where it would be nice to know the offset in the markers array 
            // that these 25 results correspond to so I can then just iterate through 
            // the distances array and add the data to the correct marker.
        }

        if(++callbackCount == numCallbacks) {
            // All callbacks complete do something else...
        }
    });
}

したがって、各API呼び出しのコールバック関数に、呼び出されたときのforループからの値「i」をシードする方法があれば、すべてを簡単に一致させることができますが、私はそれほど素晴らしいとは言えません。 javascriptを使用しているので、これを行う方法や、可能かどうかもわかりません。

あなたたちが提供できるどんな助けにも感謝します!

4

1 に答える 1

3

コールバック内で使用しようとしたとi思いjますが、常に最後の値と等しいことがわかりました。これは、JavaScriptには関数スコープ(ブロックではない)しかないためij宣言されるのは1回だけだからです。したがって、各反復は同じ変数を参照します。

詳細については、「 JavaScriptはローカル変数を使用したクロージャをサポートしていませんか?」を参照してください。


解決策は例と同じです(そしてこの問題がすべて発生します)。新しいスコープレベルを導入する必要があります。あなたはそれ自体あなたの問題のためにこれを非常にうまく行うことができます。

function buildResponseFor(i) {
    return function (response, status) {
        if (status == google.maps.DistanceMatrixStatus.OK) {
            var distances = response.rows[0].elements;

            // Use i here.
        }
    }
}

getDistanceMatrix次に、通話を次のように更新します。

distMatrix.getDistanceMatrix({
    origins: origin, // array containing single lat/lng
    destinations: destinations,
    travelMode: google.maps.TravelMode.DRIVING,
    unitSystem: google.maps.UnitSystem.IMPERIAL,
    avoidHighways: false,
    avoidTolls: false

}, buildResponseFor(i));

...、、、、などを関数に渡すことができますi。これらは、の宣言内で指定した名前として、コールバック関数で使用できます。jijbuildResponseForfunctionbuildResponseFor

于 2013-03-17T16:06:11.967 に答える