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,85 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/pc_miler"
|
|
3
|
+
require 'cgi' unless defined?(CGI) && defined?(CGI.escape)
|
|
4
|
+
|
|
5
|
+
module Geocoder::Lookup
|
|
6
|
+
class PcMiler < Base
|
|
7
|
+
|
|
8
|
+
# https://developer.trimblemaps.com/restful-apis/location/single-search/single-search-api/#test-the-api-now
|
|
9
|
+
def valid_region_codes
|
|
10
|
+
# AF: Africa
|
|
11
|
+
# AS: Asia
|
|
12
|
+
# EU: Europe
|
|
13
|
+
# NA: North America
|
|
14
|
+
# OC: Oceania
|
|
15
|
+
# SA: South America
|
|
16
|
+
%w[AF AS EU NA OC SA]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def name
|
|
20
|
+
"PCMiler"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private # ---------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
def base_query_url(query)
|
|
26
|
+
region_code = region(query)
|
|
27
|
+
if !valid_region_codes.include?(region_code)
|
|
28
|
+
raise "region_code '#{region_code}' is invalid. use one of #{valid_region_codes}." \
|
|
29
|
+
"https://developer.trimblemaps.com/restful-apis/location/single-search/single-search-api/#test-the-api-now"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
"#{protocol}://singlesearch.alk.com/#{region_code}/api/search?"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def results(query)
|
|
36
|
+
return [] unless data = fetch_data(query)
|
|
37
|
+
if data['Locations']
|
|
38
|
+
add_metadata_to_locations!(data)
|
|
39
|
+
data['Locations']
|
|
40
|
+
else
|
|
41
|
+
[]
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def add_metadata_to_locations!(data)
|
|
46
|
+
confidence = data['QueryConfidence']
|
|
47
|
+
data['Locations'].each do |location|
|
|
48
|
+
location['QueryConfidence'] = confidence
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def query_url_params(query)
|
|
53
|
+
if query.reverse_geocode?
|
|
54
|
+
lat,lon = query.coordinates
|
|
55
|
+
formatted_query = "#{CGI.escape(lat)},#{CGI.escape(lon)}"
|
|
56
|
+
else
|
|
57
|
+
formatted_query = query.text.to_s
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
{
|
|
61
|
+
authToken: configuration.api_key,
|
|
62
|
+
query: formatted_query,
|
|
63
|
+
# to add additional metadata to response such as QueryConfidence
|
|
64
|
+
include: 'Meta'
|
|
65
|
+
}.merge(super(query))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def region(query)
|
|
69
|
+
query.options[:region] || query.options['region'] || configuration[:region] || "NA"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def check_response_for_errors!(response)
|
|
73
|
+
if response.code.to_i == 403
|
|
74
|
+
raise_error(Geocoder::RequestDenied) ||
|
|
75
|
+
Geocoder.log(:warn, "Geocoding API error: 403 API key does not exist")
|
|
76
|
+
else
|
|
77
|
+
super(response)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def supported_protocols
|
|
82
|
+
[:https]
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/pelias'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Pelias < Base
|
|
6
|
+
def name
|
|
7
|
+
'Pelias'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def endpoint
|
|
11
|
+
configuration[:endpoint] || 'localhost'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def required_api_key_parts
|
|
15
|
+
['search-XXXX']
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private # ----------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
def base_query_url(query)
|
|
21
|
+
query_type = query.reverse_geocode? ? 'reverse' : 'search'
|
|
22
|
+
"#{protocol}://#{endpoint}/v1/#{query_type}?"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def query_url_params(query)
|
|
26
|
+
params = {
|
|
27
|
+
api_key: configuration.api_key
|
|
28
|
+
}.merge(super)
|
|
29
|
+
|
|
30
|
+
if query.reverse_geocode?
|
|
31
|
+
lat, lon = query.coordinates
|
|
32
|
+
params[:'point.lat'] = lat
|
|
33
|
+
params[:'point.lon'] = lon
|
|
34
|
+
else
|
|
35
|
+
params[:text] = query.text
|
|
36
|
+
end
|
|
37
|
+
params
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def results(query)
|
|
41
|
+
return [] unless doc = fetch_data(query)
|
|
42
|
+
|
|
43
|
+
# not all responses include a meta
|
|
44
|
+
if doc['meta']
|
|
45
|
+
error = doc.fetch('results', {}).fetch('error', {})
|
|
46
|
+
message = error.fetch('type', 'Unknown Error') + ': ' + error.fetch('message', 'No message')
|
|
47
|
+
log_message = 'Pelias Geocoding API error - ' + message
|
|
48
|
+
case doc['meta']['status_code']
|
|
49
|
+
when '200'
|
|
50
|
+
# nothing to see here
|
|
51
|
+
when '403'
|
|
52
|
+
raise_error(Geocoder::RequestDenied, message) || Geocoder.log(:warn, log_message)
|
|
53
|
+
when '429'
|
|
54
|
+
raise_error(Geocoder::OverQueryLimitError, message) || Geocoder.log(:warn, log_message)
|
|
55
|
+
else
|
|
56
|
+
raise_error(Geocoder::Error, message) || Geocoder.log(:warn, log_message)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
doc['features'] || []
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/photon'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Photon < Base
|
|
6
|
+
def name
|
|
7
|
+
'Photon'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private # ---------------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
def supported_protocols
|
|
13
|
+
[:https]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def base_query_url(query)
|
|
17
|
+
host = configuration[:host] || 'photon.komoot.io'
|
|
18
|
+
method = query.reverse_geocode? ? 'reverse' : 'api'
|
|
19
|
+
"#{protocol}://#{host}/#{method}?"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def results(query)
|
|
23
|
+
return [] unless (doc = fetch_data(query))
|
|
24
|
+
return [] unless doc['type'] == 'FeatureCollection'
|
|
25
|
+
return [] unless doc['features'] || doc['features'].present?
|
|
26
|
+
|
|
27
|
+
doc['features']
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def query_url_params(query)
|
|
31
|
+
lang = query.language || configuration.language
|
|
32
|
+
params = { lang: lang, limit: query.options[:limit] }
|
|
33
|
+
|
|
34
|
+
if query.reverse_geocode?
|
|
35
|
+
params.merge!(query_url_params_reverse(query))
|
|
36
|
+
else
|
|
37
|
+
params.merge!(query_url_params_coordinates(query))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
params.merge!(super)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def query_url_params_coordinates(query)
|
|
44
|
+
params = { q: query.sanitized_text }
|
|
45
|
+
|
|
46
|
+
if (bias = query.options[:bias])
|
|
47
|
+
params.merge!(lat: bias[:latitude], lon: bias[:longitude], location_bias_scale: bias[:scale])
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
if (filter = query_url_params_coordinates_filter(query))
|
|
51
|
+
params.merge!(filter)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
params
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def query_url_params_coordinates_filter(query)
|
|
58
|
+
filter = query.options[:filter]
|
|
59
|
+
return unless filter
|
|
60
|
+
|
|
61
|
+
bbox = filter[:bbox]
|
|
62
|
+
{
|
|
63
|
+
bbox: bbox.is_a?(Array) ? bbox.join(',') : bbox,
|
|
64
|
+
osm_tag: filter[:osm_tag]
|
|
65
|
+
}
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def query_url_params_reverse(query)
|
|
69
|
+
params = { lat: query.coordinates[0], lon: query.coordinates[1], radius: query.options[:radius] }
|
|
70
|
+
|
|
71
|
+
if (dsort = query.options[:distance_sort])
|
|
72
|
+
params[:distance_sort] = dsort ? 'true' : 'false'
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
if (filter = query_url_params_reverse_filter(query))
|
|
76
|
+
params.merge!(filter)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
params
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def query_url_params_reverse_filter(query)
|
|
83
|
+
filter = query.options[:filter]
|
|
84
|
+
return unless filter
|
|
85
|
+
|
|
86
|
+
{ query_string_filter: filter[:string] }
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require "geocoder/lookups/nominatim"
|
|
2
|
+
require "geocoder/results/pickpoint"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Pickpoint < Nominatim
|
|
6
|
+
def name
|
|
7
|
+
"Pickpoint"
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def supported_protocols
|
|
11
|
+
[:https]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def required_api_key_parts
|
|
15
|
+
["api_key"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private # ----------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
def base_query_url(query)
|
|
21
|
+
method = query.reverse_geocode? ? "reverse" : "forward"
|
|
22
|
+
"#{protocol}://api.pickpoint.io/v1/#{method}?"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def query_url_params(query)
|
|
26
|
+
{
|
|
27
|
+
key: configuration.api_key
|
|
28
|
+
}.merge(super)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def results(query)
|
|
32
|
+
return [] unless doc = fetch_data(query)
|
|
33
|
+
|
|
34
|
+
if !doc.is_a?(Array) && doc['message'] == 'Unauthorized'
|
|
35
|
+
raise_error(Geocoder::InvalidApiKey, 'Unauthorized')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
doc.is_a?(Array) ? doc : [doc]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -13,14 +13,18 @@ module Geocoder::Lookup
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def query_url(query)
|
|
16
|
-
"#{
|
|
16
|
+
"#{protocol}://geo.pointp.in/#{configuration.api_key}/json/#{query.sanitized_text}"
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
private # ----------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def cache_key(query)
|
|
22
|
+
"#{protocol}://geo.pointp.in/json/#{query.sanitized_text}"
|
|
23
|
+
end
|
|
20
24
|
|
|
21
25
|
def results(query)
|
|
22
|
-
# don't look up a loopback address, just return the stored result
|
|
23
|
-
return [] if query.
|
|
26
|
+
# don't look up a loopback or private address, just return the stored result
|
|
27
|
+
return [] if query.internal_ip_address?
|
|
24
28
|
doc = fetch_data(query)
|
|
25
29
|
if doc and doc.is_a?(Hash)
|
|
26
30
|
if !data_contains_error?(doc)
|
|
@@ -28,17 +32,17 @@ module Geocoder::Lookup
|
|
|
28
32
|
elsif doc['error']
|
|
29
33
|
case doc['error']
|
|
30
34
|
when "Invalid IP address"
|
|
31
|
-
raise_error(Geocoder::InvalidRequest) || warn
|
|
35
|
+
raise_error(Geocoder::InvalidRequest) || Geocoder.log(:warn, "Invalid Pointpin request.")
|
|
32
36
|
when "Invalid API key"
|
|
33
|
-
raise_error(Geocoder::InvalidApiKey) || warn
|
|
37
|
+
raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid Pointpin API key.")
|
|
34
38
|
when "Address not found"
|
|
35
|
-
warn
|
|
39
|
+
Geocoder.log(:warn, "Address not found.")
|
|
36
40
|
end
|
|
37
41
|
else
|
|
38
|
-
raise_error(Geocoder::Error) || warn
|
|
42
|
+
raise_error(Geocoder::Error) || Geocoder.log(:warn, "Pointpin server error")
|
|
39
43
|
end
|
|
40
44
|
end
|
|
41
|
-
|
|
45
|
+
|
|
42
46
|
return []
|
|
43
47
|
end
|
|
44
48
|
|
|
@@ -46,6 +50,7 @@ module Geocoder::Lookup
|
|
|
46
50
|
parsed_data.keys.include?('error')
|
|
47
51
|
end
|
|
48
52
|
|
|
53
|
+
# TODO: replace this hash with what's actually returned by Pointpin
|
|
49
54
|
def reserved_result(ip)
|
|
50
55
|
{
|
|
51
56
|
"ip" => ip,
|
|
@@ -60,9 +65,5 @@ module Geocoder::Lookup
|
|
|
60
65
|
"country_code" => "RD"
|
|
61
66
|
}
|
|
62
67
|
end
|
|
63
|
-
|
|
64
|
-
def api_key
|
|
65
|
-
configuration.api_key
|
|
66
|
-
end
|
|
67
68
|
end
|
|
68
69
|
end
|
|
@@ -4,7 +4,6 @@ require 'geocoder/results/postcode_anywhere_uk'
|
|
|
4
4
|
module Geocoder::Lookup
|
|
5
5
|
class PostcodeAnywhereUk < Base
|
|
6
6
|
# API documentation: http://www.postcodeanywhere.co.uk/Support/WebService/Geocoding/UK/Geocode/2/
|
|
7
|
-
BASE_URL_GEOCODE_V2_00 = 'services.postcodeanywhere.co.uk/Geocoding/UK/Geocode/v2.00/json.ws'
|
|
8
7
|
DAILY_LIMIT_EXEEDED_ERROR_CODES = ['8', '17'] # api docs say these two codes are the same error
|
|
9
8
|
INVALID_API_KEY_ERROR_CODE = '2'
|
|
10
9
|
|
|
@@ -16,11 +15,11 @@ module Geocoder::Lookup
|
|
|
16
15
|
%w(key)
|
|
17
16
|
end
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
format('%s://%s?%s', protocol, BASE_URL_GEOCODE_V2_00, url_query_string(query))
|
|
21
|
-
end
|
|
18
|
+
private # ----------------------------------------------------------------
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
def base_query_url(query)
|
|
21
|
+
"#{protocol}://services.postcodeanywhere.co.uk/Geocoding/UK/Geocode/v2.00/json.ws?"
|
|
22
|
+
end
|
|
24
23
|
|
|
25
24
|
def results(query)
|
|
26
25
|
response = fetch_data(query)
|
|
@@ -33,11 +32,11 @@ module Geocoder::Lookup
|
|
|
33
32
|
def raise_exception_for_response(response)
|
|
34
33
|
case response['Error']
|
|
35
34
|
when *DAILY_LIMIT_EXEEDED_ERROR_CODES
|
|
36
|
-
raise_error(Geocoder::OverQueryLimitError, response['Cause']) || warn
|
|
35
|
+
raise_error(Geocoder::OverQueryLimitError, response['Cause']) || Geocoder.log(:warn, response['Cause'])
|
|
37
36
|
when INVALID_API_KEY_ERROR_CODE
|
|
38
|
-
raise_error(Geocoder::InvalidApiKey, response['Cause']) || warn
|
|
37
|
+
raise_error(Geocoder::InvalidApiKey, response['Cause']) || Geocoder.log(:warn, response['Cause'])
|
|
39
38
|
else # anything else just raise general error with the api cause
|
|
40
|
-
raise_error(Geocoder::Error, response['Cause']) || warn
|
|
39
|
+
raise_error(Geocoder::Error, response['Cause']) || Geocoder.log(:warn, response['Cause'])
|
|
41
40
|
end
|
|
42
41
|
end
|
|
43
42
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require 'geocoder/results/postcodes_io'
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class PostcodesIo < Base
|
|
6
|
+
def name
|
|
7
|
+
'Postcodes.io'
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def query_url(query)
|
|
11
|
+
"#{protocol}://api.postcodes.io/postcodes/#{query.sanitized_text.gsub(/\s/, '')}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def supported_protocols
|
|
15
|
+
[:https]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private # ----------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
def cache_key(query)
|
|
21
|
+
query_url(query)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def results(query)
|
|
25
|
+
response = fetch_data(query)
|
|
26
|
+
return [] if response.nil? || response['status'] != 200 || response.empty?
|
|
27
|
+
|
|
28
|
+
[response['result']]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -8,23 +8,41 @@ module Geocoder::Lookup
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def required_api_key_parts
|
|
11
|
-
%w(
|
|
11
|
+
%w(auth-id auth-token)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
# required by API as of 26 March 2015
|
|
15
|
+
def supported_protocols
|
|
16
|
+
[:https]
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
private # ---------------------------------------------------------------
|
|
20
20
|
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
if international?(query)
|
|
23
|
+
"#{protocol}://international-street.api.smartystreets.com/verify?"
|
|
24
|
+
elsif zipcode_only?(query)
|
|
25
|
+
"#{protocol}://us-zipcode.api.smartystreets.com/lookup?"
|
|
26
|
+
else
|
|
27
|
+
"#{protocol}://us-street.api.smartystreets.com/street-address?"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
21
31
|
def zipcode_only?(query)
|
|
22
32
|
!query.text.is_a?(Array) and query.to_s.strip =~ /\A\d{5}(-\d{4})?\Z/
|
|
23
33
|
end
|
|
24
34
|
|
|
35
|
+
def international?(query)
|
|
36
|
+
!query.options[:country].nil?
|
|
37
|
+
end
|
|
38
|
+
|
|
25
39
|
def query_url_params(query)
|
|
26
40
|
params = {}
|
|
27
|
-
if
|
|
41
|
+
if international?(query)
|
|
42
|
+
params[:freeform] = query.sanitized_text
|
|
43
|
+
params[:country] = query.options[:country]
|
|
44
|
+
params[:geocode] = true
|
|
45
|
+
elsif zipcode_only?(query)
|
|
28
46
|
params[:zipcode] = query.sanitized_text
|
|
29
47
|
else
|
|
30
48
|
params[:street] = query.sanitized_text
|
|
@@ -39,7 +57,12 @@ module Geocoder::Lookup
|
|
|
39
57
|
end
|
|
40
58
|
|
|
41
59
|
def results(query)
|
|
42
|
-
fetch_data(query) || []
|
|
60
|
+
doc = fetch_data(query) || []
|
|
61
|
+
if doc.is_a?(Hash) and doc.key?('status') # implies there's an error
|
|
62
|
+
return []
|
|
63
|
+
else
|
|
64
|
+
return doc
|
|
65
|
+
end
|
|
43
66
|
end
|
|
44
67
|
end
|
|
45
68
|
end
|
|
@@ -8,20 +8,34 @@ module Geocoder::Lookup
|
|
|
8
8
|
"Telize"
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
def required_api_key_parts
|
|
12
|
+
configuration[:host] ? [] : ["key"]
|
|
13
|
+
end
|
|
14
|
+
|
|
11
15
|
def query_url(query)
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
if configuration[:host]
|
|
17
|
+
"#{protocol}://#{configuration[:host]}/location/#{query.sanitized_text}"
|
|
18
|
+
else
|
|
19
|
+
"#{protocol}://telize-v1.p.rapidapi.com/location/#{query.sanitized_text}?rapidapi-key=#{api_key}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def supported_protocols
|
|
24
|
+
[].tap do |array|
|
|
25
|
+
array << :https
|
|
26
|
+
array << :http if configuration[:host]
|
|
27
|
+
end
|
|
14
28
|
end
|
|
15
29
|
|
|
16
30
|
private # ---------------------------------------------------------------
|
|
17
31
|
|
|
18
|
-
def
|
|
19
|
-
|
|
32
|
+
def cache_key(query)
|
|
33
|
+
query_url(query)[/(.*)\?.*/, 1]
|
|
20
34
|
end
|
|
21
35
|
|
|
22
36
|
def results(query)
|
|
23
|
-
# don't look up a loopback address, just return the stored result
|
|
24
|
-
return [reserved_result(query.text)] if 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?
|
|
25
39
|
if (doc = fetch_data(query)).nil? or doc['code'] == 401 or empty_result?(doc)
|
|
26
40
|
[]
|
|
27
41
|
else
|
|
@@ -34,7 +48,28 @@ module Geocoder::Lookup
|
|
|
34
48
|
end
|
|
35
49
|
|
|
36
50
|
def reserved_result(ip)
|
|
37
|
-
{
|
|
51
|
+
{
|
|
52
|
+
"ip" => ip,
|
|
53
|
+
"latitude" => 0,
|
|
54
|
+
"longitude" => 0,
|
|
55
|
+
"city" => "",
|
|
56
|
+
"timezone" => "",
|
|
57
|
+
"asn" => 0,
|
|
58
|
+
"region" => "",
|
|
59
|
+
"offset" => 0,
|
|
60
|
+
"organization" => "",
|
|
61
|
+
"country_code" => "",
|
|
62
|
+
"country_code3" => "",
|
|
63
|
+
"postal_code" => "",
|
|
64
|
+
"continent_code" => "",
|
|
65
|
+
"country" => "",
|
|
66
|
+
"region_code" => ""
|
|
67
|
+
}
|
|
38
68
|
end
|
|
69
|
+
|
|
70
|
+
def api_key
|
|
71
|
+
configuration.api_key
|
|
72
|
+
end
|
|
73
|
+
|
|
39
74
|
end
|
|
40
75
|
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/tencent"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Tencent < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"Tencent"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def required_api_key_parts
|
|
12
|
+
["key"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def supported_protocols
|
|
16
|
+
[:https]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private # ---------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
"#{protocol}://apis.map.qq.com/ws/geocoder/v1/?"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def content_key
|
|
26
|
+
'result'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def results(query, reverse = false)
|
|
30
|
+
return [] unless doc = fetch_data(query)
|
|
31
|
+
case doc['status']
|
|
32
|
+
when 0
|
|
33
|
+
return [doc[content_key]]
|
|
34
|
+
when 311
|
|
35
|
+
raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
|
|
36
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: invalid api key.")
|
|
37
|
+
when 310
|
|
38
|
+
raise_error(Geocoder::InvalidRequest, "invalid request.") ||
|
|
39
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: invalid request, invalid parameters.")
|
|
40
|
+
when 306
|
|
41
|
+
raise_error(Geocoder::InvalidRequest, "invalid request.") ||
|
|
42
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: invalid request, check response for more info.")
|
|
43
|
+
when 110
|
|
44
|
+
raise_error(Geocoder::RequestDenied, "request denied.") ||
|
|
45
|
+
Geocoder.log(:warn, "#{name} Geocoding API error: request source is not authorized.")
|
|
46
|
+
end
|
|
47
|
+
return []
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def query_url_params(query)
|
|
51
|
+
{
|
|
52
|
+
(query.reverse_geocode? ? :location : :address) => query.sanitized_text,
|
|
53
|
+
:key => configuration.api_key,
|
|
54
|
+
:output => "json"
|
|
55
|
+
}.merge(super)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -18,6 +18,7 @@ module Geocoder
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def self.read_stub(query_text)
|
|
21
|
+
@default_stub ||= nil
|
|
21
22
|
stubs.fetch(query_text) {
|
|
22
23
|
return @default_stub unless @default_stub.nil?
|
|
23
24
|
raise ArgumentError, "unknown stub request #{query_text}"
|
|
@@ -28,6 +29,10 @@ module Geocoder
|
|
|
28
29
|
@stubs ||= {}
|
|
29
30
|
end
|
|
30
31
|
|
|
32
|
+
def self.delete_stub(query_text)
|
|
33
|
+
stubs.delete(query_text)
|
|
34
|
+
end
|
|
35
|
+
|
|
31
36
|
def self.reset
|
|
32
37
|
@stubs = {}
|
|
33
38
|
@default_stub = nil
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'geocoder/lookups/base'
|
|
2
|
+
require "geocoder/results/twogis"
|
|
3
|
+
|
|
4
|
+
module Geocoder::Lookup
|
|
5
|
+
class Twogis < Base
|
|
6
|
+
|
|
7
|
+
def name
|
|
8
|
+
"2gis"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def required_api_key_parts
|
|
12
|
+
["key"]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def map_link_url(coordinates)
|
|
16
|
+
"https://2gis.ru/?m=#{coordinates.join(',')}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def supported_protocols
|
|
20
|
+
[:https]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private # ---------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
def base_query_url(query)
|
|
26
|
+
"#{protocol}://catalog.api.2gis.com/3.0/items/geocode?"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def results(query)
|
|
30
|
+
return [] unless doc = fetch_data(query)
|
|
31
|
+
if doc['meta'] && doc['meta']['error']
|
|
32
|
+
Geocoder.log(:warn, "2gis Geocoding API error: #{doc['meta']["code"]} (#{doc['meta']['error']["message"]}).")
|
|
33
|
+
return []
|
|
34
|
+
end
|
|
35
|
+
if doc['result'] && doc = doc['result']['items']
|
|
36
|
+
return doc.to_a
|
|
37
|
+
else
|
|
38
|
+
Geocoder.log(:warn, "2gis Geocoding API error: unexpected response format.")
|
|
39
|
+
return []
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def query_url_params(query)
|
|
44
|
+
if query.reverse_geocode?
|
|
45
|
+
q = query.coordinates.reverse.join(",")
|
|
46
|
+
else
|
|
47
|
+
q = query.sanitized_text
|
|
48
|
+
end
|
|
49
|
+
params = {
|
|
50
|
+
:q => q,
|
|
51
|
+
:lang => "#{query.language || configuration.language}",
|
|
52
|
+
:key => configuration.api_key,
|
|
53
|
+
:fields => 'items.street,items.adm_div,items.full_address_name,items.point,items.geometry.centroid'
|
|
54
|
+
}
|
|
55
|
+
params.merge(super)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|