เมื่อใช้ 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
        }
    }
หวังว่าจะช่วยได้