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,63 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/ipstack'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Ipstack < Base
|
|
6
|
+
|
|
7
|
+
ERROR_CODES = {
|
|
8
|
+
404 => Geocoder::InvalidRequest,
|
|
9
|
+
101 => Geocoder::InvalidApiKey,
|
|
10
|
+
102 => Geocoder::Error,
|
|
11
|
+
103 => Geocoder::InvalidRequest,
|
|
12
|
+
104 => Geocoder::OverQueryLimitError,
|
|
13
|
+
105 => Geocoder::RequestDenied,
|
|
14
|
+
301 => Geocoder::InvalidRequest,
|
|
15
|
+
302 => Geocoder::InvalidRequest,
|
|
16
|
+
303 => Geocoder::RequestDenied,
|
|
17
|
+
}
|
|
18
|
+
ERROR_CODES.default = Geocoder::Error
|
|
19
|
+
|
|
20
|
+
def name
|
|
21
|
+
"Ipstack"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private # ----------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
def base_query_url(query)
|
|
27
|
+
"#{protocol}://#{host}/#{query.sanitized_text}?"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def query_url_params(query)
|
|
31
|
+
{
|
|
32
|
+
access_key: configuration.api_key
|
|
33
|
+
}.merge(super)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def results(query)
|
|
37
|
+
# don't look up a loopback or private address, just return the stored result
|
|
38
|
+
return [reserved_result(query.text)] if query.internal_ip_address?
|
|
39
|
+
|
|
40
|
+
return [] unless doc = fetch_data(query)
|
|
41
|
+
|
|
42
|
+
if error = doc['error']
|
|
43
|
+
code = error['code']
|
|
44
|
+
msg = error['info']
|
|
45
|
+
raise_error(ERROR_CODES[code], msg ) || Geocoder.log(:warn, "Ipstack Geocoding API error: #{msg}")
|
|
46
|
+
return []
|
|
47
|
+
end
|
|
48
|
+
[doc]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def reserved_result(ip)
|
|
52
|
+
{
|
|
53
|
+
"ip" => ip,
|
|
54
|
+
"country_name" => "Reserved",
|
|
55
|
+
"country_code" => "RD"
|
|
56
|
+
}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def host
|
|
60
|
+
configuration[:host] || "api.ipstack.com"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/latlon'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Latlon < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"LatLon.io"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def required_api_key_parts
|
|
12
|
+
["api_key"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private # ---------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
def base_query_url(query)
|
|
18
|
+
"#{protocol}://latlon.io/api/v1/#{'reverse_' if query.reverse_geocode?}geocode?"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def results(query)
|
|
22
|
+
return [] unless doc = fetch_data(query)
|
|
23
|
+
if doc['error'].nil?
|
|
24
|
+
[doc]
|
|
25
|
+
# The API returned a 404 response, which indicates no results found
|
|
26
|
+
elsif doc['error']['type'] == 'api_error'
|
|
27
|
+
[]
|
|
28
|
+
elsif doc['error']['type'] == 'authentication_error'
|
|
29
|
+
raise_error(Geocoder::InvalidApiKey) ||
|
|
30
|
+
Geocoder.log(:warn, "LatLon.io service error: invalid API key.")
|
|
31
|
+
else
|
|
32
|
+
[]
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def supported_protocols
|
|
37
|
+
[:https]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private # ---------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
def query_url_params(query)
|
|
43
|
+
if query.reverse_geocode?
|
|
44
|
+
{
|
|
45
|
+
:token => configuration.api_key,
|
|
46
|
+
:lat => query.coordinates[0],
|
|
47
|
+
:lon => query.coordinates[1]
|
|
48
|
+
}.merge(super)
|
|
49
|
+
else
|
|
50
|
+
{
|
|
51
|
+
:token => configuration.api_key,
|
|
52
|
+
:address => query.sanitized_text
|
|
53
|
+
}.merge(super)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'geocoder/lookups/nominatim'
|
|
2
|
+
require "geocoder/results/location_iq"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class LocationIq < Nominatim
|
|
6
|
+
def name
|
|
7
|
+
"LocationIq"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def required_api_key_parts
|
|
11
|
+
["api_key"]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def supported_protocols
|
|
15
|
+
[:https]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private # ----------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
def base_query_url(query)
|
|
21
|
+
method = query.reverse_geocode? ? "reverse" : "search"
|
|
22
|
+
"#{protocol}://#{configured_host}/v1/#{method}.php?"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def query_url_params(query)
|
|
26
|
+
{
|
|
27
|
+
key: configuration.api_key
|
|
28
|
+
}.merge(super)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def configured_host
|
|
32
|
+
configuration[:host] || "us1.locationiq.com"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def results(query)
|
|
36
|
+
return [] unless doc = fetch_data(query)
|
|
37
|
+
|
|
38
|
+
if !doc.is_a?(Array)
|
|
39
|
+
case doc['error']
|
|
40
|
+
when "Invalid key"
|
|
41
|
+
raise_error(Geocoder::InvalidApiKey, doc['error'])
|
|
42
|
+
when "Key not active - Please write to contact@unwiredlabs.com"
|
|
43
|
+
raise_error(Geocoder::RequestDenied, doc['error'])
|
|
44
|
+
when "Rate Limited"
|
|
45
|
+
raise_error(Geocoder::OverQueryLimitError, doc['error'])
|
|
46
|
+
when "Unknown error - Please try again after some time"
|
|
47
|
+
raise_error(Geocoder::InvalidRequest, doc['error'])
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
doc.is_a?(Array) ? doc : [doc]
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/mapbox"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Mapbox < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"Mapbox"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private # ---------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
def base_query_url(query)
|
|
14
|
+
"#{protocol}://api.mapbox.com/geocoding/v5/#{dataset}/#{mapbox_search_term(query)}.json?"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def results(query)
|
|
18
|
+
return [] unless data = fetch_data(query)
|
|
19
|
+
if data['features']
|
|
20
|
+
sort_relevant_feature(data['features'])
|
|
21
|
+
elsif data['message'] =~ /Invalid\sToken/
|
|
22
|
+
raise_error(Geocoder::InvalidApiKey, data['message'])
|
|
23
|
+
else
|
|
24
|
+
[]
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def query_url_params(query)
|
|
29
|
+
{access_token: configuration.api_key}.merge(super(query))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def mapbox_search_term(query)
|
|
33
|
+
require 'cgi' unless defined?(CGI) && defined?(CGI.escape)
|
|
34
|
+
if query.reverse_geocode?
|
|
35
|
+
lat,lon = query.coordinates
|
|
36
|
+
"#{CGI.escape lon},#{CGI.escape lat}"
|
|
37
|
+
else
|
|
38
|
+
# truncate at first semicolon so Mapbox doesn't go into batch mode
|
|
39
|
+
# (see Github issue #1299)
|
|
40
|
+
CGI.escape query.text.to_s.split(';').first.to_s
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def dataset
|
|
45
|
+
configuration[:dataset] || "mapbox.places"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def supported_protocols
|
|
49
|
+
[:https]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def sort_relevant_feature(features)
|
|
53
|
+
# Sort by descending relevance; Favor original order for equal relevance (eg occurs for reverse geocoding)
|
|
54
|
+
features.sort_by do |feature|
|
|
55
|
+
[feature["relevance"],-features.index(feature)]
|
|
56
|
+
end.reverse
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -13,15 +13,13 @@ module Geocoder::Lookup
|
|
|
13
13
|
["key"]
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
private # ---------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
def base_query_url(query)
|
|
17
19
|
domain = configuration[:open] ? "open" : "www"
|
|
18
|
-
|
|
19
|
-
url = "#{protocol}://#{domain}.mapquestapi.com/geocoding/v#{version}/#{search_type(query)}?"
|
|
20
|
-
url + url_query_string(query)
|
|
20
|
+
"#{protocol}://#{domain}.mapquestapi.com/geocoding/v1/#{search_type(query)}?"
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
private # ---------------------------------------------------------------
|
|
24
|
-
|
|
25
23
|
def search_type(query)
|
|
26
24
|
query.reverse_geocode? ? "reverse" : "address"
|
|
27
25
|
end
|
|
@@ -45,13 +43,13 @@ module Geocoder::Lookup
|
|
|
45
43
|
case doc['info']['statuscode']
|
|
46
44
|
when 400 # Error with input
|
|
47
45
|
raise_error(Geocoder::InvalidRequest, messages) ||
|
|
48
|
-
warn
|
|
46
|
+
Geocoder.log(:warn, "Mapquest Geocoding API error: #{messages}")
|
|
49
47
|
when 403 # Key related error
|
|
50
48
|
raise_error(Geocoder::InvalidApiKey, messages) ||
|
|
51
|
-
warn
|
|
49
|
+
Geocoder.log(:warn, "Mapquest Geocoding API error: #{messages}")
|
|
52
50
|
when 500 # Unknown error
|
|
53
51
|
raise_error(Geocoder::Error, messages) ||
|
|
54
|
-
warn
|
|
52
|
+
Geocoder.log(:warn, "Mapquest Geocoding API error: #{messages}")
|
|
55
53
|
end
|
|
56
54
|
[]
|
|
57
55
|
end
|
|
@@ -9,12 +9,12 @@ module Geocoder::Lookup
|
|
|
9
9
|
"MaxMind"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def query_url(query)
|
|
13
|
-
"#{protocol}://geoip.maxmind.com/#{service_code}?" + url_query_string(query)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
12
|
private # ---------------------------------------------------------------
|
|
17
13
|
|
|
14
|
+
def base_query_url(query)
|
|
15
|
+
"#{protocol}://geoip.maxmind.com/#{service_code}?"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
18
|
##
|
|
19
19
|
# Return the name of the configured service, or raise an exception.
|
|
20
20
|
#
|
|
@@ -57,14 +57,14 @@ module Geocoder::Lookup
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def results(query)
|
|
60
|
-
# don't look up a loopback address, just return the stored result
|
|
61
|
-
return [reserved_result] if query.
|
|
60
|
+
# don't look up a loopback or private address, just return the stored result
|
|
61
|
+
return [reserved_result] if query.internal_ip_address?
|
|
62
62
|
doc = fetch_data(query)
|
|
63
63
|
if doc and doc.is_a?(Array)
|
|
64
64
|
if !data_contains_error?(doc)
|
|
65
65
|
return [doc]
|
|
66
66
|
elsif doc.last == "INVALID_LICENSE_KEY"
|
|
67
|
-
raise_error(Geocoder::InvalidApiKey) || warn
|
|
67
|
+
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid MaxMind API key.")
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
return []
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/maxmind_geoip2'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class MaxmindGeoip2 < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"MaxMind GeoIP2"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Maxmind's GeoIP2 Precision Services only supports HTTPS,
|
|
12
|
+
# otherwise a `404 Not Found` HTTP response will be returned
|
|
13
|
+
def supported_protocols
|
|
14
|
+
[:https]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def query_url(query)
|
|
18
|
+
"#{protocol}://geoip.maxmind.com/geoip/v2.1/#{configured_service!}/#{query.sanitized_text.strip}"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private # ---------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
def cache_key(query)
|
|
24
|
+
query_url(query)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Return the name of the configured service, or raise an exception.
|
|
29
|
+
#
|
|
30
|
+
def configured_service!
|
|
31
|
+
if s = configuration[:service] and services.include?(s) and configuration[:basic_auth][:user] and configuration[:basic_auth][:password]
|
|
32
|
+
return s
|
|
33
|
+
else
|
|
34
|
+
raise(
|
|
35
|
+
Geocoder::ConfigurationError, "When using MaxMind GeoIP2 you must specify a service and credentials: Geocoder.configure(maxmind_geoip2: {service: ..., basic_auth: {user: ..., password: ...}}), where service is one of: #{services.inspect}"
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def data_contains_error?(doc)
|
|
41
|
+
(["code", "error"] - doc.keys).empty?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
##
|
|
45
|
+
# Service names used in URL.
|
|
46
|
+
#
|
|
47
|
+
def services
|
|
48
|
+
[
|
|
49
|
+
:country,
|
|
50
|
+
:city,
|
|
51
|
+
:insights,
|
|
52
|
+
]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def results(query)
|
|
56
|
+
# don't look up a loopback or private address, just return the stored result
|
|
57
|
+
return [] if query.internal_ip_address?
|
|
58
|
+
|
|
59
|
+
doc = fetch_data(query)
|
|
60
|
+
if doc
|
|
61
|
+
if !data_contains_error?(doc)
|
|
62
|
+
return [doc]
|
|
63
|
+
else
|
|
64
|
+
Geocoder.log(:warn, "MaxMind GeoIP2 Geocoding API error: #{doc['code']} (#{doc['error']}).")
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
return []
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -30,13 +30,19 @@ module Geocoder::Lookup
|
|
|
30
30
|
def results(query)
|
|
31
31
|
if configuration[:file]
|
|
32
32
|
geoip_class = RUBY_PLATFORM == "java" ? JGeoIP : GeoIP
|
|
33
|
-
|
|
34
|
-
result
|
|
33
|
+
geoip_instance = geoip_class.new(configuration[:file])
|
|
34
|
+
result =
|
|
35
|
+
if configuration[:package] == :country
|
|
36
|
+
geoip_instance.country(query.to_s)
|
|
37
|
+
else
|
|
38
|
+
geoip_instance.city(query.to_s)
|
|
39
|
+
end
|
|
40
|
+
result.nil? ? [] : [encode_hash(result.to_hash)]
|
|
35
41
|
elsif configuration[:package] == :city
|
|
36
42
|
addr = IPAddr.new(query.text).to_i
|
|
37
43
|
q = "SELECT l.country, l.region, l.city, l.latitude, l.longitude
|
|
38
44
|
FROM maxmind_geolite_city_location l WHERE l.loc_id = (SELECT b.loc_id FROM maxmind_geolite_city_blocks b
|
|
39
|
-
WHERE b.start_ip_num <= #{addr} AND #{addr} <= b.end_ip_num
|
|
45
|
+
WHERE b.start_ip_num <= #{addr} AND #{addr} <= b.end_ip_num)"
|
|
40
46
|
format_result(q, [:country_name, :region_name, :city_name, :latitude, :longitude])
|
|
41
47
|
elsif configuration[:package] == :country
|
|
42
48
|
addr = IPAddr.new(query.text).to_i
|
|
@@ -46,6 +52,13 @@ module Geocoder::Lookup
|
|
|
46
52
|
end
|
|
47
53
|
end
|
|
48
54
|
|
|
55
|
+
def encode_hash(hash, encoding = "UTF-8")
|
|
56
|
+
hash.inject({}) do |h,i|
|
|
57
|
+
h[i[0]] = i[1].is_a?(String) ? i[1].encode(encoding) : i[1]
|
|
58
|
+
h
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
49
62
|
def format_result(query, attr_names)
|
|
50
63
|
if r = ActiveRecord::Base.connection.execute(query).first
|
|
51
64
|
r = r.values if r.is_a?(Hash) # some db adapters return Hash, some Array
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/melissa_street"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class MelissaStreet < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"MelissaStreet"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def results(query)
|
|
12
|
+
return [] unless doc = fetch_data(query)
|
|
13
|
+
|
|
14
|
+
if doc["TransmissionResults"] == "GE05"
|
|
15
|
+
raise_error(Geocoder::InvalidApiKey) ||
|
|
16
|
+
Geocoder.log(:warn, "Melissa service error: invalid API key.")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
return doc["Records"]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private # ---------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
def base_query_url(query)
|
|
25
|
+
"#{protocol}://address.melissadata.net/v3/WEB/GlobalAddress/doGlobalAddress?"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def query_url_params(query)
|
|
29
|
+
params = {
|
|
30
|
+
id: configuration.api_key,
|
|
31
|
+
format: "JSON",
|
|
32
|
+
a1: query.sanitized_text,
|
|
33
|
+
loc: query.options[:city],
|
|
34
|
+
admarea: query.options[:state],
|
|
35
|
+
postal: query.options[:postal],
|
|
36
|
+
ctry: query.options[:country]
|
|
37
|
+
}
|
|
38
|
+
params.merge(super)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/nationaal_georegister_nl"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class NationaalGeoregisterNl < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
'Nationaal Georegister Nederland'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private # ---------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
def cache_key(query)
|
|
14
|
+
base_query_url(query) + hash_to_query(query_url_params(query))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def base_query_url(query)
|
|
18
|
+
"#{protocol}://geodata.nationaalgeoregister.nl/locatieserver/v3/free?"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def valid_response?(response)
|
|
22
|
+
json = parse_json(response.body)
|
|
23
|
+
super(response) if json
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def results(query)
|
|
27
|
+
return [] unless doc = fetch_data(query)
|
|
28
|
+
return doc['response']['docs']
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def query_url_params(query)
|
|
32
|
+
{
|
|
33
|
+
fl: '*',
|
|
34
|
+
q: query.text
|
|
35
|
+
}.merge(super)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -9,16 +9,28 @@ module Geocoder::Lookup
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def map_link_url(coordinates)
|
|
12
|
-
"
|
|
12
|
+
"https://www.openstreetmap.org/?lat=#{coordinates[0]}&lon=#{coordinates[1]}&zoom=15&layers=M"
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
private # ---------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
def base_query_url(query)
|
|
16
18
|
method = query.reverse_geocode? ? "reverse" : "search"
|
|
17
|
-
|
|
18
|
-
"#{protocol}://#{host}/#{method}?" + url_query_string(query)
|
|
19
|
+
"#{protocol}://#{configured_host}/#{method}?"
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
def configured_host
|
|
23
|
+
configuration[:host] || "nominatim.openstreetmap.org"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def use_ssl?
|
|
27
|
+
# nominatim.openstreetmap.org redirects HTTP requests to HTTPS
|
|
28
|
+
if configured_host == "nominatim.openstreetmap.org"
|
|
29
|
+
true
|
|
30
|
+
else
|
|
31
|
+
super
|
|
32
|
+
end
|
|
33
|
+
end
|
|
22
34
|
|
|
23
35
|
def results(query)
|
|
24
36
|
return [] unless doc = fetch_data(query)
|
|
@@ -27,7 +39,7 @@ module Geocoder::Lookup
|
|
|
27
39
|
|
|
28
40
|
def parse_raw_data(raw_data)
|
|
29
41
|
if raw_data.include?("Bandwidth limit exceeded")
|
|
30
|
-
raise_error(Geocoder::OverQueryLimitError) || warn
|
|
42
|
+
raise_error(Geocoder::OverQueryLimitError) || Geocoder.log(:warn, "Over API query limit.")
|
|
31
43
|
else
|
|
32
44
|
super(raw_data)
|
|
33
45
|
end
|
|
@@ -8,15 +8,15 @@ module Geocoder::Lookup
|
|
|
8
8
|
"OpenCageData"
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def query_url(query)
|
|
12
|
-
"#{protocol}://api.opencagedata.com/geocode/v1/json?key=#{configuration.api_key}&#{url_query_string(query)}"
|
|
13
|
-
end
|
|
14
|
-
|
|
15
11
|
def required_api_key_parts
|
|
16
12
|
["key"]
|
|
17
13
|
end
|
|
18
14
|
|
|
19
|
-
private
|
|
15
|
+
private # ----------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
def base_query_url(query)
|
|
18
|
+
"#{protocol}://api.opencagedata.com/geocode/v1/json?"
|
|
19
|
+
end
|
|
20
20
|
|
|
21
21
|
def results(query)
|
|
22
22
|
return [] unless doc = fetch_data(query)
|
|
@@ -26,16 +26,16 @@ module Geocoder::Lookup
|
|
|
26
26
|
case doc['status']['code']
|
|
27
27
|
when 400 # Error with input
|
|
28
28
|
raise_error(Geocoder::InvalidRequest, messages) ||
|
|
29
|
-
warn
|
|
29
|
+
Geocoder.log(:warn, "Opencagedata Geocoding API error: #{messages}")
|
|
30
30
|
when 403 # Key related error
|
|
31
31
|
raise_error(Geocoder::InvalidApiKey, messages) ||
|
|
32
|
-
warn
|
|
32
|
+
Geocoder.log(:warn, "Opencagedata Geocoding API error: #{messages}")
|
|
33
33
|
when 402 # Quata Exceeded
|
|
34
34
|
raise_error(Geocoder::OverQueryLimitError, messages) ||
|
|
35
|
-
warn
|
|
35
|
+
Geocoder.log(:warn, "Opencagedata Geocoding API error: #{messages}")
|
|
36
36
|
when 500 # Unknown error
|
|
37
37
|
raise_error(Geocoder::Error, messages) ||
|
|
38
|
-
warn
|
|
38
|
+
Geocoder.log(:warn, "Opencagedata Geocoding API error: #{messages}")
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
return doc["results"]
|
|
@@ -44,9 +44,16 @@ module Geocoder::Lookup
|
|
|
44
44
|
def query_url_params(query)
|
|
45
45
|
params = {
|
|
46
46
|
:q => query.sanitized_text,
|
|
47
|
+
:key => configuration.api_key,
|
|
47
48
|
:language => (query.language || configuration.language)
|
|
48
49
|
}.merge(super)
|
|
49
50
|
|
|
51
|
+
[:abbrv, :countrycode, :min_confidence, :no_dedupe, :no_annotations, :no_record, :limit].each do |option|
|
|
52
|
+
unless (option_value = query.options[option]).nil?
|
|
53
|
+
params[option] = option_value
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
50
57
|
unless (bounds = query.options[:bounds]).nil?
|
|
51
58
|
params[:bounds] = bounds.map{ |point| "%f,%f" % point }.join(',')
|
|
52
59
|
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'cgi'
|
|
2
|
+
require 'geocoder/lookups/base'
|
|
3
|
+
require 'geocoder/results/osmnames'
|
|
4
|
+
|
|
5
|
+
module Geocoder::Lookup
|
|
6
|
+
class Osmnames < Base
|
|
7
|
+
|
|
8
|
+
def name
|
|
9
|
+
'OSM Names'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def required_api_key_parts
|
|
13
|
+
configuration[:host] ? [] : ['key']
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def supported_protocols
|
|
17
|
+
[:https]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def base_query_url(query)
|
|
23
|
+
"#{base_url(query)}/#{params_url(query)}.js?"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def base_url(query)
|
|
27
|
+
host = configuration[:host] || 'geocoder.tilehosting.com'
|
|
28
|
+
"#{protocol}://#{host}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def params_url(query)
|
|
32
|
+
method, args = 'q', CGI.escape(query.sanitized_text)
|
|
33
|
+
method, args = 'r', query.coordinates.join('/') if query.reverse_geocode?
|
|
34
|
+
"#{country_limited(query)}#{method}/#{args}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def results(query)
|
|
38
|
+
return [] unless doc = fetch_data(query)
|
|
39
|
+
if (error = doc['message'])
|
|
40
|
+
raise_error(Geocoder::InvalidRequest, error) ||
|
|
41
|
+
Geocoder.log(:warn, "OSMNames Geocoding API error: #{error}")
|
|
42
|
+
else
|
|
43
|
+
return doc['results']
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def query_url_params(query)
|
|
48
|
+
{
|
|
49
|
+
key: configuration.api_key
|
|
50
|
+
}.merge(super)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def country_limited(query)
|
|
54
|
+
"#{query.options[:country_code].downcase}/" if query.options[:country_code] && !query.reverse_geocode?
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|