【问题标题】:jQuery Geocode to get Postal AddressjQuery Geocode 获取邮政地址
【发布时间】:2011-11-12 00:24:05
【问题描述】:

我不擅长 jQuery 和 Javascript。我想使用这个现有的代码,让它以邮政格式向用户提供完整的地址......就像你放在信函或联邦快递信封上一样。

用户开始在地址框中键入地址,然后 jQuery 自动完成启动。当用户看到完整的地址时,他们然后单击地址,我希望它然后用用户选择传播一个测试框,但是在邮政格式。

这是 HTML 页面

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<title>Get Address Details</title>
        <script type="text/javascript" src="js/jquery-1.6.4.min.js"></script>
        <script src="http://maps.google.com/maps/api/js?sensor=false"></script>
        <script src="js/jquery-ui-1.8.7.min.js"></script>
        <script src="js/jquery.ui.addresspicker.js"></script>
        <script type="text/javascript">
            $(document).ready(function () {
                $( "#address1" ).addresspicker({
                              elements: {
                                locality: '#city',
                                lat:      '#lat',
                                lng:      '#lng',
                                country:  '#country'
                              }
                            });
        });
        </script>

</head>

<body>

 <form action="submit.php" method="post">
      <fieldset style="width: 300px; margin-bottom: 100px;"><legend>begin typing address</legend>
      <label for="address1">Input Address: </label><input name="address1" id="address1" type="text"><br /></fieldset>
      <fieldset style="width: 300px; text-align: right;"><legend>see results here</legend>
      <label for="address2">Street Address: </label><input name="address2" id="address2" type="text"><br />

      <label for="lat">Lat: </label><input name="lat" id="lat" type="text"><br />

      <label for="lng">Lng: </label><input name="lng" id="lng" type="text"><br />

      <label for="city">City: </label><input name="city" id="city" type="text"><br />

      <label for="country">Country: </label><input name="country" id="country" type="text"><br /><br />

      <label for="postal">Postal Address: </label><textarea name="postal" id="postal" ></textarea><br />

      </fieldset>

</form>
</body>

</html>

地址选择器的javascript页面如下,其他js页面为当前版本

/*
 * jQuery UI addresspicker @VERSION
 *
 * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Progressbar
 *
 * Depends:
 *   jquery.ui.core.js
 *   jquery.ui.widget.js
 *   jquery.ui.autocomplete.js
 */
(function( $, undefined ) {

$.widget( "ui.addresspicker", {
    options: {
      appendAddressString: "",
        mapOptions: {
          zoom: 5,
          center: new google.maps.LatLng(46, 2),
          scrollwheel: false,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        },
        elements: {
          map: false,
          lat: false,
          lng: false,
          locality: false,
          country: false
        },
      draggableMarker: true
    },

    marker: function() {
        return this.gmarker;
    },

    map: function() {
      return this.gmap;
    },

  updatePosition: function() {
    this._updatePosition(this.gmarker.getPosition());
  },

  reloadPosition: function() {
    this.gmarker.setVisible(true);
    this.gmarker.setPosition(new google.maps.LatLng(this.lat.val(), this.lng.val()));
    this.gmap.setCenter(this.gmarker.getPosition());
  },

  selected: function() {
    return this.selectedResult;
  },

    _create: function() {
      this.geocoder = new google.maps.Geocoder();
      this.element.autocomplete({
            source: $.proxy(this._geocode, this),
            focus:  $.proxy(this._focusAddress, this),
            select: $.proxy(this._selectAddress, this)
        });

        this.lat      = $(this.options.elements.lat);
        this.lng      = $(this.options.elements.lng);
        this.locality = $(this.options.elements.locality);
        this.country  = $(this.options.elements.country);
        if (this.options.elements.map) {
          this.mapElement = $(this.options.elements.map);
        this._initMap();
        }
    },

  _initMap: function() {
    if (this.lat && this.lat.val()) {
      this.options.mapOptions.center = new google.maps.LatLng(this.lat.val(), this.lng.val());
    }

    this.gmap = new google.maps.Map(this.mapElement[0], this.options.mapOptions);
    this.gmarker = new google.maps.Marker({
      position: this.options.mapOptions.center,
      map:this.gmap,
      draggable: this.options.draggableMarker});
    google.maps.event.addListener(this.gmarker, 'dragend', $.proxy(this._markerMoved, this));
    this.gmarker.setVisible(false);
  },

  _updatePosition: function(location) {
    if (this.lat) {
      this.lat.val(location.lat());
    }
    if (this.lng) {
      this.lng.val(location.lng());
    }
  },

  _markerMoved: function() {
    this._updatePosition(this.gmarker.getPosition());
  },

  // Autocomplete source method: fill its suggests with google geocoder results
  _geocode: function(request, response) {
    var address = request.term, self = this;
    this.geocoder.geocode( { 'address': address + this.options.appendAddressString}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        for (var i = 0; i < results.length; i++) {
          results[i].label =  results[i].formatted_address;
        };
      }
      response(results);
    })
  },

  _findInfo: function(result, type) {
    for (var i = 0; i < result.address_components.length; i++) {
      var component = result.address_components[i];
      if (component.types.indexOf(type) !=-1) {
        return component.long_name;
      }
    }
    return false;
  },

  _focusAddress: function(event, ui) {
    var address = ui.item;
    if (!address) {
      return;
    }

    if (this.gmarker) {
      this.gmarker.setPosition(address.geometry.location);
      this.gmarker.setVisible(true);

      this.gmap.fitBounds(address.geometry.viewport);
    }
    this._updatePosition(address.geometry.location);

    if (this.locality) {
      this.locality.val(this._findInfo(address, 'locality'));
    }

        if (this.address) {
      this.address.val(this._findInfo(address, 'address'));
    }
    if (this.country) {
      this.country.val(this._findInfo(address, 'country'));
    }
  },

  _selectAddress: function(event, ui) {
    this.selectedResult = ui.item;
  }
});

$.extend( $.ui.addresspicker, {
    version: "@VERSION"
});


// make IE think it doesn't suck
if(!Array.indexOf){
    Array.prototype.indexOf = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i]==obj){
                return i;
            }
        }
        return -1;
    }
}

})( jQuery );

【问题讨论】:

    标签: jquery autocomplete geocode picker street-address


    【解决方案1】:

    我认为对于您的情况,使用该插件可能有点过头了。它包括处理地图等的代码,您不仅需要自动完成地址。使用jQueryUI autocomplete(你已经依赖于插件)只需要几行代码。

    我会使用这样的东西:

    $(document).ready(function () {
        var geocoder = new google.maps.Geocoder();
        $("#address1").autocomplete({
            source: function (request, response) {
                geocoder.geocode({ address: request.term }, function (results, status) {
                if (status === google.maps.GeocoderStatus.OK) {
                  response($.map(results, function(result) {
                    if ($.inArray("street_address", result.types) >= 0) {
                        return result.formatted_address;
                    }
                  }));
                }
              });
            },
            select: function (event, ui) {
                var parts = ui.item.label.split(",")
                    , address1 = parts[0]
                    , address2 = parts.slice(1).join(",").trim();
                $("#postal").val(address1 + "\n" + address2);
            }
        });
    });
    

    (我尝试使用 jsfiddle 或类似工具作为示例,但这些服务无法与地图 API 配合使用)。

    重要的部分是:

    • 使用函数作为source 参数来自动完成。在该函数中,使用google.maps.Geocoder 对输入地址进行地理编码。
    • 在地理编码请求的回调中,使用格式化地址更新自动完成选项。

    用户选择地址后:

    • 用逗号分割地址。
    • 取地址的第一部分并将其与最后部分结合起来。
    • 用生成的字符串填充#postal 字段。

    【讨论】:

    • 好吧,你成功了!这正是我想要做的!
    【解决方案2】:

    您将需要一个地址数据库来执行此操作。您可能可以购买或找到类似于:http://www2.royalmail.com/marketing-services/address-management-unit/address-data-products/postcode-address-file-paf?campaignid=paf_redirect

    在每次用户开始输入时运行的自动完成功能中运行地理编码器是一个糟糕的主意。大多数这些网站对地理编码查询都有每日限制,否则您必须开始付费。

    【讨论】:

    • Google 地图 API 有每天 25,000 个请求的限制。也许OP不需要担心这个限制。无论哪种方式,OP 策略的那一部分似乎都超出了这个问题的范围(在我看来)。此外,OP 实际上可能已经为商业地图 API 密钥付费,这完全没有意义。
    • 是的,我认为地理编码 google maps api 每天比我需要的要多 1000 个。我只预计每天大约 10 次使用......所以我希望利用现有的数据库,而不是创建和获取大型数据库的工作。
    • 是的,Andrew 是对的,我在这方面走在了前面。我的立场是正确的(至少对于中小型流量网站而言)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    相关资源
    最近更新 更多