Is this your first visit? You may want to subscribe to the feed.

Articles tagged with graticule

Location-based search with Sphinx and acts_as_geocodable

Sphinx, everybody’s favorite search engine, has support for location-based search, giving you geo-aware, full-text searching. So now you can find all of the garage sales on Saturday within 20 miles that have LPs and a reel mower.

All you need to do is add latitude and longitude (in radians) to the index, allowing you to limit the results to records within a distance of a point. The hardest part is getting the coordinates, but acts_as_geocodable makes that really easy.

To start, install acts_as_geocodable. Once you have that configured properly, install ThinkingSphinx, define an index on your geocodable model and add the coordinates to the index:

class Listing < ActiveRecord::Base
  acts_as_geocodable

  define_index do
    indexes title
    indexes description

    has geocoding.geocode(:id), :as => :geocode_id
    has 'RADIANS(geocodes.latitude)', :as => :latitude, :type => :float
    has 'RADIANS(geocodes.longitude)', :as => :longitude, :type => :float
  end
end

The three lines that start with has add the geocode id, and the latitude and longitude in radians to the index. Our index doesn’t need the geocode id, but we have to add it so that ThinkingSphinx properly joins the geocodes table.

After you rebuild the index and start the daemon, you can search for records by location. Here’s an example of taking a zip code from a user and finding all records with in 20 miles. (Note: you will need to grab the latest version, 0.2.9, of Graticule for this next bit of code to work)

def search
  location = Geocode.geocoder.locate(params[:zip]).coordinates.map(&:to_radians)
  @listings = Listing.search(params[:q], :geo => location,
    :with => {'@geodist' => 0.0..(20 * 1610.0)})
end

After looking up the coordinates of the zip code that the user entered, we do a search with the :geo parameter, limiting the results using the special @geodist condition. We have to pass in a range of floats that represent the distance of the points in meters (and since the US is in the stone age, I’m converting from miles).

That’s all there is to it. Now go write some cool location-based search and comment here about it.

Code: graticule Apr 14, 2009 ● updated Apr 14, 2009 3 comments

Graticule and MapQuest?

MapQuest has sent out several emails about their current geocoding API being discontinued. Here is the latest:

Dear MapQuest Platform Customer,

At the start of the New Year, MapQuest will be retiring the MapQuest OpenAPI product, having launched the more feature rich MapQuest Platform: Free Edition product. Since the MapQuest OpenAPI does not use the same backend as our newer APIs, nor does it provide the breadth in functionality, we want to provide you with a better free experience. Don’t wait – make the switch today!

If your application is currently being powered by the MapQuest OpenAPI product, you will need to migrate to one of 6 APIs available in the MapQuest Platform: Free Edition product prior to January 31, 2009.

Our MapQuest Platform: Free Edition product offers more flexibility and ease of development along with providing developer choice with six APIs:

SERVER SIDE APIs Java C++ .NET

CLIENT SIDE APIs JavaScript AS3 (ActionScript 3: Flash, Flex, AIR) FUJAX (Write JavaScript, output Flash)

Our MapQuest Platform: Free Edition product includes many additional features including:
  • COLLECTIONS: Support for multiple and remote collections (KML and GeoRSS); allowing easier handling of shape collections.
  • ADVANCED SHAPE OVERLAYS: Build applications that allow users to create and interact with a variety of overlays on maps, including custom lines, polygons, rectangles, and ellipses.
  • CUSTOM TILE LAYER SUPPORT.
  • Add REAL-TIME TRAFFIC to your map.
  • GLOBE VIEW: http://globe.mapquest.com.
  • AERIAL IMAGERY and HYBRID VIEWS.
  • SMART ROLLOVERS: Rollover windows that adapt their size and positioning based on the content placed in the window.
  • ADVANCED MAP MARKERS: With the MapQuest “declutter mode,” automatically move collided markers to positions on the map with a leader link pointing to their original location.

The MapQuest OpenAPI product servers will go offline on Saturday, January 31st, 2009. Please plan on migrating your application before this date or applications based on the MapQuest OpenAPI product will stop working.

You can find documentation and downloads for the MapQuest Platform: Free Edition product on our Developer Network: http://developer.mapquest.com.

Additional information can be found on: http://platform.mapquest.com & http://devblog.mapquest.com.

Thank you,

MapQuest, Inc.

Graticule, a ruby wrapper around many popular geocoding APIs, uses the old MapQuest API. I don’t use it, and I don’t know if anyone else does, so I’m leaving it to you, lazyweb: If you use the MapQuest API, or want to in the future, fork graticule on GitHub and update the MapQuest wrapper.

Code: graticule Dec 13, 2008 ● updated Dec 13, 2008 0 comments

Graticule can failover

Graticule has a new geocoder that simply calls other geocoders in succession until it gets a result.

geocoder = Graticule.service(:multi).new(
  Graticule.service(:google).new("api_key"),
  Graticule.service(:yahoo).new("api_key"),
)
geocoder.locate '49423' # <= tries geocoders in succession

This can also be used in acts_as_geocodable by simply setting Geocode.geocoder to the new multi-geocoder. See the API docs for more information.

Thanks to Matt King for some ideas on the implementation and Ben Tucker for nudging me to implement it.

Code: graticule Sep 12, 2007 ● updated Sep 12, 2007 5 comments

Google adds more countries to geocoder

Google has added support for India, Hong Kong, Taiwan, Singapore, and Ireland to their geocoder. If you’re using Graticule, it should Just Work™. Let me know if you have any problems.

Code: graticule Aug 02, 2007 1 comment

Google Maps geocoder adds support for UK

Good news for the Brits: UK Geocoding Now Available in the Maps API. This means that the Google geocoder in Graticule should now work in the UK. I’m interested to hear how well it works from anyone using it.

Code: graticule Jul 07, 2007 5 comments

Graticule update, site, and mailing list

Three Graticule related updates:

  1. I released Graticule 0.2.2 this evening to fix a bug in the Local Search Maps geocoder.
  2. There is a new homepage for Graticule and acts_as_geocodable over on RubyForge. Nothing fancy, but some basic docs with links to the RDoc
  3. I set up a mailing list for anyone interested in making Graticule better or needing help. Head over, sign up, and tell me why Graticule sucks (or rocks, or sucks rocks).
Code: graticule Mar 27, 2007 0 comments

Graticule and acts_as_geocodable go international

The single biggest request that I’ve gotten for Graticule and acts_as_geocodable has been for international support. So, for those outside the US (50% that read this blog according to google analytics), I have a present for you.

Last weekend I committed support for Local Search Maps (thanks to James Stewart), and PostcodeAnywhere, both of which have some international support, at least for Canada and Europe. I also added geocoder.ca.

Most of the international geocoding services seem to require a little more structured parameters, so with Graticule 0.2, all of the geocoders can take a hash (and some require it). As a result of gaining international support, the field names that Graticule uses have been changed to be more international-friendly: street, locality, region, postal_code, and country.

g = Graticule.service(:local_search_maps).new
location = g.locate :street => '48 Leicester Square', :locality => 'London', :country => 'UK'
location.coordinates  #=> [51.510036, -0.130427]

Geocoding IP Addresses

Several people mentioned that they would rather use acts_as_geocodable, but chose to use GeoKit, another good geocoding library (but with a little different philosophy), because it had support for geocoding IP addresses. So, with a flick of the wrist and a twitch of the nose, Graticule now supports HostIP for geocoding IP addresses:

g = Graitucle.service(:host_ip).new
location = g.locate "64.233.167.99"

location.coordinates  #=> [37.402, -122.078]
location.locality     #=> "Mountain View"
location.country      #=> "US"
location.region       #=> "CA"

Along with this, acts_as_geocodable has a helper method, remote_location:

@nearest_store = Store.find(:nearest, :origin => remote_location) if remote_location

Be careful not to rely too heavily on remote_location because the location of many IP addresses cannot be determined through HostIP.

Feedback

I’m just an ignorant North-American, so I would love some feedback from people using Graticule and acts_as_geocodable outside the US.

Code: graticule Mar 26, 2007 1 comment

Geocoding as easy as 1-2...

3?, nope there is no 3. Geocoding as easy as 1-2!

  1. Create your models
  2. Find them!
event = Event.create :street => "777 NE Martin Luther King, Jr. Blvd.",
  :city => "Portland", :region => "Oregon", :postal_code => 97232

# how far am I from RailsConf 2007?
event.distance_to "49423" #=> 1807.66560483205

# Find our new event, and any other ones in the area
Event.find(:all, :within => 50, :origin => "97232")

# Find the nearest restaurant with beer
Restaurant.find(:nearest, :origin => event, :conditions => 'beer = true')

I know you’re excited, so instead of blabbing on-and-on, FAQ-style:

How are you performing this voodoo?

A slick new plugin called acts_as_geocodable.

How do I get it?

script/plugin install -x git://github.com/collectiveidea/acts_as_geocodable.git

How do I set it up?

Its all in the README.

Why did you write this when there’s already several geocoding plugins?

The Ruby geocoding space is pretty fragmented right now. There’s all kinds of geocoders available, and none of them provide everything. We’re determined to fix that with Graticule and acts_as_geocodable.

We believe that all the heavy lifting of geocoding, distance calculations, etc., should be left to a gem, and only code that is directly related to Rails should be a Rails plugin. Even more, all the different geocoders should be available in the same package and have the same interface. A plugin should then be built on top of the gem that makes your apps geo-capabilities seem like voodoo.

We started our own projects because we didn’t think anyone else got it right. Recently, Bill Eisenhaur and Andre Lewis did a pretty good job, and we borrowed some of their ideas, but I still have issues with their approach and code, mainly that it’s all tied up into a Rails plugin.

Did you get it right?

I think we have a great foundation. It’s not perfect, nor does it have all the features of the other packages, but I think it is well architected.

Why don’t you work together?

Excellent idea! We would love to.

How does this fit in with JWZ’s use case?

(Why are you asking this?) A third of the problem is knowing where, a third is when, and a third is who. You’re on your own for the who and when.

Happy geocoding!

Code: graticule Feb 13, 2007 ● updated Jun 19, 2008 16 comments

Announcing Graticule geocoding API

update: Graticule is now hosted on Rubyforge.

Graticule is a geocoding API for interpolating address data into geographic coordinates written in Ruby. The goal is to provide a consistent interface into the various geocoding services, allowing other libraries to be built on top of them while remaining agnostic of the specific service that is being used.

In its current state, Graticule is just a repackaging of the different gems produced by Eric Hodel of Robot Co-op. It currently supports the Yahoo, Google, Geocoder.us, and MetaCarta APIs. The plan is to expand upon them.

Usage

You can grab the gem or check out the code from Subversion. The Rdoc is also available.

require 'rubygems'
require 'graticule'
geocoder = Graticule.service(:google).new "api_key"
location = geocoder.locate "1600 Amphitheatre Parkway, Mountain View, CA"

Feedback

I’d love to get your feedback. There are a few places where the API is still not consistent (e.g. Yahoo returns multiple results). I’d also appreciate any help with packaging and releasing as I am a newbie at creating Gems.

Code: graticule Oct 31, 2006 ● updated Jun 19, 2008 1 comment

Subscribe

Browse by Tag