diff --git a/README.md b/README.md index 9b11ad14db731e420292a5c17d02c5fee769d4cc..c5aeedceea6ffe52677f3d930d700e3e362d380e 100644 --- a/README.md +++ b/README.md @@ -637,6 +637,16 @@ Data Science Toolkit provides an API whose reponse format is like Google's but w * **Terms of Service**: http://www.itella.fi/liitteet/palvelutjatuotteet/yhteystietopalvelut/Postinumeropalvelut-Palvelukuvausjakayttoehdot.pdf * **Limitations**: ? +#### Geoportail.lu (`:geoportail_lu`) + +* **API key**: none +* **Quota**: none +* **Region**: LU +* **SSL support**: yes +* **Languages**: en +* **Documentation**: http://wiki.geoportail.lu/doku.php?id=en:api +* **Terms of Service**: http://wiki.geoportail.lu/doku.php?id=en:mcg_1 +* **Limitations**: ? #### PostcodeAnywhere Uk (`:postcode_anywhere_uk`) @@ -923,8 +933,8 @@ Now, any time Geocoder looks up "New York, NY" its results array will contain on } ] ) - -Note: + +Note: Keys must be strings not symbols when calling `add_stub` or `set_default_stub`. For example `'latitude' =>` not `:latitude =>`. diff --git a/lib/geocoder/lookup.rb b/lib/geocoder/lookup.rb index a029290ebc665c2c9f8afd690137e4721da51b24..c48960851bb4aa71656ea1102857c510cfc30ded 100644 --- a/lib/geocoder/lookup.rb +++ b/lib/geocoder/lookup.rb @@ -44,6 +44,7 @@ module Geocoder :smarty_streets, :okf, :postcode_anywhere_uk, + :geoportail_lu, :test ] end diff --git a/lib/geocoder/lookups/geoportail_lu.rb b/lib/geocoder/lookups/geoportail_lu.rb new file mode 100644 index 0000000000000000000000000000000000000000..a5ff00ea9d9e7869dd08b68f2866d787a7c35c31 --- /dev/null +++ b/lib/geocoder/lookups/geoportail_lu.rb @@ -0,0 +1,65 @@ +require 'geocoder/lookups/base' +require "geocoder/results/geoportail_lu" + +module Geocoder + module Lookup + class GeoportailLu < Base + + def name + "Geoportail.lu" + end + + def query_url(query) + url_base_path(query) + url_query_string(query) + end + + private + + def url_base_path(query) + query.reverse_geocode? ? reverse_geocode_url_base_path : search_url_base_path + end + + def search_url_base_path + "#{protocol}://api.geoportail.lu/geocoder/search?" + end + + def reverse_geocode_url_base_path + "#{protocol}://api.geoportail.lu/geocoder/reverseGeocode?" + end + + def query_url_geoportail_lu_params(query) + query.reverse_geocode? ? reverse_geocode_params(query) : search_params(query) + end + + def search_params(query) + { + queryString: query.sanitized_text + } + end + + def reverse_geocode_params(query) + lat_lon = query.coordinates + { + lat: lat_lon.first, + lon: lat_lon.last + } + end + + def query_url_params(query) + query_url_geoportail_lu_params(query).merge(super) + end + + def results(query) + return [] unless doc = fetch_data(query) + if doc['success'] == true + result = doc['results'] + else + result = [] + raise_error(Geocoder::Error) || + warn("Geportail.lu Geocoding API error") + end + result + end + end + end +end diff --git a/lib/geocoder/results/geoportail_lu.rb b/lib/geocoder/results/geoportail_lu.rb new file mode 100644 index 0000000000000000000000000000000000000000..eeccb34b68e9161c9a43ae228765a0d8f40602c1 --- /dev/null +++ b/lib/geocoder/results/geoportail_lu.rb @@ -0,0 +1,69 @@ +require 'geocoder/results/base' + +module Geocoder::Result + class GeoportailLu < Base + + def coordinates + geomlonlat['coordinates'].reverse if geolocalized? + end + + def address + full_address + end + + def city + try_to_extract 'locality', detailled_address + end + + def state + 'Luxembourg' + end + + def state_code + 'LU' + end + + def postal_code + try_to_extract 'zip', detailled_address + end + + def street_address + [street_number, street].compact.join(' ') + end + + def street_number + try_to_extract 'postnumber', detailled_address + end + + def street + try_to_extract 'street', detailled_address + end + + def full_address + data['address'] + end + + def geomlonlat + data['geomlonlat'] + end + + def detailled_address + data['AddressDetails'] + end + + alias_method :country, :state + alias_method :province, :state + alias_method :country_code, :state_code + alias_method :province_code, :state_code + + private + + def geolocalized? + try_to_extract('coordinates', geomlonlat).present? + end + + def try_to_extract(key, nullable_hash) + nullable_hash.try(:[], key) + end + end +end diff --git a/test/fixtures/geoportail_lu_boulevard_royal b/test/fixtures/geoportail_lu_boulevard_royal new file mode 100644 index 0000000000000000000000000000000000000000..d1718d25d2115bbe71fd5e9f1e3ed361c4db64b3 --- /dev/null +++ b/test/fixtures/geoportail_lu_boulevard_royal @@ -0,0 +1,38 @@ +{ +"count": 1, +"request": "2 boulevard Royal luxembourg", +"results": [ +{ +"ratio": 1, +"name": "2,Boulevard Royal 2449 Luxembourg", +"easting": 77201.38771169016, +"address": "2 Boulevard Royal,2449 Luxembourg", +"geomlonlat": { +"type": "Point", +"coordinates": [ +6.12939750216249, +49.6146720749933 +] +}, +"geom": { +"type": "Point", +"coordinates": [ +77201.38771169016, +75561.5290000001 +] +}, +"northing": 75561.5290000001, +"AddressDetails": { +"zip": "2449", +"locality": "Luxembourg", +"id_caclr_street": "55", +"street": "Boulevard Royal", +"postnumber": "2", +"id_caclr_building": "3186" +}, +"matching street": "Boulevard Royal", +"accuracy": 8 +} +], +"success": true +} diff --git a/test/fixtures/geoportail_lu_no_results b/test/fixtures/geoportail_lu_no_results new file mode 100644 index 0000000000000000000000000000000000000000..cef30afd185e4d26fd03337b87411a13ad161f88 --- /dev/null +++ b/test/fixtures/geoportail_lu_no_results @@ -0,0 +1,22 @@ +{ +"count": 1, +"request": "no results", +"results": [ +{ +"geom": null, +"ratio": 0, +"name": ", ", +"address": null, +"country": null, +"AddressDetails": { +"street": null, +"locality": null, +"zip": null, +"postnumber": null +}, +"matching street": null, +"accuracy": 1 +} +], +"success": false +} diff --git a/test/fixtures/geoportail_lu_reverse b/test/fixtures/geoportail_lu_reverse new file mode 100644 index 0000000000000000000000000000000000000000..e2a2fc9ab9c51b76c8341aa25e41c31e070e17f5 --- /dev/null +++ b/test/fixtures/geoportail_lu_reverse @@ -0,0 +1,36 @@ +{ +"count": 1, +"results": [ +{ +"distance": 55.8617929519411, +"geom": { +"type": "Point", +"coordinates": [ +76866.57071788973, +75026.12585000045 +] +}, +"name": "39,Boulevard Prince Henri 1724 Luxembourg", +"easting": 76866.57071788973, +"address": "39 Boulevard Prince Henri,1724 Luxembourg", +"geomlonlat": { +"type": "Point", +"coordinates": [ +6.12476867352074, +49.6098566608772 +] +}, +"AddressDetails": { +"zip": "1724", +"locality": "Luxembourg", +"id_caclr_street": "40", +"street": "Boulevard Prince Henri", +"postnumber": "39", +"id_caclr_building": "2459" +}, +"matching street": "Boulevard Prince Henri", +"northing": 75026.12585000045 +} +], +"success": true +} diff --git a/test/test_helper.rb b/test/test_helper.rb index 62d2817ee328f8d11f79d118bb1d109a0cf85e60..b869b88f81df31d6f65cf3ce8d15c63158280b2a 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -300,6 +300,18 @@ module Geocoder "#{fixture_prefix}_romsey" end end + + require 'geocoder/lookups/geoportail_lu' + class GeoportailLu + private + def fixture_prefix + "geoportail_lu" + end + + def default_fixture_filename + "#{fixture_prefix}_boulevard_royal" + end + end end end diff --git a/test/unit/lookups/geoportail_lu_test.rb b/test/unit/lookups/geoportail_lu_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..303e664a12705c37ba0d9a5afe82535baa6a3b00 --- /dev/null +++ b/test/unit/lookups/geoportail_lu_test.rb @@ -0,0 +1,66 @@ +# encoding: utf-8 +require 'test_helper' + +class GeoportailLuTest < GeocoderTestCase + + def setup + Geocoder.configure(lookup: :geoportail_lu) + end + + def test_query_for_geocode + query = Geocoder::Query.new('55 route de luxembourg, pontpierre') + lookup = Geocoder::Lookup.get(:geoportail_lu) + res = lookup.query_url(query) + assert_equal 'http://api.geoportail.lu/geocoder/search?queryString=55+route+de+luxembourg%2C+pontpierre', res + end + + def test_query_for_reverse_geocode + query = Geocoder::Query.new([45.423733, -75.676333]) + lookup = Geocoder::Lookup.get(:geoportail_lu) + res = lookup.query_url(query) + assert_equal 'http://api.geoportail.lu/geocoder/reverseGeocode?lat=45.423733&lon=-75.676333', res + end + + def test_results_component + result = Geocoder.search('2 boulevard Royal, luxembourg').first + assert_equal '2449', result.postal_code + assert_equal 'Luxembourg', result.country + assert_equal '2 Boulevard Royal,2449 Luxembourg', result.address + assert_equal '2', result.street_number + assert_equal 'Boulevard Royal', result.street + assert_equal '2 Boulevard Royal', result.street_address + assert_equal 'Luxembourg', result.city + assert_equal 'Luxembourg', result.state + assert_country_code result + assert_equal(49.6146720749933, result.coordinates[0]) + assert_equal(6.12939750216249, result.coordinates[1]) + end + + def test_results_component_when_reverse_geocoding + result = Geocoder.search([6.12476867352074, 49.6098566608772]).first + assert_equal '1724', result.postal_code + assert_equal 'Luxembourg', result.country + assert_equal '39 Boulevard Prince Henri,1724 Luxembourg', result.address + assert_equal '39', result.street_number + assert_equal 'Boulevard Prince Henri', result.street + assert_equal '39 Boulevard Prince Henri', result.street_address + assert_equal 'Luxembourg', result.city + assert_equal 'Luxembourg', result.state + assert_country_code result + assert_equal(49.6098566608772, result.coordinates[0]) + assert_equal(6.12476867352074, result.coordinates[1]) + end + + def test_no_results + results = Geocoder.search('no results') + assert_equal 0, results.length + end + + private + + def assert_country_code(result) + [:state_code, :country_code, :province_code].each do |method| + assert_equal 'LU', result.send(method) + end + end +end diff --git a/test/unit/result_test.rb b/test/unit/result_test.rb index 886f5dd5f610f9a79d78adea65faf091cd7d4690..7f1aeb3f6af03c9cb781e2989145397aa02d0054 100644 --- a/test/unit/result_test.rb +++ b/test/unit/result_test.rb @@ -26,7 +26,7 @@ class ResultTest < GeocoderTestCase def test_result_accepts_reverse_coords_in_reasonable_range_for_madison_square_garden Geocoder::Lookup.street_services.each do |l| next unless File.exist?(File.join("test", "fixtures", "#{l.to_s}_madison_square_garden")) - next if [:bing, :esri, :geocoder_ca, :geocoder_us].include? l # Reverse fixture does not match forward + next if [:bing, :esri, :geocoder_ca, :geocoder_us, :geoportail_lu].include? l # Reverse fixture does not match forward Geocoder.configure(:lookup => l) set_api_key!(l) result = Geocoder.search([40.750354, -73.993371]).first