<commit_before>module Geocoder
  module Lookup
    extend self

    ##
    # Query Google for the coordinates of the given phrase.
    # Returns array [lat,lon] if found, nil if not found or if network error.
    #
    def coordinates(query)
      return nil unless doc = search(query)
      # blindly use the first results (assume they are most accurate)
      place = doc['results'].first['geometry']['location']
      ['lat', 'lng'].map{ |i| place[i] }
    end


    private # ---------------------------------------------------------------

    ##
    # Query Google for geographic information about the given phrase.
    # Returns a hash representing a valid geocoder response.
    # Returns nil if non-200 HTTP response, timeout, or other error.
    #
    def search(query)
      doc = fetch_parsed_response(query)
      doc && doc['status'] == "OK" ? doc : nil
    end

    ##
    # Returns a parsed Google geocoder search result (hash).
    # This method is not intended for general use (prefer Geocoder.search).
    #
    def fetch_parsed_response(query)
      if doc = fetch_raw_response(query)
        ActiveSupport::JSON.decode(doc)
      end
    end

    ##
    # Returns a raw Google geocoder search result (JSON).
    # This method is not intended for general use (prefer Geocoder.search).
    #
    def fetch_raw_response(query)
      return nil if query.blank?

      # build URL
      params = { :address => query, :sensor  => "false" }
      url = "http://maps.google.com/maps/api/geocode/json?" + params.to_query

      # query geocoder and make sure it responds quickly
      begin
        resp = nil
        timeout(3) do
          Net::HTTP.get_response(URI.parse(url)).body
        end
      rescue SocketError, TimeoutError
        return nil
      end
    end
  end<commit_msg>Add Geocoder::Lookup.address for reverse geocoding.<commit_after>module Geocoder
  module Lookup
    extend self

    ##
    # Query Google for the coordinates of the given address.
    # Returns array [lat,lon] if found, nil if not found or if network error.
    #
    def coordinates(address)
      return nil unless doc = search(address, false)
      # blindly use first result (assume it is most accurate)
      place = doc['results'].first['geometry']['location']
      ['lat', 'lng'].map{ |i| place[i] }
    end

    ##
    # Query Google for the address of the given coordinates.
    # Returns string if found, nil if not found or if network error.
    #
    def address(latitude, longitude)
      return nil unless doc = search("#{latitude},#{longitude}", true)
      # blindly use first result (assume it is most accurate)
      doc['results'].first['formatted_address']
    end


    private # ---------------------------------------------------------------

    ##
    # Query Google for geographic information about the given phrase.
    # Returns a hash representing a valid geocoder response.
    # Returns nil if non-200 HTTP response, timeout, or other error.
    #
    def search(query, reverse = false)
      doc = fetch_parsed_response(query, reverse)
      doc && doc['status'] == "OK" ? doc : nil
    end

    ##
    # Returns a parsed Google geocoder search result (hash).
    # This method is not intended for general use (prefer Geocoder.search).
    #
    def fetch_parsed_response(query, reverse = false)
      if doc = fetch_raw_response(query, reverse)
        ActiveSupport::JSON.decode(doc)
      end
    end

    ##
    # Returns a raw Google geocoder search result (JSON).
    # This method is not intended for general use (prefer Geocoder.search).
    #
    def fetch_raw_response(query, reverse = false)
      return nil if query.blank?

      # name parameter based on forward/reverse geocoding
      param = reverse ? :latlng : :address

      # build URL
      params = { param => query, :sensor  => "false" }
      url = "http://maps.google.com/maps/api/geocode/json?" + params.to_query

      # query geocoder and make sure it responds quickly
      begin
        resp = nil
        timeout(3) do
          Net::HTTP.get_response(URI.parse(url)).body
        end
      rescue SocketError, TimeoutError
        return nil
      end
    end
  end
{'fraction_non_alphanumeric': 0.11968466316292403, 'fraction_numerical': 0.0019111323459149545, 'mean_word_length': 2.278778386844166, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6501999', 'n_tokens_mistral': 1165, 'n_tokens_neox': 1144, 'n_words': 408}