एक OVER_QUERY_LIMIT प्रतिक्रिया प्राप्त किए बिना मैं जियोकोड 20 पते कैसे कर सकता हूं?


87

Google Geocoder v3 का उपयोग करते हुए, यदि मैं 20 पतों को जियोकोड करने की कोशिश करता हूं, तो मुझे एक OVER_QUERY_LIMIT मिलता है जब तक कि मैं उन्हें ~ 1 सेकंड से अलग नहीं करता, लेकिन तब मेरे मार्करों को रखे जाने से पहले 20 सेकंड लगते हैं।

क्या ऐसा करने का कोई अन्य तरीका है, जो पहले से निर्देशांक को संग्रहीत करने के अलावा है?


क्या अभी भी यही मामला है? प्रलेखन में केवल एक ही प्रतिबंध मुझे दिखाई देता है: "प्रति दिन 2,500 जियोलोकेशन अनुरोधों की एक क्वेरी सीमा"। code.google.com/apis/maps/documentation/geocoding/…
russau

6
यह प्रति दिन प्रति उपयोगकर्ता क्वेरी की कुल राशि के बारे में नहीं है, यह कम समय में प्रश्नों की संख्या के बारे में है, जैसे कि लूप में क्वेरी करते समय।
मिकिएल वैन ओस्टरहॉट

हमारी दुकान पर हमारे पास एक व्यवसाय लाइसेंस है और हम अभी भी प्रति सेकंड 10 से अधिक अनुरोधों को संभालने में असमर्थ हैं। व्यवसाय लाइसेंस और नियमित डेवलपर के बीच एकमात्र अंतर यह है कि हमारे पास प्रति दिन 100,000 कॉल की एक बहुत सीमा है।
अभि

@michielvoo क्या आपने इसे हल किया है? यदि हाँ, तो कृपया मेरी मदद करें। मुझे OVER_QUERY_LIMIT मिल रहा है। एसओ में मेरा सवालफिडल
प्रॉप्स

जवाबों:


85

नहीं, वास्तव में कोई अन्य तरीका नहीं है: यदि आपके पास कई स्थान हैं और उन्हें मानचित्र पर प्रदर्शित करना चाहते हैं, तो सबसे अच्छा समाधान यह है:

  • जब एक स्थान बनाया जाता है, तो जियोकोडर का उपयोग करके अक्षांश + देशांतर प्राप्त करें
  • पते के साथ अपने डेटाबेस में स्टोर करें
  • और जब आप मानचित्र प्रदर्शित करना चाहते हैं तो उन संग्रहीत अक्षांशों / देशांतरों का उपयोग करें।

यह निश्चित रूप से, यह देखते हुए कि आपके पास स्थानों के परामर्श से बहुत कम सृजन / संशोधन है।


हां, इसका मतलब है कि स्थानों को सहेजते समय आपको थोड़ा और काम करना होगा - लेकिन इसका मतलब यह भी है:

  • आप भौगोलिक निर्देशांक द्वारा खोज करने में सक्षम होंगे
    • यानी " मुझे उन बिंदुओं की एक सूची चाहिए, जो अब मेरे पास हैं "
  • मानचित्र प्रदर्शित करना बहुत तेज़ होगा
    • यहां तक ​​कि उस पर 20 से अधिक स्थानों के साथ
  • ओह, और, यह भी (अंतिम लेकिन कम से कम नहीं) : यह काम करेगा ;-)
    • आप N सेकंड में X जियोकोडर कॉल की सीमा को कम मारेंगे।
    • और आप प्रति दिन वाई जियोकोडर कॉल की सीमा को कम मारेंगे।

मैं उत्सुक हूं कि आप कैसे सुनिश्चित कर सकते हैं कि कुछ समय बीत जाने के बाद परिणाम सही हैं (मान लीजिए, एक महीना)। क्या आप उन्हें हर बार एक बार फिर से क्वेरी करते हैं?
क्रिस

2
यदि पता (जो आपके पास पहले से आपके DB में है - अन्यथा आप जियोकोड में सक्षम नहीं होंगे) नहीं बदलता है, तो संभावना बहुत कम है कि अक्षांश / देशांतर को बदलना चाहिए। और, ज़ाहिर है, हर बार जब पते को संशोधित किया जाता है, तो आपको नए पते के अनुरूप अक्षांश + देशांतर प्राप्त करने के लिए, जियोकोड को फिर से क्वेरी करना चाहिए।
पास्कल मार्टिन

मैंने lat / long को DB में संग्रहित किया है और इसे AJAX के माध्यम से DB से एक सरणी के रूप में पुनः प्राप्त किया है, लेकिन फिर इसे java script पाश में फिर से पास किया जाना चाहिए, अधिक बार मुझे DB से 173 स्थान प्राप्त हुए हैं। अब यह मुझे वही OVER_QUERY_LIMIT स्थिति दिखाता है। कृपया सलाह दें ...
प्रभु एम।

20

आपको वास्तव में प्रत्येक अनुरोध के लिए एक पूर्ण सेकंड इंतजार नहीं करना होगा। मैंने पाया कि अगर मैं प्रत्येक अनुरोध के बीच 200 मिलिसेकंड प्रतीक्षा करता हूं तो मैं OVER_QUERY_LIMIT प्रतिक्रिया से बचने में सक्षम हूं और उपयोगकर्ता अनुभव पास होने योग्य है। इस समाधान से आप 4 सेकंड में 20 आइटम लोड कर सकते हैं।

$(items).each(function(i, item){

  setTimeout(function(){

    geoLocate("my address", function(myLatlng){
      ...
    });

  }, 200 * i);

}

5
लेकिन (200 * i) का अर्थ है कि प्रत्येक अनुरोध के बीच ठहराव बढ़ रहा है। तो 3 अनुरोध पर यह 600 है, फिर 800 आदि
रोमन

बस '* i'
क्रिस

9
setTimeout इसे एक बार निष्पादित करेगा। इसलिए अगर मैं सही हूं, (..., (200, * i) प्रत्येक कॉल को 200ms (जैसे ऑयटेक टिप्पणी) द्वारा अलग-अलग शेड्यूल करेगा, जो कि gabeodess हासिल करना चाहता था। वर्तमान (..., 200) उन सभी को 200ms के बाद एक ही समय में निष्पादित करेगा। या क्या मैं कुछ न कुछ भूल रहा हूं?
Lepe

@gabeodess - आपको setIntervalइसके बजाय आवश्यक अनुरोधों की संख्या पर होना चाहिए setTimeout, और इसे करने के लिए सेट करना होगा 100- बस अगर पते की राशि भविष्य में कभी-कभी राशि का विस्तार करेगी 20
रोब स्कॉट

3
@gabeodess मैं अपने समाधान की कोशिश की है, लेकिन अभी भी OVER_QUERY_LIMIT हो रही है फिडल
Prabs

6

दुर्भाग्य से यह Google मानचित्र सेवा का प्रतिबंध है।

मैं वर्तमान में जियोकोडिंग सुविधा का उपयोग करके एक एप्लिकेशन पर काम कर रहा हूं, और मैं प्रत्येक उपयोगकर्ता के आधार पर प्रत्येक अद्वितीय पते को बचा रहा हूं। मैं Google मानचित्र द्वारा दी गई जानकारी के आधार पर पते की जानकारी (शहर, सड़क, राज्य इत्यादि) उत्पन्न करता हूं, और फिर डेटाबेस में लैट / लंबी जानकारी को भी सहेजता हूं। यह आपको चीजों को फिर से कोड करने से रोकता है, और आपको अच्छी तरह से स्वरूपित पते देता है।

ऐसा करने का एक और कारण यह है कि एक विशेष आईपी पते से जियोकोड किए जा सकने वाले पतों की संख्या पर दैनिक सीमा होती है। आप नहीं चाहते कि आपका आवेदन किसी व्यक्ति के लिए उस कारण से विफल हो।


2

मैं एक ही समस्या का सामना कर रहा हूँ 140 पते जियोकोड की कोशिश कर रहा हूं।

अगले जियोकोडिंग अनुरोध के प्रत्येक लूप के लिए मेरा समाधान usleep (100000) जोड़ रहा था । यदि अनुरोध की स्थिति OVER_QUERY_LIMIT है, तो usleep 50000 से बढ़ जाता है और अनुरोध दोहराया जाता है, और इसी तरह।

और कारण सभी प्राप्त डेटा (lat / long) को XML फ़ाइल में संग्रहीत किया जाता है ताकि पृष्ठ लोड होने पर हर बार अनुरोध न चलाएं।


1
आपका उत्तर अस्पष्ट है, क्या आप सर्वर की ओर जिक्र कर रहे हैं या यह जावास्क्रिप्ट है, यदि यह बाद वाला है, तो सोता कोई फ़ंक्शन नहीं है और इसलिए यह गलत होगा, यदि यह पूर्व है, तो मैं सुझाव देता हूं कि आप अपना उत्तर स्पष्ट रूप से बताएं अस्पष्टता से बचने के लिए सर्वर साइड है।
t0mm13b

1

संपादित करें:

यह कहना भूल गए कि यह समाधान शुद्ध js में है, केवल एक चीज जो आपको चाहिए वह है एक ब्राउज़र जो वादों का समर्थन करता है https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/romise


उन लोगों के लिए जिन्हें अभी भी ऐसा करने की आवश्यकता है, मैंने अपना स्वयं का समाधान लिखा है जो टाइमआउट के साथ वादों को जोड़ती है।

कोड:

/*
    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);
            }
        });
    }
};

कृपया ध्यान दें कि यह एक बड़ी लाइब्रेरी का एक हिस्सा है जिसे मैंने गूगल मैप्स सामान को संभालने के लिए लिखा था, इसलिए टिप्पणियाँ भ्रमित हो सकती हैं।

उपयोग काफी सरल है, दृष्टिकोण, हालांकि, थोड़ा अलग है: एक समय में एक पते को लूप करने और हल करने के बजाय, आपको कक्षा में पते की एक सरणी को पास करने की आवश्यकता होगी और यह वादा करके खुद ही खोज को संभाल लेगा, जो , जब हल किया जाता है, एक सरणी को सभी हल किए गए (और अनसुलझे) पते देता है।

उदाहरण:

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 को संपादित करने के लिए स्वतंत्र महसूस करें यदि आपको लगता है कि आप कम देरी को संभालकर सुरक्षित हैं।

आशा है कि यह निकट भविष्य में किसी की मदद करता है;)


0

मैंने अभी-अभी Google जियोकोडर का परीक्षण किया है और आपको जैसी समस्या हुई है। मैंने देखा कि मुझे हर 12 अनुरोधों के बाद केवल OVER_QUERY_LIMIT का दर्जा मिलता है, इसलिए मैं 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
}

मूल होल्डऑन विधि के साथ:

private void holdOn(long delay) {
        try {
            Thread.sleep(delay);
        } catch (InterruptedException ex) {
            // ignore
        }
    }

आशा करता हूँ की ये काम करेगा

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.