<?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>Scott Blaine &#187; distance</title>
	<atom:link href="http://scottblaine.com/tag/distance/feed" rel="self" type="application/rss+xml" />
	<link>http://scottblaine.com</link>
	<description>Omaha web developer</description>
	<lastBuildDate>Wed, 12 Oct 2011 01:00:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Sorting records by distance using PHP &amp; MySQL</title>
		<link>http://scottblaine.com/sorting-records-by-distance-using-php-mysql</link>
		<comments>http://scottblaine.com/sorting-records-by-distance-using-php-mysql#comments</comments>
		<pubDate>Thu, 09 Jul 2009 01:00:00 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[distance]]></category>
		<category><![CDATA[logic]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://scottblaine.com/?p=276</guid>
		<description><![CDATA[I recently got to the point in my project where I was ready to implement sorting for the search results.&#160; I wanted to sort by the distance between two zip codes. However, I quickly realized I had a major problem on my hands. I had a (potentially) large number of search results that I needed [...]]]></description>
			<content:encoded><![CDATA[<p>I recently got to the point in my project where I was ready to implement sorting for the search results.&nbsp; I wanted to sort by the distance between two zip codes. However, I quickly realized I had a major problem on my hands. I had a (potentially) large number of search results that I needed to sort. Too many to sort using PHP; I needed a way to sort them in MySQL. But the method I&#8217;d planned to use to calculate the distance between zip codes, <a title="PHP Zip Code Range and Distance Calculation" href="http://www.micahcarrick.com/04-19-2005/php-zip-code-range-and-distance-calculation.html">Micah Carrick&#8217;s distance calculation class</a>, was implemented entirely in PHP. I needed some way for the distance to end up in the SQL query so that I could sort on it.</p>
<p>After searching around for a bit I came across <a title="A program that finds zip codes by distance from a particular zip code using the Haversine Formula" href="http://www.phpbuilder.com/snippet/download.php?type=snippet&amp;id=1363">this nice bit of code</a> which creates a MySQL query using PHP variables to calculate the distance. By combining the two methods I was able to create a very workable solution for sorting by distance. Here&#8217;s what I did:</p>
<p>First, download the zipcode SQL from <a title="PHP Zip Code Range and Distance Calculation" href="http://www.micahcarrick.com/04-19-2005/php-zip-code-range-and-distance-calculation.html">Micah&#8217;s page</a> and run each SQL file. That should give you a new shiny table called zip_code filled to the brim with (what else?) zip codes.</p>
<p>Second, you&#8217;ll need the get_zip_point function from Micah&#8217;s code:</p>
<pre>
/**
 * This function pulls just the latitude and longitude from the
 * database for a given zip code.
 */
function get_zip_point($zip)
{
	$sql = "SELECT lat, lon from zip_code WHERE zip_code='$zip'";
	$r = mysql_query($sql);
	if (!$r)
	{
		$this-&gt;last_error = mysql_error();
		return FALSE;
	}
	else
	{
		$row = mysql_fetch_array($r);
		mysql_free_result($r);
		return $row;
	}
}
</pre>
<p>Third, you&#8217;ll want a function to generate the SQL you&#8217;ll use in your query:</p>
<pre>
/**
 * Returns the SQL to calculate distance based on latitude and longitude
 */
function get_distance_SQL($lat, $lon)
{
	$sql = "
	3957 * 2 *
	atan2(
		sqrt(
			pow((sin(0.0174*(lat-$lat)/2)),2) +
			cos(0.0174*$lat) * cos(0.0174*lat) *
			pow((sin(0.0174*(lon-$lon)/2)),2)
		)
		,
		sqrt(1-
			(
				pow((sin(0.0174*(lat-$lat)/2)),2) +
				cos(0.0174*$lat) * cos(0.0174*lat) *
				pow((sin(0.0174*(lon-$lon)/2)),2)
			)
		)
	)
	as distance";

	return $sql;
}
</pre>
<p>Fourth, you wrap it all together with a few lines of PHP. I&#8217;m using CodeIgniter to handle the SQL call, so your mileage may vary a bit on the exact implementation details.</p>
<pre>
list($lat, $lon) = $this-&gt;get_zip_point($user_zip_code);

$this-&gt;db-&gt;select("users.username, zip_code.city, zip_code.state_prefix," . $this-&gt;get_distance_SQL($lat, $lon), FALSE)
		-&gt;from('users')
		-&gt;join('zip_code',"users.zip_code = zip_code.zip_code")
		-&gt;order_by('distance', 'asc');

$search_results = $this-&gt;db-&gt;get();
</pre>
<p>And shazam, you now have a way to sort a set of SQL results by distance.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottblaine.com/sorting-records-by-distance-using-php-mysql/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

