Ruby Geocoder可以在reverse_geocode调用中返回街道名称吗?

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

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

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

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

我可以设置我自己的自定义after_validation ,但是如果geocoder已经提供了这个function,我宁愿不重复function。

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

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

 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对象中Geocoder::Result字段。

您可以使用: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"]