<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>John Yerhot - Weblog &#187; Geocoding</title>
	<atom:link href="http://www.johnyerhot.com/tag/geocoding/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.johnyerhot.com</link>
	<description>im in ur computrz makin castz</description>
	<lastBuildDate>Tue, 29 Jun 2010 04:32:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Zip Code Distance Searching in Ruby on Rails</title>
		<link>http://www.johnyerhot.com/2009/06/23/zipcode-distance-searching-in-ruby-on-rails/</link>
		<comments>http://www.johnyerhot.com/2009/06/23/zipcode-distance-searching-in-ruby-on-rails/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 01:51:59 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby On Rails]]></category>
		<category><![CDATA[Geocoding]]></category>
		<category><![CDATA[Ruby On]]></category>

		<guid isPermaLink="false">http://www.johnyerhot.com/?p=105</guid>
		<description><![CDATA[In my last entry we looked at using scopes to dynamically build scopes for searching in your Ruby on Rails application.  In Tryst, we needed to let our uses search for other singles that were xxx miles from their location.  We require that new users enter their zip code, so that is what we had [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://www.johnyerhot.com/2009/06/21/smart-searching-using-named-scopes/">last entry</a> we looked at using scopes to dynamically build scopes for searching in your Ruby on Rails application.  In <a href="http://trystme.com">Tryst</a>, we needed to let our uses search for other singles that were xxx miles from their location.  We require that new users enter their zip code, so that is what we had to go off of.</p>
<p>When I was researching the best way to do this, I did a quick Twitter poll &#8211; most of my friend thought I should just use <a href="http://code.google.com/apis/maps/documentation/services.html">Google&#8217;s GeoCoding API</a>, which will let you preform these types of searches.  I really didn&#8217;t want to go this route for a couple reasons.</p>
<ol>
<li>It&#8217;s an external dependency.  Yes, Google&#8217;s uptime is impeccable, but I don&#8217;t want to rely on them</li>
<li>Google&#8217;s TOS requires that the site/app/service be free.  Tryst may end up with paid features down the road and I didn&#8217;t want to have to rewrite a substantial amount of code 1 year from now.</li>
<li>It&#8217;s a challenge.</li>
</ol>
<p>So, we decided to do our own thing.</p>
<p>Our workflow for a search would work like this &#8211; we get a distance and a zip code as search parameters, feed both of these into something that returns all the zip codes within the specified distance, and then find all the uses in those zip codes.  Easy enough.</p>
<p>PS.  I&#8217;m using MySQL here.</p>
<p>First, we need a reference for zip codes.  I found <a href="http://www.maxmind.com/app/geolitecity">this</a> great free CSV that has all zip codes, major cities, longitude, latitude, area codes, and even <a href="http://code.google.com/apis/adwords/docs/developer/adwords_api_us_metros.html">metropolitan codes</a>. Import it into your database and remove any rows that were not in the US.  I actually had a &#8216;Location&#8217; model in my Rails application that I imported this into.</p>
<p>After some digging around the webs, I found some crazy algorithms for generating distance between different locations based on their longitude and latitude.  I&#8217;m not going to pretend to understand everything that is happening here, but after some playing around I ended up with this:</p>
<pre>SELECT o.zip_code
FROM locations z, locations o, locations a

WHERE z.zip_code = #{zip_code}
AND	z.zip_code = a.zip_code
AND	(3956 * (2 * ASIN(SQRT(
		POWER(SIN(((z.latitude-o.latitude)*0.017453293)/2),2) +
		COS(z.latitude*0.017453293) *
		COS(o.latitude*0.017453293) *
		POWER(SIN(((z.longitude-o.longitude)*0.017453293)/2),2)
	)))) &lt;= #{distance}</pre>
<p>I&#8217;ll let you guess which part does the calculation. :)<br />
<strong>zip_code</strong> and <strong>distance</strong> you&#8217;ll need to pipe into the SQL, but you&#8217;ll get back all the zip codes with in your specification.  We just thew the returned array of zip odes into a scope like this:</p>
<pre># models/users.rb
def search(params)
    scope = User.scoped({})
    ...
    scope = scope.conditions "users.zip_code in (?)", zip_codes unless zip_codes.blank?
    ...
end</pre>
<p>Now, this query is fairly slow.  By slow, I mean about 25-30ms correctly indexed on my development box.  For us it&#8217;s just fine.</p>
<p>I hope that helped someone out &#8211; I had a hell of a time finding a solution I liked and I really think this is the best one.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnyerhot.com/2009/06/23/zipcode-distance-searching-in-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Integrating Google Maps in Your Rails 2.0 App.</title>
		<link>http://www.johnyerhot.com/2008/01/05/integrating-google-maps-in-your-rails-20-app/</link>
		<comments>http://www.johnyerhot.com/2008/01/05/integrating-google-maps-in-your-rails-20-app/#comments</comments>
		<pubDate>Sun, 06 Jan 2008 03:06:55 +0000</pubDate>
		<dc:creator>John</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby On Rails]]></category>
		<category><![CDATA[Geocoding]]></category>
		<category><![CDATA[Google Maps]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.johnyerhot.com/2008/01/05/integrating-google-maps-in-your-rails-20-app/</guid>
		<description><![CDATA[NOTE:  THIS IS AN OLD POST AND THE INSTRUCTIONS MAY BE OUTDATED. YMMV
In my first real post in a year, I thought I&#8217;d share some Ruby stuff I&#8217;ve recently done &#8211; Integrating your Rails 2.0 app with Google Maps.
So, here is what we are aiming to accomplish: You are going to provide an address, say [...]]]></description>
			<content:encoded><![CDATA[<p>NOTE:  THIS IS AN OLD POST AND THE INSTRUCTIONS MAY BE OUTDATED. YMMV</p>
<p>In my first <em>real</em> post in a year, I thought I&#8217;d share some Ruby stuff I&#8217;ve recently done &#8211; Integrating your Rails 2.0 app with Google Maps.</p>
<p>So, here is what we are aiming to accomplish: You are going to provide an address, say 123 Foobar St, Anywhere, MN 55812.   We are going to send it to a <a title="geocoder" href="http://en.wikipedia.org/wiki/Geocoding" target="_blank">geocoder</a>, get the longitude and latitude, send that to Google, and get back the map information.</p>
<p>whew.  Actually, its not nearly as hard as it sounds.</p>
<p>First, install the <a href="http://blog.segment7.net/articles/2006/06/13/geocoding-goodness" target="_blank">google-geocode</a> gem:<br />
<code><br />
sudo gem install google-geocode</code><br />
The install the <a href="https://rubyforge.org/projects/ym4r/" target="_blank">ym4r_gm</a>, which will talk to Google for us.<br />
<code><br />
script/plugin install svn://rubyforge.org/var/svn/ym4r/Plugins/GM/trunk/ym4r_gm</code><br />
Alright, finally, include the google-geocode gem in your controller.</p>
<p><code>require 'rubygems'<br />
require 'google_geocode'</code></p>
<p>Now,  you will need to get an API key from <a title="Google" href="http://code.google.com/apis/maps/signup.html" target="_blank">Google</a>, and then put that key in the newely created config/gmaps_api_key.yml (as <a href="http://www.styledev.com/">Drew Bushaw</a> points out) or hard code it (Which I do in the example).  There should be three keys already in there, and they will work when using your local machine, but will not with anything other than localhost.  Alternativly, if you want to hardcode it in, place it where I have &#8220;your api key here&#8221; in the next section.</p>
<p>Add to your page header (prolly your layout and view) to include the required API javascripts, etc&#8230;<br />
<code>&lt;%= GMap.header %&gt;<br />
&lt;%= @map.to_html %&gt;</code></p>
<p>Ok, now heres the fun.  To get the geocode information, simply:</p>
<p><code>gg = GoogleGeocode.new "your api key here" #hard coded<br />
#not hardcoded<br />
#gg = GoogleGeocode.new YAML.load_file(RAILS_ROOT +‘/config/gmaps_api_key.yml’)[ENV['RAILS_ENV']]</code><br />
<code> loc = gg.locate @property.full_address</code><br />
Now, I have @property and full_address is its full address (123 Foobar, Somecity, MN 55812 for example).  You can also try it without some vitals, such as zip code.</p>
<p>Now we have to send Google Maps the correct information:<br />
<code><br />
@map = GMap.new("map_div")<br />
@map.control_init(:small =&gt; true) #add :large_map =&gt; true to get zoom controls<br />
@map.center_zoom_init([loc.latitude, loc.longitude],14)<br />
@map.overlay_init(GMarker.new([loc.latitude, loc.longitude],:title =&gt; @property.name, :info_bubble =&gt; loc.address))<br />
</code><br />
Notice, &#8220;map_div&#8221;, which will come into play in the next step.  Some useful tid bits here include the :title, which will be the title of the pin on the map, :info_bubble which will appear when you hover over the pin, and where I specified &#8220;14&#8243;.  Here you specify the altitude the map will be at.  Experiment for whatever your needs are.</p>
<p>Now, the final thing you need to do is put this to work in your view.<br />
<code><br />
&lt;%= @map.div(:width =&gt; 493, :height =&gt; 300) %&gt;</code></p>
<p>As you can see, I&#8217;ve specified a :width and :height.   Now, fire everything up and you should get something similar to&#8230;</p>
<p><img src="http://www.johnyerhot.com/wp-content/uploads/2008/01/screen_.png" alt="screen_grab_google_maps_1_5_07" /></p>
<p>Now in my case I had people inputing address and if/when they enter one that is non-existent or incorrect, I had to catch it since a google-geocode will throw a big error if you give it bad information.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johnyerhot.com/2008/01/05/integrating-google-maps-in-your-rails-20-app/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
	</channel>
</rss>
