geocoder 1.7.3 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1dab5b671e230411d805a864ef61517f45eb01d4b83091a3eb5b84693dbbc06a
4
- data.tar.gz: 39fcd37053a8c6cdb3270cd6d4daaa8ee025d0ed74c534b3a7c62bf6743013b7
3
+ metadata.gz: 35c6a6d57b8ff3818e9d1b616558a8bbdc3b4b51db2b2c7dadb720eccafd27b4
4
+ data.tar.gz: 8e8fe1ba7cb9da58131a965d3d85589084f4d5dd70409990f49b89b83923f4e3
5
5
  SHA512:
6
- metadata.gz: 2b25a577d6d1522b831eb78fb6d6d9af85f1e4d592cd16e2202b8e473376fdf69a87de56c52152a6d7eddf506f6635cf887bb4766680cb8f697ab12c50fab624
7
- data.tar.gz: f8901d2a0187cbb81483a0a94334b32222ae254f08b97c0b1c1f58f39d53148871083b839a2a2e661ba94eb0783a4a399990306e7633a1cc6d3424861cd21408
6
+ metadata.gz: 0bbf04cc8488a533038783e2d250706fb2d2439de8ea1e5bf4b89950d1dd51d5e9393454540a23cb4e7fbc33b58f54fec1c71c14c98d6fbe8bb8e5caad786989
7
+ data.tar.gz: 92b8f5933a421b47cdededea9c8e8df8d2ec6f45cb25c8726b343a773b315929529fe821cae08868576ae2e8c5cdbc5fd1782bd2bfc8c56f36afdc1514f52b58
data/CHANGELOG.md CHANGED
@@ -3,6 +3,28 @@ 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.8.1 (2022 Sep 23)
7
+ -------------------
8
+ * Add support for IPBase lookup (thanks github.com/jonallured).
9
+ * Test cleanup (thanks github.com/jonallured).
10
+ * Prevent errors when existing constant name shadows a lookup class (thanks github.com/avram-twitch).
11
+
12
+ 1.8.0 (2022 May 17)
13
+ -------------------
14
+ * Add support for 2GIS lookup (thanks github.com/ggrikgg).
15
+ * Change cache configuration structure and add an expiration option. Cache prefix is now set via {cache_options: {prefix: ...}} instead of {cache_prefix: ...}. See README for details.
16
+ * Add `:fields` parameter for :google_places_details and :google_places_search lookups. If you haven't been requesting specific fields, you may start getting different data (defaults are now the APIs' defaults). See for details: https://github.com/alexreisner/geocoder/pull/1572 (thanks github.com/czlee).
17
+ * Update :here lookup to use API version 7. Query options are different, API key must be a string (not an array). See API docs at https://developer.here.com/documentation/geocoding-search-api/api-reference-swagger.html (thanks github.com/Pritilender).
18
+
19
+ 1.7.5 (2022 Mar 14)
20
+ -------------------
21
+ * Avoid lookup naming collisions in some environments.
22
+
23
+ 1.7.4 (2022 Mar 14)
24
+ -------------------
25
+ * Add ability to use app-defined lookups (thanks github.com/januszm).
26
+ * Updates to LocationIQ and FreeGeoIP lookups.
27
+
6
28
  1.7.3 (2022 Jan 17)
7
29
  -------------------
8
30
  * Get rid of unnecessary cache_prefix deprecation warnings.
data/README.md CHANGED
@@ -20,7 +20,7 @@ Compatibility:
20
20
 
21
21
  * Ruby versions: 2.1+, and JRuby.
22
22
  * Databases: MySQL, PostgreSQL, SQLite, and MongoDB.
23
- * Rails: 5.x and 6.x.
23
+ * Rails: 5.x, 6.x, and 7.x.
24
24
  * Works outside of Rails with the `json` (for MRI) or `json_pure` (for JRuby) gem.
25
25
 
26
26
 
@@ -78,7 +78,7 @@ results.first.address
78
78
  # => "Hôtel de Ville, 75004 Paris, France"
79
79
  ```
80
80
 
81
- You can also look up the location of an IP addresses:
81
+ You can also look up the location of an IP address:
82
82
 
83
83
  ```ruby
84
84
  results = Geocoder.search("172.56.21.89")
@@ -246,11 +246,10 @@ Geocoder.configure(
246
246
  units: :km,
247
247
 
248
248
  # caching (see Caching section below for details):
249
- # warning: `cache_prefix` is deprecated, use `cache_options` instead
250
249
  cache: Redis.new,
251
250
  cache_options: {
252
- expiration: 2.days, # Redis ttl
253
- prefix: "..."
251
+ expiration: 1.day, # Defaults to `nil`
252
+ prefix: "another_key:" # Defaults to `geocoder:`
254
253
  }
255
254
  )
256
255
  ```
@@ -748,7 +747,7 @@ If your application requires quick geocoding responses you will probably need to
748
747
 
749
748
  For IP address lookups in Rails applications, it is generally NOT a good idea to run `request.location` during a synchronous page load without understanding the speed/behavior of your configured lookup. If the lookup becomes slow, so will your website.
750
749
 
751
- For the most part, the speed of geocoding requests has little to do with the Geocoder gem. Please take the time to learn about your configured lookup (links to documentation are provided above) before posting performance-related issues.
750
+ For the most part, the speed of geocoding requests has little to do with the Geocoder gem. Please take the time to learn about your configured lookup before posting performance-related issues.
752
751
 
753
752
  ### Unexpected Responses from Geocoding Services
754
753
 
@@ -0,0 +1,22 @@
1
+ # To extend the Geocoder with additional lookups that come from the application,
2
+ # not shipped with the gem, define a "child" lookup in your application, based on existing one.
3
+ # This is required because the Geocoder::Configuration is a Singleton and stores one api key per lookup.
4
+
5
+ # in app/libs/geocoder/lookup/my_preciousss.rb
6
+ module Geocoder::Lookup
7
+ class MyPreciousss < Google
8
+ end
9
+ end
10
+
11
+ # Update Geocoder's street_services on initialize:
12
+ # config/initializers/geocoder.rb
13
+ Geocoder::Lookup.street_services << :my_preciousss
14
+
15
+ # Override the configuration when necessary (e.g. provide separate Google API key for the account):
16
+ Geocoder.configure(my_preciousss: { api_key: 'abcdef' })
17
+
18
+ # Lastly, search using your custom lookup service/api keys
19
+ Geocoder.search("Paris", lookup: :my_preciousss)
20
+
21
+ # This is useful when we have groups of users in the application who use Google paid services
22
+ # and we want to properly separate them and allow using individual API KEYS or timeouts.
@@ -9,7 +9,6 @@ Geocoder.configure(
9
9
  # https_proxy: nil, # HTTPS proxy server (user:pass@host:port)
10
10
  # api_key: nil, # API key for geocoding service
11
11
  # cache: nil, # cache object (must respond to #[], #[]=, and #del)
12
- # cache_prefix: 'geocoder:', # DEPRECATED, please use cache_options[:prefix] instead
13
12
 
14
13
  # Exceptions that should not be rescued by default
15
14
  # (if you want to implement custom error handling);
@@ -14,7 +14,7 @@ module Geocoder
14
14
  def [](url)
15
15
  interpret store_service.read(url)
16
16
  rescue => e
17
- warn "Geocoder cache read error: #{e}"
17
+ Geocoder.log(:warn, "Geocoder cache read error: #{e}")
18
18
  end
19
19
 
20
20
  ##
@@ -23,7 +23,7 @@ module Geocoder
23
23
  def []=(url, value)
24
24
  store_service.write(url, value)
25
25
  rescue => e
26
- warn "Geocoder cache write error: #{e}"
26
+ Geocoder.log(:warn, "Geocoder cache write error: #{e}")
27
27
  end
28
28
 
29
29
  ##
@@ -62,7 +62,6 @@ module Geocoder
62
62
  :https_proxy,
63
63
  :api_key,
64
64
  :cache,
65
- :cache_prefix,
66
65
  :always_raise,
67
66
  :units,
68
67
  :distances,
@@ -78,6 +77,10 @@ module Geocoder
78
77
  instance.set_defaults
79
78
  end
80
79
 
80
+ def self.initialize
81
+ instance.send(:initialize)
82
+ end
83
+
81
84
  OPTIONS.each do |o|
82
85
  define_method o do
83
86
  @data[o]
@@ -108,8 +111,6 @@ module Geocoder
108
111
  @data[:http_proxy] = nil # HTTP proxy server (user:pass@host:port)
109
112
  @data[:https_proxy] = nil # HTTPS proxy server (user:pass@host:port)
110
113
  @data[:api_key] = nil # API key for geocoding service
111
- @data[:cache] = nil # cache object (must respond to #[], #[]=, and optionally #keys)
112
- @data[:cache_prefix] = nil # - DEPRECATED - prefix (string) to use for all cache keys
113
114
  @data[:basic_auth] = {} # user and password for basic auth ({:user => "user", :password => "password"})
114
115
  @data[:logger] = :kernel # :kernel or Logger instance
115
116
  @data[:kernel_logger_level] = ::Logger::WARN # log level, if kernel logger is used
@@ -123,9 +124,15 @@ module Geocoder
123
124
  @data[:units] = :mi # :mi or :km
124
125
  @data[:distances] = :linear # :linear or :spherical
125
126
 
126
- # explicit cache service options
127
- @data[:cache_options] ||= {}
128
- @data[:cache_options][:prefix] = "geocoder:"
127
+ # Set the default values for the caching mechanism
128
+ # By default, the cache keys will not expire as IP addresses and phyiscal
129
+ # addresses will rarely change.
130
+ @data[:cache] = nil # cache object (must respond to #[], #[]=, and optionally #keys)
131
+ @data[:cache_prefix] = nil # - DEPRECATED - prefix (string) to use for all cache keys
132
+ @data[:cache_options] = {
133
+ prefix: 'geocoder:',
134
+ expiration: nil
135
+ }
129
136
  end
130
137
 
131
138
  instance_eval(OPTIONS.map do |option|
@@ -65,7 +65,8 @@ module Geocoder
65
65
  :melissa_street,
66
66
  :amazon_location_service,
67
67
  :geoapify,
68
- :photon
68
+ :photon,
69
+ :twogis
69
70
  ]
70
71
  end
71
72
 
@@ -91,7 +92,8 @@ module Geocoder
91
92
  :ipstack,
92
93
  :ip2location,
93
94
  :ipgeolocation,
94
- :ipqualityscore
95
+ :ipqualityscore,
96
+ :ipbase
95
97
  ]
96
98
  end
97
99
 
@@ -117,8 +119,7 @@ module Geocoder
117
119
  def spawn(name)
118
120
  if all_services.include?(name)
119
121
  name = name.to_s
120
- require "geocoder/lookups/#{name}"
121
- Geocoder::Lookup.const_get(classify_name(name)).new
122
+ instantiate_lookup(name)
122
123
  else
123
124
  valids = all_services.map(&:inspect).join(", ")
124
125
  raise ConfigurationError, "Please specify a valid lookup for Geocoder " +
@@ -132,5 +133,18 @@ module Geocoder
132
133
  def classify_name(filename)
133
134
  filename.to_s.split("_").map{ |i| i[0...1].upcase + i[1..-1] }.join
134
135
  end
136
+
137
+ ##
138
+ # Safely instantiate Lookup
139
+ #
140
+ def instantiate_lookup(name)
141
+ class_name = classify_name(name)
142
+ begin
143
+ Geocoder::Lookup.const_get(class_name, inherit=false)
144
+ rescue NameError
145
+ require "geocoder/lookups/#{name}"
146
+ end
147
+ Geocoder::Lookup.const_get(class_name).new
148
+ end
135
149
  end
136
150
  end
@@ -32,10 +32,10 @@ module Geocoder::Lookup
32
32
  return doc['geocodes'] unless doc['geocodes'].blank?
33
33
  when ['0', 'INVALID_USER_KEY']
34
34
  raise_error(Geocoder::InvalidApiKey, "invalid api key") ||
35
- warn("#{self.name} Geocoding API error: invalid api key.")
35
+ Geocoder.log(:warn, "#{self.name} Geocoding API error: invalid api key.")
36
36
  else
37
37
  raise_error(Geocoder::Error, "server error.") ||
38
- warn("#{self.name} Geocoding API error: server error - [#{doc['info']}]")
38
+ Geocoder.log(:warn, "#{self.name} Geocoding API error: server error - [#{doc['info']}]")
39
39
  end
40
40
  return []
41
41
  end
@@ -83,13 +83,8 @@ module Geocoder
83
83
  # The working Cache object.
84
84
  #
85
85
  def cache
86
- if @cache.nil? && (store = configuration.cache)
86
+ if @cache.nil? and store = configuration.cache
87
87
  cache_options = configuration.cache_options
88
- cache_prefix = (configuration.cache_prefix rescue false)
89
- if cache_prefix
90
- cache_options[:prefix] ||= configuration.cache_prefix
91
- warn '[Geocoder] cache_prefix is deprecated, please change to cache_options.prefix instead'
92
- end
93
88
  @cache = Cache.new(store, cache_options)
94
89
  end
95
90
  @cache
@@ -17,14 +17,16 @@ module Geocoder::Lookup
17
17
  end
18
18
  end
19
19
 
20
- def query_url(query)
21
- "#{protocol}://#{host}/json/#{query.sanitized_text}"
22
- end
23
-
24
20
  private # ---------------------------------------------------------------
25
21
 
26
- def cache_key(query)
27
- query_url(query)
22
+ def base_query_url(query)
23
+ "#{protocol}://#{host}/json/#{query.sanitized_text}?"
24
+ end
25
+
26
+ def query_url_params(query)
27
+ {
28
+ :apikey => configuration.api_key
29
+ }.merge(super)
28
30
  end
29
31
 
30
32
  def parse_raw_data(raw_data)
@@ -22,7 +22,13 @@ module Geocoder
22
22
  private
23
23
 
24
24
  def base_query_url(query)
25
- method = query.reverse_geocode? ? 'reverse' : 'search'
25
+ method = if query.reverse_geocode?
26
+ 'reverse'
27
+ elsif query.options[:autocomplete]
28
+ 'autocomplete'
29
+ else
30
+ 'search'
31
+ end
26
32
  "https://api.geoapify.com/v1/geocode/#{method}?"
27
33
  end
28
34
 
@@ -56,7 +56,7 @@ module Geocoder
56
56
  else
57
57
  result = []
58
58
  raise_error(Geocoder::Error) ||
59
- warn("Geportail.lu Geocoding API error")
59
+ Geocoder.log(:warn, "Geportail.lu Geocoding API error")
60
60
  end
61
61
  result
62
62
  end
@@ -33,9 +33,29 @@ module Geocoder
33
33
  result
34
34
  end
35
35
 
36
+ def fields(query)
37
+ if query.options.has_key?(:fields)
38
+ return format_fields(query.options[:fields])
39
+ end
40
+
41
+ if configuration.has_key?(:fields)
42
+ return format_fields(configuration[:fields])
43
+ end
44
+
45
+ nil # use Google Places defaults
46
+ end
47
+
48
+ def format_fields(*fields)
49
+ flattened = fields.flatten.compact
50
+ return if flattened.empty?
51
+
52
+ flattened.join(',')
53
+ end
54
+
36
55
  def query_url_google_params(query)
37
56
  {
38
57
  placeid: query.text,
58
+ fields: fields(query),
39
59
  language: query.language || configuration.language
40
60
  }
41
61
  end
@@ -31,13 +31,19 @@ module Geocoder
31
31
  input: query.text,
32
32
  inputtype: 'textquery',
33
33
  fields: fields(query),
34
+ locationbias: locationbias(query),
34
35
  language: query.language || configuration.language
35
36
  }
36
37
  end
37
38
 
38
39
  def fields(query)
39
- query_fields = query.options[:fields]
40
- return format_fields(query_fields) if query_fields
40
+ if query.options.has_key?(:fields)
41
+ return format_fields(query.options[:fields])
42
+ end
43
+
44
+ if configuration.has_key?(:fields)
45
+ return format_fields(configuration[:fields])
46
+ end
41
47
 
42
48
  default_fields
43
49
  end
@@ -52,7 +58,18 @@ module Geocoder
52
58
  end
53
59
 
54
60
  def format_fields(*fields)
55
- fields.flatten.join(',')
61
+ flattened = fields.flatten.compact
62
+ return if flattened.empty?
63
+
64
+ flattened.join(',')
65
+ end
66
+
67
+ def locationbias(query)
68
+ if query.options.has_key?(:locationbias)
69
+ query.options[:locationbias]
70
+ else
71
+ configuration[:locationbias]
72
+ end
56
73
  end
57
74
  end
58
75
  end
@@ -19,50 +19,55 @@ module Geocoder::Lookup
19
19
  private # ---------------------------------------------------------------
20
20
 
21
21
  def base_query_url(query)
22
- "#{protocol}://#{if query.reverse_geocode? then 'reverse.' end}geocoder.ls.hereapi.com/6.2/#{if query.reverse_geocode? then 'reverse' end}geocode.json?"
22
+ service = query.reverse_geocode? ? "revgeocode" : "geocode"
23
+
24
+ "#{protocol}://#{service}.search.hereapi.com/v1/#{service}?"
23
25
  end
24
26
 
25
27
  def results(query)
26
- return [] unless doc = fetch_data(query)
27
- return [] unless doc['Response'] && doc['Response']['View']
28
- if r=doc['Response']['View']
29
- return [] if r.nil? || !r.is_a?(Array) || r.empty?
30
- return r.first['Result']
28
+ unless configuration.api_key.is_a?(String)
29
+ api_key_not_string!
30
+ return []
31
31
  end
32
- []
32
+ return [] unless doc = fetch_data(query)
33
+ return [] if doc["items"].nil?
34
+
35
+ doc["items"]
33
36
  end
34
37
 
35
38
  def query_url_here_options(query, reverse_geocode)
36
39
  options = {
37
- gen: 9,
38
- apikey: configuration.api_key,
39
- language: (query.language || configuration.language)
40
+ apiKey: configuration.api_key,
41
+ lang: (query.language || configuration.language)
40
42
  }
41
- if reverse_geocode
42
- options[:mode] = :retrieveAddresses
43
- return options
44
- end
43
+ return options if reverse_geocode
45
44
 
46
45
  unless (country = query.options[:country]).nil?
47
- options[:country] = country
46
+ options[:in] = "countryCode:#{country}"
48
47
  end
49
48
 
50
- unless (mapview = query.options[:bounds]).nil?
51
- options[:mapview] = mapview.map{ |point| "%f,%f" % point }.join(';')
52
- end
53
49
  options
54
50
  end
55
51
 
56
52
  def query_url_params(query)
57
53
  if query.reverse_geocode?
58
54
  super.merge(query_url_here_options(query, true)).merge(
59
- prox: query.sanitized_text
55
+ at: query.sanitized_text
60
56
  )
61
57
  else
62
58
  super.merge(query_url_here_options(query, false)).merge(
63
- searchtext: query.sanitized_text
59
+ q: query.sanitized_text
64
60
  )
65
61
  end
66
62
  end
63
+
64
+ def api_key_not_string!
65
+ msg = <<~MSG
66
+ API key for HERE Geocoding and Search API should be a string.
67
+ For more info on how to obtain it, please see https://developer.here.com/documentation/identity-access-management/dev_guide/topics/plat-using-apikeys.html
68
+ MSG
69
+
70
+ raise_error(Geocoder::ConfigurationError, msg) || Geocoder.log(:warn, msg)
71
+ end
67
72
  end
68
73
  end
@@ -0,0 +1,49 @@
1
+ require 'geocoder/lookups/base'
2
+ require 'geocoder/results/ipbase'
3
+
4
+ module Geocoder::Lookup
5
+ class Ipbase < Base
6
+
7
+ def name
8
+ "ipbase.com"
9
+ end
10
+
11
+ def supported_protocols
12
+ [:https]
13
+ end
14
+
15
+ private # ---------------------------------------------------------------
16
+
17
+ def base_query_url(query)
18
+ "https://api.ipbase.com/v2/info?"
19
+ end
20
+
21
+ def query_url_params(query)
22
+ {
23
+ :ip => query.sanitized_text,
24
+ :apikey => configuration.api_key
25
+ }
26
+ end
27
+
28
+ def results(query)
29
+ # don't look up a loopback or private address, just return the stored result
30
+ return [reserved_result(query.text)] if query.internal_ip_address?
31
+ doc = fetch_data(query) || {}
32
+ doc.fetch("data", {})["location"] ? [doc] : []
33
+ end
34
+
35
+ def reserved_result(ip)
36
+ {
37
+ "data" => {
38
+ "ip" => ip,
39
+ "location" => {
40
+ "city" => { "name" => "" },
41
+ "country" => { "alpha2" => "RD", "name" => "Reserved" },
42
+ "region" => { "alpha2" => "", "name" => "" },
43
+ "zip" => ""
44
+ }
45
+ }
46
+ }
47
+ end
48
+ end
49
+ end
@@ -11,6 +11,10 @@ module Geocoder::Lookup
11
11
  ["api_key"]
12
12
  end
13
13
 
14
+ def supported_protocols
15
+ [:https]
16
+ end
17
+
14
18
  private # ----------------------------------------------------------------
15
19
 
16
20
  def base_query_url(query)
@@ -25,7 +29,7 @@ module Geocoder::Lookup
25
29
  end
26
30
 
27
31
  def configured_host
28
- configuration[:host] || "locationiq.org"
32
+ configuration[:host] || "us1.locationiq.com"
29
33
  end
30
34
 
31
35
  def results(query)
@@ -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}"
@@ -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
@@ -24,11 +24,11 @@ module Geocoder::Lookup
24
24
 
25
25
  def results(query)
26
26
  return [] unless doc = fetch_data(query)
27
- if err = doc['error']
28
- if err["status"] == 401 and err["message"] == "invalid key"
27
+ if [400, 403].include? doc['statusCode']
28
+ if doc['statusCode'] == 403 and doc['message'] == 'Invalid key'
29
29
  raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid API key.")
30
30
  else
31
- Geocoder.log(:warn, "Yandex Geocoding API error: #{err['status']} (#{err['message']}).")
31
+ Geocoder.log(:warn, "Yandex Geocoding API error: #{doc['statusCode']} (#{doc['message']}).")
32
32
  end
33
33
  return []
34
34
  end
@@ -7,76 +7,71 @@ module Geocoder::Result
7
7
  # A string in the given format.
8
8
  #
9
9
  def address(format = :full)
10
- address_data['Label']
10
+ address_data["label"]
11
11
  end
12
12
 
13
13
  ##
14
14
  # A two-element array: [lat, lon].
15
15
  #
16
16
  def coordinates
17
- fail unless d = @data['Location']['DisplayPosition']
18
- [d['Latitude'].to_f, d['Longitude'].to_f]
17
+ fail unless d = @data["position"]
18
+ [d["lat"].to_f, d["lng"].to_f]
19
19
  end
20
20
 
21
21
  def route
22
- address_data['Street']
22
+ address_data["street"]
23
23
  end
24
24
 
25
25
  def street_number
26
- address_data['HouseNumber']
26
+ address_data["houseNumber"]
27
27
  end
28
28
 
29
29
  def state
30
- fail unless d = address_data['AdditionalData']
31
- if v = d.find{|ad| ad['key']=='StateName'}
32
- return v['value']
33
- end
30
+ address_data["state"]
34
31
  end
35
32
 
36
33
  def province
37
- address_data['County']
34
+ address_data["county"]
38
35
  end
39
36
 
40
37
  def postal_code
41
- address_data['PostalCode']
38
+ address_data["postalCode"]
42
39
  end
43
40
 
44
41
  def city
45
- address_data['City']
42
+ address_data["city"]
46
43
  end
47
44
 
48
45
  def state_code
49
- address_data['State']
46
+ address_data["stateCode"]
50
47
  end
51
48
 
52
49
  def province_code
53
- address_data['State']
50
+ address_data["state"]
54
51
  end
55
52
 
56
53
  def country
57
- fail unless d = address_data['AdditionalData']
58
- if v = d.find{|ad| ad['key']=='CountryName'}
59
- return v['value']
60
- end
54
+ address_data["countryName"]
61
55
  end
62
56
 
63
57
  def country_code
64
- address_data['Country']
58
+ address_data["countryCode"]
65
59
  end
66
60
 
67
61
  def viewport
68
- map_view = data['Location']['MapView'] || fail
69
- south = map_view['BottomRight']['Latitude']
70
- west = map_view['TopLeft']['Longitude']
71
- north = map_view['TopLeft']['Latitude']
72
- east = map_view['BottomRight']['Longitude']
62
+ return [] if data["resultType"] == "place"
63
+ map_view = data["mapView"]
64
+ south = map_view["south"]
65
+ west = map_view["west"]
66
+ north = map_view["north"]
67
+ east = map_view["east"]
73
68
  [south, west, north, east]
74
69
  end
75
70
 
76
71
  private # ----------------------------------------------------------------
77
72
 
78
73
  def address_data
79
- @data['Location']['Address'] || fail
74
+ @data["address"] || fail
80
75
  end
81
76
  end
82
77
  end
@@ -0,0 +1,40 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Ipbase < Base
5
+ def ip
6
+ @data["data"]['ip']
7
+ end
8
+
9
+ def country_code
10
+ @data["data"]["location"]["country"]["alpha2"]
11
+ end
12
+
13
+ def country
14
+ @data["data"]["location"]["country"]["name"]
15
+ end
16
+
17
+ def state_code
18
+ @data["data"]["location"]["region"]["alpha2"]
19
+ end
20
+
21
+ def state
22
+ @data["data"]["location"]["region"]["name"]
23
+ end
24
+
25
+ def city
26
+ @data["data"]["location"]["city"]["name"]
27
+ end
28
+
29
+ def postal_code
30
+ @data["data"]["location"]["zip"]
31
+ end
32
+
33
+ def coordinates
34
+ [
35
+ @data["data"]["location"]["latitude"].to_f,
36
+ @data["data"]["location"]["longitude"].to_f
37
+ ]
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,76 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Twogis < Base
5
+ def coordinates
6
+ ['lat', 'lon'].map{ |i| @data['point'][i] } if @data['point']
7
+ end
8
+
9
+ def address(_format = :full)
10
+ @data['full_address_name'] || ''
11
+ end
12
+
13
+ def city
14
+ return '' unless @data['adm_div']
15
+ @data['adm_div'].select{|u| u["type"] == "city"}.first.try(:[], 'name') || ''
16
+ end
17
+
18
+ def region
19
+ return '' unless @data['adm_div']
20
+ @data['adm_div'].select{|u| u["type"] == "region"}.first.try(:[], 'name') || ''
21
+ end
22
+
23
+ def country
24
+ return '' unless @data['adm_div']
25
+ @data['adm_div'].select{|u| u["type"] == "country"}.first.try(:[], 'name') || ''
26
+ end
27
+
28
+ def district
29
+ return '' unless @data['adm_div']
30
+ @data['adm_div'].select{|u| u["type"] == "district"}.first.try(:[], 'name') || ''
31
+ end
32
+
33
+ def district_area
34
+ return '' unless @data['adm_div']
35
+ @data['adm_div'].select{|u| u["type"] == "district_area"}.first.try(:[], 'name') || ''
36
+ end
37
+
38
+ def street_address
39
+ @data['address_name'] || ''
40
+ end
41
+
42
+ def street
43
+ return '' unless @data['address_name']
44
+ @data['address_name'].split(', ').first
45
+ end
46
+
47
+ def street_number
48
+ return '' unless @data['address_name']
49
+ @data['address_name'].split(', ')[1] || ''
50
+ end
51
+
52
+ def type
53
+ @data['type'] || ''
54
+ end
55
+
56
+ def purpose_name
57
+ @data['purpose_name'] || ''
58
+ end
59
+
60
+ def building_name
61
+ @data['building_name'] || ''
62
+ end
63
+
64
+ def subtype
65
+ @data['subtype'] || ''
66
+ end
67
+
68
+ def subtype_specification
69
+ @data['subtype_specification'] || ''
70
+ end
71
+
72
+ def name
73
+ @data['name'] || ''
74
+ end
75
+ end
76
+ end
@@ -1,3 +1,3 @@
1
1
  module Geocoder
2
- VERSION = "1.7.3"
2
+ VERSION = "1.8.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.7.3
4
+ version: 1.8.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: 2022-01-17 00:00:00.000000000 Z
11
+ date: 2022-09-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Object geocoding (by street or IP address), reverse geocoding (coordinates
14
14
  to street address), distance queries for ActiveRecord and Mongoid, result caching,
@@ -25,6 +25,7 @@ files:
25
25
  - README.md
26
26
  - bin/console
27
27
  - bin/geocode
28
+ - examples/app_defined_lookup_services.rb
28
29
  - examples/cache_bypass.rb
29
30
  - examples/reverse_geocode_job.rb
30
31
  - lib/easting_northing.rb
@@ -74,6 +75,7 @@ files:
74
75
  - lib/geocoder/lookups/here.rb
75
76
  - lib/geocoder/lookups/ip2location.rb
76
77
  - lib/geocoder/lookups/ipapi_com.rb
78
+ - lib/geocoder/lookups/ipbase.rb
77
79
  - lib/geocoder/lookups/ipdata_co.rb
78
80
  - lib/geocoder/lookups/ipgeolocation.rb
79
81
  - lib/geocoder/lookups/ipinfo_io.rb
@@ -102,6 +104,7 @@ files:
102
104
  - lib/geocoder/lookups/telize.rb
103
105
  - lib/geocoder/lookups/tencent.rb
104
106
  - lib/geocoder/lookups/test.rb
107
+ - lib/geocoder/lookups/twogis.rb
105
108
  - lib/geocoder/lookups/uk_ordnance_survey_names.rb
106
109
  - lib/geocoder/lookups/yandex.rb
107
110
  - lib/geocoder/models/active_record.rb
@@ -136,6 +139,7 @@ files:
136
139
  - lib/geocoder/results/here.rb
137
140
  - lib/geocoder/results/ip2location.rb
138
141
  - lib/geocoder/results/ipapi_com.rb
142
+ - lib/geocoder/results/ipbase.rb
139
143
  - lib/geocoder/results/ipdata_co.rb
140
144
  - lib/geocoder/results/ipgeolocation.rb
141
145
  - lib/geocoder/results/ipinfo_io.rb
@@ -164,6 +168,7 @@ files:
164
168
  - lib/geocoder/results/telize.rb
165
169
  - lib/geocoder/results/tencent.rb
166
170
  - lib/geocoder/results/test.rb
171
+ - lib/geocoder/results/twogis.rb
167
172
  - lib/geocoder/results/uk_ordnance_survey_names.rb
168
173
  - lib/geocoder/results/yandex.rb
169
174
  - lib/geocoder/sql.rb
@@ -198,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
198
203
  - !ruby/object:Gem::Version
199
204
  version: '0'
200
205
  requirements: []
201
- rubygems_version: 3.1.2
206
+ rubygems_version: 3.1.6
202
207
  signing_key:
203
208
  specification_version: 4
204
209
  summary: Complete geocoding solution for Ruby.