geocoder 1.4.3 → 1.5.0
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 +43 -0
- data/README.md +364 -880
- data/examples/autoexpire_cache_redis.rb +3 -3
- data/lib/generators/geocoder/config/templates/initializer.rb +3 -2
- 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/cli.rb +2 -2
- data/lib/geocoder/configuration.rb +2 -2
- data/lib/geocoder/exceptions.rb +1 -1
- data/lib/geocoder/ip_address.rb +1 -1
- data/lib/geocoder/lookup.rb +9 -4
- data/lib/geocoder/lookups/amap.rb +63 -0
- data/lib/geocoder/lookups/baidu.rb +14 -10
- data/lib/geocoder/lookups/baidu_ip.rb +6 -35
- data/lib/geocoder/lookups/ban_data_gouv_fr.rb +4 -4
- data/lib/geocoder/lookups/base.rb +22 -4
- data/lib/geocoder/lookups/bing.rb +13 -12
- data/lib/geocoder/lookups/db_ip_com.rb +52 -0
- data/lib/geocoder/lookups/dstk.rb +4 -2
- data/lib/geocoder/lookups/esri.rb +1 -16
- data/lib/geocoder/lookups/freegeoip.rb +11 -2
- data/lib/geocoder/lookups/geocoder_ca.rb +4 -4
- data/lib/geocoder/lookups/geocoder_us.rb +17 -9
- data/lib/geocoder/lookups/geocodio.rb +5 -5
- data/lib/geocoder/lookups/geoportail_lu.rb +7 -7
- data/lib/geocoder/lookups/google.rb +13 -9
- data/lib/geocoder/lookups/google_places_details.rb +4 -4
- data/lib/geocoder/lookups/google_places_search.rb +4 -4
- data/lib/geocoder/lookups/google_premier.rb +11 -1
- data/lib/geocoder/lookups/here.rb +4 -4
- data/lib/geocoder/lookups/ip2location.rb +74 -0
- data/lib/geocoder/lookups/ipapi_com.rb +7 -12
- data/lib/geocoder/lookups/ipdata_co.rb +61 -0
- data/lib/geocoder/lookups/ipinfo_io.rb +10 -19
- data/lib/geocoder/lookups/ipstack.rb +63 -0
- data/lib/geocoder/lookups/latlon.rb +4 -4
- data/lib/geocoder/lookups/location_iq.rb +26 -8
- data/lib/geocoder/lookups/mapbox.rb +12 -6
- data/lib/geocoder/lookups/mapquest.rb +4 -5
- data/lib/geocoder/lookups/maxmind.rb +4 -4
- data/lib/geocoder/lookups/maxmind_geoip2.rb +4 -0
- data/lib/geocoder/lookups/nominatim.rb +17 -5
- data/lib/geocoder/lookups/opencagedata.rb +7 -6
- data/lib/geocoder/lookups/pelias.rb +6 -6
- data/lib/geocoder/lookups/pickpoint.rb +41 -0
- data/lib/geocoder/lookups/pointpin.rb +7 -6
- data/lib/geocoder/lookups/postcode_anywhere_uk.rb +4 -5
- data/lib/geocoder/lookups/postcodes_io.rb +31 -0
- data/lib/geocoder/lookups/smarty_streets.rb +8 -8
- data/lib/geocoder/lookups/telize.rb +24 -4
- data/lib/geocoder/lookups/yandex.rb +10 -6
- data/lib/geocoder/models/active_record.rb +4 -3
- data/lib/geocoder/request.rb +32 -0
- data/lib/geocoder/results/amap.rb +87 -0
- data/lib/geocoder/results/baidu.rb +10 -10
- data/lib/geocoder/results/base.rb +13 -1
- data/lib/geocoder/results/bing.rb +1 -1
- data/lib/geocoder/results/db_ip_com.rb +58 -0
- data/lib/geocoder/results/freegeoip.rb +0 -5
- data/lib/geocoder/results/geocoder_ca.rb +3 -3
- data/lib/geocoder/results/geoip2.rb +24 -10
- data/lib/geocoder/results/geoportail_lu.rb +5 -3
- data/lib/geocoder/results/google.rb +16 -5
- data/lib/geocoder/results/here.rb +8 -0
- data/lib/geocoder/results/ip2location.rb +22 -0
- data/lib/geocoder/results/ipdata_co.rb +40 -0
- data/lib/geocoder/results/ipstack.rb +60 -0
- data/lib/geocoder/results/maxmind.rb +0 -5
- data/lib/geocoder/results/maxmind_local.rb +0 -5
- data/lib/geocoder/results/nominatim.rb +12 -0
- data/lib/geocoder/results/opencagedata.rb +12 -2
- data/lib/geocoder/results/pickpoint.rb +6 -0
- data/lib/geocoder/results/postcodes_io.rb +40 -0
- data/lib/geocoder/results/smarty_streets.rb +7 -1
- data/lib/geocoder/results/telize.rb +0 -5
- data/lib/geocoder/results/test.rb +1 -1
- data/lib/geocoder/sql.rb +2 -2
- data/lib/geocoder/stores/active_record.rb +15 -4
- data/lib/geocoder/stores/base.rb +1 -2
- data/lib/geocoder/version.rb +1 -1
- data/lib/tasks/geocoder.rake +11 -3
- metadata +27 -10
- data/lib/geocoder/lookups/okf.rb +0 -44
- data/lib/geocoder/lookups/ovi.rb +0 -62
- data/lib/geocoder/results/okf.rb +0 -106
- data/lib/geocoder/results/ovi.rb +0 -71
|
@@ -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)
|
|
@@ -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)
|
|
@@ -44,10 +44,11 @@ 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
|
|
|
50
|
-
[:countrycode, :min_confidence, :no_dedupe, :no_annotations, :no_record, :limit].each do |option|
|
|
51
|
+
[:abbrv, :countrycode, :min_confidence, :no_dedupe, :no_annotations, :no_record, :limit].each do |option|
|
|
51
52
|
unless (option_value = query.options[option]).nil?
|
|
52
53
|
params[option] = option_value
|
|
53
54
|
end
|
|
@@ -11,16 +11,16 @@ module Geocoder::Lookup
|
|
|
11
11
|
configuration[:endpoint] || 'localhost'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def query_url(query)
|
|
15
|
-
query_type = query.reverse_geocode? ? 'reverse' : 'search'
|
|
16
|
-
"#{protocol}://#{endpoint}/v1/#{query_type}?" + url_query_string(query)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
14
|
def required_api_key_parts
|
|
20
15
|
['search-XXXX']
|
|
21
16
|
end
|
|
22
17
|
|
|
23
|
-
private
|
|
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
24
|
|
|
25
25
|
def query_url_params(query)
|
|
26
26
|
params = {
|
|
@@ -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
|
+
params = {
|
|
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,10 +13,14 @@ 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
26
|
# don't look up a loopback address, just return the stored result
|
|
@@ -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)
|
|
@@ -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
|
|
@@ -11,14 +11,6 @@ module Geocoder::Lookup
|
|
|
11
11
|
%w(auti-id auth-token)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def query_url(query)
|
|
15
|
-
if zipcode_only?(query)
|
|
16
|
-
"#{protocol}://us-zipcode.api.smartystreets.com/lookup?#{url_query_string(query)}"
|
|
17
|
-
else
|
|
18
|
-
"#{protocol}://us-street.api.smartystreets.com/street-address?#{url_query_string(query)}"
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
14
|
# required by API as of 26 March 2015
|
|
23
15
|
def supported_protocols
|
|
24
16
|
[:https]
|
|
@@ -26,6 +18,14 @@ module Geocoder::Lookup
|
|
|
26
18
|
|
|
27
19
|
private # ---------------------------------------------------------------
|
|
28
20
|
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
if zipcode_only?(query)
|
|
23
|
+
"#{protocol}://us-zipcode.api.smartystreets.com/lookup?"
|
|
24
|
+
else
|
|
25
|
+
"#{protocol}://us-street.api.smartystreets.com/street-address?"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
29
|
def zipcode_only?(query)
|
|
30
30
|
!query.text.is_a?(Array) and query.to_s.strip =~ /\A\d{5}(-\d{4})?\Z/
|
|
31
31
|
end
|
|
@@ -14,9 +14,9 @@ module Geocoder::Lookup
|
|
|
14
14
|
|
|
15
15
|
def query_url(query)
|
|
16
16
|
if configuration[:host]
|
|
17
|
-
"#{protocol}://#{configuration[:host]}/
|
|
17
|
+
"#{protocol}://#{configuration[:host]}/location/#{query.sanitized_text}"
|
|
18
18
|
else
|
|
19
|
-
"#{protocol}://telize-v1.p.mashape.com/
|
|
19
|
+
"#{protocol}://telize-v1.p.mashape.com/location/#{query.sanitized_text}?mashape-key=#{api_key}"
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -29,6 +29,10 @@ module Geocoder::Lookup
|
|
|
29
29
|
|
|
30
30
|
private # ---------------------------------------------------------------
|
|
31
31
|
|
|
32
|
+
def cache_key(query)
|
|
33
|
+
query_url(query)[/(.*)\?.*/, 1]
|
|
34
|
+
end
|
|
35
|
+
|
|
32
36
|
def results(query)
|
|
33
37
|
# don't look up a loopback address, just return the stored result
|
|
34
38
|
return [reserved_result(query.text)] if query.loopback_ip_address?
|
|
@@ -44,12 +48,28 @@ module Geocoder::Lookup
|
|
|
44
48
|
end
|
|
45
49
|
|
|
46
50
|
def reserved_result(ip)
|
|
47
|
-
{
|
|
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
|
+
}
|
|
48
68
|
end
|
|
49
69
|
|
|
50
70
|
def api_key
|
|
51
71
|
configuration.api_key
|
|
52
72
|
end
|
|
53
|
-
|
|
73
|
+
|
|
54
74
|
end
|
|
55
75
|
end
|
|
@@ -12,16 +12,16 @@ module Geocoder::Lookup
|
|
|
12
12
|
"http://maps.yandex.ru/?ll=#{coordinates.reverse.join(',')}"
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def query_url(query)
|
|
16
|
-
"#{protocol}://geocode-maps.yandex.ru/1.x/?" + url_query_string(query)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
15
|
def supported_protocols
|
|
20
16
|
[:https]
|
|
21
17
|
end
|
|
22
18
|
|
|
23
19
|
private # ---------------------------------------------------------------
|
|
24
20
|
|
|
21
|
+
def base_query_url(query)
|
|
22
|
+
"#{protocol}://geocode-maps.yandex.ru/1.x/?"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
25
|
def results(query)
|
|
26
26
|
return [] unless doc = fetch_data(query)
|
|
27
27
|
if err = doc['error']
|
|
@@ -47,12 +47,16 @@ module Geocoder::Lookup
|
|
|
47
47
|
else
|
|
48
48
|
q = query.sanitized_text
|
|
49
49
|
end
|
|
50
|
-
{
|
|
50
|
+
params = {
|
|
51
51
|
:geocode => q,
|
|
52
52
|
:format => "json",
|
|
53
53
|
:plng => "#{query.language || configuration.language}", # supports ru, uk, be
|
|
54
54
|
:key => configuration.api_key
|
|
55
|
-
}
|
|
55
|
+
}
|
|
56
|
+
unless (bounds = query.options[:bounds]).nil?
|
|
57
|
+
params[:bbox] = bounds.map{ |point| "%f,%f" % point }.join('~')
|
|
58
|
+
end
|
|
59
|
+
params.merge(super)
|
|
56
60
|
end
|
|
57
61
|
end
|
|
58
62
|
end
|
|
@@ -18,7 +18,8 @@ module Geocoder
|
|
|
18
18
|
:units => options[:units],
|
|
19
19
|
:method => options[:method],
|
|
20
20
|
:lookup => options[:lookup],
|
|
21
|
-
:language => options[:language]
|
|
21
|
+
:language => options[:language],
|
|
22
|
+
:params => options[:params]
|
|
22
23
|
)
|
|
23
24
|
end
|
|
24
25
|
|
|
@@ -35,7 +36,8 @@ module Geocoder
|
|
|
35
36
|
:units => options[:units],
|
|
36
37
|
:method => options[:method],
|
|
37
38
|
:lookup => options[:lookup],
|
|
38
|
-
:language => options[:language]
|
|
39
|
+
:language => options[:language],
|
|
40
|
+
:params => options[:params]
|
|
39
41
|
)
|
|
40
42
|
end
|
|
41
43
|
|
|
@@ -47,4 +49,3 @@ module Geocoder
|
|
|
47
49
|
end
|
|
48
50
|
end
|
|
49
51
|
end
|
|
50
|
-
|
data/lib/geocoder/request.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'ipaddr'
|
|
2
|
+
|
|
1
3
|
module Geocoder
|
|
2
4
|
module Request
|
|
3
5
|
|
|
@@ -54,6 +56,8 @@ module Geocoder
|
|
|
54
56
|
GEOCODER_CANDIDATE_HEADERS.each do |header|
|
|
55
57
|
if @env.has_key? header
|
|
56
58
|
addrs = geocoder_split_ip_addresses(@env[header])
|
|
59
|
+
addrs = geocoder_remove_port_from_addresses(addrs)
|
|
60
|
+
addrs = geocoder_reject_non_ipv4_addresses(addrs)
|
|
57
61
|
addrs = geocoder_reject_trusted_ip_addresses(addrs)
|
|
58
62
|
return addrs.first if addrs.any?
|
|
59
63
|
end
|
|
@@ -75,6 +79,34 @@ module Geocoder
|
|
|
75
79
|
def geocoder_reject_trusted_ip_addresses(ip_addresses)
|
|
76
80
|
ip_addresses.reject { |ip| trusted_proxy?(ip) }
|
|
77
81
|
end
|
|
82
|
+
|
|
83
|
+
def geocoder_remove_port_from_addresses(ip_addresses)
|
|
84
|
+
ip_addresses.map do |ip|
|
|
85
|
+
# IPv4
|
|
86
|
+
if ip.count('.') > 0
|
|
87
|
+
ip.split(':').first
|
|
88
|
+
# IPv6 bracket notation
|
|
89
|
+
elsif match = ip.match(/\[(\S+)\]/)
|
|
90
|
+
match.captures.first
|
|
91
|
+
# IPv6 bare notation
|
|
92
|
+
else
|
|
93
|
+
ip
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def geocoder_reject_non_ipv4_addresses(ip_addresses)
|
|
99
|
+
ips = []
|
|
100
|
+
for ip in ip_addresses
|
|
101
|
+
begin
|
|
102
|
+
valid_ip = IPAddr.new(ip)
|
|
103
|
+
rescue
|
|
104
|
+
valid_ip = false
|
|
105
|
+
end
|
|
106
|
+
ips << valid_ip.to_s if valid_ip
|
|
107
|
+
end
|
|
108
|
+
return ips.any? ? ips : ip_addresses
|
|
109
|
+
end
|
|
78
110
|
end
|
|
79
111
|
end
|
|
80
112
|
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require 'geocoder/results/base'
|
|
2
|
+
|
|
3
|
+
module Geocoder::Result
|
|
4
|
+
class Amap < Base
|
|
5
|
+
|
|
6
|
+
def coordinates
|
|
7
|
+
location = @data['location'] || @data['roadinters'].try(:first).try(:[], 'location') \
|
|
8
|
+
|| address_components.try(:[], 'streetNumber').try(:[], 'location')
|
|
9
|
+
location.to_s.split(",").reverse.map(&:to_f)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def address
|
|
13
|
+
formatted_address
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def state
|
|
17
|
+
province
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def province
|
|
21
|
+
address_components['province']
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def city
|
|
25
|
+
address_components['city'] == [] ? province : address_components["city"]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def district
|
|
29
|
+
address_components['district']
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def street
|
|
33
|
+
if address_components["neighborhood"]["name"] != []
|
|
34
|
+
return address_components["neighborhood"]["name"]
|
|
35
|
+
elsif address_components['township'] != []
|
|
36
|
+
return address_components["township"]
|
|
37
|
+
else
|
|
38
|
+
return @data['street'] || address_components['streetNumber'].try(:[], 'street')
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def street_number
|
|
43
|
+
@data['number'] || address_components['streetNumber'].try(:[], 'number')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def formatted_address
|
|
47
|
+
@data['formatted_address']
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def address_components
|
|
51
|
+
@data['addressComponent'] || @data
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def state_code
|
|
55
|
+
""
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def postal_code
|
|
59
|
+
""
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def country
|
|
63
|
+
"China"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def country_code
|
|
67
|
+
"CN"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
##
|
|
71
|
+
# Get address components of a given type. Valid types are defined in
|
|
72
|
+
# Baidu's Geocoding API documentation and include (among others):
|
|
73
|
+
#
|
|
74
|
+
# :business
|
|
75
|
+
# :cityCode
|
|
76
|
+
#
|
|
77
|
+
def self.response_attributes
|
|
78
|
+
%w[roads pois roadinters]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
response_attributes.each do |a|
|
|
82
|
+
define_method a do
|
|
83
|
+
@data[a]
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -11,34 +11,34 @@ module Geocoder::Result
|
|
|
11
11
|
@data['formatted_address']
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def state
|
|
15
|
-
province
|
|
16
|
-
end
|
|
17
|
-
|
|
18
14
|
def province
|
|
19
|
-
@data['addressComponent']['province']
|
|
15
|
+
@data['addressComponent'] and @data['addressComponent']['province'] or ""
|
|
20
16
|
end
|
|
21
17
|
|
|
18
|
+
alias_method :state, :province
|
|
19
|
+
|
|
22
20
|
def city
|
|
23
|
-
@data['addressComponent']['city']
|
|
21
|
+
@data['addressComponent'] and @data['addressComponent']['city'] or ""
|
|
24
22
|
end
|
|
25
23
|
|
|
26
24
|
def district
|
|
27
|
-
@data['addressComponent']['district']
|
|
25
|
+
@data['addressComponent'] and @data['addressComponent']['district'] or ""
|
|
28
26
|
end
|
|
29
27
|
|
|
30
28
|
def street
|
|
31
|
-
@data['addressComponent']['street']
|
|
29
|
+
@data['addressComponent'] and @data['addressComponent']['street'] or ""
|
|
32
30
|
end
|
|
33
31
|
|
|
34
32
|
def street_number
|
|
35
|
-
@data['addressComponent']['street_number']
|
|
33
|
+
@data['addressComponent'] and @data['addressComponent']['street_number']
|
|
36
34
|
end
|
|
37
35
|
|
|
38
36
|
def formatted_address
|
|
39
|
-
@data['formatted_address']
|
|
37
|
+
@data['formatted_address'] or ""
|
|
40
38
|
end
|
|
41
39
|
|
|
40
|
+
alias_method :address, :formatted_address
|
|
41
|
+
|
|
42
42
|
def address_components
|
|
43
43
|
@data['addressComponent']
|
|
44
44
|
end
|
|
@@ -20,8 +20,20 @@ module Geocoder
|
|
|
20
20
|
##
|
|
21
21
|
# A string in the given format.
|
|
22
22
|
#
|
|
23
|
+
# This default implementation dumbly follows the United States address
|
|
24
|
+
# format and will return incorrect results for most countries. Some APIs
|
|
25
|
+
# return properly formatted addresses and those should be funneled
|
|
26
|
+
# through this method.
|
|
27
|
+
#
|
|
23
28
|
def address(format = :full)
|
|
24
|
-
|
|
29
|
+
if state_code.to_s != ""
|
|
30
|
+
s = ", #{state_code}"
|
|
31
|
+
elsif state.to_s != ""
|
|
32
|
+
s = ", #{state}"
|
|
33
|
+
else
|
|
34
|
+
s = ""
|
|
35
|
+
end
|
|
36
|
+
"#{city}#{s} #{postal_code}, #{country}".sub(/^[ ,]*/, '')
|
|
25
37
|
end
|
|
26
38
|
|
|
27
39
|
##
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'geocoder/results/base'
|
|
2
|
+
|
|
3
|
+
module Geocoder::Result
|
|
4
|
+
class DbIpCom < Base
|
|
5
|
+
|
|
6
|
+
def coordinates
|
|
7
|
+
['latitude', 'longitude'].map{ |coordinate_name| @data[coordinate_name] }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def city
|
|
11
|
+
@data['city']
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def district
|
|
15
|
+
@data['district']
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def state_code
|
|
19
|
+
@data['stateProv']
|
|
20
|
+
end
|
|
21
|
+
alias_method :state, :state_code
|
|
22
|
+
|
|
23
|
+
def zip_code
|
|
24
|
+
@data['zipCode']
|
|
25
|
+
end
|
|
26
|
+
alias_method :postal_code, :zip_code
|
|
27
|
+
|
|
28
|
+
def country_name
|
|
29
|
+
@data['countryName']
|
|
30
|
+
end
|
|
31
|
+
alias_method :country, :country_name
|
|
32
|
+
|
|
33
|
+
def country_code
|
|
34
|
+
@data['countryCode']
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def continent_name
|
|
38
|
+
@data['continentName']
|
|
39
|
+
end
|
|
40
|
+
alias_method :continent, :continent_name
|
|
41
|
+
|
|
42
|
+
def continent_code
|
|
43
|
+
@data['continentCode']
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def time_zone
|
|
47
|
+
@data['timeZone']
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def gmt_offset
|
|
51
|
+
@data['gmtOffset']
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def currency_code
|
|
55
|
+
@data['currencyCode']
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -3,11 +3,6 @@ require 'geocoder/results/base'
|
|
|
3
3
|
module Geocoder::Result
|
|
4
4
|
class Freegeoip < Base
|
|
5
5
|
|
|
6
|
-
def address(format = :full)
|
|
7
|
-
s = state_code.to_s == "" ? "" : ", #{state_code}"
|
|
8
|
-
"#{city}#{s} #{postal_code}, #{country}".sub(/^[ ,]*/, "")
|
|
9
|
-
end
|
|
10
|
-
|
|
11
6
|
def city
|
|
12
7
|
@data['city']
|
|
13
8
|
end
|
|
@@ -16,17 +16,17 @@ module Geocoder::Result
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def city
|
|
19
|
-
@data['city']
|
|
19
|
+
@data['city'] or (@data['standard'] and @data['standard']['city']) or ""
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def state
|
|
23
|
-
@data['prov']
|
|
23
|
+
@data['prov'] or (@data['standard'] and @data['standard']['prov']) or ""
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
alias_method :state_code, :state
|
|
27
27
|
|
|
28
28
|
def postal_code
|
|
29
|
-
@data['postal']
|
|
29
|
+
@data['postal'] or (@data['standard'] and @data['standard']['postal']) or ""
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def country
|