geocoder 1.2.6 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +266 -1
- data/LICENSE +1 -1
- data/README.md +530 -804
- data/bin/console +13 -0
- data/examples/app_defined_lookup_services.rb +22 -0
- data/examples/reverse_geocode_job.rb +40 -0
- data/lib/easting_northing.rb +171 -0
- data/lib/generators/geocoder/config/templates/initializer.rb +22 -16
- data/lib/generators/geocoder/maxmind/geolite_city_generator.rb +2 -0
- data/lib/generators/geocoder/maxmind/geolite_country_generator.rb +2 -0
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_city.rb +1 -1
- data/lib/generators/geocoder/maxmind/templates/migration/geolite_country.rb +1 -1
- data/lib/generators/geocoder/migration_version.rb +15 -0
- data/lib/geocoder/cache.rb +20 -33
- data/lib/geocoder/cache_stores/base.rb +40 -0
- data/lib/geocoder/cache_stores/generic.rb +35 -0
- data/lib/geocoder/cache_stores/redis.rb +34 -0
- data/lib/geocoder/calculations.rb +30 -38
- data/lib/geocoder/cli.rb +2 -2
- data/lib/geocoder/configuration.rb +36 -9
- data/lib/geocoder/configuration_hash.rb +4 -4
- data/lib/geocoder/esri_token.rb +38 -0
- data/lib/geocoder/exceptions.rb +19 -0
- data/lib/geocoder/ip_address.rb +26 -11
- data/lib/geocoder/kernel_logger.rb +25 -0
- data/lib/geocoder/logger.rb +47 -0
- data/lib/geocoder/lookup.rb +63 -13
- data/lib/geocoder/lookups/abstract_api.rb +46 -0
- data/lib/geocoder/lookups/amap.rb +63 -0
- data/lib/geocoder/lookups/amazon_location_service.rb +55 -0
- data/lib/geocoder/lookups/baidu.rb +17 -9
- data/lib/geocoder/lookups/baidu_ip.rb +7 -31
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +143 -0
- data/lib/geocoder/lookups/base.rb +75 -26
- data/lib/geocoder/lookups/bing.rb +38 -15
- data/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/lib/geocoder/lookups/dstk.rb +4 -2
- data/lib/geocoder/lookups/esri.rb +78 -12
- data/lib/geocoder/lookups/freegeoip.rb +22 -7
- data/lib/geocoder/lookups/geoapify.rb +78 -0
- data/lib/geocoder/lookups/geocoder_ca.rb +5 -6
- data/lib/geocoder/lookups/geocodio.rb +8 -8
- data/lib/geocoder/lookups/geoip2.rb +13 -4
- data/lib/geocoder/lookups/geoportail_lu.rb +65 -0
- data/lib/geocoder/lookups/google.rb +44 -11
- data/lib/geocoder/lookups/google_places_details.rb +31 -17
- data/lib/geocoder/lookups/google_places_search.rb +76 -0
- data/lib/geocoder/lookups/google_premier.rb +15 -1
- data/lib/geocoder/lookups/here.rb +38 -27
- data/lib/geocoder/lookups/ip2location.rb +71 -0
- data/lib/geocoder/lookups/ipapi_com.rb +82 -0
- data/lib/geocoder/lookups/ipbase.rb +49 -0
- data/lib/geocoder/lookups/ipdata_co.rb +62 -0
- data/lib/geocoder/lookups/ipgeolocation.rb +51 -0
- data/lib/geocoder/lookups/ipinfo_io.rb +44 -0
- data/lib/geocoder/lookups/ipqualityscore.rb +50 -0
- data/lib/geocoder/lookups/ipregistry.rb +68 -0
- data/lib/geocoder/lookups/ipstack.rb +63 -0
- data/lib/geocoder/lookups/latlon.rb +58 -0
- data/lib/geocoder/lookups/location_iq.rb +54 -0
- data/lib/geocoder/lookups/mapbox.rb +59 -0
- data/lib/geocoder/lookups/mapquest.rb +7 -9
- data/lib/geocoder/lookups/maxmind.rb +7 -7
- data/lib/geocoder/lookups/maxmind_geoip2.rb +70 -0
- data/lib/geocoder/lookups/maxmind_local.rb +16 -3
- data/lib/geocoder/lookups/melissa_street.rb +41 -0
- data/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
- data/lib/geocoder/lookups/nominatim.rb +18 -6
- data/lib/geocoder/lookups/opencagedata.rb +16 -9
- data/lib/geocoder/lookups/osmnames.rb +57 -0
- data/lib/geocoder/lookups/pc_miler.rb +85 -0
- data/lib/geocoder/lookups/pelias.rb +63 -0
- data/lib/geocoder/lookups/photon.rb +89 -0
- data/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/lib/geocoder/lookups/pointpin.rb +14 -13
- data/lib/geocoder/lookups/postcode_anywhere_uk.rb +7 -8
- data/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/lib/geocoder/lookups/smarty_streets.rb +29 -6
- data/lib/geocoder/lookups/telize.rb +42 -7
- data/lib/geocoder/lookups/tencent.rb +59 -0
- data/lib/geocoder/lookups/test.rb +5 -0
- data/lib/geocoder/lookups/twogis.rb +58 -0
- data/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/lookups/yandex.rb +20 -13
- data/lib/geocoder/models/active_record.rb +4 -3
- data/lib/geocoder/models/mongo_base.rb +0 -2
- data/lib/geocoder/query.rb +15 -1
- data/lib/geocoder/railtie.rb +1 -1
- data/lib/geocoder/request.rb +103 -14
- data/lib/geocoder/results/abstract_api.rb +146 -0
- data/lib/geocoder/results/amap.rb +87 -0
- data/lib/geocoder/results/amazon_location_service.rb +57 -0
- data/lib/geocoder/results/baidu.rb +10 -14
- data/lib/geocoder/results/ban_data_gouv_fr.rb +282 -0
- data/lib/geocoder/results/base.rb +13 -1
- data/lib/geocoder/results/bing.rb +5 -1
- data/lib/geocoder/results/db_ip_com.rb +58 -0
- data/lib/geocoder/results/esri.rb +35 -8
- data/lib/geocoder/results/freegeoip.rb +2 -7
- data/lib/geocoder/results/geoapify.rb +179 -0
- data/lib/geocoder/results/geocoder_ca.rb +3 -3
- data/lib/geocoder/results/geocodio.rb +15 -3
- data/lib/geocoder/results/geoip2.rb +37 -25
- data/lib/geocoder/results/geoportail_lu.rb +71 -0
- data/lib/geocoder/results/google.rb +26 -0
- data/lib/geocoder/results/google_places_details.rb +4 -0
- data/lib/geocoder/results/google_places_search.rb +52 -0
- data/lib/geocoder/results/here.rb +30 -15
- data/lib/geocoder/results/ip2location.rb +22 -0
- data/lib/geocoder/results/ipapi_com.rb +45 -0
- data/lib/geocoder/results/ipbase.rb +40 -0
- data/lib/geocoder/results/ipdata_co.rb +40 -0
- data/lib/geocoder/results/ipgeolocation.rb +59 -0
- data/lib/geocoder/results/ipinfo_io.rb +48 -0
- data/lib/geocoder/results/ipqualityscore.rb +54 -0
- data/lib/geocoder/results/ipregistry.rb +304 -0
- data/lib/geocoder/results/ipstack.rb +60 -0
- data/lib/geocoder/results/latlon.rb +71 -0
- data/lib/geocoder/results/location_iq.rb +6 -0
- data/lib/geocoder/results/mapbox.rb +63 -0
- data/lib/geocoder/results/mapquest.rb +5 -8
- data/lib/geocoder/results/maxmind.rb +0 -5
- data/lib/geocoder/results/maxmind_geoip2.rb +9 -0
- data/lib/geocoder/results/maxmind_local.rb +0 -5
- data/lib/geocoder/results/melissa_street.rb +46 -0
- data/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
- data/lib/geocoder/results/nominatim.rb +41 -14
- data/lib/geocoder/results/opencagedata.rb +20 -2
- data/lib/geocoder/results/osmnames.rb +56 -0
- data/lib/geocoder/results/pc_miler.rb +98 -0
- data/lib/geocoder/results/pelias.rb +58 -0
- data/lib/geocoder/results/photon.rb +119 -0
- data/lib/geocoder/results/pickpoint.rb +6 -0
- data/lib/geocoder/results/pointpin.rb +0 -4
- data/lib/geocoder/results/postcodes_io.rb +40 -0
- data/lib/geocoder/results/smarty_streets.rb +55 -19
- data/lib/geocoder/results/telize.rb +0 -5
- data/lib/geocoder/results/tencent.rb +72 -0
- data/lib/geocoder/results/test.rb +1 -1
- data/lib/geocoder/results/twogis.rb +76 -0
- data/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/results/yandex.rb +240 -32
- data/lib/geocoder/sql.rb +9 -6
- data/lib/geocoder/stores/active_record.rb +49 -10
- data/lib/geocoder/stores/base.rb +2 -14
- data/lib/geocoder/stores/mongo_base.rb +0 -31
- data/lib/geocoder/util.rb +29 -0
- data/lib/geocoder/version.rb +1 -1
- data/lib/geocoder.rb +2 -1
- data/lib/maxmind_database.rb +9 -9
- data/lib/tasks/geocoder.rake +29 -4
- data/lib/tasks/maxmind.rake +1 -1
- metadata +91 -169
- data/.gitignore +0 -6
- data/.travis.yml +0 -31
- data/Rakefile +0 -25
- data/examples/autoexpire_cache_dalli.rb +0 -62
- data/examples/autoexpire_cache_redis.rb +0 -28
- data/gemfiles/Gemfile.mongoid-2.4.x +0 -16
- data/lib/geocoder/lookups/geocoder_us.rb +0 -39
- data/lib/geocoder/lookups/okf.rb +0 -43
- data/lib/geocoder/lookups/ovi.rb +0 -62
- data/lib/geocoder/lookups/yahoo.rb +0 -88
- data/lib/geocoder/results/geocoder_us.rb +0 -39
- data/lib/geocoder/results/okf.rb +0 -106
- data/lib/geocoder/results/ovi.rb +0 -62
- data/lib/geocoder/results/yahoo.rb +0 -55
- data/lib/hash_recursive_merge.rb +0 -74
- data/lib/oauth_util.rb +0 -112
- data/test/fixtures/baidu_invalid_key +0 -1
- data/test/fixtures/baidu_ip_202_198_16_3 +0 -19
- data/test/fixtures/baidu_ip_invalid_key +0 -1
- data/test/fixtures/baidu_ip_no_results +0 -1
- data/test/fixtures/baidu_no_results +0 -1
- data/test/fixtures/baidu_reverse +0 -1
- data/test/fixtures/baidu_shanghai_pearl_tower +0 -12
- data/test/fixtures/bing_invalid_key +0 -1
- data/test/fixtures/bing_madison_square_garden +0 -40
- data/test/fixtures/bing_no_results +0 -16
- data/test/fixtures/bing_reverse +0 -42
- data/test/fixtures/cloudmade_invalid_key +0 -1
- data/test/fixtures/cloudmade_madison_square_garden +0 -1
- data/test/fixtures/cloudmade_no_results +0 -1
- data/test/fixtures/esri_madison_square_garden +0 -59
- data/test/fixtures/esri_no_results +0 -8
- data/test/fixtures/esri_reverse +0 -21
- data/test/fixtures/freegeoip_74_200_247_59 +0 -12
- data/test/fixtures/freegeoip_no_results +0 -1
- data/test/fixtures/geocoder_ca_madison_square_garden +0 -1
- data/test/fixtures/geocoder_ca_no_results +0 -1
- data/test/fixtures/geocoder_ca_reverse +0 -34
- data/test/fixtures/geocoder_us_madison_square_garden +0 -1
- data/test/fixtures/geocoder_us_no_results +0 -1
- data/test/fixtures/geocodio_1101_pennsylvania_ave +0 -1
- data/test/fixtures/geocodio_bad_api_key +0 -3
- data/test/fixtures/geocodio_invalid +0 -4
- data/test/fixtures/geocodio_no_results +0 -1
- data/test/fixtures/geocodio_over_query_limit +0 -4
- data/test/fixtures/google_garbage +0 -456
- data/test/fixtures/google_madison_square_garden +0 -57
- data/test/fixtures/google_no_city_data +0 -44
- data/test/fixtures/google_no_locality +0 -51
- data/test/fixtures/google_no_results +0 -4
- data/test/fixtures/google_over_limit +0 -4
- data/test/fixtures/google_places_details_invalid_request +0 -4
- data/test/fixtures/google_places_details_madison_square_garden +0 -120
- data/test/fixtures/google_places_details_no_results +0 -4
- data/test/fixtures/google_places_details_no_reviews +0 -60
- data/test/fixtures/google_places_details_no_types +0 -66
- data/test/fixtures/here_madison_square_garden +0 -72
- data/test/fixtures/here_no_results +0 -8
- data/test/fixtures/mapquest_error +0 -16
- data/test/fixtures/mapquest_invalid_api_key +0 -16
- data/test/fixtures/mapquest_invalid_request +0 -16
- data/test/fixtures/mapquest_madison_square_garden +0 -52
- data/test/fixtures/mapquest_no_results +0 -16
- data/test/fixtures/maxmind_24_24_24_21 +0 -1
- data/test/fixtures/maxmind_24_24_24_22 +0 -1
- data/test/fixtures/maxmind_24_24_24_23 +0 -1
- data/test/fixtures/maxmind_24_24_24_24 +0 -1
- data/test/fixtures/maxmind_74_200_247_59 +0 -1
- data/test/fixtures/maxmind_invalid_key +0 -1
- data/test/fixtures/maxmind_no_results +0 -1
- data/test/fixtures/nominatim_madison_square_garden +0 -150
- data/test/fixtures/nominatim_no_results +0 -1
- data/test/fixtures/nominatim_over_limit +0 -1
- data/test/fixtures/okf_kirstinmaki +0 -67
- data/test/fixtures/okf_no_results +0 -4
- data/test/fixtures/opencagedata_invalid_api_key +0 -25
- data/test/fixtures/opencagedata_invalid_request +0 -26
- data/test/fixtures/opencagedata_madison_square_garden +0 -73
- data/test/fixtures/opencagedata_no_results +0 -29
- data/test/fixtures/opencagedata_over_limit +0 -31
- data/test/fixtures/ovi_madison_square_garden +0 -72
- data/test/fixtures/ovi_no_results +0 -8
- data/test/fixtures/pointpin_10_10_10_10 +0 -1
- data/test/fixtures/pointpin_555_555_555_555 +0 -1
- data/test/fixtures/pointpin_80_111_555_555 +0 -1
- data/test/fixtures/pointpin_no_results +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_WR26NJ +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_generic_error +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_hampshire +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_key_limit_exceeded +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_no_results +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_romsey +0 -1
- data/test/fixtures/postcode_anywhere_uk_geocode_v2_00_unknown_key +0 -1
- data/test/fixtures/smarty_streets_11211 +0 -1
- data/test/fixtures/smarty_streets_madison_square_garden +0 -47
- data/test/fixtures/smarty_streets_no_results +0 -1
- data/test/fixtures/telize_10_10_10_10 +0 -1
- data/test/fixtures/telize_555_555_555_555 +0 -4
- data/test/fixtures/telize_74_200_247_59 +0 -1
- data/test/fixtures/telize_no_results +0 -1
- data/test/fixtures/yahoo_error +0 -1
- data/test/fixtures/yahoo_invalid_key +0 -2
- data/test/fixtures/yahoo_madison_square_garden +0 -52
- data/test/fixtures/yahoo_no_results +0 -10
- data/test/fixtures/yahoo_over_limit +0 -2
- data/test/fixtures/yandex_canada_rue_dupuis_14 +0 -446
- data/test/fixtures/yandex_invalid_key +0 -1
- data/test/fixtures/yandex_kremlin +0 -48
- data/test/fixtures/yandex_new_york +0 -1
- data/test/fixtures/yandex_no_city_and_town +0 -112
- data/test/fixtures/yandex_no_results +0 -16
- data/test/integration/http_client_test.rb +0 -31
- data/test/mongoid_test_helper.rb +0 -43
- data/test/test_helper.rb +0 -416
- data/test/unit/active_record_test.rb +0 -16
- data/test/unit/cache_test.rb +0 -37
- data/test/unit/calculations_test.rb +0 -220
- data/test/unit/configuration_test.rb +0 -55
- data/test/unit/error_handling_test.rb +0 -56
- data/test/unit/geocoder_test.rb +0 -78
- data/test/unit/https_test.rb +0 -17
- data/test/unit/ip_address_test.rb +0 -27
- data/test/unit/lookup_test.rb +0 -153
- data/test/unit/lookups/bing_test.rb +0 -68
- data/test/unit/lookups/dstk_test.rb +0 -26
- data/test/unit/lookups/esri_test.rb +0 -48
- data/test/unit/lookups/freegeoip_test.rb +0 -27
- data/test/unit/lookups/geocoder_ca_test.rb +0 -17
- data/test/unit/lookups/geocodio_test.rb +0 -55
- data/test/unit/lookups/geoip2_test.rb +0 -27
- data/test/unit/lookups/google_places_details_test.rb +0 -122
- data/test/unit/lookups/google_premier_test.rb +0 -22
- data/test/unit/lookups/google_test.rb +0 -84
- data/test/unit/lookups/mapquest_test.rb +0 -60
- data/test/unit/lookups/maxmind_local_test.rb +0 -28
- data/test/unit/lookups/maxmind_test.rb +0 -63
- data/test/unit/lookups/nominatim_test.rb +0 -31
- data/test/unit/lookups/okf_test.rb +0 -38
- data/test/unit/lookups/opencagedata_test.rb +0 -64
- data/test/unit/lookups/pointpin_test.rb +0 -30
- data/test/unit/lookups/postcode_anywhere_uk_test.rb +0 -70
- data/test/unit/lookups/smarty_streets_test.rb +0 -71
- data/test/unit/lookups/telize_test.rb +0 -36
- data/test/unit/lookups/yahoo_test.rb +0 -35
- data/test/unit/method_aliases_test.rb +0 -26
- data/test/unit/model_test.rb +0 -38
- data/test/unit/mongoid_test.rb +0 -47
- data/test/unit/near_test.rb +0 -87
- data/test/unit/oauth_util_test.rb +0 -31
- data/test/unit/proxy_test.rb +0 -37
- data/test/unit/query_test.rb +0 -52
- data/test/unit/rake_task_test.rb +0 -21
- data/test/unit/request_test.rb +0 -35
- data/test/unit/result_test.rb +0 -72
- data/test/unit/test_mode_test.rb +0 -70
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'geocoder/lookups/base'
|
|
4
|
+
require 'geocoder/results/abstract_api'
|
|
5
|
+
|
|
6
|
+
module Geocoder::Lookup
|
|
7
|
+
class AbstractApi < Base
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Abstract API"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def required_api_key_parts
|
|
14
|
+
['api_key']
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def supported_protocols
|
|
18
|
+
[:https]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private # ---------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
def base_query_url(query)
|
|
24
|
+
"#{protocol}://ipgeolocation.abstractapi.com/v1/?"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def query_url_params(query)
|
|
28
|
+
params = {api_key: configuration.api_key}
|
|
29
|
+
|
|
30
|
+
ip_address = query.sanitized_text
|
|
31
|
+
if ip_address.is_a?(String) && ip_address.length > 0
|
|
32
|
+
params[:ip_address] = ip_address
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
params.merge(super)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def results(query, reverse = false)
|
|
39
|
+
if doc = fetch_data(query)
|
|
40
|
+
[doc]
|
|
41
|
+
else
|
|
42
|
+
[]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/amap"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Amap < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"AMap"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def required_api_key_parts
|
|
12
|
+
["key"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def supported_protocols
|
|
16
|
+
[:http]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private # ---------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
path = query.reverse_geocode? ? 'regeo' : 'geo'
|
|
23
|
+
"http://restapi.amap.com/v3/geocode/#{path}?"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def results(query, reverse = false)
|
|
27
|
+
return [] unless doc = fetch_data(query)
|
|
28
|
+
case [doc['status'], doc['info']]
|
|
29
|
+
when ['1', 'OK']
|
|
30
|
+
return doc['regeocodes'] unless doc['regeocodes'].blank?
|
|
31
|
+
return [doc['regeocode']] unless doc['regeocode'].blank?
|
|
32
|
+
return doc['geocodes'] unless doc['geocodes'].blank?
|
|
33
|
+
when ['0', 'INVALID_USER_KEY']
|
|
34
|
+
raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
|
|
35
|
+
Geocoder.log(:warn, "#{self.name} Geocoding API error: invalid api key.")
|
|
36
|
+
else
|
|
37
|
+
raise_error(Geocoder::Error, "server error.") ||
|
|
38
|
+
Geocoder.log(:warn, "#{self.name} Geocoding API error: server error - [#{doc['info']}]")
|
|
39
|
+
end
|
|
40
|
+
return []
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def query_url_params(query)
|
|
44
|
+
params = {
|
|
45
|
+
:key => configuration.api_key,
|
|
46
|
+
:output => "json"
|
|
47
|
+
}
|
|
48
|
+
if query.reverse_geocode?
|
|
49
|
+
params[:location] = revert_coordinates(query.text)
|
|
50
|
+
params[:extensions] = "all"
|
|
51
|
+
params[:coordsys] = "gps"
|
|
52
|
+
else
|
|
53
|
+
params[:address] = query.sanitized_text
|
|
54
|
+
end
|
|
55
|
+
params.merge(super)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def revert_coordinates(text)
|
|
59
|
+
[text[1],text[0]].join(",")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/amazon_location_service'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class AmazonLocationService < Base
|
|
6
|
+
def results(query)
|
|
7
|
+
params = query.options.dup
|
|
8
|
+
|
|
9
|
+
# index_name is required
|
|
10
|
+
# Aws::ParamValidator raises ArgumentError on missing required keys
|
|
11
|
+
params.merge!(index_name: configuration[:index_name])
|
|
12
|
+
|
|
13
|
+
# Aws::ParamValidator raises ArgumentError on unexpected keys
|
|
14
|
+
params.delete(:lookup)
|
|
15
|
+
|
|
16
|
+
resp = if query.reverse_geocode?
|
|
17
|
+
client.search_place_index_for_position(params.merge(position: query.coordinates.reverse))
|
|
18
|
+
else
|
|
19
|
+
client.search_place_index_for_text(params.merge(text: query.text))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
resp.results.map(&:place)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def client
|
|
28
|
+
return @client if @client
|
|
29
|
+
require_sdk
|
|
30
|
+
keys = configuration.api_key
|
|
31
|
+
if keys
|
|
32
|
+
@client = Aws::LocationService::Client.new(**{
|
|
33
|
+
region: keys[:region],
|
|
34
|
+
access_key_id: keys[:access_key_id],
|
|
35
|
+
secret_access_key: keys[:secret_access_key]
|
|
36
|
+
}.compact)
|
|
37
|
+
else
|
|
38
|
+
@client = Aws::LocationService::Client.new
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def require_sdk
|
|
43
|
+
begin
|
|
44
|
+
require 'aws-sdk-locationservice'
|
|
45
|
+
rescue LoadError
|
|
46
|
+
raise_error(Geocoder::ConfigurationError) ||
|
|
47
|
+
Geocoder.log(
|
|
48
|
+
:error,
|
|
49
|
+
"Couldn't load the Amazon Location Service SDK. " +
|
|
50
|
+
"Install it with: gem install aws-sdk-locationservice -v '~> 1.4'"
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -12,32 +12,41 @@ module Geocoder::Lookup
|
|
|
12
12
|
["key"]
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
# HTTP only
|
|
16
|
+
def supported_protocols
|
|
17
|
+
[:http]
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
private # ---------------------------------------------------------------
|
|
20
21
|
|
|
22
|
+
def base_query_url(query)
|
|
23
|
+
"#{protocol}://api.map.baidu.com/geocoder/v2/?"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def content_key
|
|
27
|
+
'result'
|
|
28
|
+
end
|
|
29
|
+
|
|
21
30
|
def results(query, reverse = false)
|
|
22
31
|
return [] unless doc = fetch_data(query)
|
|
23
32
|
case doc['status']
|
|
24
33
|
when 0
|
|
25
|
-
return [doc[
|
|
34
|
+
return [doc[content_key]] unless doc[content_key].blank?
|
|
26
35
|
when 1, 3, 4
|
|
27
36
|
raise_error(Geocoder::Error, "server error.") ||
|
|
28
|
-
warn
|
|
37
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: server error.")
|
|
29
38
|
when 2
|
|
30
39
|
raise_error(Geocoder::InvalidRequest, "invalid request.") ||
|
|
31
|
-
warn
|
|
40
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: invalid request.")
|
|
32
41
|
when 5
|
|
33
42
|
raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
|
|
34
|
-
warn
|
|
43
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: invalid api key.")
|
|
35
44
|
when 101, 102, 200..299
|
|
36
45
|
raise_error(Geocoder::RequestDenied, "request denied") ||
|
|
37
|
-
warn
|
|
46
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: request denied.")
|
|
38
47
|
when 300..399
|
|
39
48
|
raise_error(Geocoder::OverQueryLimitError, "over query limit.") ||
|
|
40
|
-
warn
|
|
49
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: over query limit.")
|
|
41
50
|
end
|
|
42
51
|
return []
|
|
43
52
|
end
|
|
@@ -52,4 +61,3 @@ module Geocoder::Lookup
|
|
|
52
61
|
|
|
53
62
|
end
|
|
54
63
|
end
|
|
55
|
-
|
|
@@ -1,45 +1,21 @@
|
|
|
1
|
-
require 'geocoder/lookups/
|
|
1
|
+
require 'geocoder/lookups/baidu'
|
|
2
2
|
require 'geocoder/results/baidu_ip'
|
|
3
3
|
|
|
4
4
|
module Geocoder::Lookup
|
|
5
|
-
class BaiduIp <
|
|
5
|
+
class BaiduIp < Baidu
|
|
6
6
|
|
|
7
7
|
def name
|
|
8
8
|
"Baidu IP"
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
["key"]
|
|
13
|
-
end
|
|
11
|
+
private # ---------------------------------------------------------------
|
|
14
12
|
|
|
15
|
-
def
|
|
16
|
-
"
|
|
13
|
+
def base_query_url(query)
|
|
14
|
+
"#{protocol}://api.map.baidu.com/location/ip?"
|
|
17
15
|
end
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def results(query, reverse = false)
|
|
22
|
-
return [] unless doc = fetch_data(query)
|
|
23
|
-
case doc['status']
|
|
24
|
-
when 0
|
|
25
|
-
return [doc['content']] unless doc['content'].blank?
|
|
26
|
-
when 1, 3, 4
|
|
27
|
-
raise_error(Geocoder::Error, "server error.") ||
|
|
28
|
-
warn("Baidu IP Geocoding API error: server error.")
|
|
29
|
-
when 2
|
|
30
|
-
raise_error(Geocoder::InvalidRequest, "invalid request.") ||
|
|
31
|
-
warn("Baidu IP Geocoding API error: invalid request.")
|
|
32
|
-
when 5
|
|
33
|
-
raise_error(Geocoder::InvalidApiKey, "invalid api key.") ||
|
|
34
|
-
warn("Baidu IP Geocoding API error: invalid api key.")
|
|
35
|
-
when 101, 102, 200..299
|
|
36
|
-
raise_error(Geocoder::RequestDenied, "request denied.") ||
|
|
37
|
-
warn("Baidu IP Geocoding API error: request denied.")
|
|
38
|
-
when 300..399
|
|
39
|
-
raise_error(Geocoder::OverQueryLimitError, "over query limit") ||
|
|
40
|
-
warn("Baidu IP Geocoding API error: over query limit.")
|
|
41
|
-
end
|
|
42
|
-
return []
|
|
17
|
+
def content_key
|
|
18
|
+
'content'
|
|
43
19
|
end
|
|
44
20
|
|
|
45
21
|
def query_url_params(query)
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'geocoder/lookups/base'
|
|
4
|
+
require 'geocoder/results/ban_data_gouv_fr'
|
|
5
|
+
|
|
6
|
+
module Geocoder::Lookup
|
|
7
|
+
class BanDataGouvFr < Base
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Base Adresse Nationale Française"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def map_link_url(coordinates)
|
|
14
|
+
"https://www.openstreetmap.org/#map=19/#{coordinates.join('/')}"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private # ---------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
def base_query_url(query)
|
|
20
|
+
method = query.reverse_geocode? ? "reverse" : "search"
|
|
21
|
+
"#{protocol}://api-adresse.data.gouv.fr/#{method}/?"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def any_result?(doc)
|
|
25
|
+
doc['features'] and doc['features'].any?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def results(query)
|
|
29
|
+
if doc = fetch_data(query) and any_result?(doc)
|
|
30
|
+
[doc]
|
|
31
|
+
else
|
|
32
|
+
[]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
#### PARAMS ####
|
|
37
|
+
|
|
38
|
+
def query_url_params(query)
|
|
39
|
+
query_ban_datagouv_fr_params(query).merge(super)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def query_ban_datagouv_fr_params(query)
|
|
43
|
+
query.reverse_geocode? ? reverse_geocode_ban_fr_params(query) : search_geocode_ban_fr_params(query)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#### SEARCH GEOCODING PARAMS ####
|
|
47
|
+
#
|
|
48
|
+
# :q => required, full text search param)
|
|
49
|
+
|
|
50
|
+
# :limit => force limit number of results returned by raw API
|
|
51
|
+
# (default = 5) note : only first result is taken
|
|
52
|
+
# in account in geocoder
|
|
53
|
+
#
|
|
54
|
+
# :autocomplete => pass 0 to disable autocomplete treatment of :q
|
|
55
|
+
# (default = 1)
|
|
56
|
+
#
|
|
57
|
+
# :lat => force filter results around specific lat/lon
|
|
58
|
+
#
|
|
59
|
+
# :lon => force filter results around specific lat/lon
|
|
60
|
+
#
|
|
61
|
+
# :type => force filter the returned result type
|
|
62
|
+
# (check results for a list of accepted types)
|
|
63
|
+
#
|
|
64
|
+
# :postcode => force filter results on a specific city post code
|
|
65
|
+
#
|
|
66
|
+
# :citycode => force filter results on a specific city UUID INSEE code
|
|
67
|
+
#
|
|
68
|
+
# For up to date doc (in french only) : https://adresse.data.gouv.fr/api/
|
|
69
|
+
#
|
|
70
|
+
def search_geocode_ban_fr_params(query)
|
|
71
|
+
params = {
|
|
72
|
+
q: query.sanitized_text
|
|
73
|
+
}
|
|
74
|
+
unless (limit = query.options[:limit]).nil? || !limit_param_is_valid?(limit)
|
|
75
|
+
params[:limit] = limit.to_i
|
|
76
|
+
end
|
|
77
|
+
unless (autocomplete = query.options[:autocomplete]).nil? || !autocomplete_param_is_valid?(autocomplete)
|
|
78
|
+
params[:autocomplete] = autocomplete.to_s
|
|
79
|
+
end
|
|
80
|
+
unless (type = query.options[:type]).nil? || !type_param_is_valid?(type)
|
|
81
|
+
params[:type] = type.downcase
|
|
82
|
+
end
|
|
83
|
+
unless (postcode = query.options[:postcode]).nil? || !code_param_is_valid?(postcode)
|
|
84
|
+
params[:postcode] = postcode.to_s
|
|
85
|
+
end
|
|
86
|
+
unless (citycode = query.options[:citycode]).nil? || !code_param_is_valid?(citycode)
|
|
87
|
+
params[:citycode] = citycode.to_s
|
|
88
|
+
end
|
|
89
|
+
unless (lat = query.options[:lat]).nil? || !latitude_is_valid?(lat)
|
|
90
|
+
params[:lat] = lat
|
|
91
|
+
end
|
|
92
|
+
unless (lon = query.options[:lon]).nil? || !longitude_is_valid?(lon)
|
|
93
|
+
params[:lon] = lon
|
|
94
|
+
end
|
|
95
|
+
params
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
#### REVERSE GEOCODING PARAMS ####
|
|
99
|
+
#
|
|
100
|
+
# :lat => required
|
|
101
|
+
#
|
|
102
|
+
# :lon => required
|
|
103
|
+
#
|
|
104
|
+
# :type => force returned results type
|
|
105
|
+
# (check results for a list of accepted types)
|
|
106
|
+
#
|
|
107
|
+
def reverse_geocode_ban_fr_params(query)
|
|
108
|
+
lat_lon = query.coordinates
|
|
109
|
+
params = {
|
|
110
|
+
lat: lat_lon.first,
|
|
111
|
+
lon: lat_lon.last
|
|
112
|
+
}
|
|
113
|
+
unless (type = query.options[:type]).nil? || !type_param_is_valid?(type)
|
|
114
|
+
params[:type] = type.downcase
|
|
115
|
+
end
|
|
116
|
+
params
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def limit_param_is_valid?(param)
|
|
120
|
+
param.to_i.positive?
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def autocomplete_param_is_valid?(param)
|
|
124
|
+
[0,1].include?(param.to_i)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def type_param_is_valid?(param)
|
|
128
|
+
%w(housenumber street locality municipality).include?(param.downcase)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def code_param_is_valid?(param)
|
|
132
|
+
(1..99999).include?(param.to_i)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def latitude_is_valid?(param)
|
|
136
|
+
param.to_f <= 90 && param.to_f >= -90
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def longitude_is_valid?(param)
|
|
140
|
+
param.to_f <= 180 && param.to_f >= -180
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -4,7 +4,6 @@ require 'uri'
|
|
|
4
4
|
|
|
5
5
|
unless defined?(ActiveSupport::JSON)
|
|
6
6
|
begin
|
|
7
|
-
require 'rubygems' # for Ruby 1.8
|
|
8
7
|
require 'json'
|
|
9
8
|
rescue LoadError
|
|
10
9
|
raise LoadError, "Please install the 'json' or 'json_pure' gem to parse geocoder results."
|
|
@@ -72,8 +71,12 @@ module Geocoder
|
|
|
72
71
|
##
|
|
73
72
|
# URL to use for querying the geocoding engine.
|
|
74
73
|
#
|
|
74
|
+
# Subclasses should not modify this method. Instead they should define
|
|
75
|
+
# base_query_url and url_query_string. If absolutely necessary to
|
|
76
|
+
# subclss this method, they must also subclass #cache_key.
|
|
77
|
+
#
|
|
75
78
|
def query_url(query)
|
|
76
|
-
|
|
79
|
+
base_query_url(query) + url_query_string(query)
|
|
77
80
|
end
|
|
78
81
|
|
|
79
82
|
##
|
|
@@ -81,13 +84,31 @@ module Geocoder
|
|
|
81
84
|
#
|
|
82
85
|
def cache
|
|
83
86
|
if @cache.nil? and store = configuration.cache
|
|
84
|
-
|
|
87
|
+
cache_options = configuration.cache_options
|
|
88
|
+
@cache = Cache.new(store, cache_options)
|
|
85
89
|
end
|
|
86
90
|
@cache
|
|
87
91
|
end
|
|
88
92
|
|
|
93
|
+
##
|
|
94
|
+
# Array containing the protocols supported by the api.
|
|
95
|
+
# Should be set to [:http] if only HTTP is supported
|
|
96
|
+
# or [:https] if only HTTPS is supported.
|
|
97
|
+
#
|
|
98
|
+
def supported_protocols
|
|
99
|
+
[:http, :https]
|
|
100
|
+
end
|
|
101
|
+
|
|
89
102
|
private # -------------------------------------------------------------
|
|
90
103
|
|
|
104
|
+
##
|
|
105
|
+
# String which, when concatenated with url_query_string(query)
|
|
106
|
+
# produces the full query URL. Should include the "?" a the end.
|
|
107
|
+
#
|
|
108
|
+
def base_query_url(query)
|
|
109
|
+
fail
|
|
110
|
+
end
|
|
111
|
+
|
|
91
112
|
##
|
|
92
113
|
# An object with configuration data for this particular lookup.
|
|
93
114
|
#
|
|
@@ -99,7 +120,6 @@ module Geocoder
|
|
|
99
120
|
# Object used to make HTTP requests.
|
|
100
121
|
#
|
|
101
122
|
def http_client
|
|
102
|
-
protocol = "http#{'s' if use_ssl?}"
|
|
103
123
|
proxy_name = "#{protocol}_proxy"
|
|
104
124
|
if proxy = configuration.send(proxy_name)
|
|
105
125
|
proxy_url = !!(proxy =~ /^#{protocol}/) ? proxy : protocol + '://' + proxy
|
|
@@ -139,7 +159,14 @@ module Geocoder
|
|
|
139
159
|
# something else (like the URL before OAuth encoding).
|
|
140
160
|
#
|
|
141
161
|
def cache_key(query)
|
|
142
|
-
|
|
162
|
+
base_query_url(query) + hash_to_query(cache_key_params(query))
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def cache_key_params(query)
|
|
166
|
+
# omit api_key and token because they may vary among requests
|
|
167
|
+
query_url_params(query).reject do |key,value|
|
|
168
|
+
key.to_s.match(/(key|token)/)
|
|
169
|
+
end
|
|
143
170
|
end
|
|
144
171
|
|
|
145
172
|
##
|
|
@@ -168,12 +195,14 @@ module Geocoder
|
|
|
168
195
|
def fetch_data(query)
|
|
169
196
|
parse_raw_data fetch_raw_data(query)
|
|
170
197
|
rescue SocketError => err
|
|
171
|
-
raise_error(err) or warn "Geocoding API connection cannot be established."
|
|
198
|
+
raise_error(err) or Geocoder.log(:warn, "Geocoding API connection cannot be established.")
|
|
172
199
|
rescue Errno::ECONNREFUSED => err
|
|
173
|
-
raise_error(err) or warn "Geocoding API connection refused."
|
|
174
|
-
rescue
|
|
175
|
-
raise_error(err) or warn "Geocoding API
|
|
176
|
-
|
|
200
|
+
raise_error(err) or Geocoder.log(:warn, "Geocoding API connection refused.")
|
|
201
|
+
rescue Geocoder::NetworkError => err
|
|
202
|
+
raise_error(err) or Geocoder.log(:warn, "Geocoding API connection is either unreacheable or reset by the peer")
|
|
203
|
+
rescue Timeout::Error => err
|
|
204
|
+
raise_error(err) or Geocoder.log(:warn, "Geocoding API not responding fast enough " +
|
|
205
|
+
"(use Geocoder.configure(:timeout => ...) to set limit).")
|
|
177
206
|
end
|
|
178
207
|
|
|
179
208
|
def parse_json(data)
|
|
@@ -182,6 +211,11 @@ module Geocoder
|
|
|
182
211
|
else
|
|
183
212
|
JSON.parse(data)
|
|
184
213
|
end
|
|
214
|
+
rescue
|
|
215
|
+
unless raise_error(ResponseParseError.new(data))
|
|
216
|
+
Geocoder.log(:warn, "Geocoding API's response was not valid JSON")
|
|
217
|
+
Geocoder.log(:debug, "Raw response: #{data}")
|
|
218
|
+
end
|
|
185
219
|
end
|
|
186
220
|
|
|
187
221
|
##
|
|
@@ -189,8 +223,6 @@ module Geocoder
|
|
|
189
223
|
#
|
|
190
224
|
def parse_raw_data(raw_data)
|
|
191
225
|
parse_json(raw_data)
|
|
192
|
-
rescue
|
|
193
|
-
warn "Geocoding API's response was not valid JSON."
|
|
194
226
|
end
|
|
195
227
|
|
|
196
228
|
##
|
|
@@ -242,16 +274,19 @@ module Geocoder
|
|
|
242
274
|
def check_response_for_errors!(response)
|
|
243
275
|
if response.code.to_i == 400
|
|
244
276
|
raise_error(Geocoder::InvalidRequest) ||
|
|
245
|
-
warn
|
|
277
|
+
Geocoder.log(:warn, "Geocoding API error: 400 Bad Request")
|
|
246
278
|
elsif response.code.to_i == 401
|
|
247
279
|
raise_error(Geocoder::RequestDenied) ||
|
|
248
|
-
warn
|
|
280
|
+
Geocoder.log(:warn, "Geocoding API error: 401 Unauthorized")
|
|
249
281
|
elsif response.code.to_i == 402
|
|
250
282
|
raise_error(Geocoder::OverQueryLimitError) ||
|
|
251
|
-
warn
|
|
283
|
+
Geocoder.log(:warn, "Geocoding API error: 402 Payment Required")
|
|
252
284
|
elsif response.code.to_i == 429
|
|
253
285
|
raise_error(Geocoder::OverQueryLimitError) ||
|
|
254
|
-
warn
|
|
286
|
+
Geocoder.log(:warn, "Geocoding API error: 429 Too Many Requests")
|
|
287
|
+
elsif response.code.to_i == 503
|
|
288
|
+
raise_error(Geocoder::ServiceUnavailable) ||
|
|
289
|
+
Geocoder.log(:warn, "Geocoding API error: 503 Service Unavailable")
|
|
255
290
|
end
|
|
256
291
|
end
|
|
257
292
|
|
|
@@ -260,23 +295,37 @@ module Geocoder
|
|
|
260
295
|
# return the response object.
|
|
261
296
|
#
|
|
262
297
|
def make_api_request(query)
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
298
|
+
uri = URI.parse(query_url(query))
|
|
299
|
+
Geocoder.log(:debug, "Geocoder: HTTP request being made for #{uri.to_s}")
|
|
300
|
+
http_client.start(uri.host, uri.port, use_ssl: use_ssl?, open_timeout: configuration.timeout, read_timeout: configuration.timeout) do |client|
|
|
301
|
+
configure_ssl!(client) if use_ssl?
|
|
302
|
+
req = Net::HTTP::Get.new(uri.request_uri, configuration.http_headers)
|
|
303
|
+
if configuration.basic_auth[:user] and configuration.basic_auth[:password]
|
|
304
|
+
req.basic_auth(
|
|
305
|
+
configuration.basic_auth[:user],
|
|
306
|
+
configuration.basic_auth[:password]
|
|
307
|
+
)
|
|
272
308
|
end
|
|
309
|
+
client.request(req)
|
|
273
310
|
end
|
|
311
|
+
rescue Timeout::Error
|
|
312
|
+
raise Geocoder::LookupTimeout
|
|
313
|
+
rescue Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ENETUNREACH, Errno::ECONNRESET
|
|
314
|
+
raise Geocoder::NetworkError
|
|
274
315
|
end
|
|
275
316
|
|
|
276
317
|
def use_ssl?
|
|
277
|
-
|
|
318
|
+
if supported_protocols == [:https]
|
|
319
|
+
true
|
|
320
|
+
elsif supported_protocols == [:http]
|
|
321
|
+
false
|
|
322
|
+
else
|
|
323
|
+
configuration.use_https
|
|
324
|
+
end
|
|
278
325
|
end
|
|
279
326
|
|
|
327
|
+
def configure_ssl!(client); end
|
|
328
|
+
|
|
280
329
|
def check_api_key_configuration!(query)
|
|
281
330
|
key_parts = query.lookup.required_api_key_parts
|
|
282
331
|
if key_parts.size > Array(configuration.api_key).size
|
|
@@ -16,24 +16,20 @@ module Geocoder::Lookup
|
|
|
16
16
|
["key"]
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def query_url(query)
|
|
20
|
-
base_url(query) + url_query_string(query)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
19
|
private # ---------------------------------------------------------------
|
|
24
20
|
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
text = CGI.escape(query.sanitized_text.strip)
|
|
23
|
+
url = "#{protocol}://dev.virtualearth.net/REST/v1/Locations/"
|
|
24
|
+
if query.reverse_geocode?
|
|
25
|
+
url + "#{text}?"
|
|
26
|
+
else
|
|
29
27
|
if r = query.options[:region]
|
|
30
|
-
url << "
|
|
28
|
+
url << "#{r}/"
|
|
31
29
|
end
|
|
32
30
|
# use the more forgiving 'unstructured' query format to allow special
|
|
33
31
|
# chars, newlines, brackets, typos.
|
|
34
|
-
url + "?q
|
|
35
|
-
else
|
|
36
|
-
url + "/#{URI.escape(query.sanitized_text.strip)}?"
|
|
32
|
+
url + "?q=#{text}&"
|
|
37
33
|
end
|
|
38
34
|
end
|
|
39
35
|
|
|
@@ -43,17 +39,44 @@ module Geocoder::Lookup
|
|
|
43
39
|
if doc['statusCode'] == 200
|
|
44
40
|
return doc['resourceSets'].first['estimatedTotal'] > 0 ? doc['resourceSets'].first['resources'] : []
|
|
45
41
|
elsif doc['statusCode'] == 401 and doc["authenticationResultCode"] == "InvalidCredentials"
|
|
46
|
-
raise_error(Geocoder::InvalidApiKey) || warn
|
|
42
|
+
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid Bing API key.")
|
|
43
|
+
elsif doc['statusCode'] == 403
|
|
44
|
+
raise_error(Geocoder::RequestDenied) || Geocoder.log(:warn, "Bing Geocoding API error: Forbidden Request")
|
|
45
|
+
elsif [500, 503].include?(doc['statusCode'])
|
|
46
|
+
raise_error(Geocoder::ServiceUnavailable) ||
|
|
47
|
+
Geocoder.log(:warn, "Bing Geocoding API error: Service Unavailable")
|
|
47
48
|
else
|
|
48
|
-
warn "Bing Geocoding API error: #{doc['statusCode']} (#{doc['statusDescription']})."
|
|
49
|
+
Geocoder.log(:warn, "Bing Geocoding API error: #{doc['statusCode']} (#{doc['statusDescription']}).")
|
|
49
50
|
end
|
|
50
51
|
return []
|
|
51
52
|
end
|
|
52
53
|
|
|
53
54
|
def query_url_params(query)
|
|
54
55
|
{
|
|
55
|
-
key: configuration.api_key
|
|
56
|
+
key: configuration.api_key,
|
|
57
|
+
culture: (query.language || configuration.language)
|
|
56
58
|
}.merge(super)
|
|
57
59
|
end
|
|
60
|
+
|
|
61
|
+
def check_response_for_errors!(response)
|
|
62
|
+
super
|
|
63
|
+
if server_overloaded?(response)
|
|
64
|
+
raise_error(Geocoder::ServiceUnavailable) ||
|
|
65
|
+
Geocoder.log(:warn, "Bing Geocoding API error: Service Unavailable")
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def valid_response?(response)
|
|
70
|
+
super(response) and not server_overloaded?(response)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def server_overloaded?(response)
|
|
74
|
+
# Occasionally, the servers processing service requests can be overloaded,
|
|
75
|
+
# and you may receive some responses that contain no results for queries that
|
|
76
|
+
# you would normally receive a result. To identify this situation,
|
|
77
|
+
# check the HTTP headers of the response. If the HTTP header X-MS-BM-WS-INFO is set to 1,
|
|
78
|
+
# it is best to wait a few seconds and try again.
|
|
79
|
+
response['x-ms-bm-ws-info'].to_i == 1
|
|
80
|
+
end
|
|
58
81
|
end
|
|
59
82
|
end
|