使用Google Maps API v3进行批量地理编码的更多问题

4
我正在尝试找到一种限制发送地理编码请求到 Google Maps API v3 地理编码器服务的速率的好方法。我知道 JavaScript 没有任何好的waitsleep,因为它的执行是单线程的。
每个地理编码器请求都在 jQuery 的 each 函数内部发送。所以,一般的代码框架是:
$(xml).find('foo').each(function(){
    // do stuff
    ...

    geocoder.geocode(request, function(results, status) {/* do other stuff */});

    // do more stuff
    ...
}

如何设置固定的时间间隔以等待每个geocode调用之间?如果我以JavaScript可以运行的速度发送每个请求,那么我很快就会开始收到OVER_QUERY_LIMIT响应 - 即使我只发送20个请求。这是预期的,我正在尝试让我的客户端与Google的服务友好地互动。

我愿意尝试的另一种方法是完全放弃使用Javascript进行地理编码,并用Java编写全部内容。使用Java将非常容易在请求之间休眠。

然而,我找不到一种方法来在Java中使用Google的地理编码服务(具体来说,使用API的第3版)。GeoGoogle似乎已经过时了一年以上,并且使用的是v2。

是否可以在Java中完成,并且如何实现?

4个回答

4

谷歌正在积极开发Maps API的v2和v3版本。v3是一个更加精简的版本,适用于处理有限处理能力或基本地图任务的设备(而且不需要API密钥即可工作)。

无论哪种情况,如果您需要对许多内容进行地理编码,则应该考虑使用谷歌的HTTP地理编码服务(http://code.google.com/apis/maps/documentation/geocoding/index.html)。这将避免速率限制问题。

此外:JavaScript可以使用setInterval()和setTimeout()进行基本的睡眠/等待操作。只需触发请求并在回调处理结束时重新设置计时器即可再次执行。


抱歉,但这对我来说真的没有用。您提供的HTTP地理编码服务仅适用于v2 *,并且受到相同的速率限制和日限制的限制:http://code.google.com/apis/maps/documentation/geocoding/index.html#StatusCodes。实际上,Javascript的setTimeout并不足够,因为它只是安排一个函数在未来X毫秒内运行 - 我仍然无法真正控制该函数执行之间的时间间隔。 - Matt Ball
setTimeout和setInterval是用于创建任何JavaScript计时器的基本JavaScript调用...因此实际上它正是您标记为已接受的答案。无论如何,需要对地理编码请求进行速率限制都表明应用程序设计不佳,通常是由于未保存先前的地理编码响应或使用非Google服务进行HTTP批量地理编码而导致的。 - Ty W
1
我将保存之前的地理编码响应。然而,(a) 我有大约10,000个地址需要获取初始位置,(b) 其中一些地址每天都会更改。如果我必须查找其中的20个新地址,我必须限制发送请求的速率。至于HTTP批量地理编码服务-我找不到任何一个像谷歌那样价格(免费),每日请求限制高和数据准确性好的服务-特别是具有Javascript或Java API的服务。你能指引我去哪里找到这样的服务吗? - Matt Ball
Google Map API组维护了一个非Google地理编码器页面:http://groups.google.com/group/google-maps-api/web/resources-non-google-geocoders。不知道您的应用程序情况,我无法确定它是否有所帮助,但请记住,JavaScript地理编码器请求是基于客户端IP而不是您的服务器进行限制的,因此您可能可以在某种程度上利用它。 - Ty W


2

如果您想实现某种形式的速率限制提交,最好使用计时器对象和队列。 计时器以固定速率无限期地运行(jQuery具有一些非常好的计时器实现),在计时器的主体中,您弹出队列中的某个内容并提交,然后完成。 然后,您的其他代码根据需要向该队列添加内容。


1
这听起来比尝试重构我的代码以使请求都在服务器端完成要好得多。jQuery中有内置的计时器还是作为插件添加进去的?你能推荐一个具体的吗? - Matt Ball
我个人使用过并且非常满意的一个插件可以在 http://plugins.jquery.com/project/timers 找到。祝好运! - Chris Thompson

1
这是我的脚本片段,基本上它会在遇到google.maps.GeocoderStatus.OVER_QUERY_LIMIT时再次尝试。
function(results, status) {
    // If the limit is reached try again in a second
        if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {

            window.setTimeout(
                function() {self.resolveAddress(addr);},1000
            );
        } else if (status == google.maps.GeocoderStatus.OK) {
            // Do something clever
        } else if (status == google.maps.GeocoderStatus.ZERO_RESULTS) {
            self.reduce(addr); // Try removing something from addr
        } else {
            atira.log('Something terrible happened');
        }
    });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接