智能位置表单字段

时间:2011-04-05 16:39:21

标签: php jquery html5 geolocation location

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

我基本上希望此字段能够针对Google地图(或等效)进行验证 - 只允许有效位置通过(理想情况下采用的格式为滑铁卢,伦敦伦敦,英格兰)。

要求

  1. 除了位置名称,我还希望返回该位置中心的坐标(lat,lng)(即使是广泛的,例如伦敦,英格兰),因为我将会交叉引用它以向用户提供相关信息。
  2. 当用户在字段中输入时,基于有效位置(理想情况下只是政治位置 - 而非特定街道)的自动填充列表/智能建议列表*(编辑:见下文)。
  3. 强制用户使用自动填充列表中的位置。
  4. 允许此字段的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);
    })
    

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

    任何能够改善这一点的人都会得到正确答案!

    由于

2 个答案:

答案 0 :(得分:3)

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

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

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

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

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

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

答案 1 :(得分:0)

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

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

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

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

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

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

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