geokit-rails 1.1.4 → 2.0.0.rc1

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

Potentially problematic release.


This version of geokit-rails might be problematic. Click here for more details.

@@ -1,46 +0,0 @@
1
- == 2009-10-02 / Version 1.2.0
2
- * Overhaul the test suite to be independent of a Rails project
3
- * Added concept of database adapter. Ported mysql/postgresql conditional code to their own adapter.
4
- * Added SQL Server support. THANKS http://github.com/brennandunn for all the improvements in this release
5
-
6
- == 2009-09-26 / Version 1.1.3
7
- * documentation updates and updated to work with Geokit gem v1.5.0
8
- * IMPORTANT: in the Geokit gem, Geokit::Geocoders::timeout became Geokit::Geocoders::request_timeout for jruby compatibility.
9
- The plugin sets this in config/initializers/geokit_config.rb. So if you've upgraded the gem to 1.5.0, you need to
10
- make the change manually from Geokit::Geocoders::timeout to Geokit::Geocoders::request_timeout in config/initializers/geokit_config.rb
11
-
12
- == 2009-06-08 / Version 1.1.2
13
- * Added support for hashes in :through. So you can do: acts_as_mappable :through => { :state => :country } (Thanks José Valim).
14
-
15
- == 2009-05-22 / Version 1.1.1
16
- * Support for multiple ip geocoders (Thanks dreamcat4)
17
- * Now checks if either :origin OR :bounds is passed, and proceeds with geokit query if this is true (Thanks Glenn Powell)
18
- * Raises a helpful error if someone uses through but the association does not exists or was not defined yet (Thanks José Valim)
19
-
20
- == 2009-04-11 / Version 1.1.0
21
- * Fixed :through usages so that the through model is only included in the query if there
22
- is an :origin passed in (Only if it is a geokit search) (Thanks Glenn Powell)
23
- * Move library initialisation into lib/geokit-rails. init.rb uses lib/geokit-rails now (thanks Alban Peignier)
24
- * Handle the case where a user passes a hash to the :conditions Finder option (thanks Adam Greene)
25
- * Added ability to specify domain-specific API keys (Thanks Glenn Powell)
26
-
27
- == 2009-02-20
28
- * More powerful assosciations in the Rails Plugin:You can now specify a model as mappable "through" an associated model.
29
- In other words, that associated model is the actual mappable model with "lat" and "lng" attributes, but this "through" model
30
- can still utilize all Geokit's "find by distance" finders. Also Rails 2.3 compatibility (thanks github/glennpow)
31
-
32
- == 2008-12-18
33
- * Split Rails plugin from geocoder gem
34
- * updated for Rails 2.2.2
35
-
36
- == 2008-08-20
37
- * 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+
38
-
39
- == 2008-01-16
40
- * fixed the "zero-distance" bug (calculating between two points that are the same)
41
-
42
- == 2007-11-12
43
- * fixed a small but with queries crossing meridian, and also fixed find(:closest)
44
-
45
- == 2007-10-11
46
- * Fixed Rails2/Edge compatability
@@ -1,20 +0,0 @@
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.
@@ -1,44 +0,0 @@
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/adapters/abstract.rb
14
- lib/geokit-rails/adapters/mysql.rb
15
- lib/geokit-rails/adapters/postgresql.rb
16
- lib/geokit-rails/adapters/sqlserver.rb
17
- lib/geokit-rails/defaults.rb
18
- lib/geokit-rails/geocoder_control.rb
19
- lib/geokit-rails/ip_geocode_lookup.rb
20
- test/acts_as_mappable_test.rb
21
- test/boot.rb
22
- test/database.yml
23
- test/fixtures/companies.yml
24
- test/fixtures/custom_locations.yml
25
- test/fixtures/locations.yml
26
- test/fixtures/mock_addresses.yml
27
- test/fixtures/mock_families.yml
28
- test/fixtures/mock_houses.yml
29
- test/fixtures/mock_organizations.yml
30
- test/fixtures/mock_people.yml
31
- test/fixtures/stores.yml
32
- test/ip_geocode_lookup_test.rb
33
- test/models/company.rb
34
- test/models/custom_location.rb
35
- test/models/location.rb
36
- test/models/mock_address.rb
37
- test/models/mock_family.rb
38
- test/models/mock_house.rb
39
- test/models/mock_organization.rb
40
- test/models/mock_person.rb
41
- test/models/store.rb
42
- test/schema.rb
43
- test/tasks.rake
44
- test/test_helper.rb
@@ -1,561 +0,0 @@
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 provides a fail-over mechanism, in case
37
- your input fails to geocode in one service. Geocoding is provided buy the Geokit
38
- gem, which you must have installed
39
-
40
- The goal of this plugin is to provide the common functionality for location-oriented
41
- applications (geocoding, location lookup, distance calculation) in an easy-to-use
42
- package.
43
-
44
- ## A NOTE ON TERMINOLOGY
45
-
46
- Throughout the code and API, latitude and longitude are referred to as lat
47
- and lng. We've found over the long term the abbreviation saves lots of typing time.
48
-
49
- ## LOCATION QUERIES
50
-
51
- To get started, just specify an ActiveRecord class as `acts_as_mappale`:
52
-
53
- class Location < ActiveRecord::Base
54
- acts_as_mappable
55
- end
56
-
57
- There are some defaults you can override:
58
-
59
- class Location < ActiveRecord::Base
60
- acts_as_mappable :default_units => :miles,
61
- :default_formula => :sphere,
62
- :distance_field_name => :distance,
63
- :lat_column_name => :lat,
64
- :lng_column_name => :lng
65
- end
66
-
67
-
68
- The optional parameters are :units, :formula, and distance_field_name.
69
- Values for :units can be :miles, :kms (kilometers), or :nms (nautical miles),
70
- with :miles as the default. Values for :formula can be :sphere or :flat with
71
- :sphere as the default. :sphere gives you Haversine calculations, while :flat
72
- gives the Pythagoreum Theory. These defaults persist through out the plug-in.
73
-
74
- The plug-in creates a calculated `distance` field on AR instances that have
75
- been retrieved throw a Geokit location query. By default, these fields are
76
- known as "distance" but this can be changed through the `:distance_field_name` key.
77
-
78
- You can also define alternative column names for latitude and longitude using
79
- the `:lat_column_name` and `:lng_column_name` keys. The defaults are 'lat' and
80
- 'lng' respectively.
81
-
82
- Once you've specified acts_as_mappable, a set of distance-based
83
- finder methods are available:
84
-
85
- Origin as a two-element array of latititude/longitude:
86
-
87
- find(:all, :origin => [37.792,-122.393])
88
-
89
- Origin as a geocodeable string:
90
-
91
- find(:all, :origin => '100 Spear st, San Francisco, CA')
92
-
93
- Origin as an object which responds to lat and lng methods,
94
- or latitude and longitude methods, or whatever methods you have
95
- specified for `lng_column_name` and `lat_column_name`:
96
-
97
- find(:all, :origin=>my_store) # my_store.lat and my_store.lng methods exist
98
-
99
- Often you will need to find within a certain distance. The prefered syntax is:
100
-
101
- find(:all, :origin => @somewhere, :within => 5)
102
-
103
- . . . however these syntaxes will also work:
104
-
105
- find_within(5, :origin => @somewhere)
106
- find(:all, :origin => @somewhere, :conditions => "distance < 5")
107
-
108
- Note however that the third form should be avoided. With either of the first two,
109
- Geokit automatically adds a bounding box to speed up the radial query in the database.
110
- With the third form, it does not.
111
-
112
- If you need to combine distance conditions with other conditions, you should do
113
- so like this:
114
-
115
- find(:all, :origin => @somewhere, :within => 5, :conditions=>['state=?',state])
116
-
117
- If :origin is not provided in the finder call, the find method
118
- works as normal. Further, the key is removed
119
- from the :options hash prior to invoking the superclass behavior.
120
-
121
- Other convenience methods work intuitively and are as follows:
122
-
123
- find_within(distance, :origin => @somewhere)
124
- find_beyond(distance, :origin => @somewhere)
125
- find_closest(:origin => @somewhere)
126
- find_farthest(:origin => @somewhere)
127
-
128
- where the options respect the defaults, but can be overridden if
129
- desired.
130
-
131
- Lastly, if all that is desired is the raw SQL for distance
132
- calculations, you can use the following:
133
-
134
- distance_sql(origin, units=default_units, formula=default_formula)
135
-
136
- Thereafter, you are free to use it in find_by_sql as you wish.
137
-
138
- There are methods available to enable you to get the count based upon
139
- the find condition that you have provided. These all work similarly to
140
- the finders. So for instance:
141
-
142
- count(:origin, :conditions => "distance < 5")
143
- count_within(distance, :origin => @somewhere)
144
- count_beyond(distance, :origin => @somewhere)
145
-
146
- ## FINDING WITHIN A BOUNDING BOX
147
-
148
- If you are displaying points on a map, you probably need to query for whatever falls within the rectangular bounds of the map:
149
-
150
- Store.find :all, :bounds=>[sw_point,ne_point]
151
-
152
- 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.
153
-
154
- If you need to calculate the bounding box from a point and radius, you can do that:
155
-
156
- bounds=Bounds.from_point_and_radius(home,5)
157
- Store.find :all, :bounds=>bounds
158
-
159
- ## USING INCLUDES
160
-
161
- You can use includes along with your distance finders:
162
-
163
- stores=Store.find :all, :origin=>home, :include=>[:reviews,:cities] :within=>5, :order=>'distance'
164
-
165
- *However*, ActiveRecord drops the calculated distance column when you use include. So, if you need to
166
- use the distance column, you'll have to re-calculate it post-query in Ruby:
167
-
168
- stores.sort_by_distance_from(home)
169
-
170
- In this case, you may want to just use the bounding box
171
- condition alone in your SQL (there's no use calculating the distance twice):
172
-
173
- bounds=Bounds.from_point_and_radius(home,5)
174
- stores=Store.find :all, :include=>[:reviews,:cities] :bounds=>bounds
175
- stores.sort_by_distance_from(home)
176
-
177
- ## USING :through
178
-
179
- You can also specify a model as mappable "through" another associated model.
180
- In other words, that associated model is the actual mappable model with
181
- "lat" and "lng" attributes, but this "through" model can still utilize
182
- all of the above find methods to search for records.
183
-
184
- class Location < ActiveRecord::Base
185
- belongs_to :locatable, :polymorphic => true
186
- acts_as_mappable
187
- end
188
-
189
- class Company < ActiveRecord::Base
190
- has_one :location, :as => :locatable # also works for belongs_to associations
191
- acts_as_mappable :through => :location
192
- end
193
-
194
- Then you can still call:
195
-
196
- Company.find_within(distance, :origin => @somewhere)
197
-
198
- You can also give :through a hash if you location is nested deep. For example, given:
199
-
200
- class House
201
- acts_as_mappable
202
- end
203
-
204
- class Family
205
- belongs_to :house
206
- end
207
-
208
- class Person
209
- belongs_to :family
210
- acts_as_mappable :through => { :family => :house }
211
- end
212
-
213
- Remember that the notes above about USING INCLUDES apply to the results from
214
- this find, since an include is automatically used.
215
-
216
- ## IP GEOCODING
217
-
218
- You can obtain the location for an IP at any time using the geocoder
219
- as in the following example:
220
-
221
- location = IpGeocoder.geocode('12.215.42.19')
222
-
223
- where Location is a GeoLoc instance containing the latitude,
224
- longitude, city, state, and country code. Also, the success
225
- value is true.
226
-
227
- If the IP cannot be geocoded, a GeoLoc instance is returned with a
228
- success value of false.
229
-
230
- It should be noted that the IP address needs to be visible to the
231
- Rails application. In other words, you need to ensure that the
232
- requesting IP address is forwarded by any front-end servers that
233
- are out in front of the Rails app. Otherwise, the IP will always
234
- be that of the front-end server.
235
-
236
- The Multi-Geocoder will also geocode IP addresses and provide
237
- failover among multiple IP geocoders. Just pass in an IP address for the
238
- parameter instead of a street address. Eg:
239
-
240
- location = Geocoders::MultiGeocoder.geocode('12.215.42.19')
241
-
242
- The MultiGeocoder class requires 2 configuration setting for the provider order.
243
- Ordering is done through `Geokit::Geocoders::provider_order` and
244
- `Geokit::Geocoders::ip_provider_order`, found in
245
- `config/initializers/geokit_config.rb`. If you don't already have a
246
- `geokit_config.rb` file, the plugin creates one when it is first installed.
247
-
248
-
249
- ## IP GEOCODING HELPER
250
-
251
- A class method called geocode_ip_address has been mixed into the
252
- ActionController::Base. This enables before_filter style lookup of
253
- the IP address. Since it is a filter, it can accept any of the
254
- available filter options.
255
-
256
- Usage is as below:
257
-
258
- class LocationAwareController < ActionController::Base
259
- geocode_ip_address
260
- end
261
-
262
- A first-time lookup will result in the GeoLoc class being stored
263
- in the session as `:geo_location` as well as in a cookie called
264
- `:geo_session`. Subsequent lookups will use the session value if it
265
- exists or the cookie value if it doesn't exist. The last resort is
266
- to make a call to the web service. Clients are free to manage the
267
- cookie as they wish.
268
-
269
- The intent of this feature is to be able to provide a good guess as
270
- to a new visitor's location.
271
-
272
- ## INTEGRATED FIND AND GEOCODING
273
-
274
- Geocoding has been integrated with the finders enabling you to pass
275
- a physical address or an IP address. This would look the following:
276
-
277
- Location.find_farthest(:origin => '217.15.10.9')
278
- Location.find_farthest(:origin => 'Irving, TX')
279
-
280
- where the IP or physical address would be geocoded to a location and
281
- then the resulting latitude and longitude coordinates would be used
282
- in the find. This is not expected to be common usage, but it can be
283
- done nevertheless.
284
-
285
- ## ADDRESS GEOCODING
286
-
287
- Geocoding is provided by the Geokit gem, which is required for this plugin.
288
- See the top of this file for instructions on installing the Geokit gem.
289
-
290
- Geokit can geocode addresses using multiple geocodeing web services.
291
- Geokit supports services like Google, Yahoo, and Geocoder.us, and more --
292
- see the Geokit gem API for a complete list.
293
-
294
- These geocoder services are made available through the following classes:
295
- GoogleGeocoder, YahooGeocoder, UsGeocoder, CaGeocoder, and GeonamesGeocoder.
296
- Further, an additional geocoder class called MultiGeocoder incorporates an ordered failover
297
- sequence to increase the probability of successful geocoding.
298
-
299
- All classes are called using the following signature:
300
-
301
- include Geokit::Geocoders
302
- location = XxxGeocoder.geocode(address)
303
-
304
- where you replace Xxx Geocoder with the appropriate class. A GeoLoc
305
- instance is the result of the call. This class has a "success"
306
- attribute which will be true if a successful geocoding occurred.
307
- If successful, the lat and lng properties will be populated.
308
-
309
- Geocoders are named with the convention NameGeocoder. This
310
- naming convention enables Geocoder to auto-detect its sub-classes
311
- in order to create methods called `name_geocoder(address)` so that
312
- all geocoders can be called through the base class. This is done
313
- purely for convenience; the individual geocoder classes are expected
314
- to be used independently.
315
-
316
- The MultiGeocoder class requires the configuration of a provider
317
- order which dictates what order to use the various geocoders. Ordering
318
- is done through `Geokit::Geocoders::provider_order`, found in
319
- `config/initializers/geokit_config.rb`.
320
-
321
- If you don't already have a `geokit_config.rb` file, the plugin creates one
322
- when it is first installed.
323
-
324
- Make sure your failover configuration matches the usage characteristics
325
- of your application -- for example, if you routinely get bogus input to
326
- geocode, your code will be much slower if you have to failover among
327
- multiple geocoders before determining that the input was in fact bogus.
328
-
329
- The Geocoder.geocode method returns a GeoLoc object. Basic usage:
330
-
331
- loc=Geocoder.geocode('100 Spear St, San Francisco, CA')
332
- if loc.success
333
- puts loc.lat
334
- puts loc.lng
335
- puts loc.full_address
336
- end
337
-
338
- ## REVERSE GEOCODING
339
-
340
- Currently, only the Google Geocoder supports reverse geocoding.
341
- Pass the lat/lng as a string, array or LatLng instance:
342
-
343
- res=Geokit::Geocoders::GoogleGeocoder.reverse_geocode "37.791821,-122.394679"
344
- => #<Geokit::GeoLoc:0x558ed0 ...
345
- res.full_address
346
- "101-115 Main St, San Francisco, CA 94105, USA"
347
-
348
- The address will usually appear as a range, as it does in the above example.
349
-
350
-
351
- ## INTEGRATED FIND WITH ADDRESS GEOCODING
352
-
353
- Just has you can pass an IP address directly into an ActiveRecord finder
354
- as the origin, you can also pass a physical address as the origin:
355
-
356
- Location.find_closest(:origin => '100 Spear st, San Francisco, CA')
357
-
358
- where the physical address would be geocoded to a location and then the
359
- resulting latitude and longitude coordinates would be used in the
360
- find.
361
-
362
- Note that if the address fails to geocode, the find method will raise an
363
- ActiveRecord::GeocodeError you must be prepared to catch. Alternatively,
364
- You can geocoder the address beforehand, and pass the resulting lat/lng
365
- into the finder if successful.
366
-
367
- ## Auto Geocoding
368
-
369
- If your geocoding needs are simple, you can tell your model to automatically
370
- geocode itself on create:
371
-
372
- class Store < ActiveRecord::Base
373
- acts_as_mappable :auto_geocode=>true
374
- end
375
-
376
- It takes two optional params:
377
-
378
- class Store < ActiveRecord::Base
379
- acts_as_mappable :auto_geocode=>{:field=>:address, :error_message=>'Could not geocode address'}
380
- end
381
-
382
- . . . which is equivilent to:
383
-
384
- class Store << ActiveRecord::Base
385
- acts_as_mappable
386
- before_validation_on_create :geocode_address
387
-
388
- private
389
- def geocode_address
390
- geo=Geokit::Geocoders::MultiGeocoder.geocode (address)
391
- errors.add(:address, "Could not Geocode address") if !geo.success
392
- self.lat, self.lng = geo.lat,geo.lng if geo.success
393
- end
394
- end
395
-
396
- If you need any more complicated geocoding behavior for your model, you should roll your own
397
- `before_validate` callback.
398
-
399
-
400
- ## Distances, headings, endpoints, and midpoints
401
-
402
- distance=home.distance_from(work, :units=>:miles)
403
- heading=home.heading_to(work) # result is in degrees, 0 is north
404
- endpoint=home.endpoint(90,2) # two miles due east
405
- midpoing=home.midpoint_to(work)
406
-
407
- ## Cool stuff you can do with bounds
408
-
409
- bounds=Bounds.new(sw_point,ne_point)
410
- bounds.contains?(home)
411
- puts bounds.center
412
-
413
-
414
- HOW TO . . .
415
- =================================================================================
416
-
417
- A few quick examples to get you started ....
418
-
419
- ## How to install the Geokit Rails plugin
420
- (See the very top of this file)
421
-
422
- ## How to find all stores within a 10-mile radius of a given lat/lng
423
- 1. ensure your stores table has lat and lng columns with numeric or float
424
- datatypes to store your latitude/longitude
425
-
426
- 3. use `acts_as_mappable` on your store model:
427
-
428
- class Store < ActiveRecord::Base
429
- acts_as_mappable
430
- ...
431
- end
432
-
433
- 3. finders now have extra capabilities:
434
-
435
- Store.find(:all, :origin =>[32.951613,-96.958444], :within=>10)
436
-
437
- ## How to geocode an address
438
-
439
- 1. configure your geocoder key(s) in `config/initializers/geokit_config.rb`
440
-
441
- 2. also in `geokit_config.rb`, make sure that `Geokit::Geocoders::provider_order` reflects the
442
- geocoder(s). If you only want to use one geocoder, there should
443
- be only one symbol in the array. For example:
444
-
445
- Geokit::Geocoders::provider_order=[:google]
446
-
447
- 3. Test it out in script/console
448
-
449
- include Geokit::Geocoders
450
- res = MultiGeocoder.geocode('100 Spear St, San Francisco, CA')
451
- puts res.lat
452
- puts res.lng
453
- puts res.full_address
454
- ... etc. The return type is GeoLoc, see the API for
455
- all the methods you can call on it.
456
-
457
- ## How to find all stores within 10 miles of a given address
458
-
459
- 1. as above, ensure your table has the lat/lng columns, and you've
460
- applied `acts_as_mappable` to the Store model.
461
-
462
- 2. configure and test out your geocoder, as above
463
-
464
- 3. pass the address in under the :origin key
465
-
466
- Store.find(:all, :origin=>'100 Spear st, San Francisco, CA',
467
- :within=>10)
468
-
469
- 4. you can also use a zipcode, or anything else that's geocodable:
470
-
471
- Store.find(:all, :origin=>'94117',
472
- :conditions=>'distance<10')
473
-
474
- ## How to sort a query by distance from an origin
475
-
476
- You now have access to a 'distance' column, and you can use it
477
- as you would any other column. For example:
478
- Store.find(:all, :origin=>'94117', :order=>'distance')
479
-
480
- ## How to elements of an array according to distance from a common point
481
-
482
- Usually, you can do your sorting in the database as part of your find call.
483
- If you need to sort things post-query, you can do so:
484
-
485
- stores=Store.find :all
486
- stores.sort_by_distance_from(home)
487
- puts stores.first.distance
488
-
489
- Obviously, each of the items in the array must have a latitude/longitude so
490
- they can be sorted by distance.
491
-
492
- ## Database indexes
493
-
494
- MySQL can't create indexes on a calculated field such as those Geokit uses to
495
- calculate distance based on latitude/longitude values for a record. However,
496
- indexing the lat and lng columns does improve Geokit distance calculation
497
- performance since the lat and lng columns are used in a straight comparison
498
- for distance calculation. Assuming a Page model that is incorporating the
499
- Geokit plugin the migration would be as follows.
500
-
501
- class AddIndexOPageLatAndLng < ActiveRecord::Migration
502
-
503
- def self.up
504
- add_index :pages, [:lat, :lng]
505
- end
506
-
507
- def self.down
508
- remove_index :pages, [:lat, :lng]
509
- end
510
- end
511
-
512
- ## Database Compatability
513
-
514
- * Geokit works with MySQL (tested with version 5.0.41), PostgreSQL (tested with version 8.2.6) and Microsoft SQL Server (tested with 2000).
515
- * Geokit does *not* work with SQLite, as it lacks the necessary geometry functions.
516
- * Geokit is known to *not* work with Postgres versions under 8.1 -- it uses the least() funciton.
517
-
518
-
519
- ## HIGH-LEVEL NOTES ON WHAT'S WHERE
520
-
521
- `acts_as_mappable.rb`, as you'd expect, contains the ActsAsMappable
522
- module which gets mixed into your models to provide the
523
- location-based finder goodness.
524
-
525
- `ip_geocode_lookup.rb` contains the before_filter helper method which
526
- enables auto lookup of the requesting IP address.
527
-
528
- ### The Geokit gem provides the building blocks of distance-based operations:
529
-
530
- The Mappable module, which provides basic
531
- distance calculation methods, i.e., calculating the distance
532
- between two points.
533
-
534
- The LatLng class is a simple container for latitude and longitude, but
535
- it's made more powerful by mixing in the above-mentioned Mappable
536
- module -- therefore, you can calculate easily the distance between two
537
- LatLng ojbects with `distance = first.distance_to(other)`
538
-
539
- GeoLoc represents an address or location which
540
- has been geocoded. You can get the city, zipcode, street address, etc.
541
- from a GeoLoc object. GeoLoc extends LatLng, so you also get lat/lng
542
- AND the Mappable modeule goodness for free.
543
-
544
- ## GOOGLE GROUP
545
-
546
- Follow the Google Group for updates and discussion on Geokit: http://groups.google.com/group/geokit
547
-
548
- ## IMPORTANT POST-INSTALLATION NOTES:
549
-
550
- *1. The configuration file*: Geokit for Rails uses a configuration file in config/initializers.
551
- You *must* add your own keys for the various geocoding services if you want to use geocoding.
552
- If you need to refer to the original template again, see the `assets/api_keys_template` file.
553
-
554
- *2. The gem dependency*: Geokit for Rails depends on the Geokit gem. Tell Rails about this
555
- dependency in `config/environment.rb`, within the initializer block:
556
- config.gem "geokit"
557
-
558
- *If you're having trouble with dependencies ....*
559
-
560
- Try installing the gem manually (sudo gem install geokit), then adding a `require 'geokit'` to the top of
561
- `vendor/plugins/geokit-rails/init.rb` and/or `config/geokit_config.rb`.