geocoder 1.8.1 → 1.8.3

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: 35c6a6d57b8ff3818e9d1b616558a8bbdc3b4b51db2b2c7dadb720eccafd27b4
4
- data.tar.gz: 8e8fe1ba7cb9da58131a965d3d85589084f4d5dd70409990f49b89b83923f4e3
3
+ metadata.gz: 447dfedeffcb5c111f6441badccf6d1c25c38a3a0fed32aaeb31151d27425a3d
4
+ data.tar.gz: 89b7f5b123d125ccb329d66f0172ef0a46d3176d6e215cc1a884b0a2249ae4cd
5
5
  SHA512:
6
- metadata.gz: 0bbf04cc8488a533038783e2d250706fb2d2439de8ea1e5bf4b89950d1dd51d5e9393454540a23cb4e7fbc33b58f54fec1c71c14c98d6fbe8bb8e5caad786989
7
- data.tar.gz: 92b8f5933a421b47cdededea9c8e8df8d2ec6f45cb25c8726b343a773b315929529fe821cae08868576ae2e8c5cdbc5fd1782bd2bfc8c56f36afdc1514f52b58
6
+ metadata.gz: a90b21dfcc3aeb50ac94fad6eafeec0141ba320bb638912b2e0091f80beb30b306f58cc104db8a55ab47cf8a5543edbabe9372dbda7c63dcbeb560c42b92a957
7
+ data.tar.gz: c0489e8f2b3c4d98cf40235e2b60fc5c8d129cd74aecc65f57bfd9adee7549db804fb0bcdf6b68c14933478fd3a0ea06124350208987a575c916a0992c28adb7
data/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@ 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.3 (2024 May 2)
7
+ -------------------
8
+ * Add support for IP2Location LITE lookup (thanks github.com/ip2location).
9
+ * Add support for PDOK NL lookup (thanks github.com/opensourceame).
10
+ * Remove support for Data Science Toolkit lookup (defunct).
11
+
12
+ 1.8.2 (2023 Jul 4)
13
+ -------------------
14
+ * Add support for PC Miler lookup (thanks github.com/alexdean).
15
+ * Minor fixes for :maxmind_local, :esri, and :ban_data_gouv_fr lookups.
16
+
6
17
  1.8.1 (2022 Sep 23)
7
18
  -------------------
8
19
  * Add support for IPBase lookup (thanks github.com/jonallured).
data/README.md CHANGED
@@ -5,7 +5,6 @@ Geocoder
5
5
 
6
6
  [![Gem Version](https://badge.fury.io/rb/geocoder.svg)](http://badge.fury.io/rb/geocoder)
7
7
  [![Code Climate](https://codeclimate.com/github/alexreisner/geocoder/badges/gpa.svg)](https://codeclimate.com/github/alexreisner/geocoder)
8
- [![Build Status](https://travis-ci.com/alexreisner/geocoder.svg?branch=master)](https://travis-ci.com/alexreisner/geocoder)
9
8
 
10
9
  Key features:
11
10
 
@@ -368,7 +367,7 @@ If you need to expire cached content:
368
367
  ```ruby
369
368
  Geocoder::Lookup.get(Geocoder.config[:lookup]).cache.expire(:all) # expire cached results for current Lookup
370
369
  Geocoder::Lookup.get(:nominatim).cache.expire("http://...") # expire cached result for a specific URL
371
- Geocoder::Lookup.get(:nominatim).cache.expire(:all) # expire cached results for Google Lookup
370
+ Geocoder::Lookup.get(:nominatim).cache.expire(:all) # expire cached results for Nominatim
372
371
  # expire all cached results for all Lookups.
373
372
  # Be aware that this methods spawns a new Lookup object for each Service
374
373
  Geocoder::Lookup.all_services.each{|service| Geocoder::Lookup.get(service).cache.expire(:all)}
@@ -376,10 +375,9 @@ Geocoder::Lookup.all_services.each{|service| Geocoder::Lookup.get(service).cache
376
375
 
377
376
  Do *not* include the prefix when passing a URL to be expired. Expiring `:all` will only expire keys with the configured prefix -- it will *not* expire every entry in your key/value store.
378
377
 
379
- For an example of a cache store with URL expiry, please see examples/autoexpire_cache.rb
380
-
381
378
  _Before you implement caching in your app please be sure that doing so does not violate the Terms of Service for your geocoding service._
382
379
 
380
+ Not all services support caching, [check the service limitations in the API guide for more information](https://github.com/alexreisner/geocoder/blob/master/README_API_GUIDE.md).
383
381
 
384
382
  Advanced Model Configuration
385
383
  ----------------------------
@@ -736,8 +734,34 @@ you should check your Gemfile to make sure the Mongoid gem is listed _before_ Ge
736
734
 
737
735
  A lot of debugging time can be saved by understanding how Geocoder works with ActiveRecord. When you use the `near` scope or the `nearbys` method of a geocoded object, Geocoder creates an ActiveModel::Relation object which adds some attributes (eg: distance, bearing) to the SELECT clause. It also adds a condition to the WHERE clause to check that distance is within the given radius. Because the SELECT clause is modified, anything else that modifies the SELECT clause may produce strange results, for example:
738
736
 
739
- * using the `pluck` method (selects only a single column)
740
- * specifying another model through `includes` (selects columns from other tables)
737
+ * using [`select` method (selects one or more columns)](https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-select)
738
+ * using the [`pluck` method (gets an array with selecting one or more columns)](https://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-pluck)
739
+ * The same problem will appear with [ActiveRecord's `ids` method](https://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-ids).
740
+ * specifying another model through [`includes` (selects columns from other tables)](https://api.rubyonrails.org/classes/ActiveRecord/QueryMethods.html#method-i-includes)
741
+ * See also Known Issues [using-near-with-includes](#using-near-with-select) section.
742
+
743
+ If you get an error in the above cases, try the following:
744
+
745
+ ```ruby
746
+ # Use the :select option with the near scope to get the columns you want.
747
+ # Instead of City.near(...).select(:id, :name), try:
748
+ City.near("Omaha, NE", 20, select: "id, name")
749
+
750
+ # Pass a :select option to the near scope to get the columns you want.
751
+ # Then, Ruby's built-in pluck method gets arrays you want.
752
+ # Instead of City.near(...).pluck(:id) or City.near(...).ids,, try:
753
+ City.near("Omaha, NE", 20, select: "id, name").to_a.pluck(:id, :name)
754
+ City.near("Omaha, NE", 20, select: "id").to_a.pluck(:id)
755
+
756
+ # Pass a :select option to the near scope to get the columns you want.
757
+ # Instead of City.near(...).includes(:venues), try:
758
+ City.near("Omaha, NE", 20, select: "cities.*, venues.*").joins(:venues)
759
+
760
+ # This preload call will normally trigger two queries regardless of the
761
+ # number of results; one query on hotels, and one query on administrators.
762
+ # Instead of Hotel.near(...).includes(:administrator), try:
763
+ Hotel.near("London, UK", 50).joins(:administrator).preload(:administrator)
764
+ ```
741
765
 
742
766
  ### Geocoding is Slow
743
767
 
@@ -4,7 +4,7 @@ module Geocoder
4
4
  class Cache
5
5
 
6
6
  def initialize(store, config)
7
- @class = (Object.const_get("Geocoder::CacheStore::#{store.class}") rescue Geocoder::CacheStore::Generic)
7
+ @class = (Geocoder::CacheStore.const_get("#{store.class}", false) rescue Geocoder::CacheStore::Generic)
8
8
  @store_service = @class.new(store, config)
9
9
  end
10
10
 
@@ -9,8 +9,11 @@ module Geocoder
9
9
 
10
10
  def initialize(ip)
11
11
  ip = ip.to_string if ip.is_a?(IPAddr)
12
-
13
- super(ip)
12
+ if ip.is_a?(Hash)
13
+ super(**ip)
14
+ else
15
+ super(ip)
16
+ end
14
17
  end
15
18
 
16
19
  def internal?
@@ -23,7 +23,7 @@ module Geocoder
23
23
  # For example, Amazon Location Service uses the AWS gem, not HTTP REST requests, to fetch data.
24
24
  #
25
25
  def all_services_with_http_requests
26
- all_services_except_test - [:amazon_location_service]
26
+ all_services_except_test - [:amazon_location_service, :maxmind_local, :geoip2, :ip2location_lite]
27
27
  end
28
28
 
29
29
  ##
@@ -32,7 +32,6 @@ module Geocoder
32
32
  def street_services
33
33
  @street_services ||= [
34
34
  :location_iq,
35
- :dstk,
36
35
  :esri,
37
36
  :google,
38
37
  :google_premier,
@@ -48,6 +47,7 @@ module Geocoder
48
47
  :uk_ordnance_survey_names,
49
48
  :opencagedata,
50
49
  :pelias,
50
+ :pdok_nl,
51
51
  :pickpoint,
52
52
  :here,
53
53
  :baidu,
@@ -66,7 +66,8 @@ module Geocoder
66
66
  :amazon_location_service,
67
67
  :geoapify,
68
68
  :photon,
69
- :twogis
69
+ :twogis,
70
+ :pc_miler
70
71
  ]
71
72
  end
72
73
 
@@ -93,7 +94,9 @@ module Geocoder
93
94
  :ip2location,
94
95
  :ipgeolocation,
95
96
  :ipqualityscore,
96
- :ipbase
97
+ :ipbase,
98
+ :ip2location_io,
99
+ :ip2location_lite
97
100
  ]
98
101
  end
99
102
 
@@ -19,7 +19,7 @@ module Geocoder::Lookup
19
19
  client.search_place_index_for_text(params.merge(text: query.text))
20
20
  end
21
21
 
22
- resp.results.map(&:place)
22
+ resp.results
23
23
  end
24
24
 
25
25
  private
@@ -29,10 +29,11 @@ module Geocoder::Lookup
29
29
  require_sdk
30
30
  keys = configuration.api_key
31
31
  if keys
32
- @client = Aws::LocationService::Client.new(
32
+ @client = Aws::LocationService::Client.new(**{
33
+ region: keys[:region],
33
34
  access_key_id: keys[:access_key_id],
34
- secret_access_key: keys[:secret_access_key],
35
- )
35
+ secret_access_key: keys[:secret_access_key]
36
+ }.compact)
36
37
  else
37
38
  @client = Aws::LocationService::Client.new
38
39
  end
@@ -125,7 +125,7 @@ module Geocoder::Lookup
125
125
  end
126
126
 
127
127
  def type_param_is_valid?(param)
128
- %w(housenumber street locality village town city).include?(param.downcase)
128
+ %w(housenumber street locality municipality).include?(param.downcase)
129
129
  end
130
130
 
131
131
  def code_param_is_valid?(param)
@@ -23,15 +23,28 @@ module Geocoder::Lookup
23
23
  def results(query)
24
24
  return [] unless doc = fetch_data(query)
25
25
 
26
- if (!query.reverse_geocode?)
27
- return [] if !doc['locations'] || doc['locations'].empty?
28
- end
29
-
30
26
  if (doc['error'].nil?)
27
+ if (!query.reverse_geocode?)
28
+ return [] if !doc['locations'] || doc['locations'].empty?
29
+ end
31
30
  return [ doc ]
32
31
  else
33
- return []
32
+ case [ doc['error']['code'] ]
33
+ when [498]
34
+ raise_error(Geocoder::InvalidApiKey, doc['error']['message']) ||
35
+ Geocoder.log(:warn, "#{self.name} Geocoding API error: #{doc['error']['message']}")
36
+ when [ 403 ]
37
+ raise_error(Geocoder::RequestDenied, 'ESRI request denied') ||
38
+ Geocoder.log(:warn, "#{self.name} ESRI request denied: #{doc['error']['message']}")
39
+ when [ 500 ], [501]
40
+ raise_error(Geocoder::ServiceUnavailable, 'ESRI service unavailable') ||
41
+ Geocoder.log(:warn, "#{self.name} ESRI service error: #{doc['error']['message']}")
42
+ else
43
+ raise_error(Geocoder::Error, doc['error']['message']) ||
44
+ Geocoder.log(:warn, "#{self.name} Geocoding error: #{doc['error']['message']}")
45
+ end
34
46
  end
47
+ return []
35
48
  end
36
49
 
37
50
  def query_url_params(query)
@@ -49,12 +49,11 @@ module Geocoder
49
49
  end
50
50
 
51
51
  def default_fields
52
- legacy = %w[id reference]
53
52
  basic = %w[business_status formatted_address geometry icon name
54
53
  photos place_id plus_code types]
55
54
  contact = %w[opening_hours]
56
55
  atmosphere = %W[price_level rating user_ratings_total]
57
- format_fields(legacy, basic, contact, atmosphere)
56
+ format_fields(basic, contact, atmosphere)
58
57
  end
59
58
 
60
59
  def format_fields(*fields)
@@ -0,0 +1,62 @@
1
+ require 'geocoder/lookups/base'
2
+ require 'geocoder/results/ip2location_io'
3
+
4
+ module Geocoder::Lookup
5
+ class Ip2locationIo < Base
6
+
7
+ def name
8
+ "IP2LocationIOApi"
9
+ end
10
+
11
+ def required_api_key_parts
12
+ ['key']
13
+ end
14
+
15
+ def supported_protocols
16
+ [:http, :https]
17
+ end
18
+
19
+ private # ----------------------------------------------------------------
20
+
21
+ def base_query_url(query)
22
+ "#{protocol}://api.ip2location.io/?"
23
+ end
24
+
25
+ def query_url_params(query)
26
+ super.merge(
27
+ key: configuration.api_key,
28
+ ip: query.sanitized_text,
29
+ )
30
+ end
31
+
32
+ def results(query)
33
+ # don't look up a loopback or private address, just return the stored result
34
+ return [reserved_result(query.text)] if query.internal_ip_address?
35
+ return [] unless doc = fetch_data(query)
36
+ if doc["response"] == "INVALID ACCOUNT"
37
+ raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "INVALID ACCOUNT")
38
+ return []
39
+ else
40
+ return [doc]
41
+ end
42
+ end
43
+
44
+ def reserved_result(query)
45
+ {
46
+ "ip" => "-",
47
+ "country_code" => "-",
48
+ "country_name" => "-",
49
+ "region_name" => "-",
50
+ "city_name" => "-",
51
+ "latitude" => null,
52
+ "longitude" => null,
53
+ "zip_code" => "-",
54
+ "time_zone" => "-",
55
+ "asn" => "-",
56
+ "as" => "-",
57
+ "is_proxy" => false
58
+ }
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,40 @@
1
+ require 'geocoder/lookups/base'
2
+ require 'geocoder/results/ip2location_lite'
3
+
4
+ module Geocoder
5
+ module Lookup
6
+ class Ip2locationLite < Base
7
+ attr_reader :gem_name
8
+
9
+ def initialize
10
+ unless configuration[:file].nil?
11
+ begin
12
+ @gem_name = 'ip2location_ruby'
13
+ require @gem_name
14
+ rescue LoadError
15
+ raise "Could not load IP2Location DB dependency. To use the IP2LocationLite lookup you must add the #{@gem_name} gem to your Gemfile or have it installed in your system."
16
+ end
17
+ end
18
+ super
19
+ end
20
+
21
+ def name
22
+ 'IP2LocationLite'
23
+ end
24
+
25
+ def required_api_key_parts
26
+ []
27
+ end
28
+
29
+ private
30
+
31
+ def results(query)
32
+ return [] unless configuration[:file]
33
+
34
+ i2l = Ip2location.new.open(configuration[:file].to_s)
35
+ result = i2l.get_all(query.to_s)
36
+ result.nil? ? [] : [result]
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,85 @@
1
+ require 'geocoder/lookups/base'
2
+ require "geocoder/results/pc_miler"
3
+ require 'cgi' unless defined?(CGI) && defined?(CGI.escape)
4
+
5
+ module Geocoder::Lookup
6
+ class PcMiler < Base
7
+
8
+ # https://developer.trimblemaps.com/restful-apis/location/single-search/single-search-api/#test-the-api-now
9
+ def valid_region_codes
10
+ # AF: Africa
11
+ # AS: Asia
12
+ # EU: Europe
13
+ # NA: North America
14
+ # OC: Oceania
15
+ # SA: South America
16
+ %w[AF AS EU NA OC SA]
17
+ end
18
+
19
+ def name
20
+ "PCMiler"
21
+ end
22
+
23
+ private # ---------------------------------------------------------------
24
+
25
+ def base_query_url(query)
26
+ region_code = region(query)
27
+ if !valid_region_codes.include?(region_code)
28
+ raise "region_code '#{region_code}' is invalid. use one of #{valid_region_codes}." \
29
+ "https://developer.trimblemaps.com/restful-apis/location/single-search/single-search-api/#test-the-api-now"
30
+ end
31
+
32
+ "#{protocol}://singlesearch.alk.com/#{region_code}/api/search?"
33
+ end
34
+
35
+ def results(query)
36
+ return [] unless data = fetch_data(query)
37
+ if data['Locations']
38
+ add_metadata_to_locations!(data)
39
+ data['Locations']
40
+ else
41
+ []
42
+ end
43
+ end
44
+
45
+ def add_metadata_to_locations!(data)
46
+ confidence = data['QueryConfidence']
47
+ data['Locations'].each do |location|
48
+ location['QueryConfidence'] = confidence
49
+ end
50
+ end
51
+
52
+ def query_url_params(query)
53
+ if query.reverse_geocode?
54
+ lat,lon = query.coordinates
55
+ formatted_query = "#{CGI.escape(lat)},#{CGI.escape(lon)}"
56
+ else
57
+ formatted_query = query.text.to_s
58
+ end
59
+
60
+ {
61
+ authToken: configuration.api_key,
62
+ query: formatted_query,
63
+ # to add additional metadata to response such as QueryConfidence
64
+ include: 'Meta'
65
+ }.merge(super(query))
66
+ end
67
+
68
+ def region(query)
69
+ query.options[:region] || query.options['region'] || configuration[:region] || "NA"
70
+ end
71
+
72
+ def check_response_for_errors!(response)
73
+ if response.code.to_i == 403
74
+ raise_error(Geocoder::RequestDenied) ||
75
+ Geocoder.log(:warn, "Geocoding API error: 403 API key does not exist")
76
+ else
77
+ super(response)
78
+ end
79
+ end
80
+
81
+ def supported_protocols
82
+ [:https]
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,43 @@
1
+ require 'geocoder/lookups/base'
2
+ require "geocoder/results/pdok_nl"
3
+
4
+ module Geocoder::Lookup
5
+ class PdokNl < Base
6
+
7
+ def name
8
+ 'pdok NL'
9
+ end
10
+
11
+ def supported_protocols
12
+ [:https]
13
+ end
14
+
15
+ private # ---------------------------------------------------------------
16
+
17
+ def cache_key(query)
18
+ base_query_url(query) + hash_to_query(query_url_params(query))
19
+ end
20
+
21
+ def base_query_url(query)
22
+ "#{protocol}://api.pdok.nl/bzk/locatieserver/search/v3_1/free?"
23
+ end
24
+
25
+ def valid_response?(response)
26
+ json = parse_json(response.body)
27
+ super(response) if json
28
+ end
29
+
30
+ def results(query)
31
+ return [] unless doc = fetch_data(query)
32
+ return doc['response']['docs']
33
+ end
34
+
35
+ def query_url_params(query)
36
+ {
37
+ fl: '*',
38
+ q: query.text,
39
+ wt: 'json'
40
+ }.merge(super)
41
+ end
42
+ end
43
+ end
@@ -3,7 +3,8 @@ require 'geocoder/results/base'
3
3
  module Geocoder::Result
4
4
  class AmazonLocationService < Base
5
5
  def initialize(result)
6
- @place = result
6
+ @place = result.place
7
+ super
7
8
  end
8
9
 
9
10
  def coordinates
@@ -53,5 +54,9 @@ module Geocoder::Result
53
54
  def country_code
54
55
  @place.country
55
56
  end
57
+
58
+ def place_id
59
+ data.place_id if data.respond_to?(:place_id)
60
+ end
56
61
  end
57
62
  end
@@ -275,7 +275,7 @@ module Geocoder::Result
275
275
  private
276
276
 
277
277
  def city?(result_type)
278
- %w(village town city).include?(result_type)
278
+ result_type == 'municipality'
279
279
  end
280
280
 
281
281
  end
@@ -0,0 +1,21 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Ip2locationIo < Base
5
+
6
+ def address(format = :full)
7
+ "#{city_name} #{zip_code}, #{country_name}".sub(/^[ ,]*/, '')
8
+ end
9
+
10
+ def self.response_attributes
11
+ %w[ip country_code country_name region_name city_name latitude longitude
12
+ zip_code time_zone asn as is_proxy]
13
+ end
14
+
15
+ response_attributes.each do |attr|
16
+ define_method attr do
17
+ @data[attr] || ""
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class Ip2locationLite < Base
5
+
6
+ def coordinates
7
+ [@data[:latitude], @data[:longitude]]
8
+ end
9
+
10
+ def city
11
+ @data[:city]
12
+ end
13
+
14
+ def state
15
+ @data[:region]
16
+ end
17
+
18
+ def state_code
19
+ "" # Not available in Maxmind's database
20
+ end
21
+
22
+ def country
23
+ @data[:country_long]
24
+ end
25
+
26
+ def country_code
27
+ @data[:country_short]
28
+ end
29
+
30
+ def postal_code
31
+ @data[:zipcode]
32
+ end
33
+
34
+ def self.response_attributes
35
+ %w[country_short country_long region latitude longitude isp
36
+ domain netspeed areacode iddcode timezone zipcode weatherstationname
37
+ weatherstationcode mcc mnc mobilebrand elevation usagetype addresstype
38
+ category district asn as]
39
+ end
40
+
41
+ response_attributes.each do |a|
42
+ define_method a do
43
+ @data[a] || ""
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,98 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class PcMiler < Base
5
+ # sample response:
6
+ # https://singlesearch.alk.com/na/api/search?authToken=<TOKEN>&include=Meta&query=Feasterville
7
+ #
8
+ # {
9
+ # "Err": 0,
10
+ # "ErrString": "OK",
11
+ # "QueryConfidence": 1,
12
+ # "TimeInMilliseconds": 93,
13
+ # "GridDataVersion": "GRD_ALK.NA.2023.01.18.29.1.1",
14
+ # "CommitID": "pcmws-22.08.11.0-1778-g586da49bd1b: 05/30/2023 20:14",
15
+ # "Locations": [
16
+ # {
17
+ # "Address": {
18
+ # "StreetAddress": "",
19
+ # "LocalArea": "",
20
+ # "City": "Feasterville",
21
+ # "State": "PA",
22
+ # "StateName": "Pennsylvania",
23
+ # "Zip": "19053",
24
+ # "County": "Bucks",
25
+ # "Country": "US",
26
+ # "CountryFullName": "United States",
27
+ # "SPLC": null
28
+ # },
29
+ # "Coords": {
30
+ # "Lat": "40.150025",
31
+ # "Lon": "-75.002511"
32
+ # },
33
+ # "StreetCoords": {
34
+ # "Lat": "40.150098",
35
+ # "Lon": "-75.002827"
36
+ # },
37
+ # "Region": 4,
38
+ # "POITypeID": 0,
39
+ # "PersistentPOIID": -1,
40
+ # "SiteID": -1,
41
+ # "ResultType": 4,
42
+ # "ShortString": "Feasterville",
43
+ # "GridID": 37172748,
44
+ # "LinkID": 188,
45
+ # "Percent": 6291,
46
+ # "TimeZone": "GMT-4:00 EDT"
47
+ # }
48
+ # ]
49
+ # }
50
+
51
+ def address(format=:unused)
52
+ [street, city, state, postal_code, country]
53
+ .map { |i| i == '' ? nil : i }
54
+ .compact
55
+ .join(', ')
56
+ end
57
+
58
+ def coordinates
59
+ coords = data["Coords"] || {}
60
+ [coords["Lat"].to_f, coords["Lon"].to_f]
61
+ end
62
+
63
+ def street
64
+ address_data["StreetAddress"]
65
+ end
66
+
67
+ def city
68
+ address_data["City"]
69
+ end
70
+
71
+ def state
72
+ address_data["StateName"]
73
+ end
74
+
75
+ def state_code
76
+ address_data["State"]
77
+ end
78
+
79
+ def postal_code
80
+ address_data["Zip"]
81
+ end
82
+
83
+ def country
84
+ address_data["CountryFullName"]
85
+ end
86
+
87
+ def country_code
88
+ address_data["Country"]
89
+ end
90
+
91
+ private
92
+
93
+ def address_data
94
+ data["Address"] || {}
95
+ end
96
+ end
97
+ end
98
+
@@ -0,0 +1,62 @@
1
+ require 'geocoder/results/base'
2
+
3
+ module Geocoder::Result
4
+ class PdokNl < 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
@@ -1,3 +1,3 @@
1
1
  module Geocoder
2
- VERSION = "1.8.1"
2
+ VERSION = "1.8.3"
3
3
  end
@@ -6,9 +6,9 @@ module Geocoder
6
6
  extend self
7
7
 
8
8
  def download(package, dir = "tmp")
9
- filepath = File.expand_path(File.join(dir, archive_filename(package)))
9
+ filepath = File.expand_path(File.join(dir, "#{archive_edition(package)}.zip"))
10
10
  open(filepath, 'wb') do |file|
11
- uri = URI.parse(archive_url(package))
11
+ uri = URI.parse(base_url(package))
12
12
  Net::HTTP.start(uri.host, uri.port) do |http|
13
13
  http.request_get(uri.path) do |resp|
14
14
  # TODO: show progress
@@ -35,6 +35,14 @@ module Geocoder
35
35
  p[s..-1]
36
36
  end
37
37
 
38
+ def archive_edition(package)
39
+ {
40
+ geolite_country_csv: "GeoLite2-Country-CSV",
41
+ geolite_city_csv: "GeoLite2-City-CSV",
42
+ geolite_asn_csv: "GeoLite2-ASN-CSV"
43
+ }[package]
44
+ end
45
+
38
46
  private # -------------------------------------------------------------
39
47
 
40
48
  def table_columns(table_name)
@@ -94,16 +102,8 @@ module Geocoder
94
102
  base_url + archive_url_path(package)
95
103
  end
96
104
 
97
- def archive_url_path(package)
98
- {
99
- geolite_country_csv: "GeoLite2-Country-CSV.zip",
100
- geolite_city_csv: "GeoLite2-City-CSV.zip",
101
- geolite_asn_csv: "GeoLite2-ASN-CSV.zip"
102
- }[package]
103
- end
104
-
105
- def base_url
106
- "http://geolite.maxmind.com/download/geoip/database/"
105
+ def base_url(edition)
106
+ "https://download.maxmind.com/app/geoip_download?edition_id=#{edition}&license_key=#{ENV['LICENSE_KEY']}&suffix=zip"
107
107
  end
108
108
  end
109
109
  end
@@ -54,7 +54,7 @@ module MaxmindTask
54
54
  end
55
55
  require 'fileutils'
56
56
  p = "geolite_#{package}_csv".intern
57
- archive_filename = Geocoder::MaxmindDatabase.archive_filename(p)
57
+ archive_filename = "#{Geocoder::MaxmindDatabase.archive_edition(p)}.zip"
58
58
  Zip::File.open(File.join(options[:dir], archive_filename)).each do |entry|
59
59
  filepath = File.join(options[:dir], entry.name)
60
60
  if File.exist? filepath
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geocoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
4
+ version: 1.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Reisner
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-23 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2024-05-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: base64
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: csv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.0
13
41
  description: Object geocoding (by street or IP address), reverse geocoding (coordinates
14
42
  to street address), distance queries for ActiveRecord and Mongoid, result caching,
15
43
  and more. Designed for Rails but works with Sinatra and other Rack frameworks too.
@@ -60,7 +88,6 @@ files:
60
88
  - lib/geocoder/lookups/base.rb
61
89
  - lib/geocoder/lookups/bing.rb
62
90
  - lib/geocoder/lookups/db_ip_com.rb
63
- - lib/geocoder/lookups/dstk.rb
64
91
  - lib/geocoder/lookups/esri.rb
65
92
  - lib/geocoder/lookups/freegeoip.rb
66
93
  - lib/geocoder/lookups/geoapify.rb
@@ -74,6 +101,8 @@ files:
74
101
  - lib/geocoder/lookups/google_premier.rb
75
102
  - lib/geocoder/lookups/here.rb
76
103
  - lib/geocoder/lookups/ip2location.rb
104
+ - lib/geocoder/lookups/ip2location_io.rb
105
+ - lib/geocoder/lookups/ip2location_lite.rb
77
106
  - lib/geocoder/lookups/ipapi_com.rb
78
107
  - lib/geocoder/lookups/ipbase.rb
79
108
  - lib/geocoder/lookups/ipdata_co.rb
@@ -94,6 +123,8 @@ files:
94
123
  - lib/geocoder/lookups/nominatim.rb
95
124
  - lib/geocoder/lookups/opencagedata.rb
96
125
  - lib/geocoder/lookups/osmnames.rb
126
+ - lib/geocoder/lookups/pc_miler.rb
127
+ - lib/geocoder/lookups/pdok_nl.rb
97
128
  - lib/geocoder/lookups/pelias.rb
98
129
  - lib/geocoder/lookups/photon.rb
99
130
  - lib/geocoder/lookups/pickpoint.rb
@@ -124,7 +155,6 @@ files:
124
155
  - lib/geocoder/results/base.rb
125
156
  - lib/geocoder/results/bing.rb
126
157
  - lib/geocoder/results/db_ip_com.rb
127
- - lib/geocoder/results/dstk.rb
128
158
  - lib/geocoder/results/esri.rb
129
159
  - lib/geocoder/results/freegeoip.rb
130
160
  - lib/geocoder/results/geoapify.rb
@@ -138,6 +168,8 @@ files:
138
168
  - lib/geocoder/results/google_premier.rb
139
169
  - lib/geocoder/results/here.rb
140
170
  - lib/geocoder/results/ip2location.rb
171
+ - lib/geocoder/results/ip2location_io.rb
172
+ - lib/geocoder/results/ip2location_lite.rb
141
173
  - lib/geocoder/results/ipapi_com.rb
142
174
  - lib/geocoder/results/ipbase.rb
143
175
  - lib/geocoder/results/ipdata_co.rb
@@ -158,6 +190,8 @@ files:
158
190
  - lib/geocoder/results/nominatim.rb
159
191
  - lib/geocoder/results/opencagedata.rb
160
192
  - lib/geocoder/results/osmnames.rb
193
+ - lib/geocoder/results/pc_miler.rb
194
+ - lib/geocoder/results/pdok_nl.rb
161
195
  - lib/geocoder/results/pelias.rb
162
196
  - lib/geocoder/results/photon.rb
163
197
  - lib/geocoder/results/pickpoint.rb
@@ -188,7 +222,7 @@ licenses:
188
222
  metadata:
189
223
  source_code_uri: https://github.com/alexreisner/geocoder
190
224
  changelog_uri: https://github.com/alexreisner/geocoder/blob/master/CHANGELOG.md
191
- post_install_message:
225
+ post_install_message:
192
226
  rdoc_options: []
193
227
  require_paths:
194
228
  - lib
@@ -203,8 +237,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
203
237
  - !ruby/object:Gem::Version
204
238
  version: '0'
205
239
  requirements: []
206
- rubygems_version: 3.1.6
207
- signing_key:
240
+ rubygems_version: 3.3.26
241
+ signing_key:
208
242
  specification_version: 4
209
243
  summary: Complete geocoding solution for Ruby.
210
244
  test_files: []
@@ -1,22 +0,0 @@
1
- # More information about the Data Science Toolkit can be found at:
2
- # http://www.datasciencetoolkit.org/. The provided APIs mimic the
3
- # Google geocoding api.
4
-
5
- require 'geocoder/lookups/google'
6
- require 'geocoder/results/dstk'
7
-
8
- module Geocoder::Lookup
9
- class Dstk < Google
10
-
11
- def name
12
- "Data Science Toolkit"
13
- end
14
-
15
- private # ----------------------------------------------------------------
16
-
17
- def base_query_url(query)
18
- host = configuration[:host] || "www.datasciencetoolkit.org"
19
- "#{protocol}://#{host}/maps/api/geocode/json?"
20
- end
21
- end
22
- end
@@ -1,6 +0,0 @@
1
- require 'geocoder/results/google'
2
-
3
- module Geocoder::Result
4
- class Dstk < Google
5
- end
6
- end