<?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>jsha/README</title>
	<atom:link href="http://jacob.hoffman-andrews.com/README/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://jacob.hoffman-andrews.com/README</link>
	<description>a blog by Jacob Hoffman-Andrews</description>
	<lastBuildDate>Thu, 14 Apr 2011 21:49:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Ruby function STFU: temporarily redirect noisy stdout writes to /dev/null</title>
		<link>http://jacob.hoffman-andrews.com/README/index.php/2011/04/14/ruby-function-stfu-temporarily-redirect-noisy-stdout-writes-to-devnull/</link>
		<comments>http://jacob.hoffman-andrews.com/README/index.php/2011/04/14/ruby-function-stfu-temporarily-redirect-noisy-stdout-writes-to-devnull/#comments</comments>
		<pubDate>Thu, 14 Apr 2011 21:45:20 +0000</pubDate>
		<dc:creator>jsha</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jacob.hoffman-andrews.com/README/index.php/2011/04/14/ruby-function-stfu-temporarily-redirect-noisy-stdout-writes-to-devnull/</guid>
		<description><![CDATA[This function is handy if you have some third-party gem that generates writes to stdout or stderr which you wish to suppress.  Simple wrap your call to the noisy function in an `stfu&#8217; block.  If an exception is thrown, it will be reopened with stdout and stderr pointing to the console again.
  [...]]]></description>
			<content:encoded><![CDATA[<p>This function is handy if you have some third-party gem that generates writes to stdout or stderr which you wish to suppress.  Simple wrap your call to the noisy function in an `stfu&#8217; block.  If an exception is thrown, it will be reopened with stdout and stderr pointing to the console again.</p>
<pre>  def stfu
    begin
      orig_stderr = $stderr.clone
      orig_stdout = $stdout.clone
      $stderr.reopen File.new('/dev/null', 'w')
      $stdout.reopen File.new('/dev/null', 'w')
      retval = yield
    rescue Exception => e
      $stdout.reopen orig_stdout
      $stderr.reopen orig_stderr
      raise e
    ensure
      $stdout.reopen orig_stdout
      $stderr.reopen orig_stderr
    end
    retval
  end

  require 'some_noisy_gem'
  stfu do
    some_function_that_generates_a_lot_of_cruft_on_stdout
  end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://jacob.hoffman-andrews.com/README/index.php/2011/04/14/ruby-function-stfu-temporarily-redirect-noisy-stdout-writes-to-devnull/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Add an HTTP Host column to Wireshark</title>
		<link>http://jacob.hoffman-andrews.com/README/index.php/2011/04/01/add-an-http-host-column-to-wireshark/</link>
		<comments>http://jacob.hoffman-andrews.com/README/index.php/2011/04/01/add-an-http-host-column-to-wireshark/#comments</comments>
		<pubDate>Fri, 01 Apr 2011 20:55:24 +0000</pubDate>
		<dc:creator>jsha</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jacob.hoffman-andrews.com/README/index.php/2011/04/01/add-an-http-host-column-to-wireshark/</guid>
		<description><![CDATA[Diagnosing HTTP traffic in Wireshark can be a pain because it is not always clear from the Info column where the traffic is going. All those &#8220;GET / HTTP/1.1&#8243; blend together.  Fortunately it&#8217;s easy to add a column.
Go to Edit -> Preferences -> User Interface -> Columns.  Click &#8220;+ Add&#8221;, and for &#8220;Field [...]]]></description>
			<content:encoded><![CDATA[<p>Diagnosing HTTP traffic in Wireshark can be a pain because it is not always clear from the Info column where the traffic is going. All those &#8220;GET / HTTP/1.1&#8243; blend together.  Fortunately it&#8217;s easy to add a column.</p>
<p>Go to Edit -> Preferences -> User Interface -> Columns.  Click &#8220;+ Add&#8221;, and for &#8220;Field type&#8221; select Custom.  The &#8220;Field name&#8221; box will now be enabled.  In it type &#8220;http.host&#8221;.  Click the &#8220;New column&#8221; text above to set the display name to &#8220;HTTP Host.&#8221;  Hit OK and you are done!</p>
<p><img src="http://jacob.hoffman-andrews.com/README/wp-content/uploads/2011/04/Screen-shot-2011-04-01-at-1.59.25-PM.png" alt="Screen shot 2011-04-01 at 1.59.25 PM" title="Screen shot 2011-04-01 at 1.59.25 PM" width="700" height="72" class="alignnone size-full wp-image-99" /></p>
]]></content:encoded>
			<wfw:commentRss>http://jacob.hoffman-andrews.com/README/index.php/2011/04/01/add-an-http-host-column-to-wireshark/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generate a self-signed SSL certificate with subjectAlternateName extension</title>
		<link>http://jacob.hoffman-andrews.com/README/index.php/2010/12/06/generate-a-self-signed-ssl-certificate-with-subjectalternatename-extension/</link>
		<comments>http://jacob.hoffman-andrews.com/README/index.php/2010/12/06/generate-a-self-signed-ssl-certificate-with-subjectalternatename-extension/#comments</comments>
		<pubDate>Mon, 06 Dec 2010 23:07:38 +0000</pubDate>
		<dc:creator>jsha</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jacob.hoffman-andrews.com/README/?p=88</guid>
		<description><![CDATA[It&#8217;s often useful to create self-signed SSL certificates for testing or when you don&#8217;t need the authentication that CA signing provides.  I started with Akadia&#8217;s handy tutorial on self-signing here: http://www.akadia.com/services/ssh_test_certificate.html.
Then I needed to add a list of subjectAlternateName (SAN) fields.  This is an x509v3 extension that allows a single certificate to be valid for [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s often useful to create self-signed SSL certificates for testing or when you don&#8217;t need the authentication that CA signing provides.  I started with Akadia&#8217;s handy tutorial on self-signing here: <a href="http://www.akadia.com/services/ssh_test_certificate.html">http://www.akadia.com/services/ssh_test_certificate.html</a>.</p>
<p>Then I needed to add a list of subjectAlternateName (SAN) fields.  This is an x509v3 extension that allows a single certificate to be valid for multiple DNS names.  Here&#8217;s a shortened version of how to create a self-signed cert using those fields:</p>
<p><code><br />
echo -e &gt;extensions.cnf "basicConstraints=CA:true\nsubjectAltName=DNS:mysite1.com, DNS:mysite2.com"</code></p>
<p><code> </code></p>
<p><code>openssl genrsa -out server.key 2048 &amp;&amp; openssl req -new -key server.key -out server.csr -subj /CN=localhost.twitter.com &amp;&amp; openssl x509 -req -days 3650 -extfile extensions.cnf -in server.csr -signkey server.key -out server.crt<br />
</code></p>
<p>Import server.crt into your list of trusted root certs and install server.crt and server.key in your Apache configuration.  Your Apache should now be able to serve trusted SSL for the domains you specified, to your browser or any other one that imports your new certificate as a root.</p>
<p>NOTE: Guard your server.key carefully.  Because you have just imported this as a CA cert, an attacker who gained control of your server.key could use it to impersonate any server on the web to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacob.hoffman-andrews.com/README/index.php/2010/12/06/generate-a-self-signed-ssl-certificate-with-subjectalternatename-extension/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Youtube geotagging</title>
		<link>http://jacob.hoffman-andrews.com/README/index.php/2010/08/08/youtube-geotagging/</link>
		<comments>http://jacob.hoffman-andrews.com/README/index.php/2010/08/08/youtube-geotagging/#comments</comments>
		<pubDate>Sun, 08 Aug 2010 15:25:40 +0000</pubDate>
		<dc:creator>jsha</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jacob.hoffman-andrews.com/README/?p=77</guid>
		<description><![CDATA[The documentation on how geotagging works in Youtube is a little slim, so I&#8217;m documenting what I&#8217;ve learned about it recently.
When you pull a Youtube feed in JSON-C format, e.g. http://gdata.youtube.com/feeds/api/users/greenpeaceusa/uploads?alt=jsonc&#38;v=2&#38;max-results=50&#38;category=oilspilltruth, sometimes you will get geotags like this:
{
  data: {
     ...
     items: [
    [...]]]></description>
			<content:encoded><![CDATA[<p>The documentation on how geotagging works in Youtube is a little slim, so I&#8217;m documenting what I&#8217;ve learned about it recently.</p>
<p>When you pull a Youtube feed in JSON-C format, e.g. <a href="http://gdata.youtube.com/feeds/api/users/greenpeaceusa/uploads?alt=jsonc&amp;v=2&amp;max-results=50&amp;category=oilspilltruth">http://gdata.youtube.com/feeds/api/users/greenpeaceusa/uploads?alt=jsonc&amp;v=2&amp;max-results=50&amp;category=oilspilltruth</a>, sometimes you will get geotags like this:</p>
<pre>{
  data: {
     ...
     items: [
       {
         id: "s-QQWRdF-5Y"
         ...
         geoCoordinates: {
           latitude: 29.149463653564453
           longitude: -90.47636413574219
         }
       }
       ....</pre>
<p>And sometimes, instead of geoCoordinates, you will get <code>location</code>:</p>
<pre>          location: "cat island, louisiana"</pre>
<p>The difference between these two lies in how the video was geotagged.  If a user geotagged the video by simply typing a location name into the map widget and hitting enter, it will receive a <code>location:</code> attribute.  If a user geotagged the video by typing a location name and then dragging the marker, or simply by dragging the marker, then the video will receive a <code>geoCoordinates:</code> attribute.  In theory whenever a video has a <code>location:</code> attribute, you should be able to send it through <a href="http://code.google.com/apis/maps/documentation/geocoding/">Google&#8217;s geocoding service</a> and be confident that you will receive an answer close to what the user intended.  In practice, Google&#8217;s geocoding index will occasionally change, and the answer may not be exactly the same as what the user saw when they originally geotagged a video.</p>
<h2>How do I geotag a video?</h2>
<p>Assuming you already have a video uploaded, go to <a href="http://www.youtube.com/my_videos">http://www.youtube.com/my_videos</a>.  Click &#8216;Edit&#8217; for one of your videos:</p>
<p><img class="alignnone size-full wp-image-79" title="Youtube video list" src="http://jacob.hoffman-andrews.com/README/wp-content/uploads/2010/08/Screen-shot-2010-08-08-at-11.08.48-AM.png" alt="Youtube video list" width="832" height="202" /></p>
<p>In the lower right of the video Edit page, you will see a Date and Map panel:</p>
<p><img class="alignnone size-full wp-image-80" title="Screen shot 2010-08-08 at 11.11.34 AM" src="http://jacob.hoffman-andrews.com/README/wp-content/uploads/2010/08/Screen-shot-2010-08-08-at-11.11.34-AM.png" alt="Screen shot 2010-08-08 at 11.11.34 AM" width="509" height="559" /></p>
<p>You can fly to a location by typing its name:</p>
<p><img class="alignnone size-full wp-image-81" title="Screen shot 2010-08-08 at 11.13.14 AM" src="http://jacob.hoffman-andrews.com/README/wp-content/uploads/2010/08/Screen-shot-2010-08-08-at-11.13.14-AM.png" alt="Screen shot 2010-08-08 at 11.13.14 AM" width="497" height="551" /></p>
<p>Make sure to hit the &#8220;Save changes&#8221; button in the upper left.  After doing this, your video will receive a location: attribute.  However, if you want a more precise location, or you want your video to receive the easier-to-plot geoCoordinates attribute, zoom in and drag the pin to the exact location you want:</p>
<p><img class="alignnone size-full wp-image-82" title="Screen shot 2010-08-08 at 11.15.55 AM" src="http://jacob.hoffman-andrews.com/README/wp-content/uploads/2010/08/Screen-shot-2010-08-08-at-11.15.55-AM.png" alt="Screen shot 2010-08-08 at 11.15.55 AM" width="501" height="558" /></p>
<p>Notice that the &#8220;Map Location&#8221; box now contains exact latitude and longitude coordinates.  Hit &#8220;Save changes&#8221; in the upper left, and your video is now tagged with precise coordinates.  You should see these show up as the geoCoordinates attribute in JSON-C output.</p>
<h2>How can I tell if a Youtube video is geotagged?</h2>
<p>As far as I can tell, there is no way to figure this out through the user interface on Youtube.com.  I believe the only way to access Youtube geotags is through the API.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacob.hoffman-andrews.com/README/index.php/2010/08/08/youtube-geotagging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rendered my first OSM image!</title>
		<link>http://jacob.hoffman-andrews.com/README/index.php/2010/03/26/rendered-my-first-osm-image/</link>
		<comments>http://jacob.hoffman-andrews.com/README/index.php/2010/03/26/rendered-my-first-osm-image/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 20:47:41 +0000</pubDate>
		<dc:creator>jsha</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jacob.hoffman-andrews.com/README/?p=73</guid>
		<description><![CDATA[I&#8217;ve been playing around with OpenStreetMaps recently.  I downloaded a subset of the world data set covering San Francisco by using this tool: http://78.46.81.38/.  I loaded the data into a local PostGIS database with osm2pgsql.  Then I spent a couple hours installing the prerequisites for Mapnik and building Mapnik itself, which was the hardest [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been playing around with OpenStreetMaps recently.  I downloaded a subset of the world data set covering San Francisco by using this tool: <a href="http://78.46.81.38/">http://78.46.81.38/</a>.  I loaded the data into a local PostGIS database with <a href="http://wiki.openstreetmap.org/wiki/Osm2pgsql">osm2pgsql</a>.  Then I spent a couple hours installing the prerequisites for <a href="http://wiki.openstreetmap.org/wiki/Mapnik">Mapnik</a> and building Mapnik itself, which was the hardest part but still very doable.  Once Mapnik was installed, I was able to use the generate_image.py script to generate a quick map of SF.  Next step is to learn how to build tiles for slippy maps, and then how to customize them.</p>
<p><a href="http://jacob.hoffman-andrews.com/osm/first-sf-render.png"><img class="alignnone" src="http://jacob.hoffman-andrews.com/osm/first-sf-render-thumb.png" alt="" width="400" height="400" /></a></p>
<p>The process was mostly easy and rewarding.  One funny quirk: osm2pgsql can&#8217;t do password authentication to the database, so it&#8217;s most convenient to use a passwordless account.  Mapnik, on the other hand, appears to choke if it is given an empty password string, so you need to add a password to the account once you get to the Mapnik stage.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacob.hoffman-andrews.com/README/index.php/2010/03/26/rendered-my-first-osm-image/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>HOWTO Encrypt an existing home directory on Ubuntu Karmic Koala</title>
		<link>http://jacob.hoffman-andrews.com/README/index.php/2009/12/08/howto-encrypt-an-existing-home-directory-on-ubuntu-karmic-koala/</link>
		<comments>http://jacob.hoffman-andrews.com/README/index.php/2009/12/08/howto-encrypt-an-existing-home-directory-on-ubuntu-karmic-koala/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 06:44:55 +0000</pubDate>
		<dc:creator>jsha</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jacob.hoffman-andrews.com/README/?p=51</guid>
		<description><![CDATA[
.instructions {
margin: 1em;
background-color: #f4f4f4;
}

Karmic Koala, the latest release of Ubuntu, made it really easy for new installs to use encryption for  home directories.  However, for users who upgraded from previous releases (Jaunty Jackalope, Intrepid Ibex, etc), the process to encrypt an existing home directory is not so obvious.  Here&#8217;s one way to do it.
You&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<style>
.instructions {
margin: 1em;
background-color: #f4f4f4;
}
</style>
<p><a href="https://wiki.ubuntu.com/KarmicKoala">Karmic Koala</a>, the latest release of Ubuntu, made it really easy for new installs to use encryption for  home directories.  However, for users who upgraded from previous releases (Jaunty Jackalope, Intrepid Ibex, etc), the process to encrypt an existing home directory is not so obvious.  Here&#8217;s one way to do it.</p>
<p>You&#8217;ll need enough free space for two copies of your entire home directory.  If you don&#8217;t have that, first move your existing home directory onto external media, and modify these instructions as appropriate.</p>
<p>First, log out of your normal account, which we&#8217;ll term <strong>myrealusername</strong>.  Login as root.  Create a new, temporary user, using the &#8211;encrypt-home flag to adduser.  Use the same password as your current user account.</p>
<div class=instructions># adduser &#8211;encrypt-home tmpuser<br />
************************************************************************<br />
YOU SHOULD RECORD YOUR MOUNT PASSPHRASE AND STORE IT IN A SAFE LOCATION.<br />
ecryptfs-unwrap-passphrase ~/.ecryptfs/wrapped-passphrase<br />
THIS WILL BE REQUIRED IF YOU NEED TO RECOVER YOUR DATA AT A LATER TIME.<br />
************************************************************************</p>
<p>Done configuring.</p>
<p>Enter new UNIX password: <strong>USE YOUR EXISTING PASSWORD</strong><br />
Retype new UNIX password:<br />
No password supplied<br />
Enter new UNIX password:<br />
Retype new UNIX password:<br />
passwd: password updated successfully<br />
Changing the user information for tmpuser<br />
Enter the new value, or press ENTER for the default<br />
Full Name []:<br />
Room Number []:<br />
Work Phone []:<br />
Home Phone []:<br />
Other []:<br />
Is the information correct? [Y/n]
</div>
<p>When you ran &#8216;adduser&#8217;, it created two important directories: /home/.ecryptfs/tmpuser/.Private and /home/.ecryptfs/tmpuser/.ecryptfs.  These are both symlinked into a skeleton home directory at /home/tmpuser.  I say skeleton here, because the directory so created is only ever visible when &#8216;tmpuser&#8217; is logged out.  Once &#8216;tmpuser&#8217; is logged in, the contents of /home/.ecryptfs/tmpuser/.Private are decrypted and mounted <em>on top of</em> /home/tmpuser.  We want the same thing to happen for <strong>myrealusername</strong>.  Before we put the skeleton directory in place, however, we want to move your existing, unencrypted home aside.  That way when you log in with an encrypted home it isn&#8217;t hidden and we&#8217;re able to copy files into your new, encrypted home.</p>
<div class=instructions># mv /home/<strong>myrealusername</strong> /home/<strong>myrealusername</strong>.orig
</div>
<p>Now you want to copy these skeleton files to /home/.ecryptfs/<strong>myrealusername</strong> and change the ownership:</p>
<div class=instructions># REALUSER=<strong>myrealusername</strong><br />
# cd /home<br />
# mkdir -m 0700 $REALUSER<br />
# cp -r .ecryptfs/tmpuser .ecryptfs/$REALUSER<br />
# chown -R $REALUSER.$REALUSER .ecryptfs/$REALUSER $REALUSER<br />
# ln -s /home/.ecryptfs/$REALUSER/.* $REALUSER/
</div>
<p>You also need to edit a mount description file which still refers to &#8216;tmpuser&#8217;:</p>
<div class=instructions># sed -i s/tmpuser/$REALUSER/ .ecryptfs/$REALUSER/.ecryptfs/Private.mnt
</div>
<p>Just for good measure we&#8217;ll copy the two informational symlinks from the skeleton directory.  These are handy because if they show up when you&#8217;re logged in, you know something went wrong and you&#8217;re not accessing your encrypted home dir.</p>
<div class=instructions># cp tmpuser/* $REALUSER/<br />
# chown $REALUSER.$REALUSER $REALUSER/*
</div>
<p>At this point, you&#8217;re ready to log in as <strong>myrealusername</strong>.  Go ahead.  I&#8217;ll wait.</p>
<p>Got it?  You should have a mostly empty home directory.  If you have a file named Access-Your-Private-Data.desktop, something went wrong.</p>
<p>If all&#8217;s well, copy your original home directory into the new, encrypted home directory.  It&#8217;s best to do this as root, on the off chance you have some files in your home dir which you don&#8217;t own, but want to preserve exactly.  You may be tempted to do this as an &#8216;mv&#8217; if you&#8217;re low on disk space.  That should work just the same, but it won&#8217;t actually unlink the original until *everything* is copied, meaning you still need enough space for two copies of your home dir.  In a pinch you could move one subdirectory at a time, which means you don&#8217;t need as much spare space.</p>
<p>Note the trailing slashes on the rsync &#8211; those are important.</p>
<div class=instructions><strong>myrealusername</strong>$ su<br />
# rsync -av /home/<strong>myrealusername</strong>.orig/ /home/<strong>myrealusername</strong>/
</div>
<p>Bingo!  Your home directory is now encrypted.  Once you&#8217;re satisfied that everything is there, don&#8217;t forget to remove your original, unencrypted home.  To be tidy you may want to delete the &#8216;tmpuser&#8217; account too.</p>
<div class=instructions># rm -rf /home/<strong>myrealusername</strong>.orig<br />
# userdel -r tmpuser
</div>
]]></content:encoded>
			<wfw:commentRss>http://jacob.hoffman-andrews.com/README/index.php/2009/12/08/howto-encrypt-an-existing-home-directory-on-ubuntu-karmic-koala/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>HOWTO Turn a shapefile into a KML file under Ubuntu</title>
		<link>http://jacob.hoffman-andrews.com/README/index.php/2008/10/29/howto-turn-a-shapefile-into-a-kml-file-under-ubuntu/</link>
		<comments>http://jacob.hoffman-andrews.com/README/index.php/2008/10/29/howto-turn-a-shapefile-into-a-kml-file-under-ubuntu/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 18:50:02 +0000</pubDate>
		<dc:creator>jsha</dc:creator>
				<category><![CDATA[HOWTO]]></category>

		<guid isPermaLink="false">http://jacob.hoffman-andrews.com/README/?p=20</guid>
		<description><![CDATA[Shapefiles and KML are two common geographic formats.  Shapefiles tend to be used by geographic databases like ESRI and PostGIS, while KML originated with Google Earth, back when it was called Keyhole.  KML files are more common for data that is intended primarily to display to users.  They are supported  both in Google Earth [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Shapefile">Shapefiles</a> and <a href="http://en.wikipedia.org/wiki/KML">KML</a> are two common geographic formats.  Shapefiles tend to be used by geographic databases like ESRI and PostGIS, while KML originated with Google Earth, back when it was called Keyhole.  KML files are more common for data that is intended primarily to display to users.  They are supported  both in Google Earth and in Google Maps, through <a href="http://local.google.com/support/bin/answer.py?hl=en&amp;answer=68480#import">importing to a My Map</a>.</p>
<p>But for all that both formats are really popular, it&#8217;s not easy to go back and forth between the two.  Further, it&#8217;s really hard to simplify a KML file that has highly detailed polygons.  This is important because, while Google Earth may be able to handle a large number of points, Google Maps has to execute in the browser and so has tight limits on how many points can be in a polygon.  This can result in a group of polygons being split by Maps across multiple pages so they can be rendered in a reasonable amount of time.</p>
<p>I had some shapefile data I wanted to simplify and display in a My Map.  My solution was to bite the bullet and install PostgreSQL and PostGIS.  Both are free software and are available as packages on Ubuntu Intrepid Ibex.  Similar directions should apply for other Linux distributions.</p>
<p>First, install PostgreSQL and the PostGIS geographic layer on top of it:</p>
<p><code><br />
$ sudo apt-get install postgresql-8.3-postgis postgis gdal-bin<br />
</code></p>
<p>Become the postgres user to create the procedural language, initialize the geographic functions, and fill the spatial_ref_sys table:</p>
<p><code><br />
$ sudo su postgres<br />
postgres$ createlang plpgsql<br />
postgres$ psql -d postgres -f /usr/share/postgresql-8.3-postgis/lwpostgis.sql<br />
postgres$ psql -d postgres -f /usr/share/postgresql-8.3-postgis/spatial_ref_sys.sql<br />
postgres$ createuser username<br />
Shall the new role be a superuser? (y/n) y<br />
CREATE ROLE<br />
postgres$ exit<br />
</code></p>
<p>Import the shapefile into your database.  The -d parameter drops the table before creating it, useful if you may be reimporting the data multiple times.  If you have a large file you may want to add the -D parameter, which uses the more efficient dump format for faster ingestion.  The -s parameter specifies the SRID of your input data, and you should be able to figure it out from the .prj file that came with the shapefile.</p>
<p><code><br />
$ shp2pgsql -d -s 2877 election_precincts election_precincts_table postgres | psql -d postgres<br />
</code></p>
<p>And dump output into KML.  Note that you can put any criteria you want into the -sql param, so you could restrict the set of features you output.</p>
<p><code><br />
$ ogr2ogr -f "KML" election_precincts.kml PG:"dbname=postgres" -dsco NameField=precinct -sql "select precinct, transform(simplify(the_geom, 100), 4326) from election_precincts_table"<br />
</code></p>
<p>Note: KML explicitly supports only one SRID: 4326.  That refers to <a href="http://en.wikipedia.org/wiki/WGS84">WGS84</a>.  So in the ogr2ogr command above, you need the transform(&#8230;, 4326) call to produce valid lat/longs for KML.  Evidently Google Maps has another SRID, 900913, but I haven&#8217;t played with that one at all.  If you&#8217;re using KML as your input to Google Maps, 4326 should be fine.</p>
<p>You can increase or decrease the parameter to simplify().  Higher numbers mean more simplification, lower numbers mean less.</p>
<p>The NameField param is a KML-specific parameter to ogr2ogr which specifies which field from the query should be used as the name for a given KML feature.</p>
<p>Here are some other pages I found useful when working this all out:</p>
<p><a href="http://postgis.refractions.net/support/wiki/index.php?PostgisOnUbuntu">PostGIS Wiki : Postgis On Ubuntu</a><br />
<a href="http://www.perrygeo.net/wordpress/?p=56">PerryGeo » Converting Shapefiles (and more) to KML</a><br />
<a href="http://www.arcwebservices.com/arcwebonline/services/pcs_alpha.htm">Projected coordinates listed by name</a><a href="http://postgis.refractions.net/documentation/manual-1.3/"><br />
</a><a href="http://postgis.refractions.net/documentation/manual-1.3/">PostGIS Manual</a><br />
<a href="http://www.bostongis.com/postgis_simplify.snippet">PostGIS Simplify</a><br />
<a href="http://www.bostongis.com/postgis_quickguide.bqg">PostGIS ver. 1.3.1 Quick Guide &#8211; Cheatsheet</a><br />
<a href="http://trac.osgeo.org/gdal/ticket/2271">#2271 (Add built in reprojection support to KML driver) &#8211; GDAL &#8211; Trac</a><br />
<a href="http://postgis.refractions.net/pipermail/postgis-users/2001-September/000330.html">[postgis] SRID for LAT/LONG</a><br />
<a href="http://postgis.refractions.net/pipermail/postgis-users/2004-June/005011.html">[postgis-users] addgeometrycolumn() does not exist</a><br />
<a href="http://lists.maptools.org/pipermail/fwtools/2007-April/000750.html">[FWTools] ogr2ogr shp &#8211;&gt; kml conversion failing on some complicated polygons</a><br />
<a href="http://www.geo-news.net/index_norm.php">Generalize Vectors &#8211; GEO UTILITIES</a><br />
<a href="http://postgis.refractions.net/documentation/manual-1.3/"><br />
</a><a href="http://postgis.refractions.net/support/wiki/index.php?PostgisOnUbuntu"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jacob.hoffman-andrews.com/README/index.php/2008/10/29/howto-turn-a-shapefile-into-a-kml-file-under-ubuntu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JavaScript compiler roundup</title>
		<link>http://jacob.hoffman-andrews.com/README/index.php/2008/09/22/javascript-compiler-roundup/</link>
		<comments>http://jacob.hoffman-andrews.com/README/index.php/2008/09/22/javascript-compiler-roundup/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 17:22:00 +0000</pubDate>
		<dc:creator>jsha</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://jacob.hoffman-andrews.com/README/?p=14</guid>
		<description><![CDATA[I&#8217;m looking to start compiling JavaScript for a personal project, so I did a quick roundup of freely available JS compilers / obfuscators / minifiers.
Dojo Shrinksafe &#8211; http://dojotoolkit.org/docs/shrinksafe
YUI Compressor &#8211; http://www.julienlecomte.net/yuicompressor/
JavaScript Obfuscator by Stunnix &#8211; http://www.stunnix.com/prod/jo/
JSMin &#8211; http://www.crockford.com/javascript/jsmin.html
Packer- http://dean.edwards.name/packer/
So far I&#8217;ve tried Shrinksafe and YUI Compressor.  I couldn&#8217;t get Shrinksafe to produce any output, even [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m looking to start compiling JavaScript for a personal project, so I did a quick roundup of freely available JS compilers / obfuscators / minifiers.</p>
<p>Dojo Shrinksafe &#8211; http://dojotoolkit.org/docs/shrinksafe</p>
<p>YUI Compressor &#8211; http://www.julienlecomte.net/yuicompressor/</p>
<p>JavaScript Obfuscator by Stunnix &#8211; http://www.stunnix.com/prod/jo/</p>
<p>JSMin &#8211; http://www.crockford.com/javascript/jsmin.html</p>
<p>Packer- http://dean.edwards.name/packer/</p>
<p>So far I&#8217;ve tried Shrinksafe and YUI Compressor.  I couldn&#8217;t get Shrinksafe to produce any output, even though it seemed to be parsing my JS since it threw errors when I had something wrong.</p>
<p>YUI compressor ran on my input JS and produced output, but it had a couple of problems.  Backslash-escaped strings get unescaped from the output.  For instance,</p>
<pre>alert("two \n lines");

Becomes:

alert("two
 lines");

Also, it seemed to have trouble with "else if (...) {" constructs, turning them into "else{if(...){".</pre>
]]></content:encoded>
			<wfw:commentRss>http://jacob.hoffman-andrews.com/README/index.php/2008/09/22/javascript-compiler-roundup/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Importing Evolution addressbook contacts into GMail</title>
		<link>http://jacob.hoffman-andrews.com/README/index.php/2008/09/10/importing-evolution-addressbook-contacts-into-gmail/</link>
		<comments>http://jacob.hoffman-andrews.com/README/index.php/2008/09/10/importing-evolution-addressbook-contacts-into-gmail/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 21:48:43 +0000</pubDate>
		<dc:creator>jsha</dc:creator>
				<category><![CDATA[HOWTO]]></category>

		<guid isPermaLink="false">http://jacob.hoffman-andrews.com/README/?p=13</guid>
		<description><![CDATA[GMail&#8217;s Contacts section now has support for a full-featured set of contacts, including phone numbers, addresses, etc.  I tried importing my addressbook from Evolution, but it wasn&#8217;t easy.  Step 1: Export your addressbook in vCard format.  Step 2: Tweak the output.GMail doesn&#8217;t like plain TEL records, it wants them to always beprefixed by phone., e.g.:phone.TEL;TYPE=CELL,OTHER:(510) [...]]]></description>
			<content:encoded><![CDATA[<p>GMail&#8217;s Contacts section now has support for a full-featured set of contacts, including phone numbers, addresses, etc.  I tried importing my addressbook from Evolution, but it wasn&#8217;t easy.  Step 1: Export your addressbook in vCard format.  Step 2: Tweak the output.GMail doesn&#8217;t like plain TEL records, it wants them to always beprefixed by phone., e.g.:phone.TEL;TYPE=CELL,OTHER:(510) 334-3594
<p id=":2a" class="ArwC7c ckChnd"> Versus</p>
<p>TEL;TYPE=CELL,OTHER:(510) 555-1212Also GMail doesn&#8217;t like blank lines between vCard records.Here are a pair of vim commands to fix the above two problems::%s,^TEL,phone.TEL:v/./d
<p id=":2a" class="ArwC7c ckChnd"> </p>
<p id=":2a" class="ArwC7c ckChnd">Once you&#8217;ve edited the file appropriately you should be able to import it using the Contacts &gt; Import function within GMail.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacob.hoffman-andrews.com/README/index.php/2008/09/10/importing-evolution-addressbook-contacts-into-gmail/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>HOWTO Tunnel an Rdesktop (RDC) connection over SSH from Linux</title>
		<link>http://jacob.hoffman-andrews.com/README/index.php/2008/08/25/howto-tunnel-an-rdesktop-rdc-connection-over-ssh-from-linux/</link>
		<comments>http://jacob.hoffman-andrews.com/README/index.php/2008/08/25/howto-tunnel-an-rdesktop-rdc-connection-over-ssh-from-linux/#comments</comments>
		<pubDate>Tue, 26 Aug 2008 02:25:54 +0000</pubDate>
		<dc:creator>jsha</dc:creator>
				<category><![CDATA[HOWTO]]></category>

		<guid isPermaLink="false">http://jacob.hoffman-andrews.com/README/?p=12</guid>
		<description><![CDATA[I have an SSH connection into work, and wanted to be able to access a Windows machine there via rdesktop.  I tried this:
$ ssh -L 3890:windows-machine:3890
$ rdesktop localhost:3890
But the rdesktop command hung for a long time then died.  Some poking around revealed this page: http://www.bluestream.org/Networking/SSHTunnelRDP.htm, which details an occasional problem that occurs when trying to [...]]]></description>
			<content:encoded><![CDATA[<p>I have an SSH connection into work, and wanted to be able to access a Windows machine there via rdesktop.  I tried this:</p>
<p>$ ssh -L 3890:windows-machine:3890</p>
<p>$ rdesktop localhost:3890</p>
<p>But the rdesktop command hung for a long time then died.  Some poking around revealed this page: <a href="http://www.bluestream.org/Networking/SSHTunnelRDP.htm">http://www.bluestream.org/Networking/SSHTunnelRDP.htm</a>, which details an occasional problem that occurs when trying to connect to a forwarded port on localhost.  Their suggestion was to bind to a non-localhost interface.  Since their tutorial is for Putty, here&#8217;s the equivalent for OpenSSH:</p>
<p>$ ssh -L mymachinename:3890:windows-machine:3890</p>
<p>$ rdesktop mymachinename:3890</p>
<p>Where mymachinename is the actual hostname of your machine, which should in theory resolve to the IP of your ethernet adaptor.</p>
]]></content:encoded>
			<wfw:commentRss>http://jacob.hoffman-andrews.com/README/index.php/2008/08/25/howto-tunnel-an-rdesktop-rdc-connection-over-ssh-from-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

