Search code examples
ruby-on-railsrails-geocoder

Can Ruby Geocoder return just the street name on reverse_geocode calls?


The geocoder gem will automatically reverse geocode on save if the line after_validation :reverse_geocode is included in the model. This results in a long string of text being saved as the address, though - the format is something like "Street Name, City Name, County Name, State Name, Zip Code, Country Name".

I'm only interested in the street name for this particular project, so I'm wondering if there's a way to modify the after_validation call to only save that information.

If I do the reverse geocoding manually, I can access the road value in the result:

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

I could set up my own custom after_validation that does just this, but I'd rather not duplicate functionality if geocoder already provides this.

Alternatively, if there's an entirely different way that I can convert latitude/longitude to street name I'd be interested in hearing about it. It would be OK if this option included the address number or address range as well.


Solution

  • You can customize the reverse_geocode method by providing a block which takes the object to be geocoded and an array of Geocoder::Result objects.

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

    Every Geocoder::Result object, result, provides the following data:

    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
    

    More information can be found in the geocode docs. You might even be able to find more fields that you can pull off of the Geocoder::Result object.