geocoder 1.2.6 → 1.6.1
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 +189 -1
- data/LICENSE +1 -1
- data/README.md +387 -755
- data/examples/autoexpire_cache_redis.rb +5 -3
- data/examples/reverse_geocode_job.rb +40 -0
- data/lib/generators/geocoder/config/templates/initializer.rb +17 -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 +6 -2
- data/lib/geocoder/calculations.rb +30 -38
- data/lib/geocoder/cli.rb +2 -2
- data/lib/geocoder/configuration.rb +18 -5
- data/lib/geocoder/esri_token.rb +38 -0
- data/lib/geocoder/exceptions.rb +19 -0
- data/lib/geocoder/ip_address.rb +16 -11
- data/lib/geocoder/kernel_logger.rb +25 -0
- data/lib/geocoder/logger.rb +47 -0
- data/lib/geocoder/lookup.rb +31 -12
- data/lib/geocoder/lookups/amap.rb +63 -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 +73 -25
- 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 +55 -8
- data/lib/geocoder/lookups/freegeoip.rb +18 -5
- data/lib/geocoder/lookups/geocoder_ca.rb +5 -6
- data/lib/geocoder/lookups/geocodio.rb +8 -8
- data/lib/geocoder/lookups/geoip2.rb +10 -5
- data/lib/geocoder/lookups/geoportail_lu.rb +65 -0
- data/lib/geocoder/lookups/google.rb +37 -9
- data/lib/geocoder/lookups/google_places_details.rb +9 -9
- data/lib/geocoder/lookups/google_places_search.rb +33 -0
- data/lib/geocoder/lookups/google_premier.rb +11 -1
- data/lib/geocoder/lookups/here.rb +29 -23
- data/lib/geocoder/lookups/ip2location.rb +67 -0
- data/lib/geocoder/lookups/ipapi_com.rb +82 -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/ipregistry.rb +68 -0
- data/lib/geocoder/lookups/ipstack.rb +63 -0
- data/lib/geocoder/lookups/latlon.rb +59 -0
- data/lib/geocoder/lookups/location_iq.rb +50 -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 +9 -2
- 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/pelias.rb +63 -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 +23 -5
- data/lib/geocoder/lookups/telize.rb +42 -7
- data/lib/geocoder/lookups/tencent.rb +59 -0
- data/lib/geocoder/lookups/yandex.rb +17 -9
- 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/amap.rb +87 -0
- data/lib/geocoder/results/baidu.rb +10 -14
- data/lib/geocoder/results/ban_data_gouv_fr.rb +257 -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 +30 -6
- data/lib/geocoder/results/freegeoip.rb +2 -7
- 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 +21 -1
- data/lib/geocoder/results/ip2location.rb +22 -0
- data/lib/geocoder/results/ipapi_com.rb +45 -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/ipregistry.rb +308 -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 +57 -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/nominatim.rb +18 -3
- data/lib/geocoder/results/opencagedata.rb +20 -2
- data/lib/geocoder/results/osmnames.rb +56 -0
- data/lib/geocoder/results/pelias.rb +58 -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/yandex.rb +57 -7
- 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/version.rb +1 -1
- data/lib/geocoder.rb +2 -1
- data/lib/hash_recursive_merge.rb +1 -2
- data/lib/maxmind_database.rb +4 -4
- data/lib/tasks/geocoder.rake +29 -4
- metadata +56 -159
- data/.gitignore +0 -6
- data/.travis.yml +0 -31
- data/Rakefile +0 -25
- 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/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
data/lib/geocoder/lookup.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require "geocoder/lookups/test"
|
|
2
|
+
|
|
1
3
|
module Geocoder
|
|
2
4
|
module Lookup
|
|
3
5
|
extend self
|
|
@@ -20,28 +22,36 @@ module Geocoder
|
|
|
20
22
|
# All street address lookup services, default first.
|
|
21
23
|
#
|
|
22
24
|
def street_services
|
|
23
|
-
[
|
|
25
|
+
@street_services ||= [
|
|
26
|
+
:location_iq,
|
|
24
27
|
:dstk,
|
|
25
28
|
:esri,
|
|
26
29
|
:google,
|
|
27
30
|
:google_premier,
|
|
28
31
|
:google_places_details,
|
|
29
|
-
:
|
|
32
|
+
:google_places_search,
|
|
30
33
|
:bing,
|
|
31
34
|
:geocoder_ca,
|
|
32
|
-
:geocoder_us,
|
|
33
35
|
:yandex,
|
|
34
36
|
:nominatim,
|
|
37
|
+
:mapbox,
|
|
35
38
|
:mapquest,
|
|
36
39
|
:opencagedata,
|
|
37
|
-
:
|
|
40
|
+
:pelias,
|
|
41
|
+
:pickpoint,
|
|
38
42
|
:here,
|
|
39
43
|
:baidu,
|
|
44
|
+
:tencent,
|
|
40
45
|
:geocodio,
|
|
41
46
|
:smarty_streets,
|
|
42
|
-
:okf,
|
|
43
47
|
:postcode_anywhere_uk,
|
|
44
|
-
:
|
|
48
|
+
:postcodes_io,
|
|
49
|
+
:geoportail_lu,
|
|
50
|
+
:ban_data_gouv_fr,
|
|
51
|
+
:test,
|
|
52
|
+
:latlon,
|
|
53
|
+
:amap,
|
|
54
|
+
:osmnames
|
|
45
55
|
]
|
|
46
56
|
end
|
|
47
57
|
|
|
@@ -49,17 +59,28 @@ module Geocoder
|
|
|
49
59
|
# All IP address lookup services, default first.
|
|
50
60
|
#
|
|
51
61
|
def ip_services
|
|
52
|
-
[
|
|
62
|
+
@ip_services ||= [
|
|
53
63
|
:baidu_ip,
|
|
54
64
|
:freegeoip,
|
|
55
65
|
:geoip2,
|
|
56
66
|
:maxmind,
|
|
57
67
|
:maxmind_local,
|
|
58
68
|
:telize,
|
|
59
|
-
:pointpin
|
|
69
|
+
:pointpin,
|
|
70
|
+
:maxmind_geoip2,
|
|
71
|
+
:ipinfo_io,
|
|
72
|
+
:ipregistry,
|
|
73
|
+
:ipapi_com,
|
|
74
|
+
:ipdata_co,
|
|
75
|
+
:db_ip_com,
|
|
76
|
+
:ipstack,
|
|
77
|
+
:ip2location,
|
|
78
|
+
:ipgeolocation
|
|
60
79
|
]
|
|
61
80
|
end
|
|
62
81
|
|
|
82
|
+
attr_writer :street_services, :ip_services
|
|
83
|
+
|
|
63
84
|
##
|
|
64
85
|
# Retrieve a Lookup object from the store.
|
|
65
86
|
# Use this instead of Geocoder::Lookup::X.new to get an
|
|
@@ -79,6 +100,8 @@ module Geocoder
|
|
|
79
100
|
#
|
|
80
101
|
def spawn(name)
|
|
81
102
|
if all_services.include?(name)
|
|
103
|
+
name = name.to_s
|
|
104
|
+
require "geocoder/lookups/#{name}"
|
|
82
105
|
Geocoder::Lookup.const_get(classify_name(name)).new
|
|
83
106
|
else
|
|
84
107
|
valids = all_services.map(&:inspect).join(", ")
|
|
@@ -95,7 +118,3 @@ module Geocoder
|
|
|
95
118
|
end
|
|
96
119
|
end
|
|
97
120
|
end
|
|
98
|
-
|
|
99
|
-
Geocoder::Lookup.all_services.each do |name|
|
|
100
|
-
require "geocoder/lookups/#{name}"
|
|
101
|
-
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
|
+
warn("#{self.name} Geocoding API error: invalid api key.")
|
|
36
|
+
else
|
|
37
|
+
raise_error(Geocoder::Error, "server error.") ||
|
|
38
|
+
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
|
|
@@ -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'].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 village town city).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
|
##
|
|
@@ -86,8 +89,25 @@ module Geocoder
|
|
|
86
89
|
@cache
|
|
87
90
|
end
|
|
88
91
|
|
|
92
|
+
##
|
|
93
|
+
# Array containing the protocols supported by the api.
|
|
94
|
+
# Should be set to [:http] if only HTTP is supported
|
|
95
|
+
# or [:https] if only HTTPS is supported.
|
|
96
|
+
#
|
|
97
|
+
def supported_protocols
|
|
98
|
+
[:http, :https]
|
|
99
|
+
end
|
|
100
|
+
|
|
89
101
|
private # -------------------------------------------------------------
|
|
90
102
|
|
|
103
|
+
##
|
|
104
|
+
# String which, when concatenated with url_query_string(query)
|
|
105
|
+
# produces the full query URL. Should include the "?" a the end.
|
|
106
|
+
#
|
|
107
|
+
def base_query_url(query)
|
|
108
|
+
fail
|
|
109
|
+
end
|
|
110
|
+
|
|
91
111
|
##
|
|
92
112
|
# An object with configuration data for this particular lookup.
|
|
93
113
|
#
|
|
@@ -99,7 +119,6 @@ module Geocoder
|
|
|
99
119
|
# Object used to make HTTP requests.
|
|
100
120
|
#
|
|
101
121
|
def http_client
|
|
102
|
-
protocol = "http#{'s' if use_ssl?}"
|
|
103
122
|
proxy_name = "#{protocol}_proxy"
|
|
104
123
|
if proxy = configuration.send(proxy_name)
|
|
105
124
|
proxy_url = !!(proxy =~ /^#{protocol}/) ? proxy : protocol + '://' + proxy
|
|
@@ -139,7 +158,14 @@ module Geocoder
|
|
|
139
158
|
# something else (like the URL before OAuth encoding).
|
|
140
159
|
#
|
|
141
160
|
def cache_key(query)
|
|
142
|
-
|
|
161
|
+
base_query_url(query) + hash_to_query(cache_key_params(query))
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def cache_key_params(query)
|
|
165
|
+
# omit api_key and token because they may vary among requests
|
|
166
|
+
query_url_params(query).reject do |key,value|
|
|
167
|
+
key.to_s.match(/(key|token)/)
|
|
168
|
+
end
|
|
143
169
|
end
|
|
144
170
|
|
|
145
171
|
##
|
|
@@ -168,12 +194,14 @@ module Geocoder
|
|
|
168
194
|
def fetch_data(query)
|
|
169
195
|
parse_raw_data fetch_raw_data(query)
|
|
170
196
|
rescue SocketError => err
|
|
171
|
-
raise_error(err) or warn "Geocoding API connection cannot be established."
|
|
197
|
+
raise_error(err) or Geocoder.log(:warn, "Geocoding API connection cannot be established.")
|
|
172
198
|
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
|
-
|
|
199
|
+
raise_error(err) or Geocoder.log(:warn, "Geocoding API connection refused.")
|
|
200
|
+
rescue Geocoder::NetworkError => err
|
|
201
|
+
raise_error(err) or Geocoder.log(:warn, "Geocoding API connection is either unreacheable or reset by the peer")
|
|
202
|
+
rescue Timeout::Error => err
|
|
203
|
+
raise_error(err) or Geocoder.log(:warn, "Geocoding API not responding fast enough " +
|
|
204
|
+
"(use Geocoder.configure(:timeout => ...) to set limit).")
|
|
177
205
|
end
|
|
178
206
|
|
|
179
207
|
def parse_json(data)
|
|
@@ -182,6 +210,11 @@ module Geocoder
|
|
|
182
210
|
else
|
|
183
211
|
JSON.parse(data)
|
|
184
212
|
end
|
|
213
|
+
rescue
|
|
214
|
+
unless raise_error(ResponseParseError.new(data))
|
|
215
|
+
Geocoder.log(:warn, "Geocoding API's response was not valid JSON")
|
|
216
|
+
Geocoder.log(:debug, "Raw response: #{data}")
|
|
217
|
+
end
|
|
185
218
|
end
|
|
186
219
|
|
|
187
220
|
##
|
|
@@ -189,8 +222,6 @@ module Geocoder
|
|
|
189
222
|
#
|
|
190
223
|
def parse_raw_data(raw_data)
|
|
191
224
|
parse_json(raw_data)
|
|
192
|
-
rescue
|
|
193
|
-
warn "Geocoding API's response was not valid JSON."
|
|
194
225
|
end
|
|
195
226
|
|
|
196
227
|
##
|
|
@@ -242,16 +273,19 @@ module Geocoder
|
|
|
242
273
|
def check_response_for_errors!(response)
|
|
243
274
|
if response.code.to_i == 400
|
|
244
275
|
raise_error(Geocoder::InvalidRequest) ||
|
|
245
|
-
warn
|
|
276
|
+
Geocoder.log(:warn, "Geocoding API error: 400 Bad Request")
|
|
246
277
|
elsif response.code.to_i == 401
|
|
247
278
|
raise_error(Geocoder::RequestDenied) ||
|
|
248
|
-
warn
|
|
279
|
+
Geocoder.log(:warn, "Geocoding API error: 401 Unauthorized")
|
|
249
280
|
elsif response.code.to_i == 402
|
|
250
281
|
raise_error(Geocoder::OverQueryLimitError) ||
|
|
251
|
-
warn
|
|
282
|
+
Geocoder.log(:warn, "Geocoding API error: 402 Payment Required")
|
|
252
283
|
elsif response.code.to_i == 429
|
|
253
284
|
raise_error(Geocoder::OverQueryLimitError) ||
|
|
254
|
-
warn
|
|
285
|
+
Geocoder.log(:warn, "Geocoding API error: 429 Too Many Requests")
|
|
286
|
+
elsif response.code.to_i == 503
|
|
287
|
+
raise_error(Geocoder::ServiceUnavailable) ||
|
|
288
|
+
Geocoder.log(:warn, "Geocoding API error: 503 Service Unavailable")
|
|
255
289
|
end
|
|
256
290
|
end
|
|
257
291
|
|
|
@@ -260,23 +294,37 @@ module Geocoder
|
|
|
260
294
|
# return the response object.
|
|
261
295
|
#
|
|
262
296
|
def make_api_request(query)
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
297
|
+
uri = URI.parse(query_url(query))
|
|
298
|
+
Geocoder.log(:debug, "Geocoder: HTTP request being made for #{uri.to_s}")
|
|
299
|
+
http_client.start(uri.host, uri.port, use_ssl: use_ssl?, open_timeout: configuration.timeout, read_timeout: configuration.timeout) do |client|
|
|
300
|
+
configure_ssl!(client) if use_ssl?
|
|
301
|
+
req = Net::HTTP::Get.new(uri.request_uri, configuration.http_headers)
|
|
302
|
+
if configuration.basic_auth[:user] and configuration.basic_auth[:password]
|
|
303
|
+
req.basic_auth(
|
|
304
|
+
configuration.basic_auth[:user],
|
|
305
|
+
configuration.basic_auth[:password]
|
|
306
|
+
)
|
|
272
307
|
end
|
|
308
|
+
client.request(req)
|
|
273
309
|
end
|
|
310
|
+
rescue Timeout::Error
|
|
311
|
+
raise Geocoder::LookupTimeout
|
|
312
|
+
rescue Errno::EHOSTUNREACH, Errno::ETIMEDOUT, Errno::ENETUNREACH, Errno::ECONNRESET
|
|
313
|
+
raise Geocoder::NetworkError
|
|
274
314
|
end
|
|
275
315
|
|
|
276
316
|
def use_ssl?
|
|
277
|
-
|
|
317
|
+
if supported_protocols == [:https]
|
|
318
|
+
true
|
|
319
|
+
elsif supported_protocols == [:http]
|
|
320
|
+
false
|
|
321
|
+
else
|
|
322
|
+
configuration.use_https
|
|
323
|
+
end
|
|
278
324
|
end
|
|
279
325
|
|
|
326
|
+
def configure_ssl!(client); end
|
|
327
|
+
|
|
280
328
|
def check_api_key_configuration!(query)
|
|
281
329
|
key_parts = query.lookup.required_api_key_parts
|
|
282
330
|
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
|
+
language: (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
|