5

如果该线包含在模型中,则地理编码器gem 将在保存时自动反转地理编码。after_validation :reverse_geocode但是,这会导致将一长串文本保存为地址 - 格式类似于“街道名称、城市名称、县名称、州名称、邮政编码、国家名称”。

我只对这个特定项目的街道名称感兴趣,所以我想知道是否有办法修改after_validation调用以仅保存该信息。

如果我手动进行反向地理编码,我可以访问road结果中的值:

  place = Place.first
  result = Geocoder.search("#{place.latitude},#{place.longitude}")
  street = result[0].data['address']['road']

我可以设置自己的自定义来执行此操作,但如果已提供此after_validation功能,我宁愿不复制功能。geocoder

或者,如果有一种完全不同的方式可以将纬度/经度转换为街道名称,我将有兴趣了解它。如果此选项也包括地址编号或地址范围,那就可以了。

4

2 回答 2

10

您可以通过提供一个块来自定义 reverse_geocode 方法,该块将要进行地理编码的对象和一个 Geocoder::Result 对象数组。

reverse_geocoded_by :latitude, :longitude do |obj,results|
  if geo = results.first
    obj.street = geo.address
  end
end

after_validation :reverse_geocode

每个 Geocoder::Result 对象 result 提供以下数据:

result.latitude - float
result.longitude - float
result.coordinates - array of the above two
result.address - string
result.city - string
result.state - string
result.state_code - string
result.postal_code - string
result.country - string
result.country_code - string

更多信息可以在地理编码文档中找到。您甚至可以找到更多可以从Geocoder::Result对象中提取的字段。

于 2013-03-19T01:50:52.413 回答
3

您可以使用:data 方法从您正在使用的选定地理编码服务中访问所有属性。

query = "45.679, -45.567"
result = Geocoder.search(query).first 

if (result) 
   all_attributes = result.data
end

这将返回您特定坐标的所有可用键和值的 JSON 响应。如果您使用 Google 来反向地理编码,那么您会收到类似于以下内容的响应:

{
         "address_components" : [
            {
               "long_name" : "1600",
               "short_name" : "1600",
               "types" : [ "street_number" ]
            },
            {
               "long_name" : "Amphitheatre Pkwy",
               "short_name" : "Amphitheatre Pkwy",
               "types" : [ "route" ]
            },
            {
               "long_name" : "Mountain View",
               "short_name" : "Mountain View",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "Santa Clara County",
               "short_name" : "Santa Clara County",
               "types" : [ "administrative_area_level_2", "political" ]
            },
            {
               "long_name" : "California",
               "short_name" : "CA",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "United States",
               "short_name" : "US",
               "types" : [ "country", "political" ]
            },
            {
               "long_name" : "94043",
               "short_name" : "94043",
               "types" : [ "postal_code" ]
            }
         ],
         "formatted_address" : "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
         "geometry" : {
            "location" : {
               "lat" : 37.4224764,
               "lng" : -122.0842499
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 37.4238253802915,
                  "lng" : -122.0829009197085
               },
               "southwest" : {
                  "lat" : 37.4211274197085,
                  "lng" : -122.0855988802915
               }
            }
         },
         "place_id" : "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
         "types" : [ "street_address" ]
      }

因此,只需深入了解 JSON 即可获得所需的内容:

result.data["address_components"].each do |component|

  if component["types"].include?("route")
    street = component["long_name"]
  end

end

请注意,您使用的每个地理编码服务的格式都会有所不同:这是另一个使用 Yandex 的示例:

street = result.data["GeoObject"]["metaDataProperty"]["GeocoderMetaData"]["AddressDetails"]["Country"]["AdministrativeArea"]["SubAdministrativeArea"]["Locality"]["Thoroughfare"]["ThoroughfareName"]
于 2015-05-15T20:05:27.167 回答