geocoder 1.5.0 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of geocoder might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 48d97270ff2c0f4e7920eeb7bbab54348485d101
4
- data.tar.gz: 1a446c88e27b5257bd1c39815890392700e303b1
3
+ metadata.gz: e556ddf944bdad35735def9028fafebcf61ee294
4
+ data.tar.gz: a64476b63f73c13f24e385bc090193422bb92faa
5
5
  SHA512:
6
- metadata.gz: d95f68de9056c0db319dbe6781e993a72ce98db3042e46fb4175ca76fa621e56def1a4bbc8594fed25a87f74f6887849c4cccb98b816765cac48e06c7e1467a8
7
- data.tar.gz: 6a3439cbc7e28bc5c53b7b76b97bdfcf5d30040b74e2302ed11db60b79f9265953bc6b4437977b94995994f596a81a1968fa420d0640b2ad9a5393a6846c6d03
6
+ metadata.gz: '08394b88099374e31e32306a418865b2ffecc4df707044e277072b99d9cadc6f92e1acd70fc18884128f381e28c2c42571f66eb3968a983e214a5a1ca89cf839'
7
+ data.tar.gz: 87dadf53fe66e26c2f3eec8bfc671b9cebaf76f50bd08f815ae8b08592bd2c87aab8fa1812ef07b282805383b81e93f9777d5224b5c86ebe412f6261fb9fe943
@@ -3,10 +3,16 @@ Changelog
3
3
 
4
4
  Major changes to Geocoder for each release. Please see the Git log for complete list of changes.
5
5
 
6
- 1.5.0 (2018 Aug 1)
6
+ 1.5.1 (2019 Jan 23)
7
7
  -------------------
8
+ * Add support for :tencent lookup (thanks github.com/Anders-E).
9
+ * Add support for :smarty_streets international API (thanks github.com/ankane).
10
+ * Remove :mapzen lookup.
11
+
12
+ 1.5.0 (2018 Jul 31)
13
+ -------------------
14
+ * Drop support for Ruby <2.0.
8
15
  * Change default street address lookup from :google to :nominatim.
9
- * Drop support for Ruby 1.9.
10
16
  * Cache keys no longer include API credentials. This means many entries in existing cache implementations will be invalidated.
11
17
  * Test lookup fixtures should now return `coordinates` and NOT `latitude`/`longitude` attributes (see #1258). This may break some people's tests.
12
18
  * Add support for :ip2location lookup (thanks github.com/ip2location).
data/README.md CHANGED
@@ -13,7 +13,7 @@ Key features:
13
13
 
14
14
  * Forward and reverse geocoding, and IP address geocoding.
15
15
  * Connects to more than 40 APIs worldwide.
16
- * Performance-enhancing feaures like caching.
16
+ * Performance-enhancing features like caching.
17
17
  * Advanced configuration allows different parameters and APIs to be used in different conditions.
18
18
  * Integrates with ActiveRecord and Mongoid.
19
19
  * Basic geospatial queries: search within radius (or rectangle, or ring).
@@ -45,7 +45,7 @@ Advanced Features:
45
45
  * [Geospatial Calculations](#geospatial-calculations)
46
46
  * [Batch Geocoding](#batch-geocoding)
47
47
  * [Testing](#testing)
48
- * [Error Handling](#error-handing)
48
+ * [Error Handling](#error-handling)
49
49
  * [Command Line Interface](#command-line-interface)
50
50
 
51
51
  The Rest:
@@ -224,15 +224,15 @@ Some common options are:
224
224
  Please see [`lib/geocoder/configuration.rb`](https://github.com/alexreisner/geocoder/blob/master/lib/geocoder/configuration.rb) for a complete list of configuration options. Additionally, some lookups have their own special configuration options which are directly supported by Geocoder. For example, to specify a value for Google's `bounds` parameter:
225
225
 
226
226
  # with Google:
227
- Geocoder.search("Paris", bounds: [[32.1,-95.9], [33.9,-94.3]])
227
+ Geocoder.search("Middletown", bounds: [[40.6,-77.9], [39.9,-75.9]])
228
228
 
229
229
  Please see the [source code for each lookup](https://github.com/alexreisner/geocoder/tree/master/lib/geocoder/lookups) to learn about directly supported parameters. Parameters which are not directly supported can be specified using the `:params` option, which appends options to the query string of the geocoding request. For example:
230
230
 
231
231
  # Nominatim's `countrycodes` parameter:
232
- Geocoder.search("Paris", params: {countrycodes: "gb,de,fr,es,us"})
232
+ Geocoder.search("Rome", params: {countrycodes: "us,ca"})
233
233
 
234
234
  # Google's `region` parameter:
235
- Geocoder.search("Paris", params: {region: "..."})
235
+ Geocoder.search("Rome", params: {region: "..."})
236
236
 
237
237
  ### Configuring Multiple Services
238
238
 
@@ -500,9 +500,9 @@ To avoid exceeding per-day limits you can add a `LIMIT` option. However, this wi
500
500
  Testing
501
501
  -------
502
502
 
503
- When writing tests for an app that uses Geocoder it may be useful to avoid network calls and have Geocoder return consistent, configurable results. To do this, configure the `:test` lookup:
503
+ When writing tests for an app that uses Geocoder it may be useful to avoid network calls and have Geocoder return consistent, configurable results. To do this, configure the `:test` lookup and/or `:ip_lookup`
504
504
 
505
- Geocoder.configure(lookup: :test)
505
+ Geocoder.configure(lookup: :test, ip_lookup: :test)
506
506
 
507
507
  Add stubs to define the results that will be returned:
508
508
 
@@ -154,7 +154,7 @@ module Geocoder
154
154
  # Translate a bearing (float) into a compass direction (string, eg "North").
155
155
  #
156
156
  def compass_point(bearing, points = COMPASS_POINTS)
157
- seg_size = 360 / points.size
157
+ seg_size = 360.0 / points.size
158
158
  points[((bearing + (seg_size / 2)) % 360) / seg_size]
159
159
  end
160
160
 
@@ -1,11 +1,24 @@
1
1
  require 'resolv'
2
2
  module Geocoder
3
3
  class IpAddress < String
4
+ PRIVATE_IPS = [
5
+ '10.0.0.0/8',
6
+ '172.16.0.0/12',
7
+ '192.168.0.0/16',
8
+ ].map { |ip| IPAddr.new(ip) }.freeze
9
+
10
+ def internal?
11
+ loopback? || private?
12
+ end
4
13
 
5
14
  def loopback?
6
15
  valid? and !!(self == "0.0.0.0" or self.match(/\A127\./) or self == "::1")
7
16
  end
8
17
 
18
+ def private?
19
+ valid? && PRIVATE_IPS.any? { |ip| ip.include?(self) }
20
+ end
21
+
9
22
  def valid?
10
23
  !!((self =~ Resolv::IPv4::Regex) || (self =~ Resolv::IPv6::Regex))
11
24
  end
@@ -37,12 +37,12 @@ module Geocoder
37
37
  :nominatim,
38
38
  :mapbox,
39
39
  :mapquest,
40
- :mapzen,
41
40
  :opencagedata,
42
41
  :pelias,
43
42
  :pickpoint,
44
43
  :here,
45
44
  :baidu,
45
+ :tencent,
46
46
  :geocodio,
47
47
  :smarty_streets,
48
48
  :postcode_anywhere_uk,
@@ -1,4 +1,4 @@
1
- require 'geocoder/lookups/base'
1
+ require 'geocoder/lookups/baidu'
2
2
  require 'geocoder/results/baidu_ip'
3
3
 
4
4
  module Geocoder::Lookup
@@ -164,7 +164,7 @@ module Geocoder
164
164
  def cache_key_params(query)
165
165
  # omit api_key and token because they may vary among requests
166
166
  query_url_params(query).reject do |key,value|
167
- key.to_s.match /(key|token)/
167
+ key.to_s.match(/(key|token)/)
168
168
  end
169
169
  end
170
170
 
@@ -209,7 +209,10 @@ module Geocoder
209
209
  JSON.parse(data)
210
210
  end
211
211
  rescue
212
- raise_error(ResponseParseError.new(data)) or Geocoder.log(:warn, "Geocoding API's response was not valid JSON: #{data}")
212
+ unless raise_error(ResponseParseError.new(data))
213
+ Geocoder.log(:warn, "Geocoding API's response was not valid JSON")
214
+ Geocoder.log(:debug, "Raw response: #{data}")
215
+ end
213
216
  end
214
217
 
215
218
  ##
@@ -53,7 +53,8 @@ module Geocoder::Lookup
53
53
 
54
54
  def query_url_params(query)
55
55
  {
56
- key: configuration.api_key
56
+ key: configuration.api_key,
57
+ language: (query.language || configuration.language)
57
58
  }.merge(super)
58
59
  end
59
60
 
@@ -40,31 +40,56 @@ module Geocoder::Lookup
40
40
  else
41
41
  params[:text] = query.sanitized_text
42
42
  end
43
- params[:token] = token
44
- params[:forStorage] = configuration[:for_storage] if configuration[:for_storage]
43
+
44
+ params[:token] = token(query)
45
+
46
+ if for_storage_value = for_storage(query)
47
+ params[:forStorage] = for_storage_value
48
+ end
45
49
  params[:sourceCountry] = configuration[:source_country] if configuration[:source_country]
46
50
  params.merge(super)
47
51
  end
48
52
 
49
- def token
50
- create_and_save_token! if !valid_token_configured? and configuration.api_key
51
- configuration[:token].to_s unless configuration[:token].nil?
53
+ def for_storage(query)
54
+ if query.options.has_key?(:for_storage)
55
+ query.options[:for_storage]
56
+ else
57
+ configuration[:for_storage]
58
+ end
59
+ end
60
+
61
+ def token(query)
62
+ token_instance = if query.options[:token]
63
+ query.options[:token]
64
+ else
65
+ configuration[:token]
66
+ end
67
+
68
+ if !valid_token_configured?(token_instance) && configuration.api_key
69
+ token_instance = create_and_save_token!(query)
70
+ end
71
+
72
+ token_instance.to_s unless token_instance.nil?
52
73
  end
53
74
 
54
- def valid_token_configured?
55
- !configuration[:token].nil? and configuration[:token].active?
75
+ def valid_token_configured?(token_instance)
76
+ !token_instance.nil? && token_instance.active?
56
77
  end
57
78
 
58
- def create_and_save_token!
59
- save_token!(create_token)
79
+ def create_and_save_token!(query)
80
+ token_instance = create_token
81
+
82
+ if query.options[:token]
83
+ query.options[:token] = token_instance
84
+ else
85
+ Geocoder.merge_into_lookup_config(:esri, token: token_instance)
86
+ end
87
+
88
+ token_instance
60
89
  end
61
90
 
62
91
  def create_token
63
92
  Geocoder::EsriToken.generate_token(*configuration.api_key)
64
93
  end
65
-
66
- def save_token!(token_instance)
67
- Geocoder.merge_into_lookup_config(:esri, token: token_instance)
68
- end
69
94
  end
70
95
  end
@@ -7,7 +7,7 @@ module Geocoder::Lookup
7
7
  def name
8
8
  "FreeGeoIP"
9
9
  end
10
-
10
+
11
11
  def supported_protocols
12
12
  if configuration[:host]
13
13
  [:http, :https]
@@ -32,8 +32,8 @@ module Geocoder::Lookup
32
32
  end
33
33
 
34
34
  def results(query)
35
- # don't look up a loopback address, just return the stored result
36
- return [reserved_result(query.text)] if query.loopback_ip_address?
35
+ # don't look up a loopback or private address, just return the stored result
36
+ return [reserved_result(query.text)] if query.internal_ip_address?
37
37
  # note: Freegeoip.net returns plain text "Not Found" on bad request
38
38
  (doc = fetch_data(query)) ? [doc] : []
39
39
  end
@@ -28,33 +28,48 @@ module Geocoder::Lookup
28
28
  []
29
29
  end
30
30
 
31
- def query_url_params(query)
31
+ def query_url_here_options(query, reverse_geocode)
32
32
  options = {
33
- :gen=>4,
34
- :app_id=>api_key,
35
- :app_code=>api_code
33
+ gen: 9,
34
+ app_id: api_key,
35
+ app_code: api_code,
36
+ language: (query.language || configuration.language)
36
37
  }
38
+ if reverse_geocode
39
+ options[:mode] = :retrieveAddresses
40
+ return options
41
+ end
42
+
43
+ unless (country = query.options[:country]).nil?
44
+ options[:country] = country
45
+ end
37
46
 
47
+ unless (mapview = query.options[:bounds]).nil?
48
+ options[:mapview] = mapview.map{ |point| "%f,%f" % point }.join(';')
49
+ end
50
+ options
51
+ end
52
+
53
+ def query_url_params(query)
38
54
  if query.reverse_geocode?
39
- super.merge(options).merge(
40
- :prox=>query.sanitized_text,
41
- :mode=>:retrieveAddresses
55
+ super.merge(query_url_here_options(query, true)).merge(
56
+ prox: query.sanitized_text
42
57
  )
43
58
  else
44
- super.merge(options).merge(
45
- :searchtext=>query.sanitized_text
59
+ super.merge(query_url_here_options(query, false)).merge(
60
+ searchtext: query.sanitized_text
46
61
  )
47
62
  end
48
63
  end
49
64
 
50
65
  def api_key
51
- if a=configuration.api_key
66
+ if (a = configuration.api_key)
52
67
  return a.first if a.is_a?(Array)
53
68
  end
54
69
  end
55
70
 
56
71
  def api_code
57
- if a=configuration.api_key
72
+ if (a = configuration.api_key)
58
73
  return a.last if a.is_a?(Array)
59
74
  end
60
75
  end
@@ -27,7 +27,8 @@ module Geocoder::Lookup
27
27
  end
28
28
 
29
29
  def results(query)
30
- return [reserved_result(query.text)] if query.loopback_ip_address?
30
+ # don't look up a loopback or private address, just return the stored result
31
+ return [reserved_result(query.text)] if query.internal_ip_address?
31
32
  return [] unless doc = fetch_data(query)
32
33
  if doc["response"] == "INVALID ACCOUNT"
33
34
  raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "INVALID ACCOUNT")
@@ -34,7 +34,8 @@ module Geocoder::Lookup
34
34
  end
35
35
 
36
36
  def results(query)
37
- return [reserved_result(query.text)] if query.loopback_ip_address?
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?
38
39
 
39
40
  return [] unless doc = fetch_data(query)
40
41
 
@@ -13,7 +13,9 @@ module Geocoder::Lookup
13
13
  end
14
14
 
15
15
  def query_url(query)
16
- "#{protocol}://#{host}/#{query.sanitized_text}"
16
+ # Ipdata.co requires that the API key be sent as a query parameter.
17
+ # It no longer supports API keys sent as headers.
18
+ "#{protocol}://#{host}/#{query.sanitized_text}?api-key=#{configuration.api_key}"
17
19
  end
18
20
 
19
21
  private # ---------------------------------------------------------------
@@ -23,9 +25,8 @@ module Geocoder::Lookup
23
25
  end
24
26
 
25
27
  def results(query)
26
- Geocoder.configure(:ipdata_co => {:http_headers => { "api-key" => configuration.api_key }}) if configuration.api_key
27
- # don't look up a loopback address, just return the stored result
28
- return [reserved_result(query.text)] if query.loopback_ip_address?
28
+ # don't look up a loopback or private address, just return the stored result
29
+ return [reserved_result(query.text)] if query.internal_ip_address?
29
30
  # note: Ipdata.co returns plain text on bad request
30
31
  (doc = fetch_data(query)) ? [doc] : []
31
32
  end
@@ -8,15 +8,6 @@ module Geocoder::Lookup
8
8
  "Ipinfo.io"
9
9
  end
10
10
 
11
- # HTTPS available only for paid plans
12
- def supported_protocols
13
- if configuration.api_key
14
- [:http, :https]
15
- else
16
- [:http]
17
- end
18
- end
19
-
20
11
  private # ---------------------------------------------------------------
21
12
 
22
13
  def base_query_url(query)
@@ -26,8 +17,8 @@ module Geocoder::Lookup
26
17
  end
27
18
 
28
19
  def results(query)
29
- # don't look up a loopback address, just return the stored result
30
- return [reserved_result(query.text)] if query.loopback_ip_address?
20
+ # don't look up a loopback or private address, just return the stored result
21
+ return [reserved_result(query.text)] if query.internal_ip_address?
31
22
 
32
23
  if !(doc = fetch_data(query)).is_a?(Hash) or doc['error']
33
24
  []
@@ -34,8 +34,8 @@ module Geocoder::Lookup
34
34
  end
35
35
 
36
36
  def results(query)
37
- # don't look up a loopback address, just return the stored result
38
- return [reserved_result(query.text)] if query.loopback_ip_address?
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
39
 
40
40
  return [] unless doc = fetch_data(query)
41
41
 
@@ -57,8 +57,8 @@ 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.loopback_ip_address?
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)
@@ -32,11 +32,7 @@ module Geocoder::Lookup
32
32
  return s
33
33
  else
34
34
  raise(
35
- Geocoder::ConfigurationError,
36
- "When using MaxMind GeoIP2 you MUST specify a service name and basic_auth: " +
37
- "Geocoder.configure(:maxmind_geoip2 => {:service => ...}, " +
38
- ":basic_auth => {:user ..., :password => ...}), " +
39
- "where service is one of: #{services.inspect}"
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}"
40
36
  )
41
37
  end
42
38
  end
@@ -57,8 +53,9 @@ module Geocoder::Lookup
57
53
  end
58
54
 
59
55
  def results(query)
60
- # don't look up a loopback address
61
- return [] if query.loopback_ip_address?
56
+ # don't look up a loopback or private address, just return the stored result
57
+ return [] if query.internal_ip_address?
58
+
62
59
  doc = fetch_data(query)
63
60
  if doc
64
61
  if !data_contains_error?(doc)
@@ -24,12 +24,11 @@ module Geocoder::Lookup
24
24
 
25
25
  def query_url_params(query)
26
26
  params = {
27
- api_key: configuration.api_key,
28
- size: 1
27
+ api_key: configuration.api_key
29
28
  }.merge(super)
30
29
 
31
30
  if query.reverse_geocode?
32
- lat,lon = query.coordinates
31
+ lat, lon = query.coordinates
33
32
  params[:'point.lat'] = lat
34
33
  params[:'point.lon'] = lon
35
34
  else
@@ -23,8 +23,8 @@ module Geocoder::Lookup
23
23
  end
24
24
 
25
25
  def results(query)
26
- # don't look up a loopback address, just return the stored result
27
- return [] if query.loopback_ip_address?
26
+ # don't look up a loopback or private address, just return the stored result
27
+ return [] if query.internal_ip_address?
28
28
  doc = fetch_data(query)
29
29
  if doc and doc.is_a?(Hash)
30
30
  if !data_contains_error?(doc)
@@ -42,7 +42,7 @@ module Geocoder::Lookup
42
42
  raise_error(Geocoder::Error) || Geocoder.log(:warn, "Pointpin server error")
43
43
  end
44
44
  end
45
-
45
+
46
46
  return []
47
47
  end
48
48
 
@@ -8,7 +8,7 @@ module Geocoder::Lookup
8
8
  end
9
9
 
10
10
  def required_api_key_parts
11
- %w(auti-id auth-token)
11
+ %w(auth-id auth-token)
12
12
  end
13
13
 
14
14
  # required by API as of 26 March 2015
@@ -19,7 +19,9 @@ module Geocoder::Lookup
19
19
  private # ---------------------------------------------------------------
20
20
 
21
21
  def base_query_url(query)
22
- if zipcode_only?(query)
22
+ if international?(query)
23
+ "#{protocol}://international-street.api.smartystreets.com/verify?"
24
+ elsif zipcode_only?(query)
23
25
  "#{protocol}://us-zipcode.api.smartystreets.com/lookup?"
24
26
  else
25
27
  "#{protocol}://us-street.api.smartystreets.com/street-address?"
@@ -30,9 +32,17 @@ module Geocoder::Lookup
30
32
  !query.text.is_a?(Array) and query.to_s.strip =~ /\A\d{5}(-\d{4})?\Z/
31
33
  end
32
34
 
35
+ def international?(query)
36
+ !query.options[:country].nil?
37
+ end
38
+
33
39
  def query_url_params(query)
34
40
  params = {}
35
- if zipcode_only?(query)
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)
36
46
  params[:zipcode] = query.sanitized_text
37
47
  else
38
48
  params[:street] = query.sanitized_text
@@ -34,8 +34,8 @@ module Geocoder::Lookup
34
34
  end
35
35
 
36
36
  def results(query)
37
- # don't look up a loopback address, just return the stored result
38
- return [reserved_result(query.text)] if query.loopback_ip_address?
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
39
  if (doc = fetch_data(query)).nil? or doc['code'] == 401 or empty_result?(doc)
40
40
  []
41
41
  else
@@ -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 199
35
+ raise error(Geocoder::InvalidApiKey, "invalid api key") ||
36
+ Geocoder.log(:warn, "#{name} Geocoding API error: key is not enabled for web service usage.")
37
+ when 311
38
+ raise_error(Geocoder::RequestDenied, "request denied") ||
39
+ Geocoder.log(:warn, "#{name} Geocoding API error: request denied.")
40
+ when 310, 306
41
+ raise_error(Geocoder::InvalidRequest, "invalid request.") ||
42
+ Geocoder.log(:warn, "#{name} Geocoding API error: invalid request.")
43
+ when 311
44
+ raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
45
+ Geocoder.log(:warn, "#{name} Geocoding API error: invalid api key.")
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
@@ -66,6 +66,13 @@ module Geocoder
66
66
  IpAddress.new(text).valid? rescue false
67
67
  end
68
68
 
69
+ ##
70
+ # Is the Query text a loopback or private IP address?
71
+ #
72
+ def internal_ip_address?
73
+ ip_address? && IpAddress.new(text).internal?
74
+ end
75
+
69
76
  ##
70
77
  # Is the Query text a loopback IP address?
71
78
  #
@@ -73,6 +80,13 @@ module Geocoder
73
80
  ip_address? && IpAddress.new(text).loopback?
74
81
  end
75
82
 
83
+ ##
84
+ # Is the Query text a private IP address?
85
+ #
86
+ def private_ip_address?
87
+ ip_address? && IpAddress.new(text).private?
88
+ end
89
+
76
90
  ##
77
91
  # Does the given string look like latitude/longitude coordinates?
78
92
  #
@@ -4,7 +4,7 @@ module Geocoder
4
4
  if defined? Rails::Railtie
5
5
  require 'rails'
6
6
  class Railtie < Rails::Railtie
7
- initializer 'geocoder.insert_into_active_record' do
7
+ initializer 'geocoder.insert_into_active_record', before: :load_config_initializers do
8
8
  ActiveSupport.on_load :active_record do
9
9
  Geocoder::Railtie.insert
10
10
  end
@@ -15,51 +15,77 @@ module Geocoder::Result
15
15
  end
16
16
 
17
17
  def address
18
- [
19
- delivery_line_1,
20
- delivery_line_2,
21
- last_line
22
- ].select{ |i| i.to_s != "" }.join(" ")
18
+ parts =
19
+ if international_endpoint?
20
+ (1..12).map { |i| @data["address#{i}"] }
21
+ else
22
+ [
23
+ delivery_line_1,
24
+ delivery_line_2,
25
+ last_line
26
+ ]
27
+ end
28
+ parts.select{ |i| i.to_s != "" }.join(" ")
23
29
  end
24
30
 
25
31
  def state
26
- zipcode_endpoint? ?
27
- city_states.first['state'] :
32
+ if international_endpoint?
33
+ components['administrative_area']
34
+ elsif zipcode_endpoint?
35
+ city_states.first['state']
36
+ else
28
37
  components['state_abbreviation']
38
+ end
29
39
  end
30
40
 
31
41
  def state_code
32
- zipcode_endpoint? ?
33
- city_states.first['state_abbreviation'] :
42
+ if international_endpoint?
43
+ components['administrative_area']
44
+ elsif zipcode_endpoint?
45
+ city_states.first['state_abbreviation']
46
+ else
34
47
  components['state_abbreviation']
48
+ end
35
49
  end
36
50
 
37
51
  def country
38
- # SmartyStreets returns results for USA only
39
- "United States"
52
+ international_endpoint? ?
53
+ components['country_iso_3'] :
54
+ "United States"
40
55
  end
41
56
 
42
57
  def country_code
43
- # SmartyStreets returns results for USA only
44
- "US"
58
+ international_endpoint? ?
59
+ components['country_iso_3'] :
60
+ "US"
45
61
  end
46
62
 
47
63
  ## Extra methods not in base.rb ------------------------
48
64
 
49
65
  def street
50
- components['street_name']
66
+ international_endpoint? ?
67
+ components['thoroughfare_name'] :
68
+ components['street_name']
51
69
  end
52
70
 
53
71
  def city
54
- zipcode_endpoint? ?
55
- city_states.first['city'] :
72
+ if international_endpoint?
73
+ components['locality']
74
+ elsif zipcode_endpoint?
75
+ city_states.first['city']
76
+ else
56
77
  components['city_name']
78
+ end
57
79
  end
58
80
 
59
81
  def zipcode
60
- zipcode_endpoint? ?
61
- zipcodes.first['zipcode'] :
82
+ if international_endpoint?
83
+ components['postal_code']
84
+ elsif zipcode_endpoint?
85
+ zipcodes.first['zipcode']
86
+ else
62
87
  components['zipcode']
88
+ end
63
89
  end
64
90
  alias_method :postal_code, :zipcode
65
91
 
@@ -78,6 +104,10 @@ module Geocoder::Result
78
104
  zipcodes.any?
79
105
  end
80
106
 
107
+ def international_endpoint?
108
+ !@data['address1'].nil?
109
+ end
110
+
81
111
  [
82
112
  :delivery_line_1,
83
113
  :delivery_line_2,
@@ -0,0 +1,72 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Tencent < Base
5
+
6
+ def coordinates
7
+ ['lat', 'lng'].map{ |i| @data['location'][i] }
8
+ end
9
+
10
+ def address
11
+ "#{province}#{city}#{district}#{street}#{street_number}"
12
+
13
+ #@data['title'] or @data['address']
14
+ end
15
+
16
+ # NOTE: The Tencent reverse geocoding API has the field named
17
+ # 'address_component' compared to 'address_components' in the
18
+ # regular geocoding API.
19
+ def province
20
+ @data['address_components'] and (@data['address_components']['province']) or
21
+ (@data['address_component'] and @data['address_component']['province']) or
22
+ ""
23
+ end
24
+
25
+ alias_method :state, :province
26
+
27
+ def city
28
+ @data['address_components'] and (@data['address_components']['city']) or
29
+ (@data['address_component'] and @data['address_component']['city']) or
30
+ ""
31
+ end
32
+
33
+ def district
34
+ @data['address_components'] and (@data['address_components']['district']) or
35
+ (@data['address_component'] and @data['address_component']['district']) or
36
+ ""
37
+ end
38
+
39
+ def street
40
+ @data['address_components'] and (@data['address_components']['street']) or
41
+ (@data['address_component'] and @data['address_component']['street']) or
42
+ ""
43
+ end
44
+
45
+ def street_number
46
+ @data['address_components'] and (@data['address_components']['street_number']) or
47
+ (@data['address_component'] and @data['address_component']['street_number']) or
48
+ ""
49
+ end
50
+
51
+ def address_components
52
+ @data['address_components'] or @data['address_component']
53
+ end
54
+
55
+ def state_code
56
+ ""
57
+ end
58
+
59
+ def postal_code
60
+ ""
61
+ end
62
+
63
+ def country
64
+ "China"
65
+ end
66
+
67
+ def country_code
68
+ "CN"
69
+ end
70
+
71
+ end
72
+ end
@@ -60,7 +60,7 @@ module Geocoder::Store
60
60
  # corner followed by the northeast corner of the box
61
61
  # (<tt>[[sw_lat, sw_lon], [ne_lat, ne_lon]]</tt>).
62
62
  #
63
- scope :within_bounding_box, lambda{ |bounds|
63
+ scope :within_bounding_box, lambda{ |*bounds|
64
64
  sw_lat, sw_lng, ne_lat, ne_lng = bounds.flatten if bounds
65
65
  if sw_lat && sw_lng && ne_lat && ne_lng
66
66
  where(Geocoder::Sql.within_bounding_box(
@@ -1,3 +1,3 @@
1
1
  module Geocoder
2
- VERSION = "1.5.0"
2
+ VERSION = "1.5.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geocoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Reisner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-31 00:00:00.000000000 Z
11
+ date: 2019-01-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Provides object geocoding (by street or IP address), reverse geocoding
14
14
  (coordinates to street address), distance queries for ActiveRecord and Mongoid,
@@ -77,7 +77,6 @@ files:
77
77
  - lib/geocoder/lookups/location_iq.rb
78
78
  - lib/geocoder/lookups/mapbox.rb
79
79
  - lib/geocoder/lookups/mapquest.rb
80
- - lib/geocoder/lookups/mapzen.rb
81
80
  - lib/geocoder/lookups/maxmind.rb
82
81
  - lib/geocoder/lookups/maxmind_geoip2.rb
83
82
  - lib/geocoder/lookups/maxmind_local.rb
@@ -90,6 +89,7 @@ files:
90
89
  - lib/geocoder/lookups/postcodes_io.rb
91
90
  - lib/geocoder/lookups/smarty_streets.rb
92
91
  - lib/geocoder/lookups/telize.rb
92
+ - lib/geocoder/lookups/tencent.rb
93
93
  - lib/geocoder/lookups/test.rb
94
94
  - lib/geocoder/lookups/yandex.rb
95
95
  - lib/geocoder/models/active_record.rb
@@ -129,7 +129,6 @@ files:
129
129
  - lib/geocoder/results/location_iq.rb
130
130
  - lib/geocoder/results/mapbox.rb
131
131
  - lib/geocoder/results/mapquest.rb
132
- - lib/geocoder/results/mapzen.rb
133
132
  - lib/geocoder/results/maxmind.rb
134
133
  - lib/geocoder/results/maxmind_geoip2.rb
135
134
  - lib/geocoder/results/maxmind_local.rb
@@ -142,6 +141,7 @@ files:
142
141
  - lib/geocoder/results/postcodes_io.rb
143
142
  - lib/geocoder/results/smarty_streets.rb
144
143
  - lib/geocoder/results/telize.rb
144
+ - lib/geocoder/results/tencent.rb
145
145
  - lib/geocoder/results/test.rb
146
146
  - lib/geocoder/results/yandex.rb
147
147
  - lib/geocoder/sql.rb
@@ -1,15 +0,0 @@
1
- require 'geocoder/lookups/pelias'
2
- require 'geocoder/results/mapzen'
3
-
4
- # https://mapzen.com/documentation/search/search/ for more information
5
- module Geocoder::Lookup
6
- class Mapzen < Pelias
7
- def name
8
- 'Mapzen'
9
- end
10
-
11
- def endpoint
12
- configuration[:endpoint] || 'search.mapzen.com'
13
- end
14
- end
15
- end
@@ -1,5 +0,0 @@
1
- require 'geocoder/results/pelias'
2
-
3
- module Geocoder::Result
4
- class Mapzen < Pelias; end
5
- end