我在 location 的用户注册表单上有一个文本字段。
我基本上希望此字段能够针对Google地图(或等效)进行验证 - 只允许有效位置通过(理想情况下采用的格式为滑铁卢,伦敦或伦敦,英格兰)。
要求:
允许此字段的Privilages将使用HTML5 Geolocation API自动填充以获取用户lat lng然后转换为一般位置(即一般城镇 - 有点像当您点击'添加您的位置'时Chrome的Tweetdeck)。 / p>
问题是 - 解决这个问题的最佳方式是什么?我使用什么API?我将使用API的哪些部分来实现这一目标?
* 修改:在尝试使用Google Maps API v3地理编码后,似乎存在关于结果的问题(错误或设计我不确定 - http://code.google.com/p/gmaps-api-issues/issues/detail?id=2042)。例如,如果我输入滑铁卢,我得到的只是加拿大滑铁卢。所有其他滑铁卢http://en.wikipedia.org/wiki/Waterloo怎么样?我想要一个X多个列表(其中X!== 1)供用户选择。理想情况下,我预定义了X.另外,如果我在表单字段中键入“L”,我希望看到按最有可能的顺序返回的相关建议列表(可能受到偏差GeocodeRequest参数的影响) - 所以伦敦,英国,利物浦,英国,利兹,英国等。相反,我得到林堡,荷兰 - 1个随机结果。 WTF?通过Google Maps API执行此操作的替代方法是什么?
*的更新/解决方案: 好吧,我已经研究了一些使用地理名http://jsfiddle.net/ekzMN/95/的东西。虽然我确信它可以大规模改进,但它的工作非常好。您可以随意使用此代码。在我的真实世界示例中,我还将谷歌地理编码添加为辅助源,因为它比地理名称更聪明(即,如果我输入邮政编码或街道地址)。这取决于初始化Geocoder:
// Get more specific results from Google geocode
geocoder.geocode( { 'address': request.term, 'region': 'GB' }, function(results, status) {
$.map(results, function(item) {
var ignore = ['route', 'country', 'natural_feature', 'intersection', 'premise', 'subpremise', 'airport', 'park', 'point_of_interest', 'establishment', 'transit_station'];
if (valid_location(item.types, ignore) == 1) {
var sublocality;
var locality;
var region;
var country;
$.each(item.address_components, function (i, data) {
if ($.inArray('sublocality', data.types) > -1) {
sublocality = data.long_name;
}
if ($.inArray('locality', data.types) > -1) {
if (typeof sublocality == 'undefined') {
sublocality = data.long_name;
}
}
if ($.inArray('administrative_area_level_2', data.types) > -1) {
locality = data.long_name;
}
if ($.inArray('administrative_area_level_1', data.types) > -1) {
region = data.long_name;
}
if ($.inArray('country', data.types) > -1) {
country = data.long_name;
}
});
if ((country != 'United Kingdom') || ($.inArray('administrative_area_level_1', item.types) == -1)) {
var location = format_location(sublocality, locality, region, country);
if (duplicate(matches, location) == 0) {
matches.push({
label: location,
value: location,
latitude: item.geometry.location.lat(),
longitude: item.geometry.location.lng()
});
}
}
}
});
// Update autocomplete
response(matches);
})
两者的结合很好地提供了智能搜索和多种建议。困扰我的一个问题是,当我使用两个来源(地理名称和谷歌地理编码)时,输入选择范围非常不可靠 - 有时它会自动填充,选择附加部分,然后按原样保持突出显示,有时蓝色突出显示消失(虽然它仍然存在,即在按键上选择消失),而其他时候光标直接到输入的末尾。我认为与谷歌地图存在一些冲突,而不是多个源问题,因为如果我有两个地理名称来源,这不会发生吗?
任何能够改善这一点的人都会得到正确答案!
由于
答案 0 :(得分:3)
这里有一个相关的jQuery插件页面: http://plugins.jquery.com/plugin-tags/geocoding
具体来说,对于您的问题:
Google地理编码默认执行此操作。它将为广泛的区域等提供中心坐标。相关问题在这里:using jquery.getJson with Google's GeoCoding HTTP Service
这是大部分表单验证。您应该能够简单地执行最终的自动完成查找,如果它没有返回任何建议,则标记警告等。
关于使用哪些部分,这取决于您。更进一步,我们将为您编写它。我相信上面的许多API都有你可以收集的例子。
答案 1 :(得分:0)
好的..所以看看你的“解决方案”,我注意到了几个问题。首先,它在我尝试的每个浏览器中完全中断....
经过一些修复后,我发现了一些与您的“解决方案”有关的问题:
.autocomplete()
是一个初始化函数。不需要在每个keyup
上调用它。在jQuery元素上调用.autocomplete()
后自动处理。每次keyup
调用它都会导致巨大的性能损失以及其他一些神秘和/或意外的后果。
将合法值存储在全局变量中,然后使用blur
检查这些是一个坏主意。虽然我没有出售存储autocomplete
所带来的每一个合法价值的想法,但我现在想不出更好的解决方案。我所做的是将每个合法值存储在输入项的.data()
中,以便在.blur()
上进行检查。它存储为散列/关联数组,这意味着我们可以免费删除重复项。
如果您希望用户仅从后端选择合法值,则最佳解决方案是在表单提交时针对后端验证输入。 (Blur
存在问题,因为在填写所选值之前,从autocomplete
建议中选择项目会固有地模糊输入。换句话说,您很可能会找到无效的位置。)这需要您保存作为匹配数据的一部分,可以将一个字符串发送回服务器进行验证。另一个问题是,如果您的服务器速度较慢,例如GeoNames可以免费访问,则可能无法立即获得用户反馈。
话虽如此,我已修复您的代码(关于上面的第1点和第2点)以正确调用autocomplete
,并将有效的解决方案存储在input
对象中作为jQuery数据。我还将它编码为扩展,因此可以在任何jQuery选择器上调用它: