智能位置表单字段

我在位置的用户注册表单上有一个文本字段。

我基本上希望这个字段能够针对谷歌地图(或等效)进行validation – 只允许有效的地点通过(理想情况下是滑铁卢,伦敦伦敦,英格兰 )。

要求

  1. 除了位置名称,我还想返回该位置中心的坐标(lat,lng)(即使是广泛的,例如伦敦,英格兰 ),因为我将交叉引用它以向用户提供相关信息。
  2. 当用户在字段中键入时,基于有效位置(理想情况下只是政治位置 – 而不是特定街道)的自动完成列表/智能建议列表*( 编辑 :见下文)。
  3. 强制用户使用自动完成列表中的位置。

允许此字段的Privilages将使用HTML5 Geolocation API自动填充以获取用户lat lng然后转换为一般位置(即一般城镇 – 有点像当您点击’添加您的位置’时Chrome的Tweetdeck)。

问题是 – 解决这个问题的最佳方式是什么? 我使用什么API? 我使用API​​的哪些部分来实现这一目标?

* 编辑 :在尝试使用Google Maps API v3地理编码后,似乎存在关于结果的问题(错误或设计我不确定 – http://code.google.com/p/gmaps-api-issues/问题/细节?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); }) 

两者的结合很好地提供了智能搜索和多种建议。 困扰我的一个问题是,当我使用两个来源(地理名称和谷歌地理编码)时,输入选择范围非常不可靠 – 有时它会自动填充,选择附加部分,然后按原样保持高亮显示,有时蓝色突出显示消失(虽然它仍然存在,即在按键上选择消失,而其他时候光标直接到输入的结尾。 我认为与谷歌地图有些冲突,而不是多个源问题,因为如果我有两个地理名称来源,这不会发生?

正确的答案是任何可以改善这一点的人!

谢谢

好的……所以看看你的“解决方案”,我注意到了几个问题。 首先,它在我尝试的每个浏览器中完全中断….

经过一些修复后,我发现了一些与您的“解决方案”有关的问题:

  1. .autocomplete()是一个初始化函数。 不需要在每个keyup上调用它。 在jQuery元素上调用.autocomplete()之后自动处理。 在每个keyup上调用它将导致巨大的性能损失以及许多其他神秘和/或意外后果。

  2. 将合法值存储在全局变量中,然后使用blur来检查这些是一个坏主意。 虽然我没有出售存储autocomplete所带来的每个合法价值的想法,但我现在想不出更好的解决方案。 我所做的是将每个合法值存储在输入项的.data()中,以便在.blur()上进行检查。 它存储为散列/关联数组,这意味着我们可以免费删除重复项。

  3. 如果您希望用户仅从后端选择合法值,最佳解决方案是在表单提交时针对后端validation输入。 ( Blur有问题,因为从autocomplete建议中选择项目会在填写所选值之前固有地模糊输入。换句话说,您很可能会有一个无效的位置。)这将要求您保存,作为匹配数据的一部分,一个可以发送回服务器进行validation的字符串。 另一个问题是,如果您的服务器速度较慢,例如GeoNames免费访问,则可能无法立即获得用户的反馈。

话虽这么说,我已经修复了你的代码(关于上面的第1点和第2点)来正确调用autocomplete ,并将有效的解决方案作为jQuery数据存储在input对象中。 我还将它编码为扩展,因此可以在任何jQuery选择器上调用它:

http://jsfiddle.net/jtbowden/7NmLr/

这里有一页相关的jQuery插件: http : //plugins.jquery.com/plugin-tags/geocoding

具体来说,对于您的问题:

  1. Google地理编码默认执行此操作。 它将为广泛的区域等提供中心坐标。相关问题在这里: 使用jquery.getJson和Google的GeoCoding HTTP服务

  2. http://code.google.com/p/geo-autocomplete/就是一个例子

  3. 这是大多数情况下的表单validation。 您应该能够简单地执行最终的自动完成查找,如果它没有返回任何建议,则标记警告等。

至于使用哪些部分,这取决于您。 更进一步,我们会为你写它。 我相信上面的许多API都有你可以收集的例子。