เมื่อใช้ Google Geocoder v3 หากฉันพยายามระบุตำแหน่งทางภูมิศาสตร์ 20 ที่อยู่ฉันจะได้รับ OVER_QUERY_LIMIT เว้นแต่ว่าฉันจะแบ่งเวลาให้ห่างกัน ~ 1 วินาที แต่จะใช้เวลา 20 วินาทีก่อนที่จะวางเครื่องหมายทั้งหมด
มีวิธีอื่นทำได้ไหมนอกจากเก็บพิกัดล่วงหน้า
เมื่อใช้ Google Geocoder v3 หากฉันพยายามระบุตำแหน่งทางภูมิศาสตร์ 20 ที่อยู่ฉันจะได้รับ OVER_QUERY_LIMIT เว้นแต่ว่าฉันจะแบ่งเวลาให้ห่างกัน ~ 1 วินาที แต่จะใช้เวลา 20 วินาทีก่อนที่จะวางเครื่องหมายทั้งหมด
มีวิธีอื่นทำได้ไหมนอกจากเก็บพิกัดล่วงหน้า
คำตอบ:
ไม่ไม่มีวิธีอื่นจริงๆ: หากคุณมีสถานที่หลายแห่งและต้องการแสดงสถานที่เหล่านั้นบนแผนที่ทางออกที่ดีที่สุดคือ:
แน่นอนว่านี่คือการพิจารณาว่าคุณมีการสร้าง / ปรับเปลี่ยนสถานที่น้อยกว่าที่คุณให้คำปรึกษาเกี่ยวกับสถานที่ตั้งมาก
ใช่หมายความว่าคุณจะต้องทำงานเพิ่มขึ้นอีกเล็กน้อยเมื่อบันทึกสถานที่ - แต่ยังหมายถึง:
คุณไม่ต้องรอเต็มวินาทีสำหรับแต่ละคำขอ ฉันพบว่าหากฉันรอ 200 มิลลิวินาทีระหว่างแต่ละคำขอฉันสามารถหลีกเลี่ยงการตอบกลับ OVER_QUERY_LIMIT ได้และประสบการณ์ของผู้ใช้ก็ผ่านได้ ด้วยโซลูชันนี้คุณสามารถโหลด 20 รายการใน 4 วินาที
$(items).each(function(i, item){
setTimeout(function(){
geoLocate("my address", function(myLatlng){
...
});
}, 200 * i);
}
setInterval
ตามจำนวนคำขอที่ต้องการแทนที่จะเป็นsetTimeout
และตั้งค่าเป็น100
- ในกรณีที่จำนวนที่อยู่บางครั้งจะขยาย20
จำนวนเงินในอนาคต
ขออภัยนี่เป็นข้อ จำกัด ของบริการ Google แผนที่
ขณะนี้ฉันกำลังทำงานกับแอปพลิเคชันโดยใช้คุณสมบัติการเข้ารหัสทางภูมิศาสตร์และฉันกำลังบันทึกที่อยู่ที่ไม่ซ้ำกันสำหรับผู้ใช้แต่ละราย ฉันสร้างข้อมูลที่อยู่ (เมืองถนนรัฐ ฯลฯ ) ตามข้อมูลที่ Google Maps ส่งคืนจากนั้นบันทึกข้อมูล lat / long ในฐานข้อมูลด้วย วิธีนี้จะป้องกันไม่ให้คุณต้องเขียนโค้ดใหม่และให้ที่อยู่ที่จัดรูปแบบไว้อย่างสวยงาม
อีกเหตุผลหนึ่งที่คุณต้องการทำเช่นนี้เนื่องจากมีการ จำกัด จำนวนที่อยู่รายวันที่สามารถระบุพิกัดทางภูมิศาสตร์จากที่อยู่ IP หนึ่ง ๆ ได้ คุณไม่ต้องการให้ใบสมัครของคุณล้มเหลวด้วยเหตุผลดังกล่าว
ฉันประสบปัญหาเดียวกันกับการพยายามใส่รหัสภูมิศาสตร์ 140 ที่อยู่
วิธีแก้ปัญหาของฉันคือการเพิ่มusleep (100000)สำหรับแต่ละลูปของคำขอ geocoding ถัดไป หากสถานะของคำขอคือ OVER_QUERY_LIMIT ระยะเวลาใช้งานจะเพิ่มขึ้น 50000 และมีการร้องขอซ้ำไปเรื่อย ๆ
และจากสาเหตุข้อมูลที่ได้รับทั้งหมด (lat / long) จะถูกเก็บไว้ในไฟล์ XML เพื่อไม่ให้เรียกใช้คำขอทุกครั้งที่โหลดเพจ
แก้ไข:
ลืมบอกไปว่าโซลูชันนี้อยู่ใน js บริสุทธิ์สิ่งเดียวที่คุณต้องการคือเบราว์เซอร์ที่รองรับสัญญา https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Promise
สำหรับผู้ที่ยังต้องทำสิ่งนั้นให้สำเร็จฉันได้เขียนวิธีแก้ปัญหาของตัวเองที่รวมคำสัญญากับการหมดเวลา
รหัส:
/*
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);
}
});
}
};
โปรดทราบว่านี่เป็นเพียงส่วนหนึ่งของห้องสมุดขนาดใหญ่ที่ฉันเขียนขึ้นเพื่อจัดการเนื้อหาของ Google Maps ดังนั้นความคิดเห็นอาจทำให้สับสน
การใช้งานค่อนข้างง่ายอย่างไรก็ตามวิธีการนั้นแตกต่างกันเล็กน้อย: แทนที่จะวนซ้ำและแก้ไขทีละที่อยู่คุณจะต้องส่งอาร์เรย์ของที่อยู่ไปยังคลาสและจะจัดการการค้นหาด้วยตัวเองโดยส่งคืนสัญญาที่ เมื่อแก้ไขแล้วจะส่งคืนอาร์เรย์ที่มีแอดเดรสที่แก้ไข (และไม่ได้รับการแก้ไข) ทั้งหมด
ตัวอย่าง:
var myAmazingGeo = new Geolocalizer();
var locations = ["Italy","California","Dragons are thugs...","China","Georgia"];
myAmazingGeo.Localize(locations).then(function(res){
console.log(res);
});
เอาต์พุตคอนโซล:
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
ส่งคืนวัตถุ:
ความมหัศจรรย์ทั้งหมดเกิดขึ้นที่นี่:
(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);
โดยทั่วไปจะวนซ้ำทุกรายการโดยมีความล่าช้า 750 มิลลิวินาทีระหว่างแต่ละรายการดังนั้นทุกๆ 750 มิลลิวินาทีจะมีการควบคุมที่อยู่
ฉันได้ทำการทดสอบเพิ่มเติมและพบว่าแม้จะใช้เวลา 700 มิลลิวินาทีบางครั้งฉันก็ได้รับข้อผิดพลาด QUERY_LIMIT ในขณะที่ 750 ฉันไม่พบปัญหา
ไม่ว่าในกรณีใดอย่าลังเลที่จะแก้ไข 750 ข้างต้นหากคุณรู้สึกว่าปลอดภัยโดยจัดการกับความล่าช้าที่น้อยลง
หวังว่านี่จะช่วยใครบางคนในอนาคตอันใกล้นี้;)
ฉันเพิ่งทดสอบ Google Geocoder และพบปัญหาเดียวกันกับคุณ ฉันสังเกตเห็นว่าฉันได้รับสถานะ OVER_QUERY_LIMIT หนึ่งครั้งทุกๆ 12 คำขอดังนั้นฉันจึงรอ 1 วินาที (นั่นคือความล่าช้าขั้นต่ำในการรอ) แอปพลิเคชันทำให้แอปพลิเคชันช้าลง แต่น้อยกว่ารอ 1 วินาทีทุกคำขอ
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
}
ด้วยวิธี HoldOn พื้นฐาน:
private void holdOn(long delay) {
try {
Thread.sleep(delay);
} catch (InterruptedException ex) {
// ignore
}
}
หวังว่าจะช่วยได้