Search code examples
ruby-on-railsrubygeocodinggeocoderails-geocoder

Ruby on Rails - Restrict geocoder response to city and get the ID


I have a Ruby on Rails project with the users table and I need to store the location_id from the user input.

  • If user types Buckingham Palace then the location_id should be the london_id

  • If user types Wall Street then the location_id should be the new_york_id

  • If user types Statue of Liberty then the location_id should be the new_york_id

  • If user types United States then the location_id should be nil

I am using geocoder gem, but I'm failing retrieving the city ID. For instance:

Geocoder.search("London").first.place_id # => ChIJdd4hrwug2EcRmSrV3Vo6llI
Geocoder.search("Buckingham Palace").first.place_id # => ChIJtV5bzSAFdkgRpwLZFPWrJgo

I need both to be ChIJdd4hrwug2EcRmSrV3Vo6llI (the London ID)


Solution

  • Here's my updated answer. It is integrated in Geocoder structure, and only needs one search if the query is a city name :

    require 'geocoder'
    
    module Geocoder
      # Returns the Google ID of the city containing the queried location. Returns nil if nothing found or if location contains multiple cities.
      def self.get_city_id(query, options={})
        results = search(query, options)
        unless results.empty?
          result = results.first
          city = result.city
          if city then
            if city == query then
              result.place_id
            else
              sleep(1)
              search(city,options).first.place_id
            end
          end
        end
      end
    end
    
    Geocoder::Configuration.timeout = 15
    
    ["London", "Buckingham Palace", "Wall Street", "Statue of Liberty Monument", "United States", "WEIRDqueryWithNoResult"].each{|query|
      puts query
      puts Geocoder.get_city_id(query).inspect
      sleep(1)
    }
    

    It outputs :

    London
    "ChIJdd4hrwug2EcRmSrV3Vo6llI"
    Buckingham Palace
    "ChIJdd4hrwug2EcRmSrV3Vo6llI"
    Wall Street
    "ChIJOwg_06VPwokRYv534QaPC8g"
    Statue of Liberty Monument
    "ChIJOwg_06VPwokRYv534QaPC8g"
    United States
    nil
    WEIRDqueryWithNoResult
    nil
    

    For documentation purpose, here is my original answer:

    require 'geocoder'
    
    
    def get_city(search_term)
      Geocoder.search(search_term).first.city
    end
    
    def get_place_id(search_term)
      Geocoder.search(search_term).first.place_id
    end
    
    ["London", "Buckingham Palace", "Wall Street", "Statue of Liberty Monument", "United States"].each{|term|
      puts (city=get_city(term)) && sleep(1) && get_place_id(city)
      sleep(1)
    }