class Geokit::Geocoders::BingGeocoder

Bing geocoder implementation. Requires the Geokit::Geocoders::bing variable to contain a Bing Maps API key. Conforms to the interface set by the Geocoder class.

Constants

ACCURACY_MAP
PRECISION_MAP
XML_MAPPINGS

Private Class Methods

do_geocode(address, _=nil) click to toggle source

Template method which does the geocode lookup.

# File lib/geokit/geocoders/bing.rb, line 12
def self.do_geocode(address, _=nil)
  url = submit_url(address)
  res = call_geocoder_service(url)
  return GeoLoc.new unless net_adapter.success?(res)
  xml = res.body.encode!('UTF-8', 'UTF-8', invalid: :replace)
  parse :xml, xml
end
extract_location(xml) click to toggle source

extracts a single geoloc from a //Location element in the bing results xml

# File lib/geokit/geocoders/bing.rb, line 40
def self.extract_location(xml)
  loc                 = new_loc
  set_address_components(loc, xml)
  set_precision(loc, xml)
  set_bounds(loc, xml)
  loc.success         = true
  loc
end
parse_xml(xml) click to toggle source
# File lib/geokit/geocoders/bing.rb, line 27
def self.parse_xml(xml)
  return GeoLoc.new if xml.elements['//Response/StatusCode'].try(:text) != '200'
  loc = nil
  # Bing can return multiple results as //Location elements.
  # iterate through each and extract each location as a geoloc
  xml.each_element('//Location') do |l|
    extracted_geoloc = extract_location(l)
    loc.nil? ? loc = extracted_geoloc : loc.all.push(extracted_geoloc)
  end
  loc
end
set_address_components(loc, xml) click to toggle source
# File lib/geokit/geocoders/bing.rb, line 61
def self.set_address_components(loc, xml)
  set_mappings(loc, xml, XML_MAPPINGS)
end
set_bounds(loc, xml) click to toggle source
# File lib/geokit/geocoders/bing.rb, line 93
def self.set_bounds(loc, xml)
  suggested_bounds = xml.elements['.//BoundingBox']
  if suggested_bounds
    bounds = suggested_bounds.elements
    loc.suggested_bounds = Bounds.normalize(
      [bounds['.//SouthLatitude'].text, bounds['.//WestLongitude'].text],
      [bounds['.//NorthLatitude'].text, bounds['.//EastLongitude'].text])
  end
end
set_precision(loc, xml) click to toggle source
# File lib/geokit/geocoders/bing.rb, line 83
def self.set_precision(loc, xml)
  if xml.elements['.//Confidence']
    loc.accuracy = ACCURACY_MAP[xml.elements['.//Confidence'].text] || 0
  end

  if xml.elements['.//EntityType']
    loc.precision = PRECISION_MAP[xml.elements['.//EntityType'].text] || 'unknown'
  end
end
submit_url(address) click to toggle source
# File lib/geokit/geocoders/bing.rb, line 20
def self.submit_url(address)
  culture = options && options[:culture]
  culture_string = culture ? "&c=#{culture}" : ''
  address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address
  "#{protocol}://dev.virtualearth.net/REST/v1/Locations/#{URI.escape(address_str)}?key=#{key}#{culture_string}&o=xml"
end