41

これらのフォーラムでよく議論されている問題にぶつかっていますが、どの推奨事項も機能していないようです。そのため、html ファイルとして保存したときに機能する完全な JavaScript を探しています。

問題は、Javascript によって呼び出された V3 API を使用して Google マップで 11 か所以上の場所をジオコーディングしようとすると、OVER_QUERY_LIMIT エラーが発生し続けることです。ジオコーダーを呼び出す速度には制限があること (および合計ボリュームの 1 日あたりの制限) があることを理解しています。そのため、配列内の各結果の間に一時停止を導入する必要があります。

どんな助けでも大歓迎です。

これが私のコードです:

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var geocoder;
var map;
var wait = false;


  function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(51.32, 0.5);



var myOptions = {
  zoom: 8,
  center: latlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
codeAddress('KT16 8LA' + ', UK');
codeAddress('LS8 2LQ' + ', UK');
codeAddress('NE13 8AF' + ', UK');
codeAddress('KT12 2BE' + ', UK');
codeAddress('W1W 8AN' + ', UK');
codeAddress('EC3N 2LS' + ', UK');
codeAddress('BS9 3BH' + ', UK');
codeAddress('KA10 6LZ' + ', UK');
codeAddress('EC1V 9BW' + ', UK');
codeAddress('WD18 8YN' + ', UK');
codeAddress('HA3 6DQ' + ', UK');
codeAddress('W1U 3PL' + ', UK');
codeAddress('W1T 7QL' + ', UK');
codeAddress('W1S 1TD' + ', UK');
codeAddress('SW1X 8NX' + ', UK');
codeAddress('LE2 8ET' + ', UK');
codeAddress('BA3 4BH' + ', UK');
codeAddress('AL3 8JP' + ', UK');
codeAddress('DE55 4QJ' + ', UK');
codeAddress('W6 0QT' + ', UK');
codeAddress('LA1 1PP' + ', UK');
codeAddress('SW16 4DH' + ', UK');
codeAddress('WC2N 6DF' + ', UK');
codeAddress('RM6 6LS' + ', UK');
codeAddress('S25 3QZ' + ', UK');
codeAddress('WC2H 7LR' + ', UK');
codeAddress('BH24 1DW' + ', UK');
codeAddress('EC2N 6AR' + ', UK');
codeAddress('W1U 2FA' + ', UK');
codeAddress('B60 3DX' + ', UK');    
}

  function codeAddress(vPostCode) {
if (geocoder) {
  geocoder.geocode( { 'address': "'" + vPostCode + "'"}, function(results, status) {
    if (status == google.maps.GeocoderStatus.OK) {
      map.setCenter(results[0].geometry.location);
      var marker = new google.maps.Marker({
          map: map, 
          position: results[0].geometry.location
      });
    } else {
      alert("Geocode was not successful for the following reason: " + status);
    }
  });
}
}

</script>
<body style="margin:0px; padding:0px;" onload="initialize()">
<div id="map_canvas" style="width:100%; height:90%"></div>
</body>

編集:これは、関連するセクションで一時停止/待機させるために私がやろうとしたことですが、何もしません:

function codeAddress(vPostCode) {
    if (geocoder) {
    while (wait) { /* Just wait. */ };
      geocoder.geocode( { 'address': "'" + vPostCode + "'"}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          map.setCenter(results[0].geometry.location);
          var marker = new google.maps.Marker({
              map: map, 
              position: results[0].geometry.location
          });
        /* When geocoding "fails", see if it was because of over quota error: */
        } else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) { 
        wait = true;
        setTimeout("wait = true", 2000);
        //alert("OQL: " + status);
        } else {
          alert("Geocode was not successful for the following reason: " + status);
        }
      });
    }
  }
4

6 に答える 6

43

Mike Williams のチュートリアルには、次の 2 行のようなものはありません。

    wait = true;
    setTimeout("wait = true", 2000);

バージョン 3 のポートは次のとおりです。

http://acleach.me.uk/gmaps/v3/plotaddresses.htm

関連するコードは

  // ====== Geocoding ======
  function getAddress(search, next) {
    geo.geocode({address:search}, function (results,status)
      { 
        // If that was successful
        if (status == google.maps.GeocoderStatus.OK) {
          // Lets assume that the first marker is the one we want
          var p = results[0].geometry.location;
          var lat=p.lat();
          var lng=p.lng();
          // Output the data
            var msg = 'address="' + search + '" lat=' +lat+ ' lng=' +lng+ '(delay='+delay+'ms)<br>';
            document.getElementById("messages").innerHTML += msg;
          // Create a marker
          createMarker(search,lat,lng);
        }
        // ====== Decode the error status ======
        else {
          // === if we were sending the requests to fast, try this one again and increase the delay
          if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
            nextAddress--;
            delay++;
          } else {
            var reason="Code "+status;
            var msg = 'address="' + search + '" error=' +reason+ '(delay='+delay+'ms)<br>';
            document.getElementById("messages").innerHTML += msg;
          }   
        }
        next();
      }
    );
  }
于 2012-08-06T09:01:09.350 に答える
9

この質問に対する一般的な答えは次のとおりです。

ページを読み込むたびに既知の場所をジオコーディングしないでください。それらをオフラインでジオコーディングし、結果の座標を使用してページにマーカーを表示します。

制限には理由があります。

場所をオフラインでジオコーディングできない場合は、Mike Williams の v2 チュートリアルのこのページ (パート 17 複数の住所のジオコーディング)を参照してください。これには、v3 API への移植方法が記載されています。

于 2012-08-03T09:55:04.970 に答える
3

「setInterval」と「clearInterval」を使用すると、問題が解決します。

function drawMarkers(map, markers) {
    var _this = this,
        geocoder = new google.maps.Geocoder(),
        geocode_filetrs;

    _this.key = 0;

    _this.interval = setInterval(function() {
        _this.markerData = markers[_this.key];

        geocoder.geocode({ address: _this.markerData.address }, yourCallback(_this.markerData));

        _this.key++;

        if ( ! markers[_this.key]) {
            clearInterval(_this.interval);
        }

    }, 300);
}
于 2015-03-25T10:20:45.440 に答える
0

あなたはsetTimeout間違った方法を使用しています。(の 1 つ) 関数シグネチャはsetTimeout(callback, delay). したがって、どのコードをどの程度の遅延後に実行するかを簡単に指定できます。

var codeAddress = (function() {
    var index = 0;
    var delay = 100;

    function GeocodeCallback(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            map.setCenter(results[0].geometry.location);
            new google.maps.Marker({ map: map, position: results[0].geometry.location, animation: google.maps.Animation.DROP });
            console.log(results);
        }
        else alert("Geocode was not successful for the following reason: " + status);
    };

    return function(vPostCode) {
        if (geocoder) setTimeout(geocoder.geocode.bind(geocoder, { 'address': "'" + vPostCode + "'"}, GeocodeCallback), index*delay);
        index++;
    };
})();

このように、すべてのcodeAddress()呼び出しはgeocoder.geocode()、前の呼び出しから 100 ミリ秒後に呼び出されます。

また、マーカーにアニメーションを追加したので、マーカーが次々とマップに追加されて素敵なアニメーション効果が得られます。現在の Google の制限がどのくらいなのかわからないため、delay変数の値を増やす必要があるかもしれません。

また、毎回同じ住所をジオコーディングする場合は、代わりにジオコードの結果をデータベースに保存し、次回はそれらを使用する必要があります (トラフィックが節約され、アプリケーションが少し速くなります)。

于 2016-09-20T08:57:41.240 に答える