Dengan menggunakan Google Geocoder v3, jika saya mencoba untuk membuat geocode 20 alamat, saya mendapatkan OVER_QUERY_LIMIT kecuali saya mengatur waktunya dengan jarak ~ 1 detik, tetapi kemudian butuh waktu 20 detik sebelum semua penanda saya ditempatkan.
Apakah ada cara lain untuk melakukannya, selain menyimpan koordinat terlebih dahulu?
javascript
geocoding
google-maps
Michiel van Oosterhout
sumber
sumber
Jawaban:
Tidak, sebenarnya tidak ada cara lain: jika Anda memiliki banyak lokasi dan ingin menampilkannya di peta, solusi terbaik adalah:
Ini, tentu saja, mengingat Anda memiliki lebih sedikit pembuatan / modifikasi lokasi daripada Anda memiliki konsultasi lokasi.
Ya, itu berarti Anda harus melakukan lebih banyak pekerjaan saat menyimpan lokasi - tetapi itu juga berarti:
sumber
Anda sebenarnya tidak perlu menunggu satu detik penuh untuk setiap permintaan. Saya menemukan bahwa jika saya menunggu 200 milidetik di antara setiap permintaan, saya dapat menghindari tanggapan OVER_QUERY_LIMIT dan pengalaman pengguna lumayan. Dengan solusi ini Anda dapat memuat 20 item dalam 4 detik.
$(items).each(function(i, item){ setTimeout(function(){ geoLocate("my address", function(myLatlng){ ... }); }, 200 * i); }
sumber
setInterval
jumlah permintaan yang diperlukan, bukansetTimeout
, dan menyetelnya ke100
- untuk berjaga-jaga jika jumlah alamat suatu saat nanti akan menambah20
jumlahnya.Sayangnya ini adalah batasan dari layanan peta Google.
Saat ini saya sedang mengerjakan aplikasi yang menggunakan fitur geocoding, dan saya menyimpan setiap alamat unik per pengguna. Saya menghasilkan informasi alamat (kota, jalan, negara bagian, dll) berdasarkan informasi yang dikembalikan oleh peta Google, dan kemudian menyimpan informasi lintang / bujur di database juga. Ini mencegah Anda dari keharusan untuk membuat kode ulang, dan memberi Anda alamat yang diformat dengan baik.
Alasan lain Anda ingin melakukan ini adalah karena ada batasan harian pada jumlah alamat yang dapat di-geocode dari alamat IP tertentu. Anda tidak ingin lamaran Anda gagal untuk seseorang karena alasan itu.
sumber
Saya menghadapi masalah yang sama saat mencoba geocode 140 alamat.
Solusi saya adalah menambahkan usleep (100000) untuk setiap loop permintaan geocoding berikutnya. Jika status permintaan OVER_QUERY_LIMIT, usleep ditingkatkan 50000 dan permintaan diulang, dan seterusnya.
Dan karena itu semua data yang diterima (lat / long) disimpan dalam file XML agar tidak menjalankan request setiap kali halaman di-load.
sumber
EDIT:
Lupa mengatakan bahwa solusi ini murni js, satu-satunya hal yang Anda butuhkan adalah browser yang mendukung promise https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Promise
Bagi mereka yang masih perlu melakukannya, saya telah menulis solusi saya sendiri yang menggabungkan janji dengan batas waktu.
Kode:
/* class: Geolocalizer - Handles location triangulation and calculations. -- Returns various prototypes to fetch position from strings or coords or dragons or whatever. */ var Geolocalizer = function () { this.queue = []; // queue handler.. this.resolved = []; this.geolocalizer = new google.maps.Geocoder(); }; Geolocalizer.prototype = { /* @fn: Localize @scope: resolve single or multiple queued requests. @params: <array> needles @returns: <deferred> object */ Localize: function ( needles ) { var that = this; // Enqueue the needles. for ( var i = 0; i < needles.length; i++ ) { this.queue.push(needles[i]); } // return a promise and resolve it after every element have been fetched (either with success or failure), then reset the queue. return new Promise ( function (resolve, reject) { that.resolveQueueElements().then(function(resolved){ resolve(resolved); that.queue = []; that.resolved = []; }); } ); }, /* @fn: resolveQueueElements @scope: resolve queue elements. @returns: <deferred> object (promise) */ resolveQueueElements: function (callback) { var that = this; return new Promise( function(resolve, reject) { // Loop the queue and resolve each element. // Prevent QUERY_LIMIT by delaying actions by one second. (function loopWithDelay(such, queue, i){ console.log("Attempting the resolution of " +queue[i-1]); setTimeout(function(){ such.find(queue[i-1], function(res){ such.resolved.push(res); }); if (--i) { loopWithDelay(such,queue,i); } }, 1000); })(that, that.queue, that.queue.length); // Check every second if the queue has been cleared. var it = setInterval(function(){ if (that.queue.length == that.resolved.length) { resolve(that.resolved); clearInterval(it); } }, 1000); } ); }, /* @fn: find @scope: resolve an address from string @params: <string> s, <fn> Callback */ find: function (s, callback) { this.geolocalizer.geocode({ "address": s }, function(res, status){ if (status == google.maps.GeocoderStatus.OK) { var r = { originalString: s, lat: res[0].geometry.location.lat(), lng: res[0].geometry.location.lng() }; callback(r); } else { callback(undefined); console.log(status); console.log("could not locate " + s); } }); } };
Harap dicatat bahwa ini hanya bagian dari perpustakaan yang lebih besar yang saya tulis untuk menangani hal-hal peta google, maka komentar mungkin membingungkan.
Penggunaannya cukup sederhana, namun pendekatannya sedikit berbeda: alih-alih mengulang dan menyelesaikan satu alamat pada satu waktu, Anda perlu meneruskan array alamat ke kelas dan itu akan menangani pencarian dengan sendirinya, mengembalikan sebuah janji yang , ketika diselesaikan, mengembalikan larik yang berisi semua alamat yang diselesaikan (dan tidak terselesaikan).
Contoh:
var myAmazingGeo = new Geolocalizer(); var locations = ["Italy","California","Dragons are thugs...","China","Georgia"]; myAmazingGeo.Localize(locations).then(function(res){ console.log(res); });
Keluaran konsol:
Attempting the resolution of Georgia Attempting the resolution of China Attempting the resolution of Dragons are thugs... Attempting the resolution of California ZERO_RESULTS could not locate Dragons are thugs... Attempting the resolution of Italy
Objek dikembalikan:
Seluruh keajaiban terjadi di sini:
(function loopWithDelay(such, queue, i){ console.log("Attempting the resolution of " +queue[i-1]); setTimeout(function(){ such.find(queue[i-1], function(res){ such.resolved.push(res); }); if (--i) { loopWithDelay(such,queue,i); } }, 750); })(that, that.queue, that.queue.length);
Pada dasarnya, ini mengulang setiap item dengan penundaan 750 milidetik di antara mereka masing-masing, maka setiap 750 milidetik sebuah alamat dikendalikan.
Saya telah melakukan beberapa pengujian lebih lanjut dan saya menemukan bahwa bahkan pada 700 milidetik saya terkadang mendapatkan kesalahan QUERY_LIMIT, sedangkan dengan 750 saya tidak mengalami masalah sama sekali.
Bagaimanapun, silakan edit 750 di atas jika Anda merasa aman dengan menangani penundaan yang lebih rendah.
Semoga ini membantu seseorang dalam waktu dekat;)
sumber
Saya baru saja menguji Google Geocoder dan mendapatkan masalah yang sama seperti Anda. Saya perhatikan saya hanya mendapatkan status OVER_QUERY_LIMIT sekali setiap 12 permintaan Jadi saya menunggu selama 1 detik (itu adalah penundaan minimum untuk menunggu) Ini memperlambat aplikasi tetapi kurang dari menunggu 1 detik setiap permintaan
info = getInfos(getLatLng(code)); //In here I call Google API record(code, info); generated++; if(generated%interval == 0) { holdOn(delay); // Every x requests, I sleep for 1 second }
Dengan metode holdOn dasar:
private void holdOn(long delay) { try { Thread.sleep(delay); } catch (InterruptedException ex) { // ignore } }
Semoga membantu
sumber