<?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/"
	>

<channel>
	<title>larsgebhardt</title>
	<atom:link href="http://www.larsgebhardt.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.larsgebhardt.de</link>
	<description>Freelancing Web Developer, Ruby on Rails Tutorials</description>
	<pubDate>Tue, 16 Jun 2009 07:13:29 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ApplyHQ launched</title>
		<link>http://www.larsgebhardt.de/2009/06/16/applyhq-launched/</link>
		<comments>http://www.larsgebhardt.de/2009/06/16/applyhq-launched/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 07:13:29 +0000</pubDate>
		<dc:creator>Lars</dc:creator>
		
		<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://www.larsgebhardt.de/?p=423</guid>
		<description><![CDATA[After many hours of work i'm proud to say - it's done. On June, 15th ApplyHQ.com launched successfully.]]></description>
			<content:encoded><![CDATA[<p>After many hours of work i&#8217;m proud to say - it&#8217;s done. On June, 15th ApplyHQ.com launched successfully.</p>
<p>I am grateful for the support of my twitter friends. They have given me many helpful hints i&#8217;m going to implement next days and weeks.</p>
<p><a href="http://applyhq.com">ApplyHQ.com</a> is a web application providing freelancers services to apply for jobs and projects in a easier, faster and professional way. Its purpose is to simplify project and job acquisition for hard working freelancers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.larsgebhardt.de/2009/06/16/applyhq-launched/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Use tweetmeme plugin with redtime theme</title>
		<link>http://www.larsgebhardt.de/2009/06/05/use-tweetmeme-plugin-with-redtime-theme/</link>
		<comments>http://www.larsgebhardt.de/2009/06/05/use-tweetmeme-plugin-with-redtime-theme/#comments</comments>
		<pubDate>Fri, 05 Jun 2009 09:14:26 +0000</pubDate>
		<dc:creator>Lars</dc:creator>
		
		<category><![CDATA[Wordpress]]></category>

		<category><![CDATA[redtime]]></category>

		<category><![CDATA[tweetmeme]]></category>

		<guid isPermaLink="false">http://www.larsgebhardt.de/?p=402</guid>
		<description><![CDATA[While i was setting up the new theme to this blog i found a small problem with the tweetmeme plugin. The featured post wasn't displayed correctly because of the javascript code from tweetmeme. ]]></description>
			<content:encoded><![CDATA[<p>While i was setting up the new theme to this blog i found a small problem with the tweetmeme plugin. The featured post wasn&#8217;t displayed correctly because of the javascript code from tweetmeme. </p>
<p>It has costed me some efford but here comes the solution. This bug can be fixed easily by modifying the fn-general.php file inside the themes/redtime/includes folder.</p>
<p><span id="more-402"></span></p>
<p>You have to modify the function: the_content_limit around line 207.</p>
<p>Search following code in the function:</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="re0">$content</span> <span class="sy0">=</span> <a href="http://www.php.net/str_replace"><span class="kw3">str_replace</span></a><span class="br0">&#40;</span><span class="st_h">']]&gt;'</span><span class="sy0">,</span> <span class="st_h">']]&amp;gt;'</span><span class="sy0">,</span> <span class="re0">$content</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$content</span> <span class="sy0">=</span> <a href="http://www.php.net/strip_tags"><span class="kw3">strip_tags</span></a><span class="br0">&#40;</span><span class="re0">$content</span><span class="br0">&#41;</span><span class="sy0">;</span></div></td></tr></tbody></table></div>
<p>and replace it with</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="re0">$content</span> <span class="sy0">=</span> <a href="http://www.php.net/str_replace"><span class="kw3">str_replace</span></a><span class="br0">&#40;</span><span class="st_h">']]&gt;'</span><span class="sy0">,</span> <span class="st_h">']]&amp;gt;'</span><span class="sy0">,</span> <span class="re0">$content</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$content</span> <span class="sy0">=</span> <a href="http://www.php.net/preg_replace"><span class="kw3">preg_replace</span></a><span class="br0">&#40;</span><span class="st0">&quot;'&lt;script[^&gt;]*&gt;.*&lt;/script&gt;'siU&quot;</span><span class="sy0">,</span><span class="st_h">''</span><span class="sy0">,</span><span class="re0">$content</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$content</span> <span class="sy0">=</span> <a href="http://www.php.net/strip_tags"><span class="kw3">strip_tags</span></a><span class="br0">&#40;</span><span class="re0">$content</span><span class="br0">&#41;</span><span class="sy0">;</span></div></td></tr></tbody></table></div>
<p>What does this line? The regular expression removes all code between the <em>script</em> tags. So the javascript code from tweetmeme is removed and the featured post will be displayed properly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.larsgebhardt.de/2009/06/05/use-tweetmeme-plugin-with-redtime-theme/feed/</wfw:commentRss>
		</item>
		<item>
		<title>17 Visual Effects for Ruby on Rails RJS functions</title>
		<link>http://www.larsgebhardt.de/2009/06/01/17-visual-effects-for-ruby-on-rails-rjs-functions/</link>
		<comments>http://www.larsgebhardt.de/2009/06/01/17-visual-effects-for-ruby-on-rails-rjs-functions/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 18:25:06 +0000</pubDate>
		<dc:creator>Lars</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.larsgebhardt.de/?p=366</guid>
		<description><![CDATA[Ruby on Rails has a scriptaculous framework integration out of the box. The Rails helper functions are very powerful, but every time i need a visual_effect i have to search in API docs to get all Rails supported scriptaculous effects. 
To shorten the search i&#8217;m going to list all 17 supported effects.

Effects for appearing

This effects [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby on Rails has a scriptaculous framework integration out of the box. The Rails helper functions are very powerful, but every time i need a visual_effect i have to search in API docs to get all Rails supported scriptaculous effects. </p>
<p>To shorten the search i&#8217;m going to list all 17 supported effects.</p>
<p><span id="more-366"></span></p>
<h3>Effects for appearing</h3>
<p>
This effects make sence after AJAX create or show functions. They add the new content effectfully after your record is created or replace a list entry with a detail entry after show function.
</p>
<ol>
<li>
  <strong>Appear</strong> - Fades in the selected DIV.
</li>
<li>
  <strong>BlindDown</strong> - Fades in the selected DIV from top to bottom.
</li>
<li>
  <strong>SlidesDown</strong> - Slides in the selected DIV from top to bottom.
</li>
<li>
  <strong>Grow</strong> - Fades and zoomes in the selected DIV.
</li>
</ol>
<h3>Effects for disappearing</h3>
<p>
This effects you can use to remove a DIV after a destroy function was executed successfully.
</p>
<ol>
<li>
  <strong>Fade</strong> - Fades out the selected DIV
</li>
<li>
  <strong>Puff</strong> - Fades out and zoomes out the selected DIV
</li>
<li>
  <strong>Blind up</strong> - Fades out from bottom to top side of selected DIV
</li>
<li>
  <strong>SwitchOff</strong> - Flash Up and fade out
</li>
<li>
  <strong>SlideUp</strong> - Moves the DIV from bottom to top
</li>
<li>
  <strong>DropOut</strong> - Fades and moves out to bottom.
</li>
<li>
  <strong>Squish</strong> - Minimizes the DIV to left top corner.
</li>
<li>
  <strong>Fold</strong> - Foldes the DIV first to top second to left.
</li>
<li>
  <strong>Shrink</strong> - Minimize the DIV to center direction.
</li>
<li>
  <strong>Hide</strong> - Hides the DIV (thx to Nick)
</li>
</ol>
<h3>Effects for highlighting</h3>
<p>
After AJAX update functions this group of effects makes sence. It catches the attention after a record is updated.
</p>
<ol>
<li>
  <strong>Shake</strong> - Shakes the DIV horizontally.
</li>
<li>
  <strong>Pulsate</strong> - Fades out and zoomes out the selected DIV
</li>
<li>
  <strong>Highlight</strong> - Highlights the DIV with yellow flashing.
</li>
</ol>
<h3>How to use in views</h3>
<p>Use the effects in following way in your views:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sy0">&lt;%</span>= <span class="kw5">link_to_remote</span><span class="br0">&#40;</span><span class="st0">&quot;Destroy&quot;</span>, <br />
<span class="re3">:url</span> <span class="sy0">=&gt;</span> item_path<span class="br0">&#40;</span>item<span class="br0">&#41;</span>, <br />
<span class="re3">:complete</span> <span class="sy0">=&gt;</span> <span class="kw5">visual_effect</span><span class="br0">&#40;</span><span class="re3">:Fade</span>,<span class="st0">&quot;item_box_#{item.id}&quot;</span><span class="br0">&#41;</span>,<br />
<span class="re3">:method</span> <span class="sy0">=&gt;</span> <span class="re3">:delete</span><span class="br0">&#41;</span><br />
<span class="sy0">%&gt;</span></div></td></tr></tbody></table></div>
<p>Have fun.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.larsgebhardt.de/2009/06/01/17-visual-effects-for-ruby-on-rails-rjs-functions/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Nokia Sportstracker GPS data on Google Maps with Ruby on Rails</title>
		<link>http://www.larsgebhardt.de/2009/05/10/how-to-display-nokia-sportstracker-gps-data-on-google-maps-with-ruby-on-rails/</link>
		<comments>http://www.larsgebhardt.de/2009/05/10/how-to-display-nokia-sportstracker-gps-data-on-google-maps-with-ruby-on-rails/#comments</comments>
		<pubDate>Sun, 10 May 2009 18:19:05 +0000</pubDate>
		<dc:creator>Lars</dc:creator>
		
		<category><![CDATA[Geocoding]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Tutorials]]></category>

		<category><![CDATA[Google Maps]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.larsgebhardt.de/?p=325</guid>
		<description><![CDATA[In my last tutorial i have explained how to import GPX files from Nokia Sportstracker Software. We have created a small Ruby on Rails application - navtracker - which we will use again. We will display the imported data on Google Maps with Ruby on Rails.

Its a good idea to read my previous tutorial before. [...]]]></description>
			<content:encoded><![CDATA[<p>In my last tutorial i have explained how to import GPX files from Nokia Sportstracker Software. We have created a small Ruby on Rails application - navtracker - which we will use again. We will display the imported data on Google Maps with Ruby on Rails.</p>
<p><span id="more-325"></span></p>
<p>Its a good idea to <a href="http://www.larsgebhardt.de/2009/05/08/how-to-import-nokia-sportstracker-gps-data-with-ruby-on-rails-part-1/">read my previous tutorial</a> before. Information about the Google Maps API can you find <a href="http://code.google.com/apis/maps/">here</a>. We need a key for our http://localhost:3000 development environment too.</p>
<p>At first we have to update track.rb and routes.rb</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Track <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
&nbsp; <span class="kw5">has_many</span> <span class="re3">:tracksegments</span>, <span class="re3">:dependent</span> <span class="sy0">=&gt;</span> <span class="re3">:destroy</span><br />
&nbsp; <span class="kw5">has_many</span> <span class="re3">:points</span>, <span class="re3">:through</span> <span class="sy0">=&gt;</span> <span class="re3">:tracksegments</span><br />
&nbsp; has_attached_file <span class="re3">:gpx</span><br />
&nbsp; ...<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">map.<span class="me1">resources</span> <span class="re3">:tracksegments</span>, <span class="re3">:has_many</span> <span class="sy0">=&gt;</span> <span class="re3">:points</span><br />
&nbsp; map.<span class="me1">resources</span> <span class="re3">:tracks</span>, <span class="re3">:has_many</span> <span class="sy0">=&gt;</span> <span class="re3">:tracksegments</span><br />
&nbsp; map.<span class="me1">resources</span> <span class="re3">:tracks</span>, <span class="re3">:has_many</span> <span class="sy0">=&gt;</span> <span class="re3">:points</span></div></td></tr></tbody></table></div>
<p>At second, we modifiy views/tracks/show.html.erb to get a better overview.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">&lt;h2&gt;<span class="sy0">&lt;%</span>=h <span class="re1">@track</span>.<span class="me1">gpx_file_name</span> <span class="sy0">%&gt;</span> &lt;/h2&gt;<br />
&lt;table&gt;<br />
&nbsp; &nbsp; &lt;tr&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;th&gt;Point #&lt;/th&gt;&lt;th&gt;Latitude&lt;/th&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;th&gt;Longitude&lt;/th&gt;&lt;th&gt;Elevation&lt;/th&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;th&gt;Description&lt;/th&gt;&lt;th&gt;Timestamp&lt;/th&gt;<br />
&nbsp; &nbsp; &lt;/tr&gt; &nbsp; <br />
<span class="sy0">&lt;%</span> <span class="re1">@track</span>.<span class="me1">tracksegments</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>segment<span class="sy0">|%&gt;</span><br />
&nbsp; &nbsp; <span class="sy0">&lt;%</span> segment.<span class="me1">points</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>point<span class="sy0">|%&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;tr&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td&gt;<span class="sy0">&lt;%</span>= point.<span class="me1">name</span><span class="sy0">%&gt;</span>&lt;/td&gt;&lt;td&gt;<span class="sy0">&lt;%</span>= point.<span class="me1">latitude</span><span class="sy0">%&gt;</span>&lt;/td&gt; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td&gt;<span class="sy0">&lt;%</span>= point.<span class="me1">longitude</span><span class="sy0">%&gt;</span>&lt;/td&gt;&lt;td&gt;<span class="sy0">&lt;%</span>= point.<span class="me1">elevation</span><span class="sy0">%&gt;</span>m&lt;/td&gt; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td&gt;<span class="sy0">&lt;%</span>= point.<span class="me1">description</span><span class="sy0">%&gt;</span>&lt;/td&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">&lt;%</span>= point.<span class="me1">point_created_at</span>.<span class="me1">strftime</span><span class="br0">&#40;</span><span class="st0">&quot;%H:%M - %Y/%m/%d&quot;</span><span class="br0">&#41;</span><span class="sy0">%&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;/tr&gt;<br />
&nbsp; &nbsp; <span class="sy0">&lt;%</span>end<span class="sy0">%&gt;</span><br />
<span class="sy0">&lt;%</span>end<span class="sy0">%&gt;</span><br />
&lt;/table&gt;</div></td></tr></tbody></table></div>
<p>Next, we need the google maps api javascript code in layouts/tracks.html.erb</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sy0">&lt;</span>script src=<span class="st0">&quot;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;sensor=false&amp;amp;key=ABQIAAAA7oGKIGpyMHBf9frQDOIDqxTJQa0g3IQ9GZqIMmInSLzwtGDKaBTSyz-43dhS-cG7AWZa73AghbA31A&quot;</span> type=<span class="st0">&quot;text/javascript&quot;</span><span class="sy0">&gt;&lt;/</span>script<span class="sy0">&gt;</span></div></td></tr></tbody></table></div>
<p>Next we add the google maps div to views/tracks/show.html.erb:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">&lt;h2&gt;<span class="sy0">&lt;%</span>=h <span class="re1">@track</span>.<span class="me1">gpx_file_name</span> <span class="sy0">%&gt;</span> &lt;/h2&gt;<br />
&nbsp; &lt;div id=&quot;map_canvas&quot; style=&quot;width: 750px; height: 500px&quot;&gt;&lt;/div&gt;</div></td></tr></tbody></table></div>
<p>Programming the google maps api requires some javascript skills. At first we create a javascript file: googlemaps.js in /public/javascripts. We create following functions here:</p>
<div class="codecolorer-container javascript blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="javascript codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">function</span> load_segment_points<span class="br0">&#40;</span>map<span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; GDownloadUrl<span class="br0">&#40;</span><span class="st0">&quot;/tracks/&quot;</span><span class="sy0">+</span>track_id<span class="sy0">+</span><span class="st0">&quot;/points.xml&quot;</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>data<span class="sy0">,</span> responseCode<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> points <span class="sy0">=</span> <span class="kw2">new</span> Array<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> xml <span class="sy0">=</span> GXml.<span class="me1">parse</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> xml_points <span class="sy0">=</span> xml.<span class="me1">documentElement</span>.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'point'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> i <span class="sy0">&lt;</span> xml_points.<span class="me1">length</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; points<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw2">new</span> Object<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; points<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&quot;latitude&quot;</span><span class="br0">&#93;</span> <span class="sy0">=</span> xml_points<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'latitude'</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">firstChild</span>.<span class="me1">data</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; points<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&quot;longitude&quot;</span><span class="br0">&#93;</span> <span class="sy0">=</span> xml_points<span class="br0">&#91;</span>i<span class="br0">&#93;</span>.<span class="me1">getElementsByTagName</span><span class="br0">&#40;</span><span class="st0">'longitude'</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>.<span class="me1">firstChild</span>.<span class="me1">data</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; set_start_point<span class="br0">&#40;</span>points<span class="sy0">,</span>map<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; set_end_point<span class="br0">&#40;</span>points<span class="sy0">,</span>map<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; add_route<span class="br0">&#40;</span>points<span class="sy0">,</span>map<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></td></tr></tbody></table></div>
<p>We use the GDownloadUrl to get a xml file of all points of current track. We assign the track_id parameter in views/layouts/tracks.html.erb</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">&lt;script type=&quot;text/javascript&quot;&gt;<br />
&nbsp; var track_id = <span class="sy0">&lt;%</span>= <span class="re1">@track</span>.<span class="me1">id</span><span class="sy0">%&gt;</span><br />
&lt;/script&gt;</div></td></tr></tbody></table></div>
<p>And we add to views/layouts/tracks.html.erb the javascript_include_tag too:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sy0">&lt;%</span>= <span class="kw5">javascript_include_tag</span> <span class="re3">:all</span>, <span class="re3">:cache</span> <span class="sy0">=&gt;</span> <span class="kw2">true</span> <span class="sy0">%&gt;</span></div></td></tr></tbody></table></div>
<p>In our googlemaps.js file we need following functions too:</p>
<div class="codecolorer-container javascript blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="javascript codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">function</span> set_start_point<span class="br0">&#40;</span>points<span class="sy0">,</span>map<span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> point <span class="sy0">=</span> <span class="kw2">new</span> GLatLng<span class="br0">&#40;</span>points<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&quot;latitude&quot;</span><span class="br0">&#93;</span><span class="sy0">,</span> points<span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&quot;longitude&quot;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; map.<span class="me1">setCenter</span><span class="br0">&#40;</span>point<span class="sy0">,</span> <span class="nu0">13</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; map.<span class="me1">addOverlay</span><span class="br0">&#40;</span><span class="kw2">new</span> GMarker<span class="br0">&#40;</span>point<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></td></tr></tbody></table></div>
<p>set_start_point marks the point the current segment of the route is starting.</p>
<div class="codecolorer-container javascript blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="javascript codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">function</span> set_end_point<span class="br0">&#40;</span>points<span class="sy0">,</span>map<span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> max <span class="sy0">=</span> points.<span class="me1">length</span><span class="sy0">-</span><span class="nu0">1</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> point <span class="sy0">=</span> <span class="kw2">new</span> GLatLng<span class="br0">&#40;</span>points<span class="br0">&#91;</span>max<span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&quot;latitude&quot;</span><span class="br0">&#93;</span><span class="sy0">,</span> points<span class="br0">&#91;</span>max<span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&quot;longitude&quot;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; map.<span class="me1">setCenter</span><span class="br0">&#40;</span>point<span class="sy0">,</span> <span class="nu0">13</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; map.<span class="me1">addOverlay</span><span class="br0">&#40;</span><span class="kw2">new</span> GMarker<span class="br0">&#40;</span>point<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span> <br />
<span class="br0">&#125;</span></div></td></tr></tbody></table></div>
<p>set_end_point marks the latest point of current segment.</p>
<div class="codecolorer-container javascript blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="javascript codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">function</span> init_map<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> map <span class="sy0">=</span> <span class="kw2">new</span> GMap2<span class="br0">&#40;</span>document.<span class="me1">getElementById</span><span class="br0">&#40;</span><span class="st0">&quot;map_canvas&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; map.<span class="me1">setUIToDefault</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> &nbsp; <br />
&nbsp; &nbsp; load_segment_points<span class="br0">&#40;</span>map<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></td></tr></tbody></table></div>
<p>ini_map creates the Google Map and calls load_segment_points.</p>
<div class="codecolorer-container javascript blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="javascript codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">function</span> add_route<span class="br0">&#40;</span>points<span class="sy0">,</span>map<span class="br0">&#41;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> line <span class="sy0">=</span> <span class="kw2">new</span> Array<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="kw2">var</span> i <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> i <span class="sy0">&lt;</span> points.<span class="me1">length</span><span class="sy0">;</span> i<span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; line<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw2">new</span> GLatLng<span class="br0">&#40;</span>points<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&quot;latitude&quot;</span><span class="br0">&#93;</span><span class="sy0">,</span>points<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&quot;longitude&quot;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span> &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">var</span> polyline <span class="sy0">=</span> <span class="kw2">new</span> GPolyline<span class="br0">&#40;</span>line<span class="sy0">,</span> <span class="st0">&quot;#aa0000&quot;</span><span class="sy0">,</span> <span class="nu0">5</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; map.<span class="me1">addOverlay</span><span class="br0">&#40;</span>polyline<span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></td></tr></tbody></table></div>
<p>add_route creates the polyline and adds it on our Google Maps.</p>
<div class="codecolorer-container javascript blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="javascript codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">function</span> initialize<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>GBrowserIsCompatible<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; init_map<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div></td></tr></tbody></table></div>
<p>The function: initialize is called by body onload to add the map to our website. With all this javascript functions we can enter http://localhost:3000/tracks/3 (replace 3 with your test track number) and some screenshot like this:</p>
<p><img src="http://www.larsgebhardt.de/wp-content/bild-2.jpg" alt="bild-2" title="bild-2" width="650" height="524" class="alignnone size-full wp-image-345" /></p>
<p>With the both tutorials about GPX file import and display it in google maps you should be able to write your own applications working with Nokia Sportstracker GPS data.</p>
<p><strong>Update. I uploaded project files and gpx data file. Both are compressed with ZIP:</strong></p>
<p><a href='http://www.larsgebhardt.de/wp-content/uploads/navtracker.zip'>navtracker.zip</a><br />
<a href='http://www.larsgebhardt.de/wp-content/uploads/ersland-rundtgpx.zip'>ersland-rundtgpx.zip</a></p>
<p>If you like this tutorial tell it your friends and share it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.larsgebhardt.de/2009/05/10/how-to-display-nokia-sportstracker-gps-data-on-google-maps-with-ruby-on-rails/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to import Nokia Sportstracker GPS data with Ruby on Rails</title>
		<link>http://www.larsgebhardt.de/2009/05/08/how-to-import-nokia-sportstracker-gps-data-with-ruby-on-rails-part-1/</link>
		<comments>http://www.larsgebhardt.de/2009/05/08/how-to-import-nokia-sportstracker-gps-data-with-ruby-on-rails-part-1/#comments</comments>
		<pubDate>Fri, 08 May 2009 09:32:52 +0000</pubDate>
		<dc:creator>Lars</dc:creator>
		
		<category><![CDATA[Geocoding]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Tutorials]]></category>

		<guid isPermaLink="false">http://www.larsgebhardt.de/?p=253</guid>
		<description><![CDATA[In this tutorial i will explain how to import GPS data from Nokia mobile phones with Ruby on Rails and displaying them as route on a google map. 
 The first part will solve the data import of GPX formated data files. The second part will show you how to display the routes on google [...]]]></description>
			<content:encoded><![CDATA[<p>In this tutorial i will explain how to import GPS data from Nokia mobile phones with Ruby on Rails and displaying them as route on a google map. </p>
<p> The first part will solve the data import of GPX formated data files. The second part will show you how to display the routes on google map. </p>
<p><span id="more-253"></span></p>
<p>As data source i use a sample *.GPX file. It is provided from Marton who asked me to write this tutorial. The full description of xml structure you can find at <a href="http://www.topografix.com/GPX/1/1/">http://www.topografix.com/GPX/1/1/</a> </p>
<p>I will write a sample Rails Application - navtracker - covering following points of Ruby on Rails programming:</p>
<ul>
<li>Upload a *.GPX file</li>
<li>Parse a XML Data </li>
<li>Google Maps Api access to display the route</li>
</ul>
<p>Alright, lets start writing the application. All code examples are based on Rails 2.3.2.</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:640px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">rails navtracker<br />
rake db:create:all</div></div>
<p>For file upload we need the paperclip plugin.</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:640px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">script<span class="sy0">/</span>plugin <span class="kw2">install</span> git:<span class="sy0">//</span>github.com<span class="sy0">/</span>thoughtbot<span class="sy0">/</span>paperclip.git</div></div>
<p>Now we create the &#8220;Track&#8221;, &#8220;Tracksegment&#8221; and &#8220;Point&#8221; resources. One track has many tracksegments has many points. </p>
<p>Tragsegment is needed if you loss your GPS connection. The trackersoftware will create a new tracksegment if your GPS connections is etablished again.</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:640px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">script<span class="sy0">/</span>generate scaffold track name:string gpx_file_name:string<br />
gpx_content_type:string gpx_file_size:integer</div></div>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:640px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">script<span class="sy0">/</span>generate scaffold tracksegment track:references</div></div>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:640px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">script<span class="sy0">/</span>generate scaffold point name:string latitude:float <br />
longitude:float elevation:float description:string <br />
point_created_at:datetime tracksegment:references</div></div>
<p>Note: I broke the lines for better readabillity. Script/generate commands have to be written in single line. </p>
<p>After the command</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:640px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">rake db:migrate</div></div>
<p>we can write the associations into our models.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Track <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
&nbsp; <span class="kw5">has_many</span> <span class="re3">:tracksegments</span>, <span class="re3">:dependent</span> <span class="sy0">=&gt;</span> <span class="re3">:destroy</span><br />
&nbsp; has_attached_file <span class="re3">:gpx</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Tracksegment <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
&nbsp; <span class="kw5">belongs_to</span> <span class="re3">:track</span><br />
&nbsp; <span class="kw5">has_many</span> <span class="re3">:points</span>, <span class="re3">:dependent</span> <span class="sy0">=&gt;</span> <span class="re3">:destroy</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Point <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
&nbsp; <span class="kw5">belongs_to</span> <span class="re3">:tracksegment</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p></p>
<h3>Upload a GPX file</h3>
<p>For uploading a GPX file we modify our view/tracks/new.html.erb following way:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sy0">&lt;%</span> <span class="kw5">form_for</span><span class="br0">&#40;</span>@track, <span class="re3">:html</span> <span class="sy0">=&gt;</span> <span class="br0">&#123;</span> <span class="re3">:multipart</span> <span class="sy0">=&gt;</span> <span class="kw2">true</span> <span class="br0">&#125;</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>f<span class="sy0">|</span> <span class="sy0">%&gt;</span><br />
&nbsp; <span class="sy0">&lt;%</span>= f.<span class="me1">error_messages</span> <span class="sy0">%&gt;</span><br />
&nbsp; &nbsp; &lt;p&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">&lt;%</span>= f.<span class="kw5">file_field</span> <span class="re3">:gpx</span> <span class="sy0">%&gt;</span><br />
&nbsp; &nbsp; &lt;/p&gt;&nbsp; &nbsp; <br />
&nbsp; &lt;p&gt;<br />
&nbsp; &nbsp; <span class="sy0">&lt;%</span>= f.<span class="me1">submit</span> <span class="st0">'Upload GPX'</span> <span class="sy0">%&gt;</span><br />
&nbsp; &lt;/p&gt;<br />
<span class="sy0">&lt;%</span> <span class="kw1">end</span> <span class="sy0">%&gt;</span><br />
<br />
<span class="sy0">&lt;%</span>= <span class="kw5">link_to</span> <span class="st0">'Back'</span>, tracks_path <span class="sy0">%&gt;</span></div></td></tr></tbody></table></div>
<p>Upload a GPX file for testing before we start with with next section.</p>
<h3>Parsing the GPX file</h3>
<p>Let&#8217;s start with parsing.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Track <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
&nbsp; <span class="kw5">has_many</span> <span class="re3">:tracksegments</span><br />
&nbsp; has_attached_file <span class="re3">:gpx</span><br />
&nbsp; <br />
&nbsp; <span class="kw1">def</span> save_attached_files_with_parse_file <br />
&nbsp; &nbsp; save_attached_files_without_parse_file<br />
&nbsp; &nbsp; parse_file<br />
&nbsp; <span class="kw1">end</span><br />
&nbsp; <br />
&nbsp; alias_method_chain <span class="re3">:save_attached_files</span>, <span class="re3">:parse_file</span> <br />
&nbsp; <br />
&nbsp; <span class="kw1">def</span> parse_file<br />
&nbsp; &nbsp; ...<br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>We like to parse the uploaded GPX file directly after upload. That tricky because the paperclip pluging uses the after_create callback. If we use after_create it will be executed before paperclip plugin upload. It will cause an error &#8220;File not found&#8221;. We workaround with alias chain method.</p>
<p>We need following steps to parse an xml file:</p>
<ul>
<li>Open the uploaded GPX file</li>
<li>Parse the GPX file</li>
<li>Close GPX file</li>
</ul>
<h4>Open GPX file and prepare for parsing</h4>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Track <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
&nbsp; <span class="kw5">has_many</span> <span class="re3">:tracksegments</span><br />
&nbsp; has_attached_file <span class="re3">:gpx</span><br />
&nbsp; <br />
&nbsp; attr_accessor <span class="re3">:file_handler</span>, <span class="re3">:gpx_document</span><br />
&nbsp; <br />
&nbsp; <span class="kw1">def</span> save_attached_files_with_parse_file <br />
&nbsp; &nbsp; save_attached_files_without_parse_file<br />
&nbsp; &nbsp; parse_file<br />
&nbsp; <span class="kw1">end</span><br />
&nbsp; <br />
&nbsp; alias_method_chain <span class="re3">:save_attached_files</span>, <span class="re3">:parse_file</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span class="kw1">def</span> parse_file<br />
&nbsp; &nbsp; prepare_gpx_file<br />
&nbsp; &nbsp; parse_xml<br />
&nbsp; &nbsp; cleanup_gpx_file<br />
&nbsp; <span class="kw1">end</span><br />
&nbsp; ...<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>In the first step we prepare the file for parsing. We need a file handler to open the gpx xml file with REXML. For this reason i added two attributes to the model <strong>in line 5</strong>.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> parse_xml<br />
&nbsp; &nbsp; ...<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>Parse_xml executes the parsing. I will explain it later.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> prepare_gpx_file<br />
&nbsp; logger.<span class="me1">info</span> <span class="st0">&quot;Prepare GPX file ...&quot;</span><br />
&nbsp; make_file_handler<br />
&nbsp; open_gpx_xml<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>Prepare_gpx_file calls functions to make a file_handler and<br />
and gpx_xml handler.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> make_file_handler<br />
&nbsp; logger.<span class="me1">info</span> <span class="st0">&quot;Make file handler ...&quot;</span><br />
&nbsp; file_handler = <span class="kw4">File</span>.<span class="kw5">new</span><span class="br0">&#40;</span><span class="kw4">File</span>.<span class="me1">join</span><span class="br0">&#40;</span>RAILS_ROOT,<span class="st0">'public'</span>,<br />
&nbsp; gpx.<span class="me1">url</span>.<span class="kw3">split</span><span class="br0">&#40;</span><span class="st0">&quot;?&quot;</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>,<span class="st0">&quot;r&quot;</span><span class="br0">&#41;</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>make_file_handler assigns the file_handler. The file open is a little bit tricky. We have to remove the parameters after ? from gpx.url. So we use a simple &#8220;split&#8221; and take the first array element from it.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> open_gpx_xml<br />
&nbsp; logger.<span class="me1">info</span> <span class="st0">&quot;Open GPX XML file ...&quot;</span><br />
&nbsp; gpx_document = <span class="re2">REXML::Document</span>.<span class="kw5">new</span> file_handler<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>open_gpx_xml assigns the xml handler. We use REXML to parse the file.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> cleanup_gpx_file<br />
&nbsp; file_handler.<span class="me1">close</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>cleanup_gpx_file closes the file afterwards.</p>
<h4>Parse the GPX file</h4>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">attr_accessor ..., <span class="re3">:tmp_segment</span>, <span class="re3">:tmp_point</span></div></td></tr></tbody></table></div>
<p>We need two more attributes: tmp_segment and tmp_point. This attributes contain the temporary data while parsing.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> parse_xml<br />
&nbsp; <span class="kw2">self</span>.<span class="me1">gpx_document</span>.<span class="me1">root</span>.<span class="me1">each_element</span> <span class="kw1">do</span> <span class="sy0">|</span>node<span class="sy0">|</span><br />
&nbsp; &nbsp; parse_tracks<span class="br0">&#40;</span>node<span class="br0">&#41;</span><br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>parse_xml loops the root level for each node it can find.<br />
For each node we start the function parse_tracks with the current node as parameter.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> parse_tracks<span class="br0">&#40;</span>node<span class="br0">&#41;</span><br />
&nbsp; <span class="kw1">if</span> node.<span class="me1">name</span>.<span class="me1">eql</span>? <span class="st0">&quot;trk&quot;</span><br />
&nbsp; &nbsp; node.<span class="me1">each_element</span> <span class="kw1">do</span> <span class="sy0">|</span>node<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; parse_track_segments<span class="br0">&#40;</span>node<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">end</span> &nbsp;<br />
&nbsp; <span class="kw1">end</span> &nbsp; &nbsp;<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>parse_tracks function checks the node name. If the name is &#8220;trk&#8221; then we go a level deeper and loop all nodes from the current &#8220;trk&#8221; node. For each node we call<br />
parse_track_segments(node).</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> parse_track_segments<span class="br0">&#40;</span>node<span class="br0">&#41;</span><br />
&nbsp; <span class="kw1">if</span> node.<span class="me1">name</span>.<span class="me1">eql</span>? <span class="st0">&quot;trkseg&quot;</span><br />
&nbsp; &nbsp; tmp_segment = Tracksegment.<span class="kw5">new</span><br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">tracksegments</span> <span class="sy0">&lt;&lt;</span> tmp_segment<br />
&nbsp; &nbsp; node.<span class="me1">each_element</span> <span class="kw1">do</span> <span class="sy0">|</span>node<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; parse_points<span class="br0">&#40;</span>node,tmp_segment<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>In parse_track_segments we check for the name &#8220;trkseg&#8221;. If so then create a new segment. We go a level deeper now and loop all nodes of &#8220;trkseg&#8221; node. For each of this node we start parse_points.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> parse_points<span class="br0">&#40;</span>node,tmp_segment<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> node.<span class="me1">name</span>.<span class="me1">eql</span>? <span class="st0">&quot;trkpt&quot;</span><br />
&nbsp; &nbsp; &nbsp; tmp_point = Point.<span class="kw5">new</span><br />
&nbsp; &nbsp; &nbsp; node.<span class="me1">attributes</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>key,value<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; tmp_point.<span class="me1">latitude</span> = value <span class="kw1">if</span> key.<span class="me1">eql</span>? <span class="st0">'lat'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; tmp_point.<span class="me1">longitude</span> = value <span class="kw1">if</span> key.<span class="me1">eql</span>? <span class="st0">'lon'</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; &nbsp; node.<span class="me1">each_element</span> <span class="kw1">do</span> <span class="sy0">|</span>node<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; tmp_point.<span class="me1">name</span> = node.<span class="me1">text</span>.<span class="kw5">to_s</span> <span class="kw1">if</span> node.<span class="me1">name</span>.<span class="me1">eql</span>? <span class="st0">'name'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; tmp_point.<span class="me1">elevation</span> = node.<span class="me1">text</span>.<span class="kw5">to_s</span> <span class="kw1">if</span> node.<span class="me1">name</span>.<span class="me1">eql</span>? <span class="st0">'ele'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; tmp_point.<span class="me1">description</span> = node.<span class="me1">text</span>.<span class="kw5">to_s</span> <span class="kw1">if</span> node.<span class="me1">name</span>.<span class="me1">eql</span>? <span class="st0">'desc'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; tmp_point.<span class="me1">point_created_at</span> = node.<span class="me1">text</span>.<span class="kw5">to_s</span> <span class="kw1">if</span> node.<span class="me1">name</span>.<span class="me1">eql</span>? <span class="st0">'time'</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; &nbsp; tmp_segment.<span class="me1">points</span> <span class="sy0">&lt;&lt;</span> tmp_point<br />
&nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; <span class="kw1">end</span><br />
&nbsp; ...</div></td></tr></tbody></table></div>
<p>In parse_points the real action is starting. We check for node name &#8220;trkpt&#8221;. If so we create a new point object and read this node attributes lat and lon. We save it in the point object attributes latitude and longitude.</p>
<p>Next we start with looping all elements of current node &#8220;trkpt&#8221;. Inside loop we check for name, ele, desc and time. If one of this node names match we assign it to the corresponding attribute of point. At last we add the temporary point to the tmp_segment.</p>
<h4>Comming next</h4>
<p>In next tutorial we are going to care about display the route in google maps with Ruby on Rails.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.larsgebhardt.de/2009/05/08/how-to-import-nokia-sportstracker-gps-data-with-ruby-on-rails-part-1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Create Your Own Geodatabase using Ruby on Rails and Google Maps</title>
		<link>http://www.larsgebhardt.de/2009/05/04/create-your-own-geo-database-with-ruby-on-rails-and-google-maps/</link>
		<comments>http://www.larsgebhardt.de/2009/05/04/create-your-own-geo-database-with-ruby-on-rails-and-google-maps/#comments</comments>
		<pubDate>Mon, 04 May 2009 07:26:39 +0000</pubDate>
		<dc:creator>Lars</dc:creator>
		
		<category><![CDATA[Geocoding]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Tutorials]]></category>

		<category><![CDATA[Real Estate]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.larsgebhardt.de/?p=147</guid>
		<description><![CDATA[Geocoding with Ruby on Rails isn't a big deal. But sometimes you have do more than simple geocoding. For real estate webpages you need information about state, county or suburb for a given address. This tutorial will show you how to build your own geodatabase without overusing google maps requests(limited on 15000 Requests per Ip/month).]]></description>
			<content:encoded><![CDATA[<p>Geocoding with Ruby on Rails isn&#8217;t a big deal. But sometimes you have do more than simple geocoding. For real estate webpages you need information about state, county or suburb for a given address. </p>
<p>This tutorial will show you how to build your own geodatabase without overusing google maps requests(limited on 15000 Requests per Ip/month).</p>
<p><span id="more-147"></span></p>
<p>Before you can start you must have a fresh rails application and a google maps api key. You can signup for one here: <a href="http://code.google.com/apis/maps/">http://code.google.com/apis/maps/</a></p>
<p>This tutorial has following parts:</p>
<ol>
<li>Geocode an address</li>
<li>Get extented information to this address</li>
<li>An Pratical example</li>
</ol>
<p>We touch only the model layer(thin controllers fat models). I will use an address ressource like follows:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:640px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">script<span class="sy0">/</span>generate scaffold Address country:string state:string <br />
county:string city:string suburb:string zipcode:string street:string <br />
streetno:string longitude:float latitude:float error_code:string</div></div>
<p>and</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:640px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">rake db:migrate</div></div>
<p>You can use this address ressources for many purposes. But more on this later. You need some ruby-gems too.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Address <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
&nbsp; <span class="kw3">require</span> <span class="st0">'open-uri'</span><br />
&nbsp; <span class="kw3">require</span> <span class="st0">'cgi'</span><br />
&nbsp; <span class="kw3">require</span> <span class="st0">'hpricot'</span><br />
&nbsp; <span class="kw3">require</span> <span class="st0">'iconv'</span><br />
&nbsp; ...<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<h3>Geocode an address</h3>
<p>For geocoding an address you can use a simple callback function.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> <span class="kw5">before_create</span><br />
&nbsp; geocode<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>And the gecode function itself:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> geocode<br />
&nbsp; url = <span class="br0">&#91;</span><span class="st0">&quot;http://maps.google.com/maps/geo?q=&quot;</span><span class="br0">&#93;</span><br />
&nbsp; url <span class="sy0">&lt;&lt;</span> address_for_geocoding<br />
&nbsp; url <span class="sy0">&lt;&lt;</span> <span class="st0">&quot;&amp;output=xml&amp;key=&quot;</span><br />
&nbsp; url <span class="sy0">&lt;&lt;</span> <span class="st0">&quot;your_google_maps_api_key&quot;</span><br />
&nbsp; &nbsp; <span class="kw3">open</span><span class="br0">&#40;</span>url.<span class="kw5">to_s</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>file<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; <span class="re1">@body</span> = file.<span class="me1">read</span><br />
&nbsp; &nbsp; &nbsp; doc = Hpricot<span class="br0">&#40;</span>@body<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>doc<span class="sy0">/</span>:status<span class="sy0">/</span>:code<span class="br0">&#41;</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>code<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">error_code</span> = code.<span class="me1">inner_html</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>doc<span class="sy0">/</span>:point<span class="sy0">/</span>:coordinates<span class="br0">&#41;</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>link<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">longitude</span>, <span class="kw2">self</span>.<span class="me1">latitude</span> = link.<span class="me1">inner_html</span>.<span class="kw3">split</span><span class="br0">&#40;</span><span class="st0">','</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span class="kw1">end</span> &nbsp;<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p><strong>On line 3</strong> i need  an encoded address for proper geocoding. This function catches incomplete address information too.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> address_for_geocoding<br />
&nbsp; addressline = <span class="br0">&#91;</span><span class="br0">&#93;</span>&nbsp; &nbsp; &nbsp; <br />
&nbsp; addressline <span class="sy0">&lt;&lt;</span> streetno.<span class="kw5">to_i</span> <span class="kw1">unless</span> <span class="br0">&#40;</span>streetno <span class="sy0">||</span> <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>.<span class="me1">blank</span>?<br />
&nbsp; addressline <span class="sy0">&lt;&lt;</span> street <span class="kw1">unless</span> <span class="br0">&#40;</span>street <span class="sy0">||</span> <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>.<span class="me1">blank</span>?<br />
&nbsp; addressline <span class="sy0">&lt;&lt;</span> zipcode <span class="kw1">unless</span> <span class="br0">&#40;</span>zipcode <span class="sy0">||</span> <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>.<span class="me1">blank</span>?<br />
&nbsp; addressline <span class="sy0">&lt;&lt;</span> city <span class="kw1">unless</span> <span class="br0">&#40;</span>city <span class="sy0">||</span> <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span>.<span class="me1">blank</span>?&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span class="kw4">CGI</span>::escape<span class="br0">&#40;</span>addressline.<span class="me1">join</span><span class="br0">&#40;</span><span class="st0">' '</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p><strong>On line 8</strong> we start the parsing of the returned xml-data from google maps. For more information about the xml structure you can read: <a href="http://code.google.com/apis/maps/documentation/geocoding/index.html#KML"> Google Maps XML Structure</a></p>
<p><strong>On line 15</strong> we assign the longitude and latitude to our address attributes. So you get the coordinates into address model before rails creates it.</p>
<h3>Get extented information</h3>
<p>You can read at <a href="http://code.google.com/apis/maps/documentation/geocoding/index.html#KML"> Google Maps XML Structure</a> that far more information can delivered from google maps. So we update our geocode function:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> geocode<br />
&nbsp; url = <span class="br0">&#91;</span><span class="st0">&quot;http://maps.google.com/maps/geo?q=&quot;</span><span class="br0">&#93;</span><br />
&nbsp; url <span class="sy0">&lt;&lt;</span> address_for_geocoding<br />
&nbsp; url <span class="sy0">&lt;&lt;</span> <span class="st0">&quot;&amp;output=xml&amp;key=&quot;</span><br />
&nbsp; url <span class="sy0">&lt;&lt;</span> <span class="st0">&quot;your_google_maps_api_key&quot;</span><br />
&nbsp; &nbsp; <span class="kw3">open</span><span class="br0">&#40;</span>url.<span class="kw5">to_s</span><span class="br0">&#41;</span> <span class="kw1">do</span> <span class="sy0">|</span>file<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; <span class="re1">@body</span> = file.<span class="me1">read</span><br />
&nbsp; &nbsp; &nbsp; doc = Hpricot<span class="br0">&#40;</span>@body<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>doc<span class="sy0">/</span>:status<span class="sy0">/</span>:code<span class="br0">&#41;</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>code<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">error_code</span> = code.<span class="me1">inner_html</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>doc<span class="sy0">/</span>:country<span class="sy0">/</span>:countrynamecode<span class="br0">&#41;</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>country_code<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">country</span> = country_code.<span class="me1">inner_html</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>doc<span class="sy0">/</span>:country<span class="sy0">/</span>:administrativearea<span class="sy0">/</span>:administrativeareaname<span class="br0">&#41;</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>area<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">state</span> = <span class="kw4">Iconv</span>.<span class="me1">conv</span><span class="br0">&#40;</span><span class="st0">'utf-8'</span>, <span class="st0">'ISO-8859-1'</span>, area.<span class="me1">inner_html</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>doc<span class="sy0">/</span>:country<span class="sy0">/</span>:administrativearea<span class="sy0">/</span>:subadministrativearea<span class="sy0">/</span>:subadministrativeareaname<span class="br0">&#41;</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>sub_area<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">county</span> = <span class="kw4">Iconv</span>.<span class="me1">conv</span><span class="br0">&#40;</span><span class="st0">'utf-8'</span>, <span class="st0">'ISO-8859-1'</span>, sub_area.<span class="me1">inner_html</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>doc<span class="sy0">/</span>:country<span class="sy0">/</span>:administrativearea<span class="sy0">/</span>:subadministrativearea<span class="sy0">/</span>:locality<span class="sy0">/</span>:dependentlocality<span class="sy0">/</span>:dependentlocalityname<span class="br0">&#41;</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>t_area<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">suburb</span> = <span class="kw4">Iconv</span>.<span class="me1">conv</span><span class="br0">&#40;</span><span class="st0">'utf-8'</span>, <span class="st0">'ISO-8859-1'</span>, t_area.<span class="me1">inner_html</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#40;</span>doc<span class="sy0">/</span>:point<span class="sy0">/</span>:coordinates<span class="br0">&#41;</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>link<span class="sy0">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">longitude</span>, <span class="kw2">self</span>.<span class="me1">latitude</span> = link.<span class="me1">inner_html</span>.<span class="kw3">split</span><span class="br0">&#40;</span><span class="st0">','</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">end</span> &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span class="kw1">end</span> &nbsp;<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>So we get extented information about country, state, county and suburb related to the address information you entered. You have now the complete set of address, administrative-level information and geo coordinates.</p>
<h3>A practical example</h3>
<p>It&#8217;s time for some practical stuff. I will use real estate example. In this example i will geocode a house location and add administrative information to it.</p>
<p>So let&#8217;s start with a property ressource scaffold:</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:640px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">script<span class="sy0">/</span>generate scaffold Property title:string description:text <br />
street:string streetno:string <span class="kw2">zip</span>:string city:string address_id:integer</div></div>
<p>and</p>
<div class="codecolorer-container bash blackboard" style="overflow:auto;white-space:nowrap;width:640px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">rake db:migrate</div></div>
<p>I know there are some redundant address information, but it&#8217;s necessary to trace typing errors from users.</p>
<p>Lets go to the model layer an make some associations. One house can only have one address but one address can have many houses. So we write:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Address <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
&nbsp; <span class="kw5">has_many</span> <span class="re3">:properties</span><br />
&nbsp; ...<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>and</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Property <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
&nbsp; <span class="kw5">belongs_to</span> <span class="re3">:address</span><br />
&nbsp; ...<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>Now lets start coding:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Property <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
&nbsp; <span class="kw5">belongs_to</span> <span class="re3">:address</span><br />
&nbsp; <br />
&nbsp; <span class="kw5">after_save</span> <span class="re3">:get_location</span><br />
<br />
&nbsp; protected &nbsp;<br />
<br />
&nbsp; <span class="kw1">def</span> get_location<br />
&nbsp; &nbsp; address = address_exist?<br />
&nbsp; &nbsp; address =Address.<span class="me1">create</span><span class="br0">&#40;</span><span class="re3">:streetno</span> <span class="sy0">=&gt;</span>self.<span class="me1">streetno</span>, <br />
&nbsp; &nbsp; &nbsp;<span class="re3">:street</span> <span class="sy0">=&gt;</span> <span class="kw2">self</span>.<span class="me1">street</span>,:zip <span class="sy0">=&gt;</span> <span class="kw2">self</span>.<span class="me1">zip</span>, <br />
&nbsp; &nbsp; &nbsp;<span class="re3">:city</span> <span class="sy0">=&gt;</span> <span class="kw2">self</span>.<span class="me1">city</span><span class="br0">&#41;</span> <span class="kw1">unless</span> address<br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">address</span> = address<br />
&nbsp; <span class="kw1">end</span><br />
<br />
&nbsp; <span class="kw1">def</span> address_exist?<br />
&nbsp; &nbsp; address = Address.<span class="me1">find</span><span class="br0">&#40;</span><span class="re3">:first</span>,<br />
&nbsp; &nbsp; <span class="re3">:conditions</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;streetno = ? and street= ? <br />
&nbsp; &nbsp; and zip = ? and city = ?&quot;</span>,<br />
&nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">streetno</span>,<span class="kw2">self</span>.<span class="me1">street</span>,<span class="kw2">self</span>.<span class="me1">zip</span>,<span class="kw2">self</span>.<span class="me1">city</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; address ? address : <span class="kw2">false</span><br />
&nbsp; <span class="kw1">end</span><br />
&nbsp;<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>Done. What happened? If you enter property data the property will saved. After save we call the get_location function to assign a address to our new property.</p>
<p><strong>On line 7</strong> we call the address_exist? function which try to find an address in our database. If this address doesn&#8217;t exist we create a new one <strong>on line 8</strong>.</p>
<p>Everytime a user adds unknown property your address database will grow. Once an address is saved it will resused every time a property with same address is entered.</p>
<p>Now you can get property listings like:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Property <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
&nbsp; <span class="kw5">belongs_to</span> <span class="re3">:address</span><br />
&nbsp; ...<br />
&nbsp; <span class="kw1">def</span> get_all_properties_with_same_streetname<br />
&nbsp; &nbsp; addresses = Address.<span class="me1">find</span><span class="br0">&#40;</span><span class="re3">:all</span>,<br />
&nbsp; &nbsp; <span class="re3">:conditions</span> <span class="sy0">=&gt;</span> <span class="br0">&#91;</span><span class="st0">&quot;street = ?&quot;</span>,<span class="kw2">self</span>.<span class="me1">street</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; addresses.<span class="me1">collect</span> <span class="br0">&#123;</span> <span class="sy0">|</span>address<span class="sy0">|</span> address.<span class="me1">properties</span> <span class="br0">&#125;</span><br />
&nbsp; <span class="kw1">end</span><br />
&nbsp; ...<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>I hope i could help you with this tutorial. Please write a comment if you have any questions or critics.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.larsgebhardt.de/2009/05/04/create-your-own-geo-database-with-ruby-on-rails-and-google-maps/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Extract zip files with Ruby on Rails</title>
		<link>http://www.larsgebhardt.de/2009/04/13/extract-zip-files-with-ruby-on-rails/</link>
		<comments>http://www.larsgebhardt.de/2009/04/13/extract-zip-files-with-ruby-on-rails/#comments</comments>
		<pubDate>Mon, 13 Apr 2009 09:36:36 +0000</pubDate>
		<dc:creator>Lars</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Tutorials]]></category>

		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.larsgebhardt.de/?p=120</guid>
		<description><![CDATA[Some friends of mine found my first tutorial difficult to understand. So i&#8217;m going to start with smaller pieces of code and start with basic unzip functions in Ruby on Rails.

123456789require 'fileutils'
require 'zip/zip'
require 'zip/zipfilesystem'

def unzip
  Zip::ZipFile.open&#40;&#34;/path/to/file.zip&#34;&#41;.each do &#124;single_file&#124;
    single_file.extract&#40;single_file.name&#41;
  end
end
It extracts all files of file.zip into current folder. If you like to get some special file out [...]]]></description>
			<content:encoded><![CDATA[<p>Some friends of mine found my first tutorial difficult to understand. So i&#8217;m going to start with smaller pieces of code and start with basic unzip functions in Ruby on Rails.</p>
<p><span id="more-120"></span></p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw3">require</span> <span class="st0">'fileutils'</span><br />
<span class="kw3">require</span> <span class="st0">'zip/zip'</span><br />
<span class="kw3">require</span> <span class="st0">'zip/zipfilesystem'</span><br />
<br />
<span class="kw1">def</span> unzip<br />
  <span class="re2">Zip::ZipFile</span>.<span class="kw3">open</span><span class="br0">&#40;</span><span class="st0">&quot;/path/to/file.zip&quot;</span><span class="br0">&#41;</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>single_file<span class="sy0">|</span><br />
    single_file.<span class="me1">extract</span><span class="br0">&#40;</span>single_file.<span class="me1">name</span><span class="br0">&#41;</span><br />
  <span class="kw1">end</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>It extracts all files of file.zip into current folder. If you like to get some special file out of this zipfile you can use regular expressions to filter it out. The following example shows how to get<br />
the xml file:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">...<br />
<span class="kw1">if</span> single_file.<span class="me1">name</span>.<span class="me1">downcase</span> =~ <span class="sy0">/</span>.<span class="me1">xml</span><span class="sy0">/</span><br />
&nbsp; special_filename = single_file.<span class="me1">name</span><br />
<span class="kw1">end</span><br />
...</div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.larsgebhardt.de/2009/04/13/extract-zip-files-with-ruby-on-rails/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to process multiple zip-files with Ruby on Rails</title>
		<link>http://www.larsgebhardt.de/2009/03/22/how-to-import-zipped-data-packages-with-ruby-on-rails-part1/</link>
		<comments>http://www.larsgebhardt.de/2009/03/22/how-to-import-zipped-data-packages-with-ruby-on-rails-part1/#comments</comments>
		<pubDate>Sun, 22 Mar 2009 16:52:31 +0000</pubDate>
		<dc:creator>Lars</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Tutorials]]></category>

		<category><![CDATA[Ruby on Rails]]></category>

		<category><![CDATA[Tutorial]]></category>

		<category><![CDATA[XML]]></category>

		<category><![CDATA[ZIP]]></category>

		<guid isPermaLink="false">http://www.larsgebhardt.de/?p=42</guid>
		<description><![CDATA[Sometimes you have to integrate exported data from third party desktop software. One way to do is to pack all data into a zipped file and push it via FTP onto your server. This tutorial will explain how to process zip-files with your Ruby on Rails™ application.
I will take an example from a real estate managing [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you have to integrate exported data from third party desktop software. One way to do is to pack all data into a zipped file and push it via FTP onto your server. This tutorial will explain how to process zip-files with your Ruby on Rails™ application.</p>
<p>I will take an example from a real estate managing software. It&#8217;s a common way for this kind of software to pack and push their data to online real estate listing services.</p>
<p><span id="more-42"></span></p>
<p>The zip-file contains:</p>
<ul>
<li>A xml file with property data</li>
<li>Some picture files</li>
</ul>
<p>The zip files are transfered by real estate managing software into a specific folder. There can be multiple zip files whose have to processed in correct time order.</p>
<p>The tutorial will cover following points:</p>
<ul>
<li>Processing multiple zip-files</li>
<li>Parsing the included XML File to get the data</li>
<li>Processing binary data like pictures or documents</li>
<li>Error handling an cleaning up</li>
</ul>
<p>Alright people, let&#8217;s start.</p>
<h3>Processing multiple zip-files</h3>
<p>All zip files will be uploaded into following directory. You have to create this directory with read/write access for your rails application. Furthermore you have to configure a FTP-User with write only access (&#8221;Postbox&#8221;-Setup). So you can use this ftp access for different clients.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">RAILS_ROOT<span class="sy0">/</span>external_uploads</div></td></tr></tbody></table></div>
<p> The file</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">RAILS_ROOT<span class="sy0">/</span>external_uploads<span class="sy0">/</span>zipdata.<span class="me1">zip</span></div></td></tr></tbody></table></div>
<p>has following content:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">data.<span class="me1">xml</span><br />
picture1.<span class="me1">jpg</span><br />
picture2.<span class="me1">jpg</span><br />
picture3.<span class="me1">jpg</span><br />
picture4.<span class="me1">jpg</span><br />
picture5.<span class="me1">jpg</span></div></td></tr></tbody></table></div>
<p>The complete import will be executed in model layer. So we need an Import class. Some ruby packages are required, too.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">class</span> Import <span class="sy0">&lt;</span> <span class="re2">ActiveRecord::Base</span><br />
<br />
<span class="kw3">require</span> <span class="st0">'fileutils'</span><br />
<span class="kw3">require</span> <span class="st0">'zip/zip'</span><br />
<span class="kw3">require</span> <span class="st0">'zip/zipfilesystem'</span><br />
<span class="kw3">require</span> <span class="st0">'RMagick'</span><br />
<span class="kw3">require</span> <span class="st0">'find'</span><br />
<br />
attr_accessor <span class="re3">:current_source_file</span>, <span class="re3">:current_hash</span>, <span class="re3">:current_xml_file</span>, <span class="re3">:file_handler</span>, <span class="re3">:xml_document</span>, <span class="re3">:tmp_property</span>, <span class="re3">:expose</span>, <span class="re3">:tmp_attachment</span>, <span class="re3">:company</span>, <span class="re3">:current_is_topobjekt</span><br />
....<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>Before we start we need some supporting class functions. This function returns a random string. We need it to create a temporary directory to extract the zip file:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1"># returns a random string</span><br />
<span class="kw1">def</span> <span class="kw2">self</span>.<span class="me1">make_random_string</span><span class="br0">&#40;</span>len=<span class="nu0">10</span><span class="br0">&#41;</span><br />
chars = <span class="br0">&#40;</span><span class="st0">&quot;a&quot;</span>..<span class="st0">&quot;z&quot;</span><span class="br0">&#41;</span>.<span class="kw5">to_a</span> <span class="sy0">+</span> <span class="br0">&#40;</span><span class="st0">&quot;A&quot;</span>..<span class="st0">&quot;Z&quot;</span><span class="br0">&#41;</span>.<span class="kw5">to_a</span> <span class="sy0">+</span> <span class="br0">&#40;</span><span class="st0">&quot;0&quot;</span>..<span class="st0">&quot;9&quot;</span><span class="br0">&#41;</span>.<span class="kw5">to_a</span><br />
random_string = <span class="st0">&quot;&quot;</span><br />
1.<span class="me1">upto</span><span class="br0">&#40;</span>len<span class="br0">&#41;</span> <span class="br0">&#123;</span> <span class="sy0">|</span>i<span class="sy0">|</span> random_string <span class="sy0">&lt;&lt;</span> chars<span class="br0">&#91;</span><span class="kw3">rand</span><span class="br0">&#40;</span>chars.<span class="me1">size</span><span class="sy0">-</span><span class="nu0">1</span><span class="br0">&#41;</span><span class="br0">&#93;</span> <span class="br0">&#125;</span><br />
<span class="kw2">return</span> random_string<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>The next function returns a list of all zipfiles of your directory sortet by date. It&#8217;s important because the zip files depent from each other. </p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1"># returns the sorted file list from oldest to latest timestamp</span><br />
<span class="kw1">def</span> <span class="kw2">self</span>.<span class="me1">sorted_filelist</span><br />
unsortet_files = <span class="kw4">Dir</span>.<span class="me1">glob</span><span class="br0">&#40;</span>RAILS_ROOT<span class="sy0">+</span><span class="st0">'/external_uploads/*.zip'</span><span class="br0">&#41;</span><br />
unsortet_files.<span class="me1">sort</span><span class="br0">&#123;</span><span class="sy0">|</span>a,b<span class="sy0">|</span> <span class="kw4">File</span>.<span class="me1">mtime</span><span class="br0">&#40;</span>a<span class="br0">&#41;</span> <span class="sy0">&lt;=&gt;</span> <span class="kw4">File</span>.<span class="me1">mtime</span><span class="br0">&#40;</span>b<span class="br0">&#41;</span><span class="br0">&#125;</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>This code loops throught our external_uploads directory and starts the process for each zipfile:</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> <span class="kw2">self</span>.<span class="me1">go</span><br />
<span class="kw2">self</span>.<span class="me1">sorted_filelist</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>single_zip_file<span class="sy0">|</span><br />
current_import = Import.<span class="kw5">new</span><span class="br0">&#40;</span><br />
<span class="re3">:current_source_file</span> <span class="sy0">=&gt;</span> single_zip_file,<br />
<span class="re3">:current_hash</span> <span class="sy0">=&gt;</span> make_random_string<span class="br0">&#41;</span><br />
current_import.<span class="me1">start</span><br />
<span class="kw1">end</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>The object function start calls all sub processes once for each zipfile.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1"># processing the zipfile</span><br />
<span class="kw1">def</span> start<br />
make_tmp_path<br />
unzip<br />
open_xml_file<br />
parse_xml_file<br />
close_xml_file<br />
clean_up<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>The function make_tmp_path creates a temporary directory. Each zipfile must have an own temporary directory. With current_hash we can guarantee it.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> tmp_path<br />
<span class="kw4">File</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="st0">'external_uploads'</span>,<span class="st0">'tmp'</span>,current_hash<span class="br0">&#41;</span><br />
<span class="kw1">end</span><br />
<br />
<span class="kw1">def</span> make_tmp_path<br />
<span class="kw4">FileUtils</span>.<span class="me1">mkdir_p</span> tmp_path<br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>The unzip function extracts the currently selected zip-file into temporary directory. The rescue block catches errors.</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw1">def</span> add_path<span class="br0">&#40;</span>filename<span class="br0">&#41;</span><br />
<span class="kw4">File</span>.<span class="me1">join</span><span class="br0">&#40;</span>tmp_path,filename<span class="br0">&#41;</span><br />
<span class="kw1">end</span><br />
<br />
<span class="kw1">def</span> unzip<br />
<span class="kw1">begin</span><br />
<span class="re2">Zip::ZipFile</span>.<span class="kw3">open</span><span class="br0">&#40;</span>current_source_file<span class="br0">&#41;</span>.<span class="kw5">each</span> <span class="kw1">do</span> <span class="sy0">|</span>single_file<span class="sy0">|</span><br />
<span class="kw1">if</span> single_file.<span class="me1">name</span>.<span class="me1">downcase</span> =~ <span class="sy0">/</span>.<span class="me1">xml</span><span class="sy0">/</span><br />
<span class="kw2">self</span>.<span class="me1">current_xml_file</span> = add_path<span class="br0">&#40;</span>single_file.<span class="me1">name</span><span class="br0">&#41;</span><br />
<span class="kw1">end</span><br />
single_file.<span class="me1">extract</span><span class="br0">&#40;</span>add_path<span class="br0">&#40;</span>single_file.<span class="me1">name</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="kw1">end</span><br />
<span class="kw1">rescue</span><br />
remove_tmp_path<br />
<span class="kw1">end</span><br />
<span class="kw1">end</span></div></td></tr></tbody></table></div>
<p>I use a regular expression to get the included XML-File. The file and the corresponding path will saved into current_xml_file attribute.</p>
<p>Now we have the files</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">data.<span class="me1">xml</span><br />
picture1.<span class="me1">jpg</span><br />
picture2.<span class="me1">jpg</span><br />
picture3.<span class="me1">jpg</span><br />
picture4.<span class="me1">jpg</span><br />
picture5.<span class="me1">jpg</span></div></td></tr></tbody></table></div>
<p>unzipped into directory</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">RAILS_ROOT<span class="sy0">/</span>external_uploads<span class="sy0">/</span>tmp<span class="sy0">/</span>adFvdSDed<span class="sy0">/</span></div></td></tr></tbody></table></div>
<p>The current_xml_file attribute contains</p>
<div class="codecolorer-container rails blackboard" style="overflow:auto;white-space:nowrap;width:640px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br /></div></td><td><div class="rails codecolorer" style="font-family:Monaco,Lucida Console,monospace">RAILS_ROOT<span class="sy0">/</span>external_uploads<span class="sy0">/</span>tmp<span class="sy0">/</span>adFvdSDed<span class="sy0">/</span>data.<span class="me1">xml</span></div></td></tr></tbody></table></div>
<p>In the next part of this tutorial we will process the xml-file with REXML. We will do some image processing on the picture files with RMagick.</p>
<p>UPDATE: I canceled the second part of this tutorial because my latest tutorial will cover the XML parsing theme.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.larsgebhardt.de/2009/03/22/how-to-import-zipped-data-packages-with-ruby-on-rails-part1/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
