albanpeignier-geokit-rails 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ == 2008-02-20
2
+ * More powerful assosciations in the Rails Plugin:You can now specify a model as mappable "through" an associated model.
3
+ In other words, that associated model is the actual mappable model with "lat" and "lng" attributes, but this "through" model
4
+ can still utilize all Geokit's "find by distance" finders. Also Rails 2.3 compatibility (thanks github/glennpow)
5
+
6
+ == 2008-12-18
7
+ * Split Rails plugin from geocoder gem
8
+ * updated for Rails 2.2.2
9
+
10
+ == 2008-08-20
11
+ * Further fix of distance calculation, this time in SQL. Now uses least() function, which is available in MySQL version 3.22.5+ and postgres versions 8.1+
12
+
13
+ == 2008-01-16
14
+ * fixed the "zero-distance" bug (calculating between two points that are the same)
15
+
16
+ == 2007-11-12
17
+ * fixed a small but with queries crossing meridian, and also fixed find(:closest)
18
+
19
+ == 2008-10-11
20
+ * Fixed Rails2/Edge compatability
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007 Bill Eisenhauer & Andre Lewis
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,25 @@
1
+ CHANGELOG.rdoc
2
+ MIT-LICENSE
3
+ Manifest.txt
4
+ README.markdown
5
+ Rakefile
6
+ about.yml
7
+ assets/api_keys_template
8
+ geokit-rails.gemspec
9
+ init.rb
10
+ install.rb
11
+ lib/geokit-rails.rb
12
+ lib/geokit-rails/acts_as_mappable.rb
13
+ lib/geokit-rails/defaults.rb
14
+ lib/geokit-rails/ip_geocode_lookup.rb
15
+ test/acts_as_mappable_test.rb
16
+ test/database.yml
17
+ test/fixtures/companies.yml
18
+ test/fixtures/custom_locations.yml
19
+ test/fixtures/locations.yml
20
+ test/fixtures/mock_addresses.yml
21
+ test/fixtures/mock_organizations.yml
22
+ test/fixtures/stores.yml
23
+ test/ip_geocode_lookup_test.rb
24
+ test/schema.rb
25
+ test/test_helper.rb
@@ -0,0 +1,528 @@
1
+ ## INSTALLATION
2
+
3
+ Geokit consists of a Gem ([geokit-gem](http://github.com/andre/geokit-gem/tree/master)) and a Rails plugin ([geokit-rails](http://github.com/andre/geokit-rails/tree/master)).
4
+
5
+ #### 1. Install the Rails plugin:
6
+
7
+ cd [YOUR_RAILS_APP_ROOT]
8
+ script/plugin install git://github.com/andre/geokit-rails.git
9
+
10
+ #### 2. Add this line to your environment.rb
11
+ (inside the Rails::Initializer.run do |config| block)
12
+
13
+ config.gem "geokit"
14
+
15
+ This informs Rails of the gem dependency.
16
+
17
+ #### 3. Tell Rails to install the gem:
18
+
19
+ rake gems:install
20
+
21
+ And you're good to go! If you're running an older verion of Rails, just install the gem manually: `sudo gem install rails`
22
+
23
+ ## FEATURE SUMMARY
24
+
25
+ Geokit provides key functionality for location-oriented Rails applications:
26
+
27
+ - Distance calculations, for both flat and spherical environments. For example,
28
+ given the location of two points on the earth, you can calculate the miles/KM
29
+ between them.
30
+ - ActiveRecord distance-based finders. For example, you can find all the points
31
+ in your database within a 50-mile radius.
32
+ - IP-based location lookup utilizing hostip.info. Provide an IP address, and get
33
+ city name and latitude/longitude in return
34
+ - A before_filter helper to geocoder the user's location based on IP address,
35
+ and retain the location in a cookie.
36
+ - Geocoding from multiple providers. It currently supports Google, Yahoo,
37
+ Geocoder.us, and Geocoder.ca geocoders, and it provides a uniform response
38
+ structure from all of them. It also provides a fail-over mechanism, in case
39
+ your input fails to geocode in one service. Geocoding is provided buy the Geokit
40
+ gem, which you must have installed
41
+
42
+ The goal of this plugin is to provide the common functionality for location-oriented
43
+ applications (geocoding, location lookup, distance calculation) in an easy-to-use
44
+ package.
45
+
46
+ ## A NOTE ON TERMINOLOGY
47
+
48
+ Throughout the code and API, latitude and longitude are referred to as lat
49
+ and lng. We've found over the long term the abbreviation saves lots of typing time.
50
+
51
+ ## DISTANCE CALCULATIONS AND QUERIES
52
+
53
+ If you want only distance calculation services, you need only mix in the Mappable
54
+ module like so:
55
+
56
+ class Location
57
+ include Geokit::Mappable
58
+ end
59
+
60
+ After doing so, you can do things like:
61
+
62
+ Location.distance_between(from, to)
63
+
64
+ with optional parameters :units and :formula. Values for :units can be :miles,
65
+ :kms (kilometers), or :nms (nautical miles) with :miles as the default. Values for :formula can be :sphere or :flat with
66
+ :sphere as the default. :sphere gives you Haversine calculations, while :flat
67
+ gives the Pythagoreum Theory. These defaults persist through out the plug-in.
68
+
69
+ You can also do:
70
+
71
+ location.distance_to(other)
72
+
73
+ The real power and utility of the plug-in is in its query support. This is
74
+ achieved through mixing into an ActiveRecord model object:
75
+
76
+ class Location < ActiveRecord::Base
77
+ acts_as_mappable
78
+ end
79
+
80
+ The plug-in uses the above-mentioned defaults, but can be modified to use
81
+ different units and a different formulae. This is done through the `:default_units`
82
+ and `:default_formula` keys which accept the same values as mentioned above.
83
+
84
+ The plug-in creates a calculated column and potentially a calculated condition.
85
+ By default, these are known as "distance" but this can be changed through the
86
+ `:distance_field_name` key.
87
+
88
+ So, an alternative invocation would look as below:
89
+
90
+ class Location < ActiveRecord::Base
91
+ acts_as_mappable :default_units => :kms,
92
+ :default_formula => :flat,
93
+ :distance_field_name => :distance
94
+ end
95
+
96
+ You can also define alternative column names for latitude and longitude using
97
+ the `:lat_column_name` and `:lng_column_name` keys. The defaults are 'lat' and
98
+ 'lng' respectively.
99
+
100
+ Thereafter, a set of finder methods are made available. Below are the
101
+ different combinations:
102
+
103
+ Origin as a two-element array of latititude/longitude:
104
+
105
+ find(:all, :origin => [37.792,-122.393])
106
+
107
+ Origin as a geocodeable string:
108
+
109
+ find(:all, :origin => '100 Spear st, San Francisco, CA')
110
+
111
+ Origin as an object which responds to lat and lng methods,
112
+ or latitude and longitude methods, or whatever methods you have
113
+ specified for `lng_column_name` and `lat_column_name`:
114
+
115
+ find(:all, :origin=>my_store) # my_store.lat and my_store.lng methods exist
116
+
117
+ Often you will need to find within a certain distance. The prefered syntax is:
118
+
119
+ find(:all, :origin => @somewhere, :within => 5)
120
+
121
+ . . . however these syntaxes will also work:
122
+
123
+ find_within(5, :origin => @somewhere)
124
+ find(:all, :origin => @somewhere, :conditions => "distance < 5")
125
+
126
+ Note however that the third form should be avoided. With either of the first two,
127
+ Geokit automatically adds a bounding box to speed up the radial query in the database.
128
+ With the third form, it does not.
129
+
130
+ If you need to combine distance conditions with other conditions, you should do
131
+ so like this:
132
+
133
+ find(:all, :origin => @somewhere, :within => 5, :conditions=>['state=?',state])
134
+
135
+ If :origin is not provided in the finder call, the find method
136
+ works as normal. Further, the key is removed
137
+ from the :options hash prior to invoking the superclass behavior.
138
+
139
+ Other convenience methods work intuitively and are as follows:
140
+
141
+ find_within(distance, :origin => @somewhere)
142
+ find_beyond(distance, :origin => @somewhere)
143
+ find_closest(:origin => @somewhere)
144
+ find_farthest(:origin => @somewhere)
145
+
146
+ where the options respect the defaults, but can be overridden if
147
+ desired.
148
+
149
+ Lastly, if all that is desired is the raw SQL for distance
150
+ calculations, you can use the following:
151
+
152
+ distance_sql(origin, units=default_units, formula=default_formula)
153
+
154
+ Thereafter, you are free to use it in find_by_sql as you wish.
155
+
156
+ There are methods available to enable you to get the count based upon
157
+ the find condition that you have provided. These all work similarly to
158
+ the finders. So for instance:
159
+
160
+ count(:origin, :conditions => "distance < 5")
161
+ count_within(distance, :origin => @somewhere)
162
+ count_beyond(distance, :origin => @somewhere)
163
+
164
+ ## FINDING WITHIN A BOUNDING BOX
165
+
166
+ If you are displaying points on a map, you probably need to query for whatever falls within the rectangular bounds of the map:
167
+
168
+ Store.find :all, :bounds=>[sw_point,ne_point]
169
+
170
+ The input to :bounds can be array with the two points or a Bounds object. However you provide them, the order should always be the southwest corner, northeast corner of the rectangle. Typically, you will be getting the sw_point and ne_point from a map that is displayed on a web page.
171
+
172
+ If you need to calculate the bounding box from a point and radius, you can do that:
173
+
174
+ bounds=Bounds.from_point_and_radius(home,5)
175
+ Store.find :all, :bounds=>bounds
176
+
177
+ ## USING INCLUDES
178
+
179
+ You can use includes along with your distance finders:
180
+
181
+ stores=Store.find :all, :origin=>home, :include=>[:reviews,:cities] :within=>5, :order=>'distance'
182
+
183
+ *However*, ActiveRecord drops the calculated distance column when you use include. So, if you need to
184
+ use the distance column, you'll have to re-calculate it post-query in Ruby:
185
+
186
+ stores.sort_by_distance_from(home)
187
+
188
+ In this case, you may want to just use the bounding box
189
+ condition alone in your SQL (there's no use calculating the distance twice):
190
+
191
+ bounds=Bounds.from_point_and_radius(home,5)
192
+ stores=Store.find :all, :include=>[:reviews,:cities] :bounds=>bounds
193
+ stores.sort_by_distance_from(home)
194
+
195
+ ## USING :through
196
+
197
+ You can also specify a model as mappable "through" another associated model. In other words, that associated model is the
198
+ actual mappable model with "lat" and "lng" attributes, but this "through" model can still utilize all of the above find methods
199
+ to search for records.
200
+
201
+ class Location < ActiveRecord::Base
202
+ belongs_to :locatable, :polymorphic => true
203
+ acts_as_mappable
204
+ end
205
+
206
+ class Company < ActiveRecord::Base
207
+ has_one :location, :as => :locatable # also works for belongs_to associations
208
+ acts_as_mappable :through => :location
209
+ end
210
+
211
+ Then you can still call:
212
+
213
+ Company.find_within(distance, :origin => @somewhere)
214
+
215
+ Remember that the notes above about USING INCLUDES apply to the results from this find, since an include is automatically used.
216
+
217
+ ## IP GEOCODING
218
+
219
+ You can obtain the location for an IP at any time using the geocoder
220
+ as in the following example:
221
+
222
+ location = IpGeocoder.geocode('12.215.42.19')
223
+
224
+ where Location is a GeoLoc instance containing the latitude,
225
+ longitude, city, state, and country code. Also, the success
226
+ value is true.
227
+
228
+ If the IP cannot be geocoded, a GeoLoc instance is returned with a
229
+ success value of false.
230
+
231
+ It should be noted that the IP address needs to be visible to the
232
+ Rails application. In other words, you need to ensure that the
233
+ requesting IP address is forwarded by any front-end servers that
234
+ are out in front of the Rails app. Otherwise, the IP will always
235
+ be that of the front-end server.
236
+
237
+ ## IP GEOCODING HELPER
238
+
239
+ A class method called geocode_ip_address has been mixed into the
240
+ ActionController::Base. This enables before_filter style lookup of
241
+ the IP address. Since it is a filter, it can accept any of the
242
+ available filter options.
243
+
244
+ Usage is as below:
245
+
246
+ class LocationAwareController < ActionController::Base
247
+ geocode_ip_address
248
+ end
249
+
250
+ A first-time lookup will result in the GeoLoc class being stored
251
+ in the session as `:geo_location` as well as in a cookie called
252
+ `:geo_session`. Subsequent lookups will use the session value if it
253
+ exists or the cookie value if it doesn't exist. The last resort is
254
+ to make a call to the web service. Clients are free to manage the
255
+ cookie as they wish.
256
+
257
+ The intent of this feature is to be able to provide a good guess as
258
+ to a new visitor's location.
259
+
260
+ ## INTEGRATED FIND AND GEOCODING
261
+
262
+ Geocoding has been integrated with the finders enabling you to pass
263
+ a physical address or an IP address. This would look the following:
264
+
265
+ Location.find_farthest(:origin => '217.15.10.9')
266
+ Location.find_farthest(:origin => 'Irving, TX')
267
+
268
+ where the IP or physical address would be geocoded to a location and
269
+ then the resulting latitude and longitude coordinates would be used
270
+ in the find. This is not expected to be common usage, but it can be
271
+ done nevertheless.
272
+
273
+ ## ADDRESS GEOCODING
274
+
275
+ Geocoding is provided by the Geokit gem, which is required for this plugin.
276
+ See the top of this file for instructions on installing the Geokit gem.
277
+
278
+ Geokit can geocode addresses using multiple geocodeing web services.
279
+ Currently, Geokit supports Google, Yahoo, and Geocoder.us geocoding
280
+ services.
281
+
282
+ These geocoder services are made available through the following classes:
283
+ GoogleGeocoder, YahooGeocoder, UsGeocoder, CaGeocoder, and GeonamesGeocoder.
284
+ Further, an additional geocoder class called MultiGeocoder incorporates an ordered failover
285
+ sequence to increase the probability of successful geocoding.
286
+
287
+ All classes are called using the following signature:
288
+
289
+ include Geokit::Geocoders
290
+ location = XxxGeocoder.geocode(address)
291
+
292
+ where you replace Xxx Geocoder with the appropriate class. A GeoLoc
293
+ instance is the result of the call. This class has a "success"
294
+ attribute which will be true if a successful geocoding occurred.
295
+ If successful, the lat and lng properties will be populated.
296
+
297
+ Geocoders are named with the naming convention NameGeocoder. This
298
+ naming convention enables Geocoder to auto-detect its sub-classes
299
+ in order to create methods called `name_geocoder(address)` so that
300
+ all geocoders are called through the base class. This is done
301
+ purely for convenience; the individual geocoder classes are expected
302
+ to be used independently.
303
+
304
+ The MultiGeocoder class requires the configuration of a provider
305
+ order which dictates what order to use the various geocoders. Ordering
306
+ is done through `Geokit::Geocoders::provider_order`, found in
307
+ `config/initializers/geokit_config.rb`.
308
+
309
+ If you don't already have a `geokit_config.rb` file, the plugin creates one
310
+ when it is first installed.
311
+
312
+ Make sure your failover configuration matches the usage characteristics
313
+ of your application -- for example, if you routinely get bogus input to
314
+ geocode, your code will be much slower if you have to failover among
315
+ multiple geocoders before determining that the input was in fact bogus.
316
+
317
+ The Geocoder.geocode method returns a GeoLoc object. Basic usage:
318
+
319
+ loc=Geocoder.geocode('100 Spear St, San Francisco, CA')
320
+ if loc.success
321
+ puts loc.lat
322
+ puts loc.lng
323
+ puts loc.full_address
324
+ end
325
+
326
+ ## REVERSE GEOCODING
327
+
328
+ Currently, only the Google Geocoder supports reverse geocoding. Pass the lat/lng as a string, array or LatLng instance:
329
+
330
+ res=Geokit::Geocoders::GoogleGeocoder.reverse_geocode "37.791821,-122.394679"
331
+ => #<Geokit::GeoLoc:0x558ed0 ...
332
+ res.full_address
333
+ "101-115 Main St, San Francisco, CA 94105, USA"
334
+
335
+ The address will usually appear as a range, as it does in the above example.
336
+
337
+
338
+ ## INTEGRATED FIND WITH ADDRESS GEOCODING
339
+
340
+ Just has you can pass an IP address directly into an ActiveRecord finder
341
+ as the origin, you can also pass a physical address as the origin:
342
+
343
+ Location.find_closest(:origin => '100 Spear st, San Francisco, CA')
344
+
345
+ where the physical address would be geocoded to a location and then the
346
+ resulting latitude and longitude coordinates would be used in the
347
+ find.
348
+
349
+ Note that if the address fails to geocode, the find method will raise an
350
+ ActiveRecord::GeocodeError you must be prepared to catch. Alternatively,
351
+ You can geocoder the address beforehand, and pass the resulting lat/lng
352
+ into the finder if successful.
353
+
354
+ ## Auto Geocoding
355
+
356
+ If your geocoding needs are simple, you can tell your model to automatically
357
+ geocode itself on create:
358
+
359
+ class Store < ActiveRecord::Base
360
+ acts_as_mappable :auto_geocode=>true
361
+ end
362
+
363
+ It takes two optional params:
364
+
365
+ class Store < ActiveRecord::Base
366
+ acts_as_mappable :auto_geocode=>{:field=>:address, :error_message=>'Could not geocode address'}
367
+ end
368
+
369
+ . . . which is equivilent to:
370
+
371
+ class Store << ActiveRecord::Base
372
+ acts_as_mappable
373
+ before_validation_on_create :geocode_address
374
+
375
+ private
376
+ def geocode_address
377
+ geo=Geokit::Geocoders::MultiGeocoder.geocode (address)
378
+ errors.add(:address, "Could not Geocode address") if !geo.success
379
+ self.lat, self.lng = geo.lat,geo.lng if geo.success
380
+ end
381
+ end
382
+
383
+ If you need any more complicated geocoding behavior for your model, you should roll your own
384
+ `before_validate` callback.
385
+
386
+
387
+ ## Distances, headings, endpoints, and midpoints
388
+
389
+ distance=home.distance_from(work, :units=>:miles)
390
+ heading=home.heading_to(work) # result is in degrees, 0 is north
391
+ endpoint=home.endpoint(90,2) # two miles due east
392
+ midpoing=home.midpoint_to(work)
393
+
394
+ ## Cool stuff you can do with bounds
395
+
396
+ bounds=Bounds.new(sw_point,ne_point)
397
+ bounds.contains?(home)
398
+ puts bounds.center
399
+
400
+
401
+ HOW TO . . .
402
+ =================================================================================
403
+
404
+ A few quick examples to get you started ....
405
+
406
+ ## How to install the Geokit Rails plugin
407
+ (See the very top of this file)
408
+
409
+ ## How to find all stores within a 10-mile radius of a given lat/lng
410
+ 1. ensure your stores table has lat and lng columns with numeric or float
411
+ datatypes to store your latitude/longitude
412
+
413
+ 3. use `acts_as_mappable` on your store model:
414
+
415
+ class Store < ActiveRecord::Base
416
+ acts_as_mappable
417
+ ...
418
+ end
419
+
420
+ 3. finders now have extra capabilities:
421
+
422
+ Store.find(:all, :origin =>[32.951613,-96.958444], :within=>10)
423
+
424
+ ## How to geocode an address
425
+
426
+ 1. configure your geocoder key(s) in `config/initializers/geokit_config.rb`
427
+
428
+ 2. also in `geokit_config.rb`, make sure that `Geokit::Geocoders::provider_order` reflects the
429
+ geocoder(s). If you only want to use one geocoder, there should
430
+ be only one symbol in the array. For example:
431
+
432
+ Geokit::Geocoders::provider_order=[:google]
433
+
434
+ 3. Test it out in script/console
435
+
436
+ include Geokit::Geocoders
437
+ res = MultiGeocoder.geocode('100 Spear St, San Francisco, CA')
438
+ puts res.lat
439
+ puts res.lng
440
+ puts res.full_address
441
+ ... etc. The return type is GeoLoc, see the API for
442
+ all the methods you can call on it.
443
+
444
+ ## How to find all stores within 10 miles of a given address
445
+
446
+ 1. as above, ensure your table has the lat/lng columns, and you've
447
+ applied `acts_as_mappable` to the Store model.
448
+
449
+ 2. configure and test out your geocoder, as above
450
+
451
+ 3. pass the address in under the :origin key
452
+
453
+ Store.find(:all, :origin=>'100 Spear st, San Francisco, CA',
454
+ :within=>10)
455
+
456
+ 4. you can also use a zipcode, or anything else that's geocodable:
457
+
458
+ Store.find(:all, :origin=>'94117',
459
+ :conditions=>'distance<10')
460
+
461
+ ## How to sort a query by distance from an origin
462
+
463
+ You now have access to a 'distance' column, and you can use it
464
+ as you would any other column. For example:
465
+ Store.find(:all, :origin=>'94117', :order=>'distance')
466
+
467
+ ## How to elements of an array according to distance from a common point
468
+
469
+ Usually, you can do your sorting in the database as part of your find call.
470
+ If you need to sort things post-query, you can do so:
471
+
472
+ stores=Store.find :all
473
+ stores.sort_by_distance_from(home)
474
+ puts stores.first.distance
475
+
476
+ Obviously, each of the items in the array must have a latitude/longitude so
477
+ they can be sorted by distance.
478
+
479
+ ## Database Compatability
480
+
481
+ * Geokit works with MySQL (tested with version 5.0.41) or PostgreSQL (tested with version 8.2.6)
482
+ * Geokit does *not* work with SQLite, as it lacks the necessary geometry functions.
483
+ * Geokit is known to *not* work with Postgres versions under 8.1 -- it uses the least() funciton.
484
+
485
+
486
+ ## HIGH-LEVEL NOTES ON WHAT'S WHERE
487
+
488
+ `acts_as_mappable.rb`, as you'd expect, contains the ActsAsMappable
489
+ module which gets mixed into your models to provide the
490
+ location-based finder goodness.
491
+
492
+ `ip_geocode_lookup.rb` contains the before_filter helper method which
493
+ enables auto lookup of the requesting IP address.
494
+
495
+ ### The Geokit gem provides the building blocks of distance-based operations:
496
+
497
+ The Mappable module, which provides basic
498
+ distance calculation methods, i.e., calculating the distance
499
+ between two points.
500
+
501
+ The LatLng class is a simple container for latitude and longitude, but
502
+ it's made more powerful by mixing in the above-mentioned Mappable
503
+ module -- therefore, you can calculate easily the distance between two
504
+ LatLng ojbects with `distance = first.distance_to(other)`
505
+
506
+ GeoLoc represents an address or location which
507
+ has been geocoded. You can get the city, zipcode, street address, etc.
508
+ from a GeoLoc object. GeoLoc extends LatLng, so you also get lat/lng
509
+ AND the Mappable modeule goodness for free.
510
+
511
+ ## GOOGLE GROUP
512
+
513
+ Follow the Google Group for updates and discussion on Geokit: http://groups.google.com/group/geokit
514
+
515
+ ## IMPORTANT POST-INSTALLATION NOTES:
516
+
517
+ *1. The configuration file*: Geokit for Rails uses a configuration file in config/initializers.
518
+ You *must* add your own keys for the various geocoding services if you want to use geocoding.
519
+ If you need to refer to the original template again, see the `assets/api_keys_template` file.
520
+
521
+ *2. The gem dependency*: Geokit for Rails depends on the Geokit gem. Tell Rails about this
522
+ dependency in `config/environment.rb`, within the initializer block:
523
+ config.gem "geokit"
524
+
525
+ *If you're having trouble with dependencies ....*
526
+
527
+ Try installing the gem manually (sudo gem install geokit), then adding a `require 'geokit'` to the top of
528
+ `vendor/plugins/geokit-rails/init.rb` and/or `config/geokit_config.rb`.