geocoder 1.6.0 → 1.6.5
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 +4 -4
- data/CHANGELOG.md +26 -0
- data/LICENSE +1 -1
- data/README.md +7 -30
- data/bin/console +13 -0
- data/lib/easting_northing.rb +171 -0
- data/lib/geocoder/configuration.rb +2 -1
- data/lib/geocoder/configuration_hash.rb +4 -4
- data/lib/geocoder/ip_address.rb +2 -1
- data/lib/geocoder/lookup.rb +2 -0
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +1 -1
- data/lib/geocoder/lookups/esri.rb +6 -0
- data/lib/geocoder/lookups/geocodio.rb +1 -1
- data/lib/geocoder/lookups/google.rb +7 -2
- data/lib/geocoder/lookups/google_places_details.rb +8 -14
- data/lib/geocoder/lookups/google_places_search.rb +28 -2
- data/lib/geocoder/lookups/google_premier.rb +4 -0
- data/lib/geocoder/lookups/ipgeolocation.rb +6 -18
- data/lib/geocoder/lookups/latlon.rb +1 -2
- data/lib/geocoder/lookups/maxmind_local.rb +7 -1
- data/lib/geocoder/lookups/nationaal_georegister_nl.rb +38 -0
- data/lib/geocoder/lookups/smarty_streets.rb +6 -1
- data/lib/geocoder/lookups/telize.rb +1 -1
- data/lib/geocoder/lookups/test.rb +4 -0
- data/lib/geocoder/lookups/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/lookups/yandex.rb +1 -2
- data/lib/geocoder/results/ban_data_gouv_fr.rb +26 -1
- data/lib/geocoder/results/db_ip_com.rb +1 -1
- data/lib/geocoder/results/ipregistry.rb +4 -8
- data/lib/geocoder/results/nationaal_georegister_nl.rb +62 -0
- data/lib/geocoder/results/nominatim.rb +4 -0
- data/lib/geocoder/results/uk_ordnance_survey_names.rb +59 -0
- data/lib/geocoder/results/yandex.rb +217 -59
- data/lib/geocoder/sql.rb +4 -4
- data/lib/geocoder/util.rb +29 -0
- data/lib/geocoder/version.rb +1 -1
- metadata +13 -8
- data/lib/hash_recursive_merge.rb +0 -73
@@ -18,16 +18,42 @@ module Geocoder
|
|
18
18
|
|
19
19
|
private
|
20
20
|
|
21
|
+
def result_root_attr
|
22
|
+
'candidates'
|
23
|
+
end
|
24
|
+
|
21
25
|
def base_query_url(query)
|
22
|
-
"#{protocol}://maps.googleapis.com/maps/api/place/
|
26
|
+
"#{protocol}://maps.googleapis.com/maps/api/place/findplacefromtext/json?"
|
23
27
|
end
|
24
28
|
|
25
29
|
def query_url_google_params(query)
|
26
30
|
{
|
27
|
-
|
31
|
+
input: query.text,
|
32
|
+
inputtype: 'textquery',
|
33
|
+
fields: fields(query),
|
28
34
|
language: query.language || configuration.language
|
29
35
|
}
|
30
36
|
end
|
37
|
+
|
38
|
+
def fields(query)
|
39
|
+
query_fields = query.options[:fields]
|
40
|
+
return format_fields(query_fields) if query_fields
|
41
|
+
|
42
|
+
default_fields
|
43
|
+
end
|
44
|
+
|
45
|
+
def default_fields
|
46
|
+
legacy = %w[id reference]
|
47
|
+
basic = %w[business_status formatted_address geometry icon name
|
48
|
+
photos place_id plus_code types]
|
49
|
+
contact = %w[opening_hours]
|
50
|
+
atmosphere = %W[price_level rating user_ratings_total]
|
51
|
+
format_fields(legacy, basic, contact, atmosphere)
|
52
|
+
end
|
53
|
+
|
54
|
+
def format_fields(*fields)
|
55
|
+
fields.flatten.join(',')
|
56
|
+
end
|
31
57
|
end
|
32
58
|
end
|
33
59
|
end
|
@@ -21,6 +21,10 @@ module Geocoder::Lookup
|
|
21
21
|
|
22
22
|
private # ---------------------------------------------------------------
|
23
23
|
|
24
|
+
def result_root_attr
|
25
|
+
'results'
|
26
|
+
end
|
27
|
+
|
24
28
|
def cache_key(query)
|
25
29
|
"#{protocol}://maps.googleapis.com/maps/api/geocode/json?" + hash_to_query(cache_key_params(query))
|
26
30
|
end
|
@@ -6,16 +6,11 @@ module Geocoder::Lookup
|
|
6
6
|
class Ipgeolocation < Base
|
7
7
|
|
8
8
|
ERROR_CODES = {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
104 => Geocoder::OverQueryLimitError,
|
15
|
-
105 => Geocoder::RequestDenied,
|
16
|
-
301 => Geocoder::InvalidRequest,
|
17
|
-
302 => Geocoder::InvalidRequest,
|
18
|
-
303 => Geocoder::RequestDenied,
|
9
|
+
400 => Geocoder::RequestDenied, # subscription is paused
|
10
|
+
401 => Geocoder::InvalidApiKey, # missing/invalid API key
|
11
|
+
403 => Geocoder::InvalidRequest, # invalid IP address
|
12
|
+
404 => Geocoder::InvalidRequest, # not found
|
13
|
+
423 => Geocoder::InvalidRequest # bogon/reserved IP address
|
19
14
|
}
|
20
15
|
ERROR_CODES.default = Geocoder::Error
|
21
16
|
|
@@ -42,14 +37,7 @@ module Geocoder::Lookup
|
|
42
37
|
def results(query)
|
43
38
|
# don't look up a loopback or private address, just return the stored result
|
44
39
|
return [reserved_result(query.text)] if query.internal_ip_address?
|
45
|
-
|
46
|
-
if error = doc['error']
|
47
|
-
code = error['code']
|
48
|
-
msg = error['info']
|
49
|
-
raise_error(ERROR_CODES[code], msg ) || Geocoder.log(:warn, "Ipgeolocation Geocoding API error: #{msg}")
|
50
|
-
return []
|
51
|
-
end
|
52
|
-
[doc]
|
40
|
+
[fetch_data(query)]
|
53
41
|
end
|
54
42
|
|
55
43
|
def reserved_result(ip)
|
@@ -25,8 +25,7 @@ module Geocoder::Lookup
|
|
25
25
|
# The API returned a 404 response, which indicates no results found
|
26
26
|
elsif doc['error']['type'] == 'api_error'
|
27
27
|
[]
|
28
|
-
elsif
|
29
|
-
doc['error']['type'] == 'authentication_error'
|
28
|
+
elsif doc['error']['type'] == 'authentication_error'
|
30
29
|
raise_error(Geocoder::InvalidApiKey) ||
|
31
30
|
Geocoder.log(:warn, "LatLon.io service error: invalid API key.")
|
32
31
|
else
|
@@ -30,7 +30,13 @@ module Geocoder::Lookup
|
|
30
30
|
def results(query)
|
31
31
|
if configuration[:file]
|
32
32
|
geoip_class = RUBY_PLATFORM == "java" ? JGeoIP : GeoIP
|
33
|
-
|
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
|
34
40
|
result.nil? ? [] : [encode_hash(result.to_hash)]
|
35
41
|
elsif configuration[:package] == :city
|
36
42
|
addr = IPAddr.new(query.text).to_i
|
@@ -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
|
@@ -57,7 +57,12 @@ module Geocoder::Lookup
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def results(query)
|
60
|
-
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
|
61
66
|
end
|
62
67
|
end
|
63
68
|
end
|
@@ -16,7 +16,7 @@ module Geocoder::Lookup
|
|
16
16
|
if configuration[:host]
|
17
17
|
"#{protocol}://#{configuration[:host]}/location/#{query.sanitized_text}"
|
18
18
|
else
|
19
|
-
"#{protocol}://telize-v1.p.
|
19
|
+
"#{protocol}://telize-v1.p.rapidapi.com/location/#{query.sanitized_text}?rapidapi-key=#{api_key}"
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/uk_ordnance_survey_names'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class UkOrdnanceSurveyNames < Base
|
6
|
+
|
7
|
+
def name
|
8
|
+
'Ordance Survey Names'
|
9
|
+
end
|
10
|
+
|
11
|
+
def supported_protocols
|
12
|
+
[:https]
|
13
|
+
end
|
14
|
+
|
15
|
+
def base_query_url(query)
|
16
|
+
"#{protocol}://api.ordnancesurvey.co.uk/opennames/v1/find?"
|
17
|
+
end
|
18
|
+
|
19
|
+
def required_api_key_parts
|
20
|
+
["key"]
|
21
|
+
end
|
22
|
+
|
23
|
+
def query_url(query)
|
24
|
+
base_query_url(query) + url_query_string(query)
|
25
|
+
end
|
26
|
+
|
27
|
+
private # -------------------------------------------------------------
|
28
|
+
|
29
|
+
def results(query)
|
30
|
+
return [] unless doc = fetch_data(query)
|
31
|
+
return [] if doc['header']['totalresults'].zero?
|
32
|
+
return doc['results'].map { |r| r['GAZETTEER_ENTRY'] }
|
33
|
+
end
|
34
|
+
|
35
|
+
def query_url_params(query)
|
36
|
+
{
|
37
|
+
query: query.sanitized_text,
|
38
|
+
key: configuration.api_key,
|
39
|
+
fq: filter
|
40
|
+
}.merge(super)
|
41
|
+
end
|
42
|
+
|
43
|
+
def local_types
|
44
|
+
%w[
|
45
|
+
City
|
46
|
+
Hamlet
|
47
|
+
Other_Settlement
|
48
|
+
Town
|
49
|
+
Village
|
50
|
+
Postcode
|
51
|
+
]
|
52
|
+
end
|
53
|
+
|
54
|
+
def filter
|
55
|
+
local_types.map { |t| "local_type:#{t}" }.join(' ')
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -33,8 +33,7 @@ module Geocoder::Lookup
|
|
33
33
|
return []
|
34
34
|
end
|
35
35
|
if doc = doc['response']['GeoObjectCollection']
|
36
|
-
|
37
|
-
return meta['found'].to_i > 0 ? doc['featureMember'] : []
|
36
|
+
return doc['featureMember'].to_a
|
38
37
|
else
|
39
38
|
Geocoder.log(:warn, "Yandex Geocoding API error: unexpected response format.")
|
40
39
|
return []
|
@@ -4,6 +4,27 @@ require 'geocoder/results/base'
|
|
4
4
|
module Geocoder::Result
|
5
5
|
class BanDataGouvFr < Base
|
6
6
|
|
7
|
+
STATE_CODE_MAPPINGS = {
|
8
|
+
"Guadeloupe" => "01",
|
9
|
+
"Martinique" => "02",
|
10
|
+
"Guyane" => "03",
|
11
|
+
"La Réunion" => "04",
|
12
|
+
"Mayotte" => "06",
|
13
|
+
"Île-de-France" => "11",
|
14
|
+
"Centre-Val de Loire" => "24",
|
15
|
+
"Bourgogne-Franche-Comté" => "27",
|
16
|
+
"Normandie" => "28",
|
17
|
+
"Hauts-de-France" => "32",
|
18
|
+
"Grand Est" => "44",
|
19
|
+
"Pays de la Loire" => "52",
|
20
|
+
"Bretagne" => "53",
|
21
|
+
"Nouvelle-Aquitaine" => "75",
|
22
|
+
"Occitanie" => "76",
|
23
|
+
"Auvergne-Rhône-Alpes" => "84",
|
24
|
+
"Provence-Alpes-Côte d'Azur" => "93",
|
25
|
+
"Corse" => "94"
|
26
|
+
}.freeze
|
27
|
+
|
7
28
|
#### BASE METHODS ####
|
8
29
|
|
9
30
|
def self.response_attributes
|
@@ -209,6 +230,10 @@ module Geocoder::Result
|
|
209
230
|
end
|
210
231
|
end
|
211
232
|
|
233
|
+
def region_code
|
234
|
+
STATE_CODE_MAPPINGS[region_name]
|
235
|
+
end
|
236
|
+
|
212
237
|
def country
|
213
238
|
"France"
|
214
239
|
end
|
@@ -235,7 +260,7 @@ module Geocoder::Result
|
|
235
260
|
alias_method :street, :street_name
|
236
261
|
alias_method :city, :city_name
|
237
262
|
alias_method :state, :region_name
|
238
|
-
alias_method :state_code, :
|
263
|
+
alias_method :state_code, :region_code
|
239
264
|
|
240
265
|
#### CITIES' METHODS ####
|
241
266
|
|
@@ -9,6 +9,10 @@ module Geocoder::Result
|
|
9
9
|
@data = flatten_hash(data)
|
10
10
|
end
|
11
11
|
|
12
|
+
def coordinates
|
13
|
+
[@data['location_latitude'], @data['location_longitude']]
|
14
|
+
end
|
15
|
+
|
12
16
|
def flatten_hash(hash)
|
13
17
|
hash.each_with_object({}) do |(k, v), h|
|
14
18
|
if v.is_a? Hash
|
@@ -35,14 +39,6 @@ module Geocoder::Result
|
|
35
39
|
@data['location_country_code']
|
36
40
|
end
|
37
41
|
|
38
|
-
def latitude
|
39
|
-
@data['location_latitude']
|
40
|
-
end
|
41
|
-
|
42
|
-
def longitude
|
43
|
-
@data['location_longitude']
|
44
|
-
end
|
45
|
-
|
46
42
|
def postal_code
|
47
43
|
@data['location_postal']
|
48
44
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'geocoder/results/base'
|
2
|
+
|
3
|
+
module Geocoder::Result
|
4
|
+
class NationaalGeoregisterNl < Base
|
5
|
+
|
6
|
+
def response_attributes
|
7
|
+
@data
|
8
|
+
end
|
9
|
+
|
10
|
+
def coordinates
|
11
|
+
@data['centroide_ll'][6..-2].split(' ').map(&:to_f).reverse
|
12
|
+
end
|
13
|
+
|
14
|
+
def formatted_address
|
15
|
+
@data['weergavenaam']
|
16
|
+
end
|
17
|
+
|
18
|
+
alias_method :address, :formatted_address
|
19
|
+
|
20
|
+
def province
|
21
|
+
@data['provincienaam']
|
22
|
+
end
|
23
|
+
|
24
|
+
alias_method :state, :province
|
25
|
+
|
26
|
+
def city
|
27
|
+
@data['woonplaatsnaam']
|
28
|
+
end
|
29
|
+
|
30
|
+
def district
|
31
|
+
@data['gemeentenaam']
|
32
|
+
end
|
33
|
+
|
34
|
+
def street
|
35
|
+
@data['straatnaam']
|
36
|
+
end
|
37
|
+
|
38
|
+
def street_number
|
39
|
+
@data['huis_nlt']
|
40
|
+
end
|
41
|
+
|
42
|
+
def address_components
|
43
|
+
@data
|
44
|
+
end
|
45
|
+
|
46
|
+
def state_code
|
47
|
+
@data['provinciecode']
|
48
|
+
end
|
49
|
+
|
50
|
+
def postal_code
|
51
|
+
@data['postcode']
|
52
|
+
end
|
53
|
+
|
54
|
+
def country
|
55
|
+
"Netherlands"
|
56
|
+
end
|
57
|
+
|
58
|
+
def country_code
|
59
|
+
"NL"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'geocoder/results/base'
|
2
|
+
require 'easting_northing'
|
3
|
+
|
4
|
+
module Geocoder::Result
|
5
|
+
class UkOrdnanceSurveyNames < Base
|
6
|
+
|
7
|
+
def coordinates
|
8
|
+
@coordinates ||= Geocoder::EastingNorthing.new(
|
9
|
+
easting: data['GEOMETRY_X'],
|
10
|
+
northing: data['GEOMETRY_Y'],
|
11
|
+
).lat_lng
|
12
|
+
end
|
13
|
+
|
14
|
+
def city
|
15
|
+
is_postcode? ? data['DISTRICT_BOROUGH'] : data['NAME1']
|
16
|
+
end
|
17
|
+
|
18
|
+
def county
|
19
|
+
data['COUNTY_UNITARY']
|
20
|
+
end
|
21
|
+
alias state county
|
22
|
+
|
23
|
+
def county_code
|
24
|
+
code_from_uri data['COUNTY_UNITARY_URI']
|
25
|
+
end
|
26
|
+
alias state_code county_code
|
27
|
+
|
28
|
+
def province
|
29
|
+
data['REGION']
|
30
|
+
end
|
31
|
+
|
32
|
+
def province_code
|
33
|
+
code_from_uri data['REGION_URI']
|
34
|
+
end
|
35
|
+
|
36
|
+
def postal_code
|
37
|
+
is_postcode? ? data['NAME1'] : ''
|
38
|
+
end
|
39
|
+
|
40
|
+
def country
|
41
|
+
'United Kingdom'
|
42
|
+
end
|
43
|
+
|
44
|
+
def country_code
|
45
|
+
'UK'
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def is_postcode?
|
51
|
+
data['LOCAL_TYPE'] == 'Postcode'
|
52
|
+
end
|
53
|
+
|
54
|
+
def code_from_uri(uri)
|
55
|
+
return '' if uri.nil?
|
56
|
+
uri.split('/').last
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|