diff --git a/lib/geocoder.rb b/lib/geocoder.rb index 5bce2283b9e2463c76edf7ba9e4e99e1bd830ff7..b73e6e9cf2d71eaabee62652f58751f5fbb88c04 100644 --- a/lib/geocoder.rb +++ b/lib/geocoder.rb @@ -56,7 +56,7 @@ module Geocoder # All street address lookups, default first. # def street_lookups - [:google, :google_premier, :yahoo, :bing, :geocoder_ca, :yandex] + [:google, :google_premier, :yahoo, :bing, :geocoder_ca, :yandex, :nominatim] end ## diff --git a/lib/geocoder/lookups/nominatim.rb b/lib/geocoder/lookups/nominatim.rb new file mode 100644 index 0000000000000000000000000000000000000000..7e4f85de895795e8db9b98e235a0c501ba7739ba --- /dev/null +++ b/lib/geocoder/lookups/nominatim.rb @@ -0,0 +1,45 @@ +require 'geocoder/lookups/base' +require "geocoder/results/nominatim" + +module Geocoder::Lookup + class Nominatim < Base + + def map_link_url(coordinates) + "http://nominatim.openstreetmap.org/reverse?format=html&lat=#{coordinates[0]}&lon=#{coordinates[1]}&zoom=18&addressdetails=1" + end + + def results(query, reverse = false) + return [] unless doc = fetch_data(query, reverse) + if doc.kind_of?(Array) + if doc.any? + return doc[0]['place_id'] != "" ? doc : [] + else + warn "Address not found or Nominatim Geocoding API error." + return [] + end + else + return doc['place_id'] != "" ? doc = [] << doc : [] + end + end + + def query_url(query, reverse = false) + params = { + :format => "json", + :polygon => "1", + :addressdetails => "1", +# :locale => "#{Geocoder::Configuration.language}_US", + } + if (reverse) + method = 'reverse' + parts = query.split(/\s*,\s*/); + params[:lat] = parts[0] + params[:lon] = parts[1] + else + method = 'search' + params[:q] = query + end + "http://nominatim.openstreetmap.org/#{method}?" + hash_to_query(params) + end + + end +end \ No newline at end of file diff --git a/lib/geocoder/results/nominatim.rb b/lib/geocoder/results/nominatim.rb new file mode 100644 index 0000000000000000000000000000000000000000..f81071e762cc81b6685b3da545ba02cd819fbcc0 --- /dev/null +++ b/lib/geocoder/results/nominatim.rb @@ -0,0 +1,68 @@ +require 'geocoder/results/base' + +module Geocoder::Result + class Nominatim < Base + + def house_number + @data['address']['house_number'] + end + + def address + @data['display_name'] + end + + def street + @data['address']['road'] + end + + def city + @data['address']['city'] + end + + def village + @data['address']['villiage'] + end + + def town + @data['address']['town'] + end + + def state + @data['address']['state'] + end + + alias_method :state_code, :state + + def postal_code + @data['address']['postcode'] + end + + def county + @data['address']['county'] + end + + def country + @data['address']['country'] + end + + def country_code + @data['address']['country_code'] + end + + def coordinates + [@data['lat'].to_f, @data['lon'].to_f] + end + + def self.response_attributes + %w[place_id, osm_type, osm_id, boundingbox, license, + polygonpoints, display_name, class, type, stadium, suburb] + end + + response_attributes.each do |a| + define_method a do + @data[a] + end + end + + end +end \ No newline at end of file diff --git a/test/fixtures/nominatim_madison_square_garden.json b/test/fixtures/nominatim_madison_square_garden.json new file mode 100644 index 0000000000000000000000000000000000000000..a1d709ecf93735169922e6c10e661d815a3839c0 --- /dev/null +++ b/test/fixtures/nominatim_madison_square_garden.json @@ -0,0 +1,150 @@ +[ + + { + "place_id": "30632629", + "licence": "Data Copyright OpenStreetMap Contributors, Some Rights Reserved. CC-BY-SA 2.0.", + "osm_type": "way", + "osm_id": "24801588", + "boundingbox": [ + "40.749828338623", + "40.7511596679688", + "-73.9943389892578", + "-73.9926528930664" + ], + "polygonpoints": [ + [ + "-73.9943346", + "40.7503638" + ], + [ + "-73.9942745", + "40.7504158" + ], + [ + "-73.9942593", + "40.750629" + ], + [ + "-73.9941343", + "40.7508432" + ], + [ + "-73.9939794", + "40.7509703" + ], + [ + "-73.9938042", + "40.7510532" + ], + [ + "-73.9938025", + "40.7511311" + ], + [ + "-73.9936051", + "40.7511571" + ], + [ + "-73.9935673", + "40.751105" + ], + [ + "-73.9934095", + "40.7511089" + ], + [ + "-73.9931235", + "40.7510548" + ], + [ + "-73.9928863", + "40.7509311" + ], + [ + "-73.9928068", + "40.750949" + ], + [ + "-73.992721", + "40.7508515" + ], + [ + "-73.9927444", + "40.7507889" + ], + [ + "-73.9926693", + "40.7506457" + ], + [ + "-73.9926597", + "40.7503657" + ], + [ + "-73.9928305", + "40.7500953" + ], + [ + "-73.9929757", + "40.7499911" + ], + [ + "-73.9931281", + "40.7499238" + ], + [ + "-73.993133", + "40.7498631" + ], + [ + "-73.9932961", + "40.7498306" + ], + [ + "-73.9933664", + "40.7498742" + ], + [ + "-73.993471", + "40.7498701" + ], + [ + "-73.9938023", + "40.7499263" + ], + [ + "-73.9940703", + "40.7500756" + ], + [ + "-73.9941876", + "40.7502038" + ], + [ + "-73.9942831", + "40.7502142" + ], + [ + "-73.9943346", + "40.7503638" + ] + ], + "lat": "40.7504928941818", + "lon": "-73.993466492276", + "display_name": "Madison Square Garden, West 31st Street, Long Island City, New York City, New York, 10001, United States of America", + "class": "leisure", + "type": "stadium", + "address": { + "stadium": "Madison Square Garden", + "road": "West 31st Street", + "suburb": "Long Island City", + "city": "New York City", + "county": "New York", + "state": "New York", + "postcode": "10001", + "country": "United States of America", + "country_code": "us" + } + } + +] \ No newline at end of file diff --git a/test/fixtures/nominatim_no_results.json b/test/fixtures/nominatim_no_results.json new file mode 100644 index 0000000000000000000000000000000000000000..1e3ec7217afba05e6dcd456b0e89ec7f17bf7b55 --- /dev/null +++ b/test/fixtures/nominatim_no_results.json @@ -0,0 +1 @@ +[ ] diff --git a/test/services_test.rb b/test/services_test.rb index b01b84abcbdb03c4c2f466f6b39859d687b26774..479ce2e79ec7e0cf2020da392ec9e817fca8fb82 100644 --- a/test/services_test.rb +++ b/test/services_test.rb @@ -110,4 +110,22 @@ class ServicesTest < Test::Unit::TestCase results = Geocoder.search("no results") assert_equal 0, results.length end + + # --- Nominatim --- + + def test_nominatim_result_components + Geocoder::Configuration.lookup = :nominatim + result = Geocoder.search("Madison Square Garden, New York, NY").first + assert_equal "10001", result.postal_code + end + + def test_nominatim_address_formatting + Geocoder::Configuration.lookup = :nominatim + result = Geocoder.search("Madison Square Garden, New York, NY").first + assert_equal "Madison Square Garden, West 31st Street, Long Island City, New York City, New York, 10001, United States of America", + result.address + end + + + end diff --git a/test/test_helper.rb b/test/test_helper.rb index 137f756fdbad489f0880c08e64f452d0bf2ef7cb..94d3ebf072e31f6dad5da7ba9ec4b40b927e5aaf 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -150,6 +150,19 @@ module Geocoder end end + class Nominatim < Base + private #----------------------------------------------------------------- + def fetch_raw_data(query, reverse = false) + raise TimeoutError if query == "timeout" + raise SocketError if query == "socket_error" + file = case query + when "no results"; :no_results + else :madison_square_garden + end + read_fixture "nominatim_#{file}.json" + end + end + end end