class Geokit::Geocoders::OsmGeocoder

Open Street Map geocoder implementation.

Private Class Methods

do_geocode(address, options = {}) click to toggle source

Template method which does the geocode lookup.

# File lib/geokit/geocoders/openstreetmap.rb, line 8
def self.do_geocode(address, options = {})
  options_str = generate_bool_param_for_option(:polygon, options)
  options_str << generate_param_for_option(:json_callback, options)
  options_str << generate_param_for_option(:countrycodes, options)
  options_str << generate_param_for_option(:viewbox, options)
  options_str << generate_param_for_option(:'accept-language', options)
  options_str << generate_param_for_option(:email, options)

  address_str = address.is_a?(GeoLoc) ? address.to_geocodeable_s : address

  url = "https://nominatim.openstreetmap.org/search?format=json#{options_str}&addressdetails=1&q=#{Geokit::Inflector.url_escape(address_str)}"
  process :json, url
end
do_reverse_geocode(latlng, options = {}) click to toggle source
# File lib/geokit/geocoders/openstreetmap.rb, line 22
def self.do_reverse_geocode(latlng, options = {})
  latlng = LatLng.normalize(latlng)
  options_str = generate_param_for(:lat, latlng.lat)
  options_str << generate_param_for(:lon, latlng.lng)
  options_str << generate_param_for_option(:'accept-language', options)
  options_str << generate_param_for_option(:email, options)
  options_str << generate_param_for_option(:zoom, options)
  options_str << generate_param_for_option(:osm_type, options)
  options_str << generate_param_for_option(:osm_id, options)
  options_str << generate_param_for_option(:json_callback, options)
  url = "https://nominatim.openstreetmap.org/reverse?format=json&addressdetails=1#{options_str}"
  process :json, url
end
extract_geoloc(result_json) click to toggle source
# File lib/geokit/geocoders/openstreetmap.rb, line 67
def self.extract_geoloc(result_json)
  loc = new_loc

  # basic
  loc.lat = result_json['lat']
  loc.lng = result_json['lon']

  set_address_components(result_json['address'], loc)
  set_precision(result_json, loc)
  set_bounds(result_json['boundingbox'], loc)
  loc.success = true

  loc
end
generate_bool_param_for_option(param, options) click to toggle source
# File lib/geokit/geocoders/openstreetmap.rb, line 44
def self.generate_bool_param_for_option(param, options)
  options[param] ? "&#{param}=1" : "&#{param}=0"
end
generate_param_for(param, value) click to toggle source
# File lib/geokit/geocoders/openstreetmap.rb, line 36
def self.generate_param_for(param, value)
  "&#{param}=#{Geokit::Inflector.url_escape(value.to_s)}"
end
generate_param_for_option(param, options) click to toggle source
# File lib/geokit/geocoders/openstreetmap.rb, line 40
def self.generate_param_for_option(param, options)
  options[param] ? "&#{param}=#{Geokit::Inflector.url_escape(options[param])}" : ''
end
parse_json(results) click to toggle source
# File lib/geokit/geocoders/openstreetmap.rb, line 48
def self.parse_json(results)
  if results.is_a?(Hash)
    return GeoLoc.new if results['error']
    results = [results]
  end
  return GeoLoc.new if results.empty?

  loc = nil
  results.each do |result|
    extract_geoloc = extract_geoloc(result)
    if loc.nil?
      loc = extract_geoloc
    else
      loc.all.push(extract_geoloc)
    end
  end
  loc
end
set_address_components(address_data, loc) click to toggle source
# File lib/geokit/geocoders/openstreetmap.rb, line 82
def self.set_address_components(address_data, loc)
  return unless address_data
  loc.country = address_data['country']
  loc.country_code = address_data['country_code'].upcase if address_data['country_code']
  loc.state_name = address_data['state']
  loc.city = address_data['city']
  loc.city = address_data['county'] if loc.city.nil? && address_data['county']
  loc.zip = address_data['postcode']
  loc.district = address_data['city_district']
  loc.district = address_data['state_district'] if loc.district.nil? && address_data['state_district']
  loc.street_address = "#{address_data['road']} #{address_data['house_number']}".strip if address_data['road']
  loc.street_name = address_data['road']
  loc.street_number = address_data['house_number']
end
set_bounds(result_json, loc) click to toggle source
# File lib/geokit/geocoders/openstreetmap.rb, line 104
def self.set_bounds(result_json, loc)
  return unless result_json
  loc.suggested_bounds = Bounds.normalize(
    [result_json[0], result_json[1]],
    [result_json[2], result_json[3]],
  )
end
set_precision(result_json, loc) click to toggle source
# File lib/geokit/geocoders/openstreetmap.rb, line 97
def self.set_precision(result_json, loc)
  # Todo accuracy does not work as Yahoo and Google maps on OSM
  # loc.accuracy = %w{unknown amenity building highway historic landuse leisure natural place railway shop tourism waterway man_made}.index(loc.precision)
  loc.precision = result_json['class']
  loc.accuracy = result_json['type']
end