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

<channel>
	<title>Dan Theurer &#187; Programming</title>
	<atom:link href="http://www.theurer.cc/blog/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.theurer.cc/blog</link>
	<description>Web services, technology and random thoughts!</description>
	<lastBuildDate>Thu, 28 May 2009 03:21:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>BBAuth Coding &#8211; Single Sign On</title>
		<link>http://www.theurer.cc/blog/2006/09/29/bbauth-coding-single-sign-on/</link>
		<comments>http://www.theurer.cc/blog/2006/09/29/bbauth-coding-single-sign-on/#comments</comments>
		<pubDate>Fri, 29 Sep 2006 17:34:49 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web services]]></category>
		<category><![CDATA[sso]]></category>

		<guid isPermaLink="false">http://www.theurer.cc/blog/2006/09/29/bbauth-coding-single-sign-on/</guid>
		<description><![CDATA[I put together a BBAuth sample to test the userhash / SSO feature and you can download the source code for it. The application uses a database connection to store the userhash and the data that the user submitted. If you want to use it for more than just a sample I recommend adding error [...]]]></description>
			<content:encoded><![CDATA[<p>I put together a <a href="http://theurer.cc/code/sso">BBAuth sample</a> to test the userhash / SSO feature and you can <a href="http://theurer.cc/code/sso/sso.zip">download the source code</a> for it. The application uses a database connection to store the userhash and the data that the user submitted. If you want to use it for more than just a sample I recommend adding error handling.</p>
<p>To make the sample work you need to get your own appid:</p>
<ol>
<li>Go to <a href="https://developer.yahoo.com/wsregapp/">https://developer.yahoo.com/wsregapp/</a></li>
<li>Fill in your info &#8211; The Web Application URL is where Yahoo! redirects the user after he signs in successfully. This should be PATHTOTHEFILES/success.php</li>
<li>Pick the scope that is called something like &#8220;Yahoo Authentication, no user data access&#8221; (SSO)</li>
<li>Follow the steps in the flow until you get your appid / secret</li>
<li>Enter both in the <strong>bbauth.inc</strong> file where it says appid and secret.</li>
<li>At this point the redirect to Yahoo and redirect back to the server should work, but the success.php will fail because of the missing database.</li>
<li>Set up a database &#8211; feed <strong>sso.sql</strong> to your db</li>
<li>Enter the database info in <strong>success.php </strong>where it says &#8220;Edit your info here:&#8221;<strong><br />
</strong></li>
<li>Now it should run like a Prius in the carpool lane.</li>
</ol>
<p><span id="more-52"></span><br />
Let&#8217;s start with the <strong>index.php</strong> page. Index has only two lines of actual code, everything else is markup:<br />
<code>< ?php<br />
//pulls in the bbauth functionality / appid / secret<br />
include "bbauth.inc";</code><br />
</code><code>//sign the redirect url and request userhash (send_userhash=1)<br />
$app_login_url =  yahoo_sign_url ( $wslogin_server_long . "?appid=" . $appid . "&#038;send_userhash=1", $secret );<br />
?></code></p>
<p><strong>bbauth.inc </strong>contain the yahoo_sign_url and others functions that are needed to deal with that Yahoo! login servers. The three functions listed below make the authentication flow pretty clear.</p>
<p><code>yahoo_sign_url( $url, $secret )</code><br />
Signs the the URL that sends the user to the Yahoo! login server with your secret. That lets Yahoo ensure that the request comes from someone who has the secret. The user logs in and get redirected to your app.</p>
<p><code>function yahoo_sig_validate( $secret)</code><br />
This function validates the signature that that is attached to the URL where the login server sends the user after he or she signs in successfully. This protects your app from someone forging a request. The request will also contain a token that can be used to request a cookie.<code /></p>
<p><code>get_cookie( $url )</code><br />
Once you have the token you can request a cookie to make calls on behalf of the user - that is not part of the SSO sample. Jason put a <a href="http://developer.yahoo.com/auth/quickstart/bbauth_quickstart.zip">quick start guide</a> on YDN that talks about that in more detail.</p>
<p><strong>success.php</strong> gets called when the user get redirected back to your app and the signature gets validated. After that it's some html / sql to get some content on the screen</p>
<p><strong>sso.sql</strong> creates a table called 'sso' with five columns.</p>
<p>Let me know if you have any feedback.</p>
<p>Another really cool SSO sample is the one from <a href="http://kentbrewster.com/ybbs/">Kent Brewster</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theurer.cc/blog/2006/09/29/bbauth-coding-single-sign-on/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Launching the Un-Launch-Able</title>
		<link>http://www.theurer.cc/blog/2006/09/29/launching-the-un-launch-able/</link>
		<comments>http://www.theurer.cc/blog/2006/09/29/launching-the-un-launch-able/#comments</comments>
		<pubDate>Fri, 29 Sep 2006 16:12:26 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Business]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web services]]></category>
		<category><![CDATA[Yahoo]]></category>
		<category><![CDATA[hackday]]></category>

		<guid isPermaLink="false">http://www.theurer.cc/blog/2006/09/29/launching-the-un-launch-able/</guid>
		<description><![CDATA[Opening up Yahoo! I&#8217;ve been looking forward to this day and writing this exact post for quite some time now! So this is it! Wow, this feels great! We just pushed Browser Based Authentication (BBAuth) out the door.
Let’s start this post with what BBAuth is and what it can be used for. It was designed [...]]]></description>
			<content:encoded><![CDATA[<p>Opening up Yahoo! I&#8217;ve been looking forward to this day and writing this exact post for quite some time now! So this is it! Wow, this feels great! We just pushed <a href="http://developer.yahoo.com/auth">Browser Based Authentication</a> (BBAuth) out the door.</p>
<p>Let’s start this post with what BBAuth is and what it can be used for. It was designed to allow third-party applications to interact with user-specific data with the users&#8217; consent. On top of doing the obvious, it supports <a href="http://theurer.cc/code/sso">Single Sign-On</a> out of the box.</p>
<p>That means you can build applications that instead of creating your own sign-up flow, which requires users to pick yet another username and password, you can let them sign in with their existing Yahoo! account. The best thing about it is that it&#8217;s safe, the YahooId does not get shared with the applications. Your application needs to redirect the user to the Yahoo! BBAuth login and after the user successfully logs in, your app will receive an encrypted and unique userid for each user that logs in. This <a href="http://theurer.cc/code/sso">sample application makes use of SSO</a>.</p>
<p>Good or bad? That is up-to-you do decide. My opinion is that this can make navigating the web so much easier for users, and I am one of them! I don&#8217;t want to have to remember &#8216;x&#8217; usernames and &#8216;y &#8216;passwords and keep adding to the list everyday. There are also other ways of dealing with that problem, but here is a solution that is really straightforward. Feel free to leave a comment and let me know what you think! I want to add that this is not driven by a huge initiative to get everyone on Yahoo!, but an attempt to put out another tool that developers can decide to adopt if they like it.</p>
<p>But that&#8217;s not all! <a href="http://developer.yahoo.com/photos">Yahoo! Photos</a> opened up an API that takes advantage of BBAuth as well. I wrote a <a href="http://theurer.cc/code/auth">sample application</a> that is using it, which allows user to view and update titles and descriptions for photos stored on Yahoo!. The ajaxy parts are using the <a href="http://developer.yahoo.com/yui">YUI libraries</a>. On top of all that, we are doing a private beta for developers who attend our public <a href="http://hackday.org">Hackday</a>! The new <a href="http://mail.yahoo.com">Yahoo! Mail</a> is opening up their backend!! Appid sign-up will be limited for now but stay tuned for f<a href="http://developer.yahoo.com/blog">uture updates</a>.</p>
<p>For me, this has been quite a ride from the first time we talked about making BBAuth happen until today, the day we finally launched. In a big company like Yahoo!, you need to get input / approval from quite some folks if you want to do something out of the box and open up the company. All that makes sense and is justifiable but sometimes I wish it would have been faster. On the other side, I learned a lot about the company I work for, how big companies work in general, egos, friends and allies and most importantly how you get stuff done that is obviously not on everyone&#8217;s &#8220;need this today&#8221; list.</p>
<p>Like most platform projects that have to support a lot of different use-cases, the list of people that have made this happen is very long and I don&#8217;t even want to try to list them all. Instead I want to send a big &#8220;general&#8221; thank you out to all the thinkers and do-ers, the try-to-stop-it-ers and the must-have-today-ers! Thanks to all of you for making it what it is today!</p>
<p>Further reading: On the <a href="http://developer.yahoo.com/">Developer Network page</a> we have the official announcement. <a href="http://jeremy.zawodny.com/blog/archives/007557.html">Jeremy posted something on his blog</a> as well. Without his help to clear last minute &#8220;congestions&#8221; I am not sure if would have gone out today :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theurer.cc/blog/2006/09/29/launching-the-un-launch-able/feed/</wfw:commentRss>
		<slash:comments>42</slash:comments>
		</item>
		<item>
		<title>Hackday – Final Countdown</title>
		<link>http://www.theurer.cc/blog/2006/09/27/hackday-%e2%80%93-final-countdown/</link>
		<comments>http://www.theurer.cc/blog/2006/09/27/hackday-%e2%80%93-final-countdown/#comments</comments>
		<pubDate>Wed, 27 Sep 2006 08:01:05 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web services]]></category>
		<category><![CDATA[Yahoo]]></category>
		<category><![CDATA[hackday]]></category>

		<guid isPermaLink="false">http://www.theurer.cc/blog/2006/09/27/hackday-%e2%80%93-final-countdown/</guid>
		<description><![CDATA[It’s getting close! A little over two days are left before we kick off the Yahoo Hack Day! A lot has been written, the guest list / registration will close very soon and we are about to buckle up and go on the ride! There will be classes on Friday during the day ranging from [...]]]></description>
			<content:encoded><![CDATA[<p>It’s getting close! A little over two days are left before we kick off the <a href="http://hackday.org">Yahoo Hack Day</a>! A lot has been written, the guest list / registration will close very soon and we are about to buckle up and go on the ride! There will be <a href="http://yuiblog.com/blog/2006/09/22/yahoo-devday-schedule/">classes on Friday</a> during the day ranging from social networks to performance, and in the evening we will have a huge performance that goes way beyond all the usual corporate music gigs, you name it. People are already speculating and we will see who gets it right at the end.</p>
<p>Besides the entertainment and classes we will have networking, coding, camping, presentations, wifi, food (not free &#8211; sorry, we spent the $ somewhere else), parking and and and. It will be a lot of fun! If you didn’t sign up already, this is your last call! You can do this on <a href="http://upcoming.org/event/101629">Upcoming.org</a>.</p>
<p>Sidenote: The timer on the <a href="http://hackday.org">hackday page</a> gets powered by the RESTful <a href="http://developer.yahoo.com/util/timeservice/V1/getTime.html">getTime</a> web service that I wrote for fun. How much more basic then getTime can a web service get? That’s not the point :) The nice thing about it is that it supports <a href="http://json.org">JSON</a> and serialized PHP on top of the XML output.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theurer.cc/blog/2006/09/27/hackday-%e2%80%93-final-countdown/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python MyWeb to del.icio.us Exporter</title>
		<link>http://www.theurer.cc/blog/2006/08/29/python-myweb-to-delicious-exporter/</link>
		<comments>http://www.theurer.cc/blog/2006/08/29/python-myweb-to-delicious-exporter/#comments</comments>
		<pubDate>Tue, 29 Aug 2006 16:27:42 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web services]]></category>

		<guid isPermaLink="false">http://www.theurer.cc/blog/2006/08/29/python-myweb-to-delicious-exporter/</guid>
		<description><![CDATA[Last week I put together a Python script that takes MyWeb bookmarks and imports them into del.icio.us. The source is linked to below.
Big parts about Web2.0 are openness, web services (which support #1), a social network and, and, and!
Openness…! I was using del.icio.us and when MyWeb launched I tried that out for a while. A [...]]]></description>
			<content:encoded><![CDATA[<p>Last week I put together a Python script that takes MyWeb bookmarks and imports them into del.icio.us. The source is linked to below.</p>
<p>Big parts about Web2.0 are openness, web services (which support #1), a social network and, and, and!</p>
<p class="MsoNormal"><strong>Openness…!</strong> I was using <a href="http://del.icio.us">del.icio.us</a> and when <a href="http://myweb2.search.yahoo.com/">MyWeb</a> launched I tried that out for a while. A couple of days back I decided to export the MyWeb links to sync the two accounts.</p>
<p class="MsoNormal"><strong>The problem:</strong> The MyWeb web interface only gives you a <a href="http://myweb.yahoo.com/myweb/bookmarks">list of bookmarks</a> similar what Netscape 4.71 did.</p>
<p class="MsoNormal"><strong>The good news:</strong> MyWeb has an <a href="http://developer.yahoo.com/search/myweb/index.html">API</a> that let’s you get to the links, tags, description…! One limitation is that the API does not support authentication and therefore only returns public bookmarks. Del.icio.us on the other hand supports authentication which enables application to add links on behalf of a user. That is all that’s needed to solve the problem above.</p>
<p class="MsoNormal"><strong>Why <a href="http://python.org">Python</a>?:</strong> I didn’t program in that language before and inspired by <a href="http://simon.incutio.com/">Simon’s</a> <a href="http://developer.yahoo.com/python/">Python  Developer Center</a> I had to give it a shot.</p>
<p class="MsoNormal">Check out the <a id="p43" href="http://www.theurer.cc/blog/wp-content/uploads/2006/08/mwToDel.txt">Source Code &#8211; Python MyWeb to del.icio.us Exporter</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theurer.cc/blog/2006/08/29/python-myweb-to-delicious-exporter/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>JSON  re-loaded &#8211; Travel API lauched</title>
		<link>http://www.theurer.cc/blog/2005/12/20/json-re-loaded-travel-api-lauched/</link>
		<comments>http://www.theurer.cc/blog/2005/12/20/json-re-loaded-travel-api-lauched/#comments</comments>
		<pubDate>Wed, 21 Dec 2005 00:44:13 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web services]]></category>
		<category><![CDATA[Yahoo]]></category>

		<guid isPermaLink="false">http://www.theurer.cc/?p=31</guid>
		<description><![CDATA[On Thursday Yahoo! launched JSON support for Search and the Maps API&#8217;s and today Travel went live with two new calls that support JSON as well. The new services return detailed information about a trip created with the Yahoo! Travel Trip Planner. 
I put together a little page that uses the two new calls with [...]]]></description>
			<content:encoded><![CDATA[<p>On Thursday Yahoo! launched<a href="http://developer.yahoo.net/javascript/#docs"> JSON support</a> for <a href="http://developer.yahoo.net/search/index.html">Search</a> and the <a href="http://developer.yahoo.net/maps/index.html">Maps API&#8217;s</a> and today <a href="http://developer.yahoo.net/travel/index.html">Travel</a> went live with two new calls that support <a href="http://json.org">JSON </a>as well. The new services return detailed information about a trip created with the <a href="http://travel.yahoo.com/trip">Yahoo! Travel Trip Planner</a>. </p>
<p>I put together a little page that uses the two new calls with the JSON output to display trip details.</p>
<p align="center"><a href="http://theurer.cc/code/jsonSamples/jsonTravel.html"><img src="http://theurer.cc/code/images/jsonTravel.png" alt="jsonTravel" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.theurer.cc/blog/2005/12/20/json-re-loaded-travel-api-lauched/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>spiffYSearch</title>
		<link>http://www.theurer.cc/blog/2005/12/20/spiffysearch/</link>
		<comments>http://www.theurer.cc/blog/2005/12/20/spiffysearch/#comments</comments>
		<pubDate>Tue, 20 Dec 2005 21:51:42 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web services]]></category>
		<category><![CDATA[Yahoo]]></category>

		<guid isPermaLink="false">http://www.theurer.cc/?p=32</guid>
		<description><![CDATA[Kent Brewster wrote a really cool app that uses Y! Search JSON and can be included in any web site to display search results dynamically in that page.

]]></description>
			<content:encoded><![CDATA[<p>Kent Brewster wrote a really cool app that uses Y! Search JSON and can be included in any web site to display search results dynamically in that page.</p>
<p align="center"><a href="http://www.mindsack.com/uxe/SpiffySearch/"><img src="http://theurer.cc/code/images/spiff.png" alt="spiffYSearch" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.theurer.cc/blog/2005/12/20/spiffysearch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Services + JSON = Dump Your Proxy</title>
		<link>http://www.theurer.cc/blog/2005/12/15/web-services-json-dump-your-proxy/</link>
		<comments>http://www.theurer.cc/blog/2005/12/15/web-services-json-dump-your-proxy/#comments</comments>
		<pubDate>Thu, 15 Dec 2005 20:45:46 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web services]]></category>
		<category><![CDATA[Yahoo]]></category>

		<guid isPermaLink="false">http://www.theurer.cc/?p=30</guid>
		<description><![CDATA[In my post  on &#34;How to build a Maps Mash-up&#34; I mentioned that there are different ways to overcome the browser security restrictions to retrieve data from another domain (cross-domain restriction). The previous sample used the software proxy method to make the Web service requests and this post talks about a way to make [...]]]></description>
			<content:encoded><![CDATA[<p>In my post  on &quot;<a href="http://www.theurer.cc/blog/2005/11/03/how-to-build-a-maps-mash-up/">How to build a Maps Mash-up</a>&quot; I mentioned that there are different ways to overcome the browser security restrictions to retrieve data from another domain (cross-domain restriction). The previous sample used the software proxy method to make the Web service requests and this post talks about a way to make a request without a proxy. It&#8217;s the dynamic script tag method.</p>
<p>Today <a href="http://developer.yahoo.net/">Yahoo!</a> added a new output option for part of their Web services called <a href="http://json.org">JSON</a>. This makes it possible to make the JavaScript WS request without using the XMLHTTPRequest object. It is a great way to pull data from another domain because you can dump your proxy and all the data will not route through your server anymore. I will talk about the pros and cons of both these approaches later, but first I want to give an overview of what JSON is, how it works and show some sample code.</p>
<h3>What is JSON?</h3>
<p> On <a href="http://www.crockford.com/JSON/index.html">Doug Crockford&#8217;s page</a> it reads like that: &quot;JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate.&quot; And that&#8217;s how it look like:</p>
<p><code>{&quot;ResultSet&quot;:{&quot;Result&quot;:[{&quot;precision&quot;:&quot;city&quot;,<wbr />&quot;Latitude&quot;:&quot;34.05217&quot;,&quot;Longitude&quot;:&quot;-118.243469&quot;,&quot;<wbr />Address&quot;:&quot;&quot;,&quot;City&quot;:&quot;LOS ANGELES&quot;,&quot;State&quot;:&quot;CA&quot;,&quot;Zip&quot;:&quot;&quot;,&quot;Country&quot;:&quot;US&quot;}]}}}</code></p>
<p>The string above is returned by <a href="http://api.local.yahoo.com/MapsService/V1/geocode?appid=dantheurer&#038;location=la&#038;output=json">Y! Geocoder for the query &#8220;LA&#8221;</a>. JSON is a serialized JavaScript object, which JavaScript can turn back into an object. For Yahoo! WS the structure of the JSON string is similar to the XML result but the difference between and attribute and element can&#8217;t be made. The following is a comparison of the XML result for the same call.</p>
<p><code>&lt;ResultSet ... &gt;<br />
   &nbsp;&nbsp;&lt;Result precision=&quot;city&quot;&gt;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&lt;Latitude&gt;34.05217&lt;/Latitude&gt;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&lt;Longitude&gt;-118.243469&lt;/Longitude&gt;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&lt;Address&gt;&lt;/Address&gt;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&lt;City&gt;LOS ANGELES&lt;/City&gt;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&lt;State&gt;CA&lt;/State&gt;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&lt;Zip&gt;&lt;/Zip&gt;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&lt;Country&gt;US&lt;/Country&gt;<br />
  &nbsp;&nbsp;&lt;/Result&gt;<br />
  &lt;/ResultSet&gt;</code></p>
<p>One way to get from JSON to a JavaScript object is to call eval(), with the string as argument. The following sample uses the Geocoder result to display LA&#8217;s Latitude and Longitude in an alert box. This is just static. </p>
<p><a href="http://theurer.cc/code/jsonSamples/eval.html">eval.html</a><br />
<code>&lt;HTML&gt;<br />
  &nbsp;&nbsp;&lt;BODY&gt;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&lt;script language&quot;javascript&quot;&gt;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var location = eval({&quot;ResultSet&quot;:{&quot;Result&quot;:[{<wbr />&quot;precision&quot;:&quot;city&quot;,&quot;Latitude&quot;:&quot;34.05217&quot;,&quot;Longitude&quot;:&quot;-118.243469&quot;,&quot;Address&quot;:&quot;&quot;,<wbr />&quot;City&quot;:&quot;LOS ANGELES&quot;,&quot;State&quot;:&quot;CA&quot;,&quot;Zip&quot;:&quot;&quot;,&quot;Country&quot;:&quot;US&quot;}]}});<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(&quot;Lat:&quot; + location.ResultSet.Result[0].Latitude + &quot; Lon: &quot; + location.ResultSet.Result[0].Longitude );<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&lt;/script&gt;<br />
  &nbsp;&nbsp;&lt;/Body&gt;<br />
  &lt;/HTML&gt;<br /></code></p>
<p>This is nice but doesn&#8217;t do too much in the real world. The problem was to get the data from a Web service that is located on another domain imported without <a href="http://www.theurer.cc/blog/2005/11/03/how-to-build-a-maps-mash-up/">using a proxy</a>. </p>
<h3>The secret sauce</h3>
<p>
Adding the &lt;Script&gt; tag dynamically in the DOM tree of the browser is the answer and the JSON response helps to get the data in a format that is easy to digest for JavaScript. When a Script tags gets  dynamically  added to the DOM tree the code (script URL) gets executed on the fly. The trick is that instead pointing to a JavaScript library, we include a Web service request in the tag that returns data in the above mentioned format. The Yahoo! Web services that offer the JSON output option also supports a parameter called &#8216;callback&#8217; and all it does is wrap the return data in a function with the name of the callback value. <a href="http://api.local.yahoo.com/MapsService/V1/geocode?appid=dantheurer&amp;location=la&amp;output=json&amp;callback=getLocation">http://api.local.yahoo.com/MapsService/V1/geocode?appid=dantheurer<wbr />&#038;location=la&#038;output=json&#038;callback=getLocation</a> would result in something like this getLocation({&quot;ResultSet&quot;:{&quot;Result&quot;:[{&quot;precision&quot;:&quot;city&quot;,....) which tries to call the getLocation function (callback) that needs to be implemented to deal with the data. 
</p>
<p>Below is a sample that takes a location as an input parameter, then calls the Y! Geocoder WS and displays Long / Lat in the page. </p>
<p><a href="http://theurer.cc/code/jsonSamples/geocodeJson.html">geocodeJson.html</a><br />
<code>&lt;script type=&quot;text/javascript&quot; src=&quot;jsr_class.js&quot;&gt;&lt;/script&gt; <br />
  &lt;script type=&quot;text/javascript&quot;&gt;<br />
  &nbsp;&nbsp;//&lt;![CDATA[<br />
  &nbsp;&nbsp;var appid = &quot;dantheurer&quot;;<br /></code><code><br />
  &nbsp;&nbsp;//That is the callback function that is specified in the request url and gets executed after the data is returned<br />
  &nbsp;&nbsp;function getLocation(jData) {<br />
  &nbsp;&nbsp;&nbsp;&nbsp;if (jData == null) {<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(&quot;There was a problem parsing search results.&quot;);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;}<br />
  &nbsp;&nbsp;&nbsp;&nbsp;//get the values out of the object<br />
  &nbsp;&nbsp;&nbsp;&nbsp;var lat = jData.ResultSet.Result[0].Latitude;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;var lon = jData.ResultSet.Result[0].Longitude;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;//build some html<br />
  &nbsp;&nbsp;&nbsp;&nbsp;var smart = &quot;Long: &quot; + lon +  &quot;&lt;br /&gt;&quot; + &quot;Lat: &quot; + lat;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;//add it in the page DOM<br />
  &nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(&#8217;result&#8217;).innerHTML = smart;<br />
  &nbsp;&nbsp;}<br /></code><code><br />
   &nbsp;&nbsp;function addGeocode() {<br />
  &nbsp;&nbsp;&nbsp;&nbsp;var location = document.getElementById(&quot;geoquery&quot;).value;<br />
  &nbsp;&nbsp;&nbsp;&nbsp;// Build the Yahoo! web services call<br />
  &nbsp;&nbsp;&nbsp;&nbsp;request = 'http://api.local.yahoo.com/MapsService/V1/geocode?appid=' + appid + '&amp;location=' + location  + '&amp;output=json&amp;callback=getLocation';<br />
  &nbsp;&nbsp;&nbsp;&nbsp;// Create a new script object<br />
  &nbsp;&nbsp;&nbsp;&nbsp;aObj = new JSONscriptRequest(request);<br />
  &nbsp;&nbsp;&nbsp;&nbsp;// Build the script tag<br />
  &nbsp;&nbsp;&nbsp;&nbsp;aObj.buildScriptTag();<br />
  &nbsp;&nbsp;&nbsp;&nbsp;// Execute (add) the script tag<br />
  &nbsp;&nbsp;&nbsp;&nbsp;aObj.addScriptTag();<br />
  &nbsp;&nbsp;}<br />
  &nbsp;&nbsp;//]]&gt;<br />
  &lt;/script&gt;<br /></code>
</p>
<p>Jason, my cube neighbor, wrote a really nice class that deals with the dirty work of adding, removing and making sure the tags are unique. If you open up the file, it even has a security warning from the inventor of JSON in there. Below is the code snippet:</p>
<p><a href="http://theurer.cc/code/jsonSamples/jsr_class.js">jsr_class.js</a><br />
  <code><br />
  function JSONscriptRequest(fullUrl) {<br />
  &nbsp;&nbsp;// REST request path<br />
  &nbsp;&nbsp;this.fullUrl = fullUrl; <br />
  &nbsp;&nbsp;// Keep IE from caching requests<br />
  &nbsp;&nbsp;this.noCacheIE = '&amp;noCacheIE=' + (new Date()).getTime();<br />
  &nbsp;&nbsp;// Get the DOM location to put the script tag<br />
  &nbsp;&nbsp;this.headLoc = document.getElementsByTagName(&quot;head&quot;).item(0);<br />
  &nbsp;&nbsp;// Generate a unique script tag id<br />
  &nbsp;&nbsp;this.scriptId = 'YJscriptId' + JSONscriptRequest.scriptCounter++;<br />
  }<br /></code><code><br />
  // Static script ID counter<br />
  JSONscriptRequest.scriptCounter = 1;<br />
  </code><code><br />
  // buildScriptTag method<br />
  JSONscriptRequest.prototype.buildScriptTag = function () {<br />
   &nbsp;&nbsp;// Create the script tag<br />
  &nbsp;&nbsp;this.scriptObj = document.createElement(&quot;script&quot;);<br />
  </code><code><br />
  &nbsp;&nbsp;// Add script object attributes<br />
  &nbsp;&nbsp;this.scriptObj.setAttribute(&quot;type&quot;, &quot;text/javascript&quot;);<br />
  &nbsp;&nbsp;this.scriptObj.setAttribute(&quot;src&quot;, this.fullUrl + this.noCacheIE);<br />
  &nbsp;&nbsp;this.scriptObj.setAttribute(&quot;id&quot;, this.scriptId);<br />
  }<br /></code><code><br />
  // removeScriptTag method<br />
  JSONscriptRequest.prototype.removeScriptTag = function () {<br />
  &nbsp;&nbsp;// Destroy the script tag<br />
  &nbsp;&nbsp;this.headLoc.removeChild(this.scriptObj); <br />
  }<br /></code><code><br />
  // addScriptTag method<br />
  JSONscriptRequest.prototype.addScriptTag = function () {<br />
  &nbsp;&nbsp;// Create the script tag<br />
  &nbsp;&nbsp;this.headLoc.appendChild(this.scriptObj);<br />
  }<br />
  </code></p>
<p>Here is what the script does in some bullet points</p>
<ul>
<li>Build request URL with input parameter and callback function</li>
<li>Build the script tag that contains the request URL</li>
<li>Add the new tag to the DOM tree</li>
<li>As soon as the tag gets addes, the WS request gets executed and what gets returned is the JSON response wrapped in a function call. The name of the function got specified in the callback parameter.</li>
<li>The response, which is a function call now calls the matching function with the JSON data as  parameter. This is where the data can get extracted.</li>
<li>The script tag gets removed again</li>
</ul>
<p>The <a href="http://theurer.cc/maps/y/">sample I wrote for the Maps launch</a> depends on a PHP proxy. I took that sample and wrote a <a href="http://theurer.cc/maps/y/jsonMap.html">version that uses JSON</a> instead. Maybe it's because it's new, but for some reason I like the new version better. </p>
<p align="center">
  <a href="http://theurer.cc/maps/y/jsonMap.html"><img src="http://theurer.cc/maps/y/jsonMap.gif" alt="jsonSample" border="0" longdesc="http://theurer.cc/maps/y/jsonMap.html" /></a></p>
<p>All this is not just a hack that might not work again tomorrow because of a browser upgrade. Most of the dynamic ads use the dynamic script tag to display themselfes depending on the context. There are of course ups and downs for both technologies and not everyone agrees, but here are some points to think about.</p>
<p>Proxy method</p>
<ul>
<li> More robust, error handling is easier</li>
<li>More control on the server side</li>
<li>It has some security implications on the server side as the proxy could be abused. </li>
<li>The server side can have additional functionality implemented that is hidden to the caller e.g. login, exchange secrets...</li>
</ul>
<p>  Dynamic script tag</p>
<ul>
<li>No XML parsing necessary</li>
<li>Performance win</li>
<li>No traffic gets routed (and counted) on your end.</li>
<li>JSON converters don't know that they should define an array if they is only one nested element in a tag, even if the Schema allows 1..n </li>
<li>More cross-browser issues</li>
<li>Positive impact on rate limiting if it's done per IP</li>
<li>No need to set up a proxy</li>
</ul>
<p>For more information about JSON, JavaScript and Web services have a look at our brand new <a href="http://developer.yahoo.net/javascript">Yahoo! Developer Network JavaScript Developer Center</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theurer.cc/blog/2005/12/15/web-services-json-dump-your-proxy/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
		<item>
		<title>How to build a Maps Mash-up</title>
		<link>http://www.theurer.cc/blog/2005/11/03/how-to-build-a-maps-mash-up/</link>
		<comments>http://www.theurer.cc/blog/2005/11/03/how-to-build-a-maps-mash-up/#comments</comments>
		<pubDate>Thu, 03 Nov 2005 07:11:00 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web services]]></category>
		<category><![CDATA[Yahoo]]></category>

		<guid isPermaLink="false">http://www.theurer.cc/?p=29</guid>
		<description><![CDATA[Maps are cool!  Not only do they provide better aerial images, what makes a map even more valuable is to add data to it. This HowTo describes how this can be done and how to overcome the XmlHttpRequest cross-domain restriction.
This post will discuss the following parts needed for the Mash-up:

Map API that lets you [...]]]></description>
			<content:encoded><![CDATA[<p>Maps are cool!  Not only do they provide better aerial images, what makes a map even more valuable is to add data to it. This HowTo describes how this can be done and how to overcome the XmlHttpRequest cross-domain restriction.</p>
<p>This post will discuss the following parts needed for the Mash-up:</p>
<ul>
<li>Map API that lets you embed a map into your website</li>
<li>Data source</li>
<li>Ways to get around cross-domain restriction</li>
</ul>
<p>There are a couple of choices for embeddable Maps out there. The &#8220;oldest&#8221; one is <a href="http://maps.google.com/apis/maps/">Google Maps</a>, but there is also <a href="http://viavirtualearth.com/vve/Default.aspx">Virtual Earth,</a> and today the new <a href="http://developer.yahoo.net/maps/">Yahoo! Maps </a>launched! This is really good stuff. Yahoo! offers different ways of working with their Maps. </p>
<ul>
<li>The <a href="http://developer.yahoo.net/maps/simple/index.html">simple API</a> takes a geoRSS formated XML file and overlays the data on yesterday&#8217;s YMaps technology</li>
<li>There are three ways to interact with the brand new <a href="http://developer.yahoo.net/maps/flash/index.html">Flash Maps</a>. One of them is JavaScript, making it really easy to write super slick applications</li>
<li>The last one is an <a href="http://developer.yahoo.net/maps/ajax/index.html">AJAX API </a>that works pretty similar to what’s already out there.</li>
</ul>
<p>The sample is located at<a href="http://theurer.cc/maps/y/"> http://theurer.cc/maps/y/</a> and you can have a look at the JavaScript code by viewing the page source. It uses the AJAX API and demonstrates the following:</p>
<ul>
<li><a href="http://developer.yahoo.net/maps/rest/V1/geocode.html">Geocode </a>an address and display on the map</li>
<li>Overlay <a href="http://developer.yahoo.net/traffic/index.html">Traffic</a> information like accidents and construction zones</li>
<li>Overlay <a href="http://developer.yahoo.net/search/local/">local search</a> information</li>
</ul>
<p>The data sources used are three REST Web services that Yahoo also recently opened up. They are easy to program against as it is just a URL with parameters that returns XML.</p>
<p>Browsers like Firefox and IE enforce a cross-domain restriction, which does not allow HTTP calls from one domain to another. Since REST works over HTTP and the services are not hosted on the same server as the Maps application, we need to find a way to get around that. There are different ways to do that.</p>
<ul>
<li>Software proxy</li>
<li><a href="http://www.livejournal.com/users/premshree/66129.html">Apache mod_rewrite</a></li>
<li>Dynamically loading .js files via script tag and pass data instead of JS code.</li>
</ul>
<p>The easiest approach is to write a proxy that lives on the same server as the application and just pass the Request and Response to and from the web server. This has a slight security risk, but the example shows how you could limit it. For our scenario it works perfectly.</p>
<p>Those were the basics. Let’s look at some code! The full source:</p>
<p><code>&lt;html&gt;<br />
&lt;head&gt;<br />
&nbsp;&nbsp;&lt;script type="text/javascript"<br />
src="http://api.maps.yahoo.com/ajaxymap?v=2.0<br />
&#038;appid= dantheurer"&gt;&lt;/script&gt;<br />
&nbsp;&nbsp;&lt;style type="text/css"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;#mapbox {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height: 600px;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width: 600px;<br />
&nbsp;&nbsp;} &lt;/style&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&nbsp;&nbsp;&lt;div id="mapbox"&gt;&lt;/div&gt;<br />
&nbsp;&nbsp;&lt;script type="text/javascript"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;//init map<br />
&nbsp;&nbsp;&nbsp;&nbsp;var ymap =<br />
&nbsp;&nbsp;&nbsp;&nbsp;new  YMap(document.getElementById('mapbox'));<br />
&nbsp;&nbsp;&nbsp;&nbsp;//define a point to start at<br />
&nbsp;&nbsp;&nbsp;&nbsp;var startPoint = new YGeoPoint(37.34,-122.02);<br />
&nbsp;&nbsp;&nbsp;&nbsp;//center and draw map at given point<br />
&nbsp;&nbsp;&nbsp;&nbsp;ymap.drawZoomAndCenter(startPoint, 7);<br />
&nbsp;&nbsp;&lt;/script&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;<br />
</code></p>
<p>The <a href="http://api.search.yahoo.com/webservices/register_application">appId </a>in the script is included only for tracking purposes. Please replace it with your own. You can get an appid here. Once you have the code working, we can go ahead and add controls to the map.<br />
<code>//init map<br />
var ymap = new  YMap(document.getElementById('mapbox'));<br />
//add controls<br />
ymap.addPanControl();<br />
ymap.addZoomLong();<br />
…</code></p>
<p>All that and more can be found in the <a href="http://developer.yahoo.net/maps/ajax/index.html">GettingStartedGuide for AJAX</a>. It gets a little more interesting when data sources come into play. For this sample, I demonstrate the easiest way to overcome the cross-domain restriction. A PHP file will serve as a proxy. Yes, this has some security implications but the proxy is limited to a request with a specific (Yahoo!) domain. For the use case of a free Web service, this is “good enough”. This is all that’s needed:</p>
<p>yproxy.php<br />
<code>&lt;?php<br />
&nbsp;&nbsp;header("Content-type: text/xml\n\n");<br />
&nbsp;&nbsp;$url = $_SERVER['QUERY_STRING'];<br />
&nbsp;&nbsp;//strpos allows only calls to specified endpoint<br />
&nbsp;&nbsp;if ( strpos($url,"http://api.local.yahoo.com/") === 0)<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;$ch = curl_init($url);<br />
&nbsp;&nbsp;&nbsp;&nbsp;curl_exec($ch);<br />
&nbsp;&nbsp;}<br />
?&gt;</code></p>
<p>To run the proxy, the <a href="http://www.php.net/manual/en/ref.curl.php">PHP Curl extension</a> needs to be enabled. </p>
<p>Now that the proxy is in place we are able to make a REST call to api.local.yahoo.com. I want to follow what happens if the ‘AddLocation’ Button is pressed. The sample has an input box where the user can input an address.<br />
<code><br />
&lt;div class="inputelement"&gt;<br />
&lt;button onClick="addGeocode()"&gt;<br />
Add location&lt;/button&gt;&nbsp;&lt;input id="geoquery"<br />
value="5th Avenue,New York" size="50"&gt;<br />
&lt;/input&gt; - enter an address&lt;/div&gt;</code><code><br />
 </code></p>
<p>Once the button is pressed, the function addGeocode() gets called. Yes, the name could be better… and what it does is assemble the REST query and call the function that actually calls the proxy. </p>
<p><code><br />
var query = document.getElementById("geoquery").value;<br />
var uri =<br />
"http://api.local.yahoo.com/MapsService/V1/geocode?<br />
appid=dantheurer&#038;location=" + query;<br />
callWS(uri, "geocode");<br />
</code></p>
<p>The callWS() does an XmlHttpRequest to the proxy with the REST URL as parameter and displays ‘Loading’ while it waits for the proxy to complete the request. The PHP proxy uses CURL to make the actual request, and the callback method parseResult() gets executed once the call has succeeded.<br />
<code><br />
var url = 'yproxy.php?' + encodeURI(target);<br />
xmlhttp.open('GET', url, true);<br />
xmlhttp.onreadystatechange = function() {<br />
&nbsp;&nbsp;if(xmlhttp.readyState == 4 &#038;&#038; xmlhttp.status == 200) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById('result').innerHTML = '';<br />
&nbsp;&nbsp;&nbsp;&nbsp;parseResult(xmlhttp.responseText, service);<br />
&nbsp;&nbsp;} else {<br />
&nbsp;&nbsp;document.getElementById('result').innerHTML =<br />
&nbsp;&nbsp;"Loading...";<br />
&nbsp;&nbsp;}<br />
};<br />
xmlhttp.send(null);<br />
}<br />
</code></p>
<p>From here, all that&#8217;s left is parsing the XML and adding the markers. In this sample I used the <a href="http://xmljs.sourceforge.net/website/documentation-w3cdom.html">xmlw3cdom.js</a> parser from <a href="http://xmljs.sourceforge.net">SourceForge</a>.  It&#8217;s more than I need, but it makes things really easy. This DOM parser requires the following SAX parser <a href="http://xmljs.sourceforge.net/website/documentation-sax.html">xmlsax</a>.js to deal with the XML object. I will not discuss how to parse the XML, because it’s easier to just look it up in the source file.</p>
<p>The results are used to create a Point and a String for the Smartwindow, which get passed to the createYMarker() method.</p>
<p><code><br />
var point =<br />
new YGeoPoint(parseFloat(lat),parseFloat(lon));<br />
var smart = "Long: " + lon +  "<br />" + "Lat: " + lat;<br />
var myMarker = createYMarker(point, i, smart);<br />
</code></p>
<p>It creates the Markers on the map.</p>
<p><code><br />
var marker = new YMarker(point,'id'+number);<br />
marker.addLabel(number);<br />
YEvent.Capture(marker,EventsList.MouseClick, function() { marker.openSmartWindow(msg) });<br />
return marker;<br />
</code> </p>
<p>This is a pretty simple example but this can be the foundation for a much more complex mash-ups. Once this part is done, it only gets better. </p>
<p>Keep mashing! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.theurer.cc/blog/2005/11/03/how-to-build-a-maps-mash-up/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Virtual Earth API vs Google Maps API</title>
		<link>http://www.theurer.cc/blog/2005/09/13/virtual-earth-api-my-2-cents/</link>
		<comments>http://www.theurer.cc/blog/2005/09/13/virtual-earth-api-my-2-cents/#comments</comments>
		<pubDate>Wed, 14 Sep 2005 04:52:53 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web services]]></category>

		<guid isPermaLink="false">http://www.theurer.cc/?p=23</guid>
		<description><![CDATA[When I had the first look at Virtual Earth I was quite impressed by the details the provide on the Maps for certain areas. I checked San Jose and Seattle ant the resolution in those areas is much higher than what Google offers. Check out the Space Needle! (Sixth Avenue North Seattle, Washington 98109)
On the [...]]]></description>
			<content:encoded><![CDATA[<p>When I had the first look at <a href="http://virtualearth.com">Virtual Earth</a> I was quite impressed by the details the provide on the Maps for certain areas. I checked San Jose and Seattle ant the resolution in those areas is much higher than what Google offers. Check out the Space Needle! (Sixth Avenue North Seattle, Washington 98109)</p>
<p>On the first look the <a href="http://www.viavirtualearth.com/vve/Dashboard/Default.ashx">Virtual Earth API</a> appears to be pretty similar to what <a href="http://www.google.com/apis/maps/">Google offers</a>. That&#8217;s quite nice but why was it necessary to switch (long, lat) to (lat, long) if everything else looks so much the same? A really nice thing is that you don&#8217;t need to register your application or generate a key to use the API. </p>
<p>There biggest difference between the two API&#8217;s is that Virtual Earth only offers one class (VE_MapControl) which is the equivalent to GMap but that&#8217;s all there is. If you want to overlay information you can call a method of the class called AddPushPin() and that is not a great way to do it. What I really like a bout the G-Implementation is that I can create little &#8220;pin-objects&#8221; place them on the map and add a listener to it. This is really helpful to actually make you map interactive without writing a lot of code. VE also provides no default control to zoom in or out.  </p>
<p>Here is my <a href="http://theurer.cc/maps/ms/index.html">attempt to create something quickly</a> that offers the same set of features then <a href="http://www.theurer.cc/maps/g/">my Google Maps demo</a>. I didn&#8217;t have the time to create any controls, therefore it is not really useful. (I will be late for my hockey game!)</p>
<p>To sum this up, the maps API doesn&#8217;t seem to be very polished. VE only comes with the bare minimum of features which seems to me like it was done in a big hurry. I would not be surpised to find to missing classes in the documentations in the next couple of weeks.</p>
<p><strong>Update:</strong> Just realized that double-clicking on the VE Maps zooms in and that the satellite data for Europe is much worse than Google&#8217;s&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theurer.cc/blog/2005/09/13/virtual-earth-api-my-2-cents/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Spying on the competition &#8211; Google Maps</title>
		<link>http://www.theurer.cc/blog/2005/09/11/places-i-lived-google-maps/</link>
		<comments>http://www.theurer.cc/blog/2005/09/11/places-i-lived-google-maps/#comments</comments>
		<pubDate>Mon, 12 Sep 2005 04:46:53 +0000</pubDate>
		<dc:creator>Dan</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.theurer.cc/blog/2005/09/11/places-i-lived-google-maps/</guid>
		<description><![CDATA[A couple of days ago I counted the number of places I&#8217;ve lived at during the last 5 years. The result: 7. Following the rule: &#8220;Blog if you have something to say, write a map mashup if you want to point out some locations&#8221;, I did the latter. As Google Maps offers satellite data from [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of days ago I counted the number of places I&#8217;ve lived at during the last 5 years. The result: 7. Following the rule: &#8220;Blog if you have something to say, write a map mashup if you want to point out some locations&#8221;, I did the latter. As <a href="http://maps.google.com">Google Maps</a> offers satellite data from all over the world and half of the locations are in Germany, I finally found a reason to add the Maps to my Web site. Besides that it was a great to see what the competition offers. It was fun to write a few lines for it and the <a href="http://www.google.com/apis/maps/">documentation</a> made it really easy to get something together quicky. <a href="http://theurer.cc/gmaps">Check out the result!</a> In <a href="http://mcmanus.typepad.com/grind/2005/06/why_the_yahoo_m.html">this post</a> Jeffrey compares the Google and <a href="http://developer.yahoo.net/maps">Yahoo! Maps API</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.theurer.cc/blog/2005/09/11/places-i-lived-google-maps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
