ruby 实现 bing 的 geocode 博客分类: bing geo code bingrubygeocode
程序员文章站
2024-02-06 20:25:28
...
项目中需要进行geo_code
刚开始用的是geokit的gem, 支持多个api, google和yahoo 但是没有bing的, 客户又要求使用bing的
没办法, 搜, geocoder(https://github.com/alexreisner/geocoder)中支持bing的, 但是从rails3良好支持, rails2 的分支中好像没提到,无奈项目又是rails2.3.8的, 所以我把geo_coder源码中的bing部分抠了下来
注: 先去bing申请api key www.bingmapsportal.com
刚开始用的是geokit的gem, 支持多个api, google和yahoo 但是没有bing的, 客户又要求使用bing的
没办法, 搜, geocoder(https://github.com/alexreisner/geocoder)中支持bing的, 但是从rails3良好支持, rails2 的分支中好像没提到,无奈项目又是rails2.3.8的, 所以我把geo_coder源码中的bing部分抠了下来
注: 先去bing申请api key www.bingmapsportal.com
require 'net/http' require 'uri' require 'rubygems' require 'json' class Address def geocode(address) results(address) end def results(query) return [] unless doc = fetch_data(query) if doc['statusDescription'] == "OK" return doc['resourceSets'].first['estimatedTotal'] > 0 ? doc['resourceSets'].first['resources'] : [] else warn "Bing Geocoding API error: #{doc['statusCode']} (#{doc['statusDescription']})." return [] end end def query_url(query) params = {:key => "API-Key"} params[:query] = query base_url = "http://dev.virtualearth.net/REST/v1/Locations" url_tail = "?" base_url + url_tail + hash_to_query(params) end def hash_to_query(hash) require 'cgi' unless defined?(CGI) && defined?(CGI.escape) hash.collect{ |p| p[1].nil? ? nil : p.map{ |i| CGI.escape i.to_s } * '=' }.compact.sort * '&' end def fetch_data(query) begin parse_raw_data fetch_raw_data(query) rescue SocketError => err raise_error(err) or warn "Geocoding API connection cannot be established." rescue TimeoutError => err raise_error(err) or warn "Geocoding API not responding fast enough " + "(see Geocoder::Configuration.timeout to set limit)." end end ## # Fetches a raw search result (JSON string). # def fetch_raw_data(query) timeout(30) do url = query_url(query) uri = URI.parse(url) client = http_client.new(uri.host, uri.port) response = client.get(uri.request_uri).body response end end ## # Parses a raw search result (returns hash or array). # def parse_raw_data(raw_data) if defined?(ActiveSupport::JSON) ActiveSupport::JSON.decode(raw_data) else begin JSON.parse(raw_data) rescue warn "Geocoding API's response was not valid JSON." end end end ## # Object used to make HTTP requests. # def http_client Net::HTTP end end address = Address.new address.geocode("25 Main St, Cooperstown, NY")