如果模型中包含行after_validation :reverse_geocode
,geocoder gem将自动反转地理编码。这导致一长串文本被保存为地址,但格式类似于“街道名称,城市名称,县名,州名,邮政编码,国家名称”。
我只对这个特定项目的街道名称感兴趣,所以我想知道是否有办法修改after_validation
调用以仅保存该信息。
如果我手动执行反向地理编码,我可以访问结果中的road
值:
place = Place.first
result = Geocoder.search("#{place.latitude},#{place.longitude}")
street = result[0].data['address']['road']
我可以设置我自己的自定义after_validation
,但是如果geocoder
已经提供此功能,我宁愿不重复功能。
或者,如果有一种完全不同的方式可以将纬度/经度转换成街道名称,我会有兴趣听到它。如果此选项也包含地址编号或地址范围,则可以。
答案 0 :(得分:9)
您可以通过提供一个使对象进行地理编码的块和一个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
可以在geocode docs中找到更多信息。您甚至可以找到更多可以从Geocoder::Result
对象中删除的字段。
答案 1 :(得分:3)
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"]