geokit-rails 2.1.0 → 2.2.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.
Potentially problematic release.
This version of geokit-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/README.markdown +21 -23
- data/gemfiles/rails3.gemfile +2 -6
- data/gemfiles/rails4.gemfile +4 -7
- data/geokit-rails.gemspec +1 -0
- data/lib/generators/geokit_rails/install_generator.rb +13 -0
- data/lib/generators/templates/geokit_config.rb +100 -0
- data/lib/geokit-rails.rb +0 -1
- data/lib/geokit-rails/acts_as_mappable.rb +28 -12
- data/lib/geokit-rails/geocoder_control.rb +4 -2
- data/lib/geokit-rails/ip_geocode_lookup.rb +17 -13
- data/lib/geokit-rails/railtie.rb +0 -1
- data/lib/geokit-rails/version.rb +1 -1
- data/test/acts_as_mappable_test.rb +6 -6
- data/test/boot.rb +0 -1
- data/test/fixtures/custom_locations.yml +8 -1
- data/test/fixtures/locations.yml +8 -1
- data/test/test_helper.rb +10 -4
- metadata +19 -4
- data/lib/geokit-rails/defaults.rb +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea862dfaa5a3d928db10ab95a7c65c5fce23491c
|
4
|
+
data.tar.gz: 6ffd65c47a279ed164c7d875078dc44d5d28ff78
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f6b87d14fc319e5331327953f683201a08c164529ff2b5d2a52ed1ca266af0878b22453901405da5cb79576319b7f2bc40c2e8d6d66efbbd43abccde3069497
|
7
|
+
data.tar.gz: c60c6c131318bd68e34388250fb41a3c2934fd79e84a971c8946a6dc26e48dd1769928c4edba763d15e5c8b4251ae206321ceb671809319c8279735a8874186e
|
data/.travis.yml
CHANGED
data/README.markdown
CHANGED
@@ -3,7 +3,7 @@ Geokit Rails
|
|
3
3
|
|
4
4
|
[](http://badge.fury.io/rb/geokit-rails)
|
5
5
|
[](https://travis-ci.org/geokit/geokit-rails)
|
6
|
-
[](https://coveralls.io/r/geokit/geokit-rails)
|
6
|
+
[](https://coveralls.io/r/geokit/geokit-rails)
|
7
7
|
[](https://gemnasium.com/geokit/geokit-rails)
|
8
8
|
[](https://codeclimate.com/github/geokit/geokit-rails)
|
9
9
|
|
@@ -49,7 +49,7 @@ Geokit provides key functionality for location-oriented Rails applications:
|
|
49
49
|
in your database within a 50-mile radius.
|
50
50
|
- IP-based location lookup utilizing hostip.info. Provide an IP address, and get
|
51
51
|
city name and latitude/longitude in return
|
52
|
-
- A
|
52
|
+
- A before_action helper to geocoder the user's location based on IP address,
|
53
53
|
and retain the location in a cookie.
|
54
54
|
- Geocoding from multiple providers. It provides a fail-over mechanism, in case
|
55
55
|
your input fails to geocode in one service. Geocoding is provided by the Geokit
|
@@ -90,7 +90,7 @@ end
|
|
90
90
|
|
91
91
|
The optional parameters are `units`, `formula`, and `distance_field_name`.
|
92
92
|
Values for **units** can be `:miles`, `:kms` (kilometers), or `:nms` (nautical miles),
|
93
|
-
with `:miles` as the default.
|
93
|
+
with `:miles` as the default.
|
94
94
|
Values for **formula** can be `:sphere` or `:flat` with `:sphere` as the default.
|
95
95
|
`:sphere` gives you Haversine calculations, while `:flat` gives the Pythagoreum Theory.
|
96
96
|
These defaults persist through out the gem.
|
@@ -122,13 +122,13 @@ A few examples :
|
|
122
122
|
Location.within(5, :origin => @somewhere)
|
123
123
|
# is the same as
|
124
124
|
Location.geo_scope(:within => 5, :origin => @somewhere)
|
125
|
-
```
|
125
|
+
```
|
126
126
|
|
127
127
|
```ruby
|
128
128
|
Location.in_range(2..5, :origin => @somewhere)
|
129
129
|
# is the same as
|
130
130
|
Location.geo_scope(:range => 2..5, :origin => @somewhere)
|
131
|
-
```
|
131
|
+
```
|
132
132
|
|
133
133
|
```ruby
|
134
134
|
Location.in_bounds([@south_west_point, @north_east_point], :origin => @somewhere)
|
@@ -242,7 +242,7 @@ One would expect to build a query like this :
|
|
242
242
|
|
243
243
|
```ruby
|
244
244
|
scoped = Location.geo_scope(:origin => @somewhere)
|
245
|
-
scoped = scoped.where('distance <= 5)
|
245
|
+
scoped = scoped.where('distance <= 5')
|
246
246
|
results = scoped.all
|
247
247
|
```
|
248
248
|
|
@@ -390,7 +390,7 @@ Ordering is done through `Geokit::Geocoders::provider_order` and
|
|
390
390
|
## IP GEOCODING HELPER
|
391
391
|
|
392
392
|
A class method called geocode_ip_address has been mixed into the
|
393
|
-
ActionController::Base. This enables
|
393
|
+
ActionController::Base. This enables before_action style lookup of
|
394
394
|
the IP address. Since it is a filter, it can accept any of the
|
395
395
|
available filter options.
|
396
396
|
|
@@ -585,20 +585,20 @@ A few quick examples to get you started ....
|
|
585
585
|
datatypes to store your latitude/longitude
|
586
586
|
|
587
587
|
2. use `acts_as_mappable` on your store model:
|
588
|
-
3.
|
588
|
+
3.
|
589
589
|
```ruby
|
590
590
|
class Store < ActiveRecord::Base
|
591
591
|
acts_as_mappable
|
592
592
|
...
|
593
593
|
end
|
594
594
|
```
|
595
|
-
|
595
|
+
|
596
596
|
3. finders now have extra capabilities:
|
597
|
-
|
597
|
+
|
598
598
|
```ruby
|
599
599
|
Store.find(:all, :origin =>[32.951613,-96.958444], :within=>10)
|
600
600
|
```
|
601
|
-
|
601
|
+
|
602
602
|
## How to geocode an address
|
603
603
|
|
604
604
|
1. configure your geocoder key(s) in `config/initializers/geokit_config.rb`
|
@@ -610,7 +610,7 @@ A few quick examples to get you started ....
|
|
610
610
|
```ruby
|
611
611
|
Geokit::Geocoders::provider_order=[:google]
|
612
612
|
```
|
613
|
-
|
613
|
+
|
614
614
|
3. Test it out in script/console
|
615
615
|
|
616
616
|
```ruby
|
@@ -620,7 +620,7 @@ A few quick examples to get you started ....
|
|
620
620
|
puts res.lng
|
621
621
|
puts res.full_address
|
622
622
|
```
|
623
|
-
|
623
|
+
|
624
624
|
... etc. The return type is GeoLoc, see the API for
|
625
625
|
all the methods you can call on it.
|
626
626
|
|
@@ -636,13 +636,13 @@ A few quick examples to get you started ....
|
|
636
636
|
```ruby
|
637
637
|
Store.find(:all, :origin=>'100 Spear st, San Francisco, CA', :within=>10)
|
638
638
|
```
|
639
|
-
|
639
|
+
|
640
640
|
4. you can also use a zipcode, or anything else that's geocodable:
|
641
641
|
|
642
642
|
```ruby
|
643
643
|
Store.find(:all, :origin=>'94117', :conditions=>'distance<10')
|
644
644
|
```
|
645
|
-
|
645
|
+
|
646
646
|
## How to sort a query by distance from an origin
|
647
647
|
|
648
648
|
You now have access to a 'distance' column, and you can use it
|
@@ -690,7 +690,7 @@ end
|
|
690
690
|
## Database Compatability
|
691
691
|
|
692
692
|
* Geokit works with MySQL (tested with version 5.0.41), PostgreSQL (tested with version 8.2.6) and Microsoft SQL Server (tested with 2000).
|
693
|
-
* Geokit is known to *not* work with Postgres versions under 8.1 -- it uses the least()
|
693
|
+
* Geokit is known to *not* work with Postgres versions under 8.1 -- it uses the least() function.
|
694
694
|
|
695
695
|
|
696
696
|
## HIGH-LEVEL NOTES ON WHAT'S WHERE
|
@@ -699,7 +699,7 @@ end
|
|
699
699
|
module which gets mixed into your models to provide the
|
700
700
|
location-based finder goodness.
|
701
701
|
|
702
|
-
`ip_geocode_lookup.rb` contains the
|
702
|
+
`ip_geocode_lookup.rb` contains the before_action helper method which
|
703
703
|
enables auto lookup of the requesting IP address.
|
704
704
|
|
705
705
|
### The Geokit gem provides the building blocks of distance-based operations:
|
@@ -721,9 +721,7 @@ AND the Mappable module goodness for free.
|
|
721
721
|
## IMPORTANT POST-INSTALLATION NOTES:
|
722
722
|
|
723
723
|
*1. The configuration file*: Geokit for Rails uses a configuration file in config/initializers.
|
724
|
-
You *must* add your own keys for the various geocoding services if you want to use geocoding.
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
dependency in `config/environment.rb`, within the initializer block:
|
729
|
-
config.gem "geokit"
|
724
|
+
You *must* add your own keys for the various geocoding services if you want to use geocoding. You can generate a sample initializer file by run:
|
725
|
+
```sh
|
726
|
+
$ rails g geokit_rails:install
|
727
|
+
```
|
data/gemfiles/rails3.gemfile
CHANGED
data/gemfiles/rails4.gemfile
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
|
-
gemspec :path => "../"
|
3
2
|
|
4
3
|
group :development, :test do
|
5
|
-
gem '
|
6
|
-
gem '
|
7
|
-
gem 'simplecov'
|
8
|
-
gem 'simplecov-rcov'
|
9
|
-
gem 'sqlite3'
|
10
|
-
gem 'activerecord', '~> 4.0.0'
|
4
|
+
gem 'activerecord', '~> 4.0'
|
5
|
+
gem 'test-unit'
|
11
6
|
end
|
7
|
+
|
8
|
+
gemspec :path => "../"
|
data/geokit-rails.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "simplecov"
|
24
24
|
spec.add_development_dependency "simplecov-rcov"
|
25
25
|
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'test-unit'
|
26
27
|
spec.add_development_dependency "mocha", "~> 0.9"
|
27
28
|
spec.add_development_dependency 'coveralls'
|
28
29
|
spec.add_development_dependency "mysql", "~> 2.8"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module GeokitRails
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../templates", __FILE__)
|
5
|
+
|
6
|
+
desc "Creates a sample Geokit initializer."
|
7
|
+
|
8
|
+
def copy_initializer
|
9
|
+
copy_file "geokit_config.rb", "config/initializers/geokit_config.rb"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# These defaults are used in Geokit::Mappable.distance_to and acts_as_mappable
|
2
|
+
Geokit::default_units = :miles # others :kms, :nms, :meters
|
3
|
+
Geokit::default_formula = :sphere
|
4
|
+
|
5
|
+
# This is the timeout value in seconds to be used for calls to the geocoder web
|
6
|
+
# services. For no timeout at all, comment out the setting. The timeout unit
|
7
|
+
# is in seconds.
|
8
|
+
Geokit::Geocoders::request_timeout = 3
|
9
|
+
|
10
|
+
# This setting can be used if web service calls must be routed through a proxy.
|
11
|
+
# These setting can be nil if not needed, otherwise, a valid URI must be
|
12
|
+
# filled in at a minimum. If the proxy requires authentication, the username
|
13
|
+
# and password can be provided as well.
|
14
|
+
# Geokit::Geocoders::proxy = 'https://user:password@host:port'
|
15
|
+
|
16
|
+
# This is your yahoo application key for the Yahoo Geocoder.
|
17
|
+
# See http://developer.yahoo.com/faq/index.html#appid
|
18
|
+
# and http://developer.yahoo.com/maps/rest/V1/geocode.html
|
19
|
+
# Geokit::Geocoders::YahooGeocoder.key = 'REPLACE_WITH_YOUR_YAHOO_KEY'
|
20
|
+
# Geokit::Geocoders::YahooGeocoder.secret = 'REPLACE_WITH_YOUR_YAHOO_SECRET'
|
21
|
+
|
22
|
+
# This is your Google Maps geocoder keys (all optional).
|
23
|
+
# See http://www.google.com/apis/maps/signup.html
|
24
|
+
# and http://www.google.com/apis/maps/documentation/#Geocoding_Examples
|
25
|
+
# Geokit::Geocoders::GoogleGeocoder.client_id = ''
|
26
|
+
# Geokit::Geocoders::GoogleGeocoder.cryptographic_key = ''
|
27
|
+
# Geokit::Geocoders::GoogleGeocoder.channel = ''
|
28
|
+
|
29
|
+
# You can also use the free API key instead of signed requests
|
30
|
+
# See https://developers.google.com/maps/documentation/geocoding/#api_key
|
31
|
+
# Geokit::Geocoders::GoogleGeocoder.api_key = ''
|
32
|
+
|
33
|
+
# You can also set multiple API KEYS for different domains that may be directed
|
34
|
+
# to this same application.
|
35
|
+
# The domain from which the current user is being directed will automatically
|
36
|
+
# be updated for Geokit via
|
37
|
+
# the GeocoderControl class, which gets it's begin filter mixed
|
38
|
+
# into the ActionController.
|
39
|
+
# You define these keys with a Hash as follows:
|
40
|
+
# Geokit::Geocoders::google = {
|
41
|
+
# 'rubyonrails.org' => 'RUBY_ON_RAILS_API_KEY',
|
42
|
+
# ' ruby-docs.org' => 'RUBY_DOCS_API_KEY' }
|
43
|
+
|
44
|
+
# This is your username and password for geocoder.us.
|
45
|
+
# To use the free service, the value can be set to nil or false. For
|
46
|
+
# usage tied to an account, the value should be set to username:password.
|
47
|
+
# See http://geocoder.us
|
48
|
+
# and http://geocoder.us/user/signup
|
49
|
+
# Geokit::Geocoders::UsGeocoder.key = 'username:password'
|
50
|
+
|
51
|
+
# This is your authorization key for geocoder.ca.
|
52
|
+
# To use the free service, the value can be set to nil or false. For
|
53
|
+
# usage tied to an account, set the value to the key obtained from
|
54
|
+
# Geocoder.ca.
|
55
|
+
# See http://geocoder.ca
|
56
|
+
# and http://geocoder.ca/?register=1
|
57
|
+
# Geokit::Geocoders::CaGeocoder.key = 'KEY'
|
58
|
+
|
59
|
+
# This is your username key for geonames.
|
60
|
+
# To use this service either free or premium, you must register a key.
|
61
|
+
# See http://www.geonames.org
|
62
|
+
# Geokit::Geocoders::GeonamesGeocoder.key = 'KEY'
|
63
|
+
|
64
|
+
# Most other geocoders need either no setup or a key
|
65
|
+
# Geokit::Geocoders::BingGeocoder.key = ''
|
66
|
+
# Geokit::Geocoders::MapQuestGeocoder.key = ''
|
67
|
+
# Geokit::Geocoders::YandexGeocoder.key = ''
|
68
|
+
# Geokit::Geocoders::MapboxGeocoder.key = 'ACCESS_TOKEN'
|
69
|
+
# Geokit::Geocoders::OpencageGeocoder.key = 'some_api_key'
|
70
|
+
|
71
|
+
# Geonames has a free service and a premium service, each using a different URL
|
72
|
+
# GeonamesGeocoder.premium = true will use http://ws.geonames.net (premium)
|
73
|
+
# GeonamesGeocoder.premium = false will use http://api.geonames.org (free)
|
74
|
+
# Geokit::Geocoders::GeonamesGeocoder.premium = false
|
75
|
+
|
76
|
+
# require "external_geocoder.rb"
|
77
|
+
# Please see the section "writing your own geocoders" for more information.
|
78
|
+
# Geokit::Geocoders::external_key = 'REPLACE_WITH_YOUR_API_KEY'
|
79
|
+
|
80
|
+
# This is the order in which the geocoders are called in a failover scenario
|
81
|
+
# If you only want to use a single geocoder, put a single symbol in the array.
|
82
|
+
# Valid symbols are :google, :yahoo, :us, and :ca.
|
83
|
+
# Be aware that there are Terms of Use restrictions on how you can use the
|
84
|
+
# various geocoders. Make sure you read up on relevant Terms of Use for each
|
85
|
+
# geocoder you are going to use.
|
86
|
+
# Geokit::Geocoders::provider_order = [:google,:us]
|
87
|
+
|
88
|
+
# The IP provider order. Valid symbols are :ip,:geo_plugin.
|
89
|
+
# As before, make sure you read up on relevant Terms of Use for each.
|
90
|
+
# Geokit::Geocoders::ip_provider_order = [:external,:geo_plugin,:ip]
|
91
|
+
|
92
|
+
# Disable HTTPS globally. This option can also be set on individual
|
93
|
+
# geocoder classes.
|
94
|
+
# Geokit::Geocoders::secure = false
|
95
|
+
|
96
|
+
# Control verification of the server certificate for geocoders using HTTPS
|
97
|
+
# Geokit::Geocoders::ssl_verify_mode = OpenSSL::SSL::VERIFY_(PEER/NONE)
|
98
|
+
# Setting this to VERIFY_NONE may be needed on systems that don't have
|
99
|
+
# a complete or up to date root certificate store. Only applies to
|
100
|
+
# the Net::HTTP adapter.
|
data/lib/geokit-rails.rb
CHANGED
@@ -91,10 +91,20 @@ module Geokit
|
|
91
91
|
module ClassMethods
|
92
92
|
|
93
93
|
# A proxy to an instance of a finder adapter, inferred from the connection's adapter.
|
94
|
-
def
|
95
|
-
@
|
96
|
-
|
94
|
+
def geokit_finder_adapter
|
95
|
+
@geokit_finder_adapter ||= begin
|
96
|
+
unless Adapters.const_defined?(connection.adapter_name.camelcase)
|
97
|
+
filename = connection.adapter_name.downcase
|
98
|
+
require File.join("geokit-rails", "adapters", filename)
|
99
|
+
end
|
97
100
|
klass = Adapters.const_get(connection.adapter_name.camelcase)
|
101
|
+
if klass.class == Module
|
102
|
+
# For some reason Mysql2 adapter was defined in Adapters.constants but was Module instead of a Class
|
103
|
+
filename = connection.adapter_name.downcase
|
104
|
+
require File.join("geokit-rails", "adapters", filename)
|
105
|
+
# Re-init the klass after require
|
106
|
+
klass = Adapters.const_get(connection.adapter_name.camelcase)
|
107
|
+
end
|
98
108
|
klass.load(self) unless klass.loaded
|
99
109
|
klass.new(self)
|
100
110
|
rescue LoadError
|
@@ -104,8 +114,13 @@ module Geokit
|
|
104
114
|
|
105
115
|
def within(distance, options = {})
|
106
116
|
options[:within] = distance
|
107
|
-
#
|
108
|
-
|
117
|
+
# Add bounding box to speed up SQL request.
|
118
|
+
bounds = formulate_bounds_from_distance(
|
119
|
+
options,
|
120
|
+
normalize_point_to_lat_lng(options[:origin]),
|
121
|
+
options[:units] || default_units)
|
122
|
+
with_latlng.where(bound_conditions(bounds)).
|
123
|
+
where(distance_conditions(options))
|
109
124
|
end
|
110
125
|
alias inside within
|
111
126
|
|
@@ -134,10 +149,12 @@ module Geokit
|
|
134
149
|
origin = extract_origin_from_options(options)
|
135
150
|
units = extract_units_from_options(options)
|
136
151
|
formula = extract_formula_from_options(options)
|
137
|
-
bounds = extract_bounds_from_options(options)
|
138
152
|
distance_column_name = distance_sql(origin, units, formula)
|
139
|
-
|
140
|
-
|
153
|
+
with_latlng.order("#{distance_column_name} #{options[:reverse] ? 'DESC' : 'ASC'}")
|
154
|
+
end
|
155
|
+
|
156
|
+
def with_latlng
|
157
|
+
where("#{qualified_lat_column_name} IS NOT NULL AND #{qualified_lng_column_name} IS NOT NULL")
|
141
158
|
end
|
142
159
|
|
143
160
|
def closest(options = {})
|
@@ -214,7 +231,7 @@ module Geokit
|
|
214
231
|
distance = options[:within] if options.has_key?(:within)
|
215
232
|
distance = options[:range].last-(options[:range].exclude_end?? 1 : 0) if options.has_key?(:range)
|
216
233
|
if distance
|
217
|
-
|
234
|
+
Geokit::Bounds.from_point_and_radius(origin,distance,:units=>units)
|
218
235
|
else
|
219
236
|
nil
|
220
237
|
end
|
@@ -224,7 +241,6 @@ module Geokit
|
|
224
241
|
origin = extract_origin_from_options(options)
|
225
242
|
units = extract_units_from_options(options)
|
226
243
|
formula = extract_formula_from_options(options)
|
227
|
-
bounds = extract_bounds_from_options(options)
|
228
244
|
distance_column_name = distance_sql(origin, units, formula)
|
229
245
|
|
230
246
|
res = if options.has_key?(:within)
|
@@ -321,7 +337,7 @@ module Geokit
|
|
321
337
|
lat = deg2rad(get_lat(origin))
|
322
338
|
lng = deg2rad(get_lng(origin))
|
323
339
|
multiplier = units_sphere_multiplier(units)
|
324
|
-
|
340
|
+
geokit_finder_adapter.sphere_distance_sql(lat, lng, multiplier) if geokit_finder_adapter
|
325
341
|
end
|
326
342
|
|
327
343
|
# Returns the distance SQL using the flat-world formula (Phythagorean Theory). The SQL is tuned
|
@@ -329,7 +345,7 @@ module Geokit
|
|
329
345
|
def flat_distance_sql(origin, units)
|
330
346
|
lat_degree_units = units_per_latitude_degree(units)
|
331
347
|
lng_degree_units = units_per_longitude_degree(get_lat(origin), units)
|
332
|
-
|
348
|
+
geokit_finder_adapter.flat_distance_sql(origin, lat_degree_units, lng_degree_units)
|
333
349
|
end
|
334
350
|
|
335
351
|
def get_lat(origin)
|
@@ -5,7 +5,9 @@ module Geokit
|
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
7
|
included do
|
8
|
-
if self.respond_to? :
|
8
|
+
if self.respond_to? :before_action
|
9
|
+
self.send :before_action, :set_geokit_domain
|
10
|
+
elsif self.respond_to? :before_filter
|
9
11
|
self.send :before_filter, :set_geokit_domain
|
10
12
|
end
|
11
13
|
end
|
@@ -15,4 +17,4 @@ module Geokit
|
|
15
17
|
logger.debug("Geokit is using the domain: #{Geokit::Geocoders::domain}")
|
16
18
|
end
|
17
19
|
end
|
18
|
-
end
|
20
|
+
end
|
@@ -1,40 +1,44 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'active_support/concern'
|
3
3
|
|
4
|
-
module Geokit
|
4
|
+
module Geokit
|
5
5
|
# Contains a class method geocode_ip_address which can be used to enable automatic geocoding
|
6
|
-
# for request IP addresses. The geocoded information is stored in a cookie and in the
|
6
|
+
# for request IP addresses. The geocoded information is stored in a cookie and in the
|
7
7
|
# session to minimize web service calls. The point of the helper is to enable location-based
|
8
8
|
# websites to have a best-guess for new visitors.
|
9
9
|
module IpGeocodeLookup
|
10
10
|
extend ActiveSupport::Concern
|
11
|
-
|
11
|
+
|
12
12
|
# Class method to mix into active record.
|
13
13
|
module ClassMethods # :nodoc:
|
14
14
|
def geocode_ip_address(filter_options = {})
|
15
|
-
|
15
|
+
if respond_to? :before_action
|
16
|
+
before_action :store_ip_location, filter_options
|
17
|
+
else
|
18
|
+
before_filter :store_ip_location, filter_options
|
19
|
+
end
|
16
20
|
end
|
17
21
|
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
# Places the IP address' geocode location into the session if it
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
# Places the IP address' geocode location into the session if it
|
22
26
|
# can be found. Otherwise, looks for a geo location cookie and
|
23
27
|
# uses that value. The last resort is to call the web service to
|
24
28
|
# get the value.
|
25
29
|
def store_ip_location
|
26
30
|
session[:geo_location] ||= retrieve_location_from_cookie_or_service
|
27
31
|
cookies[:geo_location] = { :value => session[:geo_location].to_yaml, :expires => 30.days.from_now } if session[:geo_location]
|
28
|
-
end
|
29
|
-
|
32
|
+
end
|
33
|
+
|
30
34
|
# Uses the stored location value from the cookie if it exists. If
|
31
|
-
# no cookie exists, calls out to the web service to get the location.
|
35
|
+
# no cookie exists, calls out to the web service to get the location.
|
32
36
|
def retrieve_location_from_cookie_or_service
|
33
|
-
return YAML.load(cookies[:geo_location]) if cookies[:geo_location]
|
37
|
+
return GeoLoc.new(YAML.load(cookies[:geo_location])) if cookies[:geo_location]
|
34
38
|
location = Geocoders::MultiGeocoder.geocode(get_ip_address)
|
35
39
|
return location.success ? location : nil
|
36
40
|
end
|
37
|
-
|
41
|
+
|
38
42
|
# Returns the real ip address, though this could be the localhost ip
|
39
43
|
# address. No special handling here anymore.
|
40
44
|
def get_ip_address
|
data/lib/geokit-rails/railtie.rb
CHANGED
data/lib/geokit-rails/version.rb
CHANGED
@@ -241,28 +241,28 @@ class ActsAsMappableTest < GeokitTestCase
|
|
241
241
|
end
|
242
242
|
|
243
243
|
def test_ip_geocoded_find_with_distance_condition
|
244
|
-
Geokit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
|
244
|
+
Geokit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).twice.returns(@location_a)
|
245
245
|
locations = Location.within(3.97, :origin => LOCATION_A_IP)
|
246
246
|
assert_equal 5, locations.to_a.size
|
247
247
|
assert_equal 5, locations.count
|
248
248
|
end
|
249
249
|
|
250
250
|
def test_ip_geocoded_find_within
|
251
|
-
Geokit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
|
251
|
+
Geokit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).twice.returns(@location_a)
|
252
252
|
locations = Location.within(3.97, :origin => LOCATION_A_IP)
|
253
253
|
assert_equal 5, locations.to_a.size
|
254
254
|
assert_equal 5, locations.count
|
255
255
|
end
|
256
256
|
|
257
257
|
def test_ip_geocoded_find_with_compound_condition
|
258
|
-
Geokit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
|
258
|
+
Geokit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).twice.returns(@location_a)
|
259
259
|
locations = Location.within(5, :origin => LOCATION_A_IP).where("city = 'Coppell'")
|
260
260
|
assert_equal 2, locations.to_a.size
|
261
261
|
assert_equal 2, locations.count
|
262
262
|
end
|
263
263
|
|
264
264
|
def test_ip_geocoded_find_with_secure_compound_condition
|
265
|
-
Geokit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).returns(@location_a)
|
265
|
+
Geokit::Geocoders::MultiGeocoder.expects(:geocode).with(LOCATION_A_IP).twice.returns(@location_a)
|
266
266
|
locations = Location.within(5, :origin => LOCATION_A_IP).where(["city = ?", 'Coppell'])
|
267
267
|
assert_equal 2, locations.to_a.size
|
268
268
|
assert_equal 2, locations.count
|
@@ -293,7 +293,7 @@ class ActsAsMappableTest < GeokitTestCase
|
|
293
293
|
end
|
294
294
|
|
295
295
|
def test_address_geocode
|
296
|
-
Geokit::Geocoders::MultiGeocoder.expects(:geocode).with('Irving, TX').returns(@location_a)
|
296
|
+
Geokit::Geocoders::MultiGeocoder.expects(:geocode).with('Irving, TX').twice.returns(@location_a)
|
297
297
|
#locations = Location.geo_scope(:origin => 'Irving, TX').where(["distance < ? and city = ?", 5, 'Coppell'])
|
298
298
|
locations = Location.within(5, :origin => 'Irving, TX').where(["city = ?", 'Coppell'])
|
299
299
|
assert_equal 2, locations.to_a.size
|
@@ -449,7 +449,7 @@ class ActsAsMappableTest < GeokitTestCase
|
|
449
449
|
end
|
450
450
|
|
451
451
|
def test_sort_by_distance_from
|
452
|
-
locations = Location.all
|
452
|
+
locations = Location.with_latlng.all
|
453
453
|
unsorted = [locations(:a), locations(:b), locations(:c), locations(:d), locations(:e), locations(:f)]
|
454
454
|
sorted = [locations(:a), locations(:b), locations(:c), locations(:f), locations(:d), locations(:e)]
|
455
455
|
assert_equal sorted, locations.sort_by{|l| l.distance_to(locations(:a))}
|
data/test/boot.rb
CHANGED
data/test/fixtures/locations.yml
CHANGED
data/test/test_helper.rb
CHANGED
@@ -3,11 +3,17 @@ require 'pathname'
|
|
3
3
|
require 'boot'
|
4
4
|
require 'mocha/setup'
|
5
5
|
|
6
|
-
|
7
|
-
COVERAGE_THRESHOLD =
|
6
|
+
unless ENV['COVERAGE'] == 'off'
|
7
|
+
COVERAGE_THRESHOLD = 35
|
8
8
|
require 'simplecov'
|
9
9
|
require 'simplecov-rcov'
|
10
|
-
|
10
|
+
require 'coveralls'
|
11
|
+
Coveralls.wear!
|
12
|
+
|
13
|
+
SimpleCov.formatters = [
|
14
|
+
SimpleCov::Formatter::RcovFormatter,
|
15
|
+
Coveralls::SimpleCov::Formatter
|
16
|
+
]
|
11
17
|
SimpleCov.start do
|
12
18
|
add_filter '/test/'
|
13
19
|
add_group 'lib', 'lib'
|
@@ -41,4 +47,4 @@ class GeokitTestCase < ActiveSupport::TestCase
|
|
41
47
|
self.use_instantiated_fixtures = false
|
42
48
|
|
43
49
|
fixtures :all
|
44
|
-
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geokit-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Noack
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2016-07-13 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rails
|
@@ -97,6 +97,20 @@ dependencies:
|
|
97
97
|
- - ">="
|
98
98
|
- !ruby/object:Gem::Version
|
99
99
|
version: '0'
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
name: test-unit
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
type: :development
|
108
|
+
prerelease: false
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
100
114
|
- !ruby/object:Gem::Dependency
|
101
115
|
name: mocha
|
102
116
|
requirement: !ruby/object:Gem::Requirement
|
@@ -217,6 +231,8 @@ files:
|
|
217
231
|
- gemfiles/rails3.gemfile
|
218
232
|
- gemfiles/rails4.gemfile
|
219
233
|
- geokit-rails.gemspec
|
234
|
+
- lib/generators/geokit_rails/install_generator.rb
|
235
|
+
- lib/generators/templates/geokit_config.rb
|
220
236
|
- lib/geokit-rails.rb
|
221
237
|
- lib/geokit-rails/acts_as_mappable.rb
|
222
238
|
- lib/geokit-rails/adapters/abstract.rb
|
@@ -228,7 +244,6 @@ files:
|
|
228
244
|
- lib/geokit-rails/adapters/sqlite.rb
|
229
245
|
- lib/geokit-rails/adapters/sqlserver.rb
|
230
246
|
- lib/geokit-rails/core_extensions.rb
|
231
|
-
- lib/geokit-rails/defaults.rb
|
232
247
|
- lib/geokit-rails/geocoder_control.rb
|
233
248
|
- lib/geokit-rails/ip_geocode_lookup.rb
|
234
249
|
- lib/geokit-rails/railtie.rb
|
@@ -278,7 +293,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
278
293
|
version: '0'
|
279
294
|
requirements: []
|
280
295
|
rubyforge_project:
|
281
|
-
rubygems_version: 2.4.
|
296
|
+
rubygems_version: 2.4.8
|
282
297
|
signing_key:
|
283
298
|
specification_version: 4
|
284
299
|
summary: Geokit helpers for rails apps.
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Geokit
|
2
|
-
# These defaults are used in Geokit::Mappable.distance_to and in acts_as_mappable
|
3
|
-
@@default_units = :miles
|
4
|
-
@@default_formula = :sphere
|
5
|
-
|
6
|
-
[:default_units, :default_formula].each do |sym|
|
7
|
-
class_eval <<-EOS, __FILE__, __LINE__
|
8
|
-
def self.#{sym}
|
9
|
-
if defined?(#{sym.to_s.upcase})
|
10
|
-
#{sym.to_s.upcase}
|
11
|
-
else
|
12
|
-
@@#{sym}
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.#{sym}=(obj)
|
17
|
-
@@#{sym} = obj
|
18
|
-
end
|
19
|
-
EOS
|
20
|
-
end
|
21
|
-
end
|