GeoKit: all about the :origin argument

Feb 15, 2007 by Andre

The whole point of the acts_as_mappable mixin is to let you find things by location:

class Store < ActiveRecord::Base
    acts_as_mappable
    ...
end

...

Store.find(:all, :origin=>[37.792,-122.393])

But, what all can be supplied in the :origin argument? There are three possibilities.

1. Pass in a two-element array with latitudes/longitude values

Store.find(:all, :origin=>[37.792,-122.393])

Whenever :origin is an array, the code assumes in an array of two numbers representing latitude and longitude. If you pass in an array of anything else, you'll get an error.

2. Pass in a geocodeable string

Store.find(:all, :origin=>'100 Spear st, San Francisco, CA')

Again, the detection is based on the type of thing passed in under origin. So, if you expect GeoKit to geocode it, it better be in the format of a string. Zip codes are fine, but it better be a string. So, this will work:

Store.find(:all, :origin=>'94111') # it's a string, so it gets geocoded

But this will not:

# WON'T WORK -- it's not a string, so it doesn't get geocoded
Store.find(:all, :origin=>94111)

3. pass an object

Specifically, an object that has lat and lng methods, or latitude and longitude methods, or whatever methods you have specified for lng_column_name and lat_column_name.

Store.find(:all, :origin=>an_object_with_the_right_methods)

So, what sort of objects have lat and lng methods? Well, our own GeoKit::LatLng objects for starters. So, this will certainly work:

ll=LatLng.new(37.792,-122.393])
Store.find(:all, :origin=>ll)

GeoKit::GeoLoc also has lat and lng methods, so it will work too. By the way, GeoLoc is what gets returned when you make a geocoding call:

loc = GeoKit::Geocoders.GoogleGeocoder.geocode('94117')
Store.find(:all, :origin=>loc)

So far so good. What else has the appropriate methods? Well, anything that mixes in actsasmappable needs to have some sort of latitude/longitude methods. Say you already have an instance of Store -- you can pass the instance in as the origin:

starbucks=Store.find_by_name('Starbucks')
Store.find(:all, :origin=>starbucks)

In Summary . . .

There are three things you can pass into the :origin argument: 1) a two-element array containing latitude and longitude; 2) a geocodable string; 3) an object which will respond to lat/lng or latitude/longitude calls. Typically, you'll find yourself passing in LatLng or GeoLoc objects, or possibly other instances of whatever model you've mixed ActsAsMappable into.

Comments

1

arron mabrey on Apr 15

I just installed GeoKit and like it pretty well
I'm getting results from my store table when I hard code the lat/lng columns

How would I go about using GeoKit to populate the lat/lng columns when I create a new store?

I'm just starting rails and am not so sure about the structure.
I have an "admin controller" and a "store model" I don't know if the code will need to go into the controller that creates the new store object through the store model or in the model itself with the validation and stuff.

I think i'm going to have to some-how pull out the address info for the store using Active-Record for use in the goeloc feature and then get the lat/lng back into the same store record.

How does this all work at the same time so when I first create a store it will have lat/lng to search by.

Thank you for any help

2

Andre on Apr 16

Arron, add a before_validation callback in your model, and geocode the address there. If the geocoding fails, add an error to the model.

3

alex gong on May 14

ignore my previous comment about fulltext / geokit overwriting sql
it was executing, but my error that it wasn't searching proper area.

everything worked properly! :)

thanks for making and releasing such a great plugin

Post a comment

 
This is so filters can reject the spam-bots. Thanks!