使用地理编码器从纬度/经度获取子位置或邻域

时间:2014-09-22 01:15:14

标签: google-maps ruby-on-rails-4 rails-geocoder

使用Geocoder,我已经能够解析给定的纬度/经度并获得城市,省等。虽然我需要的是子地区,但我还没有看到变量为了那个原因。我一直在使用Google地图自动填充功能,并且很多建议中都有子地区。例如,从安大略省多伦多的Etobicoke,我需要抓住Etobicoke。有没有办法用Geocoder做到这一点?

  @location = Geocoder.coordinates(params[:search_address])
  result = Geocoder.search(@location).first
  cookies[:display_location] = "#{need the region here}, #{result.city}, #{result.state_code}"

1 个答案:

答案 0 :(得分:1)

答案比我想象的要简单,我只是不清楚正在寻找的位置类型的正确术语。在Geocoder :: Result模块中,我找到了方法neighborhood

module Geocoder::Result
  class Google < Base

    def coordinates
      ['lat', 'lng'].map{ |i| geometry['location'][i] }
    end

    def address(format = :full)
      formatted_address
    end

    def neighborhood
      if neighborhood = address_components_of_type(:neighborhood).first
        neighborhood['long_name']
      end
    end

    def city
      fields = [:locality, :sublocality,
        :administrative_area_level_3,
        :administrative_area_level_2]
      fields.each do |f|
        if entity = address_components_of_type(f).first
          return entity['long_name']
        end
      end
      return nil # no appropriate components found
    end

    def state
      if state = address_components_of_type(:administrative_area_level_1).first
        state['long_name']
      end
    end

    def state_code
      if state = address_components_of_type(:administrative_area_level_1).first
        state['short_name']
      end
    end

    def sub_state
      if state = address_components_of_type(:administrative_area_level_2).first
        state['long_name']
      end
    end

    def sub_state_code
      if state = address_components_of_type(:administrative_area_level_2).first
        state['short_name']
      end
    end

    def country
      if country = address_components_of_type(:country).first
        country['long_name']
      end
    end

    def country_code
      if country = address_components_of_type(:country).first
        country['short_name']
      end
    end

    def postal_code
      if postal = address_components_of_type(:postal_code).first
        postal['long_name']
      end
    end

    def route
      if route = address_components_of_type(:route).first
        route['long_name']
      end
    end

    def street_number
      if street_number = address_components_of_type(:street_number).first
        street_number['long_name']
      end
    end

    def street_address
      [street_number, route].compact.join(' ')
    end

    def types
      @data['types']
    end

    def formatted_address
      @data['formatted_address']
    end

    def address_components
      @data['address_components']
    end

    ##
    # Get address components of a given type. Valid types are defined in
    # Google's Geocoding API documentation and include (among others):
    #
    #   :street_number
    #   :locality
    #   :neighborhood
    #   :route
    #   :postal_code
    #
    def address_components_of_type(type)
      address_components.select{ |c| c['types'].include?(type.to_s) }
    end

    def geometry
      @data['geometry']
    end

    def precision
      geometry['location_type'] if geometry
    end
  end
end

我是编码的新手,这可能会被重构,但这就是我正在使用的:

      @latlng = Geocoder.coordinates(params[:searched_address])
      result = Geocoder.search(@latlng).first

      if result.address_components_of_type(:neighborhood).first.nil?
          @display_location = "#{result.city}, #{result.state_code}"
      else
          neighborhood = result.address_components_of_type(:neighborhood).first['short_name']
          @display_location = "#{neighborhood}, #{result.city}, #{result.state_code}"
      end

大多数地址都没有sublocality,所以我使用if语句来防止它在返回nil值时失败。如果您使用neighborhood切换sublocality,它可能会为您提供更好的结果。我还是要玩弄它。