解析谷歌地理编码

时间:2009-10-25 04:16:58

标签: ruby-on-rails api geocoding

我在我的应用中使用谷歌地理编码api但我发现很难可靠地解析返回的地址信息。我希望有人有一个图书馆或解析信息的方式,以防止我写这个我自己并涵盖每个案例。

我使用json api,可以轻松提取地址线和坐标 并将它们存储在数据库中,但问题是以可靠的方式提取其他地址信息,以便我可以存储它。

我已经看过谷歌用于地理编码数据的XAL结构化地址规范,但我的问题是,它可以满足每个国家/地区的每种地址类型,从而难以解析结果。

像邮政编码一样简单的东西可以嵌套在任何父标签组合的深处。即使在一个国家内,树的出现方式也会有所不同,这使得解析比预期更难。

具有讽刺意味的是,我的最终目标是将其存储在我的数据库中的树(想想rails acts_as_tree或类似物)中,以便用户以后可以轻松找到这些项目。例如,点击国家,州,地区,城镇,然后郊区等

我在rails工作

2 个答案:

答案 0 :(得分:2)

有一个gem和插件可以为您封装所有这些内容。它被称为GeoKit

可以使用Google或少数其他地理编码服务提供商。如果你的模型有适当的字段,它也可以进行距离计算(真正干净的是数学,这是在SQL中完成的)。

我一直在我的一个生产应用程序中使用它来计算例如zipcodes之间的距离。正如我所提到的,我已经在生产中使用它已经有一段时间了,所以我对代码的完整性没有任何担忧。

答案 1 :(得分:1)

我已经做了几次。他们的(谷歌)示例代码有效,但很脆弱 - 你从谷歌回来的地理编码数据最多是不完整的,最坏的是不一致。

反正。所有的地理编码器都很糟糕,但至少谷歌是免费的,并且比其他人更糟糕......要求一致性是不是太过分了?叹。尝试以下方法;你传给它一个地标(注意getLocations AJAX方法可能会返回多个),它会规范化结果。如果你想获得幻想,请使用placemark.address字段 - 有时它将包含比单个字段更多的信息。通常情况下,它只包含您实际发送的要进行地理编码的文本。

function Mark(placemark) {
  this.latitude = 0.0;
  this.longitude = 0.0;
  this.accuracy = 0;
  this.country = null;
  this.region = null;
  this.city = null;
  this.postalCode = null;
  this.street = null;
  this.address = null;
  this.placemark = placemark;

  if (placemark) {
    if (placemark.Point && placemark.Point.coordinates) {
      this.latitude = placemark.Point.coordinates[0];
      this.longitude = placemark.Point.coordinates[1];
    }

    var elem = placemark.AddressDetails;

    if (elem) {
      this.accuracy = elem.Accuracy;

      if (elem.Country) {
        elem = elem.Country;
        this.country = elem.CountryNameCode;
      }

      if (elem.AdministrativeArea) {
        elem = elem.AdministrativeArea;
        this.region = elem.AdministrativeAreaName;
      }

      if (elem.SubAdministrativeArea) {
        elem = elem.SubAdministrativeArea;
      }

      if (elem.Locality) {
        elem = elem.Locality;
        this.city = elem.LocalityName;
      }

      if (elem.PostalCode) {
        this.postalCode = elem.PostalCode.PostalCodeNumber;
      }

      if (elem.Thoroughfare) {
        this.street = elem.Thoroughfare.ThoroughfareName;
      }
    }
  }
}