<?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>Scholars&#039; Lab</title>
	<atom:link href="http://www.scholarslab.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.scholarslab.org</link>
	<description>Works in Progress</description>
	<lastBuildDate>Fri, 23 Jul 2010 21:10:57 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>On XForms</title>
		<link>http://www.scholarslab.org/digital-libraries/on-xforms/</link>
		<comments>http://www.scholarslab.org/digital-libraries/on-xforms/#comments</comments>
		<pubDate>Fri, 23 Jul 2010 21:08:30 +0000</pubDate>
		<dc:creator>Ethan Gruber</dc:creator>
				<category><![CDATA[Digital Libraries]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[EAD]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[XForms]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=877</guid>
		<description><![CDATA[Several months ago, I wrote a post about my XForms development in the Scholars&#8217; Lab as part of a research project.  I&#8217;m currently working on two research projects that utilize the standard: EADitor (Encoded Archival Description management and dissemination framework) and Numishare (geared towards online delivery of numismatic collections, though other artifacts can be [...]]]></description>
			<content:encoded><![CDATA[<p>Several months ago, I wrote a post about my <a href="http://www.w3.org/TR/xforms11/">XForms</a> development in the Scholars&#8217; Lab as part of a research project.  I&#8217;m currently working on two research projects that utilize the standard: <a href="http://code.google.com/p/eaditor/">EADitor</a> (Encoded Archival Description management and dissemination framework) and <a href="http://code.google.com/p/numishare/">Numishare</a> (geared towards online delivery of numismatic collections, though other artifacts can be represented).  Despite its promise, XForms has not quite swept up the library world yet (though it is most definitely generating some buzz).  The W3C standard is a definition for creating dynamic webforms that handle complex, hierarchical XML data&#8211;the type of stuff libraries deal with daily.  However, only in recent years have XForms processors matured to the point they are ready for mass-market consumption.  There are numerous private firms developing XForms applications, including Wachovia, Cisco, and Pfizer.  It is also used to some degree in the academic community.  As far as I am aware, not many institutions are running it in production, though some are rapidly moving in that direction.  The <a href="https://list.mail.virginia.edu/mailman/listinfo/xforms4lib" class="broken_link">XForms4Lib listserv</a> created in the fall has 80 members from across North American and European academia.</p>
<p>Which brings me to my point.   <span id="more-877"></span></p>
<p>Matt Zumwalt, active code4lib member and Ruby on Rails/institutional repository developer, <a href="http://yourmediashelf.com/blog/2010/07/20/writing-on-the-wall-xforms-has-been-dead-for-years/">boldly declared XForms to be dead</a>.  I offer this critique:</p>
<blockquote><p>There are some inaccuracies in this post that I would like to address.  First of all, HTML 5 forms do not supplant XForms as an option for collecting user inputted data.  HTML5 is much simpler, and thus has broader appeal.  XForms enables the creation of much, much more complex models, with far more sophisticated controls and validation.  Moreover, if XForms was a dead language in January 2008, with the release of the HTML5 specification, and that IBM had dropped support, then why do you suppose the XForms 1.1 specification was released in October 2009, edited by a representative of IBM?</p>
<p>No, XForms is very much alive.  It has a small, but very active community, which is especially visible with the Orbeon development community.  XForms is best used as a definition of dynamic forms that are processed server-side, not in the browser (which pushes a lot of processing demand onto the user, which isn&#8217;t good).  There are some good, open source frameworks out there.  Orbeon is the best, and has many users from both industry and academia, including Pfizer, Leap Frog, Wachovia, UCSB, Stanford, and the National Archives.  In fact, Orbeon XForms applications form a large part of the enormous workflow of the NARA Electronic Records Archives project, which is a multi-year project contracted to Lockheed Martin and has a financial backing of close to a half a billion dollars (I have heard).  XForms, dead?</p>
<p>A lot of the design flaws you describe are in actuality implementation flaws.  Development of a Rails-based framework seems to me like an enormous waste of time and money.  You can adapt the MODS editor developed by Brown to such a task.  It has already been proven that you can interact with metadata delivered through REST from a Fedora repository.  And MODS is fairly simple as a a metadata standard.  Care to take a stab at TEI or EAD?</p>
<p>When you began your research in 2007, Orbeon was a fairly young application.  But the standard and its delivery and processing applications have evolved since then.  Only in the last two or three years has XForms grown into a viable solution.  Moreover, since it is a W3C standard, you can pick your forms up and migrate them to a new framework fairly easily.  Is your Rails application sustainable in the long term?  Are today&#8217;s jQuery functions going to work in 2015&#8217;s browsers?  These are things you need to consider when contemplating a web form standard.</p></blockquote>
<p>Fedora is a Tomcat application.  So is Solr.  So is adore-djatoka, which UVA/Hydra utilizes for jpeg2000 delivery.  And so is Orbeon.  ActiveFedora and any Rails-based MODS editor seem to me like the third wheel in the repository relationship.  But in all seriousness, the sustainability of a boutique Rails application that is heavily dependent on the javascript functions of 2010 should be a serious concern to repository developers.  jQuery is all the rage today, but it could blow away in the wind five years from now.  This is the very thing that the XForms working group set out to prevent when they introduced a standard approach to dynamic webforms.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/digital-libraries/on-xforms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WMS vs. tilecaching</title>
		<link>http://www.scholarslab.org/geospatial-and-temporal/wms-vs-tilecaching/</link>
		<comments>http://www.scholarslab.org/geospatial-and-temporal/wms-vs-tilecaching/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 11:59:35 +0000</pubDate>
		<dc:creator>Adam Soroka</dc:creator>
				<category><![CDATA[Geospatial and Temporal]]></category>
		<category><![CDATA[Visualization and Data Mining]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[gis]]></category>
		<category><![CDATA[historic]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[plugins]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=853</guid>
		<description><![CDATA[In our work on Neatline, we have made a deliberate choice to start by restraining our work to map-sources that are quickly and easily provided through WMS. This leaves out (for now) two popular sources of map imagery; Google Maps and Open Street Map. I’m going to explain why we made that choice, and why, when we do come to make these sources usable with Neatline, we will do so with great care and with an eye to scholarly method.]]></description>
			<content:encoded><![CDATA[<p>In our work on <a href="http://neatline.org/">Neatline</a>, we have made a deliberate choice to start by constraining ourselves to map-sources that are quickly and easily provided through <a href="http://www.opengeospatial.org/standards/wms">WMS</a>. This leaves out (for now) two popular sources of map imagery; <a href="http://maps.google.com/">Google Maps</a> and <a href="http://www.openstreetmap.org/">Open Street Map</a>. I&#8217;m going to explain why we made that choice, and why, when we do come to make these sources usable with Neatline, we will do so with great care and with an eye to scholarly method.  <span id="more-853"></span></p>
<p>All two-dimensional maps (as opposed to globes) are <a href="http://en.wikipedia.org/wiki/Map_projection">projected</a>. That is, the curved three-dimensional surface of the Earth is transformed onto a flat two-dimensional surface. This can be done in an infinite variety of ways, many of which have been mathematically characterized and named by cartographers, for whom they are necessary tools. We must note, however, that no such transform can obtain a perfect representation of a section of the Earth. The mapmaker must choose which qualities to preserve and in what measures. Is it more important to provide an accurate depiction of relative areas or of relative lengths? Is the area around Greenland to be kept in the focus of accuracy, or that around New Zealand?</p>
<p>Each map therefore carries with it from its creation certain choices like these, part of the arguments the map makes about the world by its very construction. We chose WMS on which to start building our tools because, amongst other reasons, it allows for the transmission of projection information as part of its operation. This fact allows us to produce imagery from historical maps (themselves in any number of projections) and maintain the original choices the mapmaker made. Google Maps and Open Street Map are not WMS sources. They can be described as tile caches, huge reservoirs of rendered imagery. As such, they offer their own choices about how the world is to be projected. (Google&#8217;s choice has become so closely associated with Google that it is known widely as &#8220;the Google projection&#8221;.)</p>
<p>Now we come to an important technical distinction; WMS services are able (depending on the capabilities of the specific software in use) to reproject their contents. That is, in response to a specific request for imagery, they can produce the imagery in a projection different from the one in which it was stored. <a href="http://geoserver.org/display/GEOS/Welcome">GeoServer</a>, the software we are using for Neatline, has a library of thousands of projections to which users can add more as desired. This allows us to take imagery from a WMS source and lay it under a historical map layer while maintaining the original projection for that of the map as a whole. Tile caches, by and large, do not allow for this. (Google Maps offers its one projection, and Open Street Map offers two.) This means that in order to lay historical map imagery over a layer from one of these sources, we would have to reproject the foreground (historical imagery) overriding the choices of the mapmaker and introducing additional choices of our own about what facets of the geographies at stake are to be preserved and which abandoned.</p>
<p>(Neogeographers will remark that georectifying a digital image introduces similar issues. This is true, but unavoidable for our purposes. We would like to avoid compounding the matter in a way that is subtle and hard to detect.)</p>
<p>We are working out means by which we can provide the undeniable utility of popular tilecaching services in a way that is respectful of the historical context and story of map artifacts. Until we do, we will continue to concentrate on the more flexible and sophisticated apparatus provided by WMS.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/geospatial-and-temporal/wms-vs-tilecaching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Expanding the Capabilities of Omeka</title>
		<link>http://www.scholarslab.org/digital-libraries/expanding-the-capabilities-of-omeka/</link>
		<comments>http://www.scholarslab.org/digital-libraries/expanding-the-capabilities-of-omeka/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 18:00:59 +0000</pubDate>
		<dc:creator>Ethan Gruber</dc:creator>
				<category><![CDATA[Digital Libraries]]></category>
		<category><![CDATA[SLab Code]]></category>
		<category><![CDATA[EAD]]></category>
		<category><![CDATA[metadata]]></category>
		<category><![CDATA[omeka]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[VRA Core]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=842</guid>
		<description><![CDATA[Because I have a keen interest in the description of cultural heritage artifacts and in doing interesting things with metadata, in recent months I have developed a handful of Omeka plugins to meet these interests.  My first foray into plugin development for the application was with the EAD Importer.  The EAD Importer, as [...]]]></description>
			<content:encoded><![CDATA[<p>Because I have a keen interest in the description of cultural heritage artifacts and in doing interesting things with metadata, in recent months I have developed a handful of Omeka plugins to meet these interests.  My first foray into plugin development for the application was with the <a href="https://addons.omeka.org/svn/plugins/EadImporter/">EAD Importer</a>.  The EAD Importer, as the name suggests, extracts item-level metadata (along with a bit of collection-level metadata, like rights) from Encoded Archival Description finding aids and generates a CSV file which can be imported through the CSV Import plugin developed by the Omeka crew.  The plugin would be useful to archivists who would like to use Omeka to build online exhibits of their collections.  I took this framework a step further to create a plugin that is capable of importing any <a href="https://addons.omeka.org/svn/plugins/GenericXmlImporter/trunk/">flat XML</a> into Omeka by transforming that file into a CSV file.</p>
<p>Most recently, I have turned my attention to expanding the descriptive abilities of Omeka into the realm of collections of artwork.  Omeka items are described with Dublin Core, which is capable of describing <em>anything</em>, though not particularly well.  I developed <a href="https://addons.omeka.org/svn/plugins/VraCoreElementSet/trunk/">VraCoreElementSet</a>, which incorporates VRA Core fields into the Edit Item form.  VRA Core is a much more semantically appropriate schema for describing art and artifacts.  Since it was conceived as an XML standard (not strictly a flat list of fields), some elements have hierarchical sub-componenets.  For example, a work may have several agents involved in its production, and each agent has a name as well as a role, culture, birth date, and, as the case may be, a death date.  The VraCoreElementSet plugin creates a table for agents so that a user may enter this data separately.  Then in the Edit Item form, the user may select VRA Core agents from a drop down menu restricted by the records in the agents table.  Items may also be exported to schema-compliant VRA Core XML.  There is still some work remaining on this plugin, but it is well on its way toward completion.</p>
<p>Now that the Scholars&#8217; Lab has contributed EAD Importer and VRA Core Element Set plugins, Omeka may attract new institutional users from the library, archive, and museum fields, who may have otherwise settled for proprietary applications to disseminate their digital collections.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/digital-libraries/expanding-the-capabilities-of-omeka/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Frontiers in Spatial Humanities (video)</title>
		<link>http://www.scholarslab.org/announcements/frontiers-in-spatial-humanities-video/</link>
		<comments>http://www.scholarslab.org/announcements/frontiers-in-spatial-humanities-video/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 13:53:38 +0000</pubDate>
		<dc:creator>joe</dc:creator>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Digital Humanities]]></category>
		<category><![CDATA[Geospatial and Temporal]]></category>
		<category><![CDATA[Podcasts]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=831</guid>
		<description><![CDATA[A video stream of the final event of our NEH-funded Institute for Enabling Geospatial Scholarship (or #geoinst as it&#8217;s known on Twitter) is now available!  Thanks to all our wonderful participants for making these lightning talks, collectively entitled &#8220;Frontiers in Spatial Humanities,&#8221; so thought-provoking.

The Scholars&#8217; Lab/NEH Institute for Enabling Geospatial Scholarship was held at [...]]]></description>
			<content:encoded><![CDATA[<p>A video stream of the final event of our NEH-funded <a href="http://lib.virginia.edu/scholarslab/geospatial">Institute for Enabling Geospatial Scholarship</a> (or <a href="http://search.twitter.com/search?q=%23geoinst" alt="geoinst">#geoinst</a> as it&#8217;s known on Twitter) is now available!  Thanks to all our wonderful participants for making these lightning talks, collectively entitled &#8220;Frontiers in Spatial Humanities,&#8221; so thought-provoking.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="500" height="356" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=12187960&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="500" height="356" src="http://vimeo.com/moogaloop.swf?clip_id=12187960&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=0&amp;show_portrait=0&amp;color=00ADEF&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>The Scholars&#8217; Lab/NEH Institute for Enabling Geospatial Scholarship was held at the University of Virginia Library May 25-27, 2010 and concluded with a set of two-minute, three-slide lightning talks by Institute attendees on their own spatial humanities projects and works-in-progress.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/announcements/frontiers-in-spatial-humanities-video/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Frontiers in Spatial Humanities</title>
		<link>http://www.scholarslab.org/announcements/frontiers-in-spatial-humanities/</link>
		<comments>http://www.scholarslab.org/announcements/frontiers-in-spatial-humanities/#comments</comments>
		<pubDate>Mon, 17 May 2010 22:11:29 +0000</pubDate>
		<dc:creator>Bethany</dc:creator>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[Digital Humanities]]></category>
		<category><![CDATA[Geospatial and Temporal]]></category>
		<category><![CDATA[gis]]></category>
		<category><![CDATA[speaker series]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=818</guid>
		<description><![CDATA[[UPDATE: video for the "Frontiers" event is now available!]
We&#8217;re crowd-sourcing the keynote to the final round of the Scholars&#8217; Lab/NEH 2009-2010 Institute for Enabling Geospatial Scholarship.  With all of these fantastic attendees on hand &#8212; not to mention the Institute faculty &#8212; how could we let the opportunity slip by?
Frontiers in Spatial Humanities:
Lightning Presentations
We [...]]]></description>
			<content:encoded><![CDATA[<p><strong>[UPDATE: <a href="/announcements/frontiers-in-spatial-humanities-video/">video for the "Frontiers" event</a> is now available!]</strong></p>
<p>We&#8217;re crowd-sourcing the keynote to the final round of the Scholars&#8217; Lab/NEH 2009-2010 <a href="http://lib.virginia.edu/scholarslab/geospatial">Institute for Enabling Geospatial Scholarship</a>.  With all of these fantastic <a href="http://www2.lib.virginia.edu/scholarslab/geospatial/participants.html#scholarship">attendees</a> on hand &#8212; not to mention the <a href="http://www2.lib.virginia.edu/scholarslab/geospatial/index.html#faculty">Institute faculty</a> &#8212; how could we let the opportunity slip by?</p>
<h4>Frontiers in Spatial Humanities:<br />
Lightning Presentations</h4>
<p>We are pleased to host 40 rapid-fire, 2-minute demos of boundary-pushing projects in spatial humanities.  The scholars presenting their work come from 27 different institutions, and were competitively selected to attend this prestigious program, funded by the <a href="http://neh.gov/odh">National Endowment for the Humanities</a>.  Some of our Institute faculty will also offer brief glimpses of their work as part of a whirlwind tour of emerging work in humanities GIS.</p>
<p>While admission to the Institute itself is now closed, &#8220;Frontiers in Spatial Humanities&#8221; and the reception that follows are open to the public!  </p>
<p>I&#8217;d like to thank the NEH for its generous funding of our training program, and the University of Virginia Library for supporting the Scholars&#8217; Lab &#8212; as well as the &#8220;Frontiers&#8221; reception, to which you&#8217;re all invited!</p>
<p>Thursday, <strong>May 27th</strong>, 3:30-5:00pm<br />
Harrison-Small Auditorium</p>
<p><a href="http://rclslab.files.wordpress.com/2010/05/geoinst-poster.jpg" class="broken_link"><img class="alignnone size-medium wp-image-1248" title="geoinst-poster" style="height:300px;" src="http://rclslab.files.wordpress.com/2010/05/geoinst-poster.jpg?w=194" alt="" width="194" height="300" /></a></p>
<p>For more information about the SLab and our NEH-funded <a href="http://www.neh.gov/grants/guidelines/IATDH.html">Institute for Advanced Topics in the Digital Humanities</a>, please visit:<br />
<a href="http://www2.lib.virginia.edu/scholarslab/geospatial/">http://lib.virginia.edu/scholarslab/geospatial/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/announcements/frontiers-in-spatial-humanities/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why Ruby?</title>
		<link>http://www.scholarslab.org/slab-code/why-ruby/</link>
		<comments>http://www.scholarslab.org/slab-code/why-ruby/#comments</comments>
		<pubDate>Tue, 11 May 2010 19:27:02 +0000</pubDate>
		<dc:creator>Wayne Graham</dc:creator>
				<category><![CDATA[SLab Code]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=741</guid>
		<description><![CDATA[Stemming from a Twitter conversation last month, I thought it would be a good idea to describe &#8212; in more than the 140 character bursts that Twitter allows &#8212; why we at the Scholars&#8217; Lab often promote Ruby, opposed to one of the other 4 or 5 languages we develop with. This isn&#8217;t an attempt [...]]]></description>
			<content:encoded><![CDATA[<p>Stemming from <a href="http://twitter.com/dougreside/status/12881732120">a Twitter conversation</a> last month, I thought it would be a good idea to describe &#8212; in more than the 140 character bursts that Twitter allows &#8212; why we at the <a href="http://lib.virginia.edu/scholarslab/">Scholars&#8217; Lab</a> often promote Ruby, opposed to one of the other 4 or 5 languages we develop with. This isn&#8217;t an attempt to declare one language &#8220;the best,&#8221; but is meant to lay out some of the fundamental reasons why we use Ruby in the context of our digital humanities work and why we think it&#8217;s a nice language to suggest to folks just starting to program.<span id="more-741"></span></p>
<h2>Qualification</h2>
<p>People often think of the Scholars&#8217; Lab as a <a href="http://www.ruby-lang.org/en/">Ruby</a> (and <a href="http://rubyonrails.org/">Rails</a>) shop, which isn&#8217;t quite the case. We code in many different languages.  In the past several moths, we have written <a href="http://metaphors.lib.virginia.edu">The Mind is a Metaphor</a> in Ruby (with Rails). <a href="http://prosody.lib.virginia.edu/">For Better For Verse</a> uses <a href="http://wordpress.org/">Wordpress</a> with <a href="http://www.tei-c.org/index.xml">TEI</a> and <a href="http://java.sun.com/products/jsp/">JSP</a>, and some more recent work on a William Faulkner audio archive employs <a href="http://cocoon.apache.org/2.1/">Cocoon</a> with <a href="http://lucene.apache.org/solr/">Solr</a>. In addition to those collaborations with UVa faculty, we&#8217;ve been writing plugins for <a href="http://omeka.org/">Omeka</a> (and dusting off our PHP skills) and have created a <a href="http://gis.lib.virginia.edu/">discovery interface</a> for our GIS infrastructure in Ruby (with <a href="http://www.sinatrarb.com/">Sinatra</a>). If you analyze the technologies we currently deploy, it turns out we use <a href="http://cocoon.apache.org/">Cocoon</a> + <a href="http://lucene.apache.org/solr/">Solr</a> more than anything else, though we&#8217;re starting to move away from that particular stack as our approach for tool development.</p>
<p>The Scholars&#8217; Lab has a lot of experience with all types of languages, and depending on the circumstances, we choose different tools to accomplish any given task. However, after quite a bit of time helping people get started on a programming path, I&#8217;ve come to appreciate some of the features Ruby provides in getting new programmers up to speed.</p>
<h2>Learning Curve</h2>
<p>Every language has a learning curve. However, once you get the hang of some of the basics of computer languages (flow control, data structures, objects, etc.), the biggest differences come from syntax. All web languages make certain programming exercises easy, and once you buy in to the way in which that language handles programming constructs, moving between languages for experienced programmers becomes a simpler exercise in exploring syntax and built-in functionality.</p>
<p>As one of my computer science professors posited, generally the first language you learn governs the way you code until something significantly better comes along. For a lot of folks getting in to programming for the first time, this usually means either taking a class or finding someone to show you the basics. If you&#8217;re in higher education, this has typically meant the tool of choice is PHP. However, having seen the look of bewilderment on the faces of enough graduate students and faculty members as I attempt to explain the difference between sprintf and printf (printf returns the length of the formatted String and sprintf returns the formatted String), I&#8217;ve come to believe that the syntax of a programming language (and it&#8217;s readability) is an exceptionally important part of a language, especially when teaching basics of software construction.</p>
<h3>Method Chaining</h3>
<p>Without getting into how the PHP and Ruby <a href="http://en.wikipedia.org/wiki/Duck_typing">duck-type</a><a href="http://en.wikipedia.org/wiki/Primitive_data_type"> primitive data types</a> and <a href="http://en.wikipedia.org/wiki/Data_structure">data structures</a>, one big difference in syntax between the two is how one combines multiple method calls together. Ruby uses method chaining for objects whereas PHP uses &#8220;bolted-on&#8221; functions (think of these as order-of-operations from your high school Algebra class). Let&#8217;s look at this brief example of addressing and sorting an associative array in PHP and its equivalent in Ruby:</p>
<pre class="brush: php;">
$projects = array(&quot;solr&quot; =&gt; 4, &quot;php&quot; =&gt; 1, &quot;rails&quot; =&gt; 2, &quot;jsp&quot; =&gt; 3);
$keys = array_keys($projects);
sort($keys);
$sorted = array_slice($keys, 0, 3);
</pre>
<p>If you&#8217;re a little more advanced, you might refactor (rewrite) the code to look more like this (methods anonymously &#8220;bolted-on&#8221; to one another):</p>
<pre class="brush: php;">
$projects = array(&quot;solr&quot; =&gt; 4, &quot;php&quot; =&gt;  1, &quot;rails&quot; =&gt; 2, &quot;jsp&quot; =&gt; 3);
$sorted = array_slice(sort(array_keys($projects)), 0, 3);
</pre>
<p>Now, the same examples in Ruby syntax:</p>
<pre class="brush: ruby;">
projects = {&quot;solr&quot; =&gt; 4, &quot;php&quot; =&gt;  1, &quot;rails&quot; =&gt; 2, &quot;jsp&quot; =&gt; 3}
sorted = projects.keys.sort.slice(0,3)
</pre>
<p>Or, even more concisely:</p>
<pre class="brush: ruby;">
projects = {&quot;solr&quot; =&gt; 4, &quot;php&quot; =&gt;  1, &quot;rails&quot; =&gt; 2, &quot;jsp&quot; =&gt; 3}
sorted = projects.keys.sort[0..3]
</pre>
<p>I&#8217;ve found that Ruby&#8217;s method chaining syntax makes more sense to new programmers than the more mathematical &#8220;bolted-on&#8221; syntax.</p>
<h3>Blocks</h3>
<p>Ruby has a neat construct that you use all over the place to create anonymous functions (a technical term for creating specific functionality without defining a new function to define the action). Let&#8217;s take a function to sort an array of projects. First, in PHP:</p>
<pre class="brush: php;">

function sort_projects_by_count($a, $b)
{
    if($a -&gt; counts == $b -&gt; counts)
    {
        return 0;
    }
    return($a -&gt; counts &gt; $b -&gt; counts) ? +1 : -1;
}

usort($projects, &quot;sort_projects_by_count&quot;);
</pre>
<p>And the same thing in Ruby:</p>
<pre class="brush: ruby;">
projects.sort do |a, b|
    a.counts &lt;=&gt; b.counts
end
</pre>
<p>Ok, so this is a bit of an unfair comparison, but here is an analogous version of the Ruby code in PHP:</p>
<pre class="brush: php;">
usort($projects, create_function($a, $b, 'if($a-&gt;counts == $b-&gt;counts){
    return 0;}return ($a-&gt;counts &gt; $b-&gt;counts ? +1 : -1));
</pre>
<p>No matter how you slice it, Ruby syntax just feels more human. Even if you don&#8217;t know exactly what&#8217;s going on, looking up one operator in the Ruby syntax as opposed to following the logic flow and determining what &#8220;? +1 : -1&#8243; means (it&#8217;s shorthand for an if-then statement) makes the act of reading code much easier.</p>
<h2>Monkeypatching</h2>
<p>If you&#8217;re not familiar with the term, &#8220;monkeypatching&#8221; is what programmers call changing or extending a base class (like an array or string object) to add functionality or change the way it works. Let&#8217;s say you really need to be able to test a string to see if it looks like an integer, you could create a monkeypatch along these lines:</p>
<pre class="brush: ruby;">
class String
    def is_int?
        self =~ /^[-+]?[0-9]*$/
    end
end
</pre>
<p>This code snip extends the String class and uses a <a href="http://en.wikipedia.org/wiki/Regular_expression">Regular Expression</a> (regex) to test if a given String is an integer (number) by simply calling &#8220;is_int?&#8221; (notice the question mark at the end of the definition; this is used for methods that return a Boolean value). That&#8217;s a little advanced, but it does show off a very useful piece of functionality of the language that allows you to do a better job dealing with a <a href="http://en.wikipedia.org/wiki/Duck_typing">duck-typed language</a>.</p>
<h2>Frameworks</h2>
<p>Many people when talking about Ruby associate its use in web development with the Rails <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC framework</a>. Just as PHP has <a href="http://framework.zend.com/">Zend</a>, <a href="http://codeigniter.com/">CodeIgniter</a>, <a href="http://cakephp.org/">CakePHP</a>, <a href="http://www.symfony-project.org/">symfony</a>, etc., Ruby has <a href="http://rubyonrails.org/">Rails</a>, <a href="http://www.merbivore.com/">Merb</a>, <a href="http://www.sinatrarb.com/">Sinatra</a>, <a href="http://camping.rubyforge.org/">Camping</a>, and many more. Rails is the 900-pound gorilla of Ruby frameworks, and has a lot of nice features to get new applications off the ground quickly and some really great online guides to setting things up (I frequent <a href="http://guides.rubyonrails.org/">RailsGuides</a>). Since we often suggest Rails to our collaborators I&#8217;ll focus on this framework, but there are several other frameworks out there to choose from.</p>
<p>Think of Ruby (or PHP for that matter) as a pile of building materials: you can to build anything you want if you know how to put everything together. Rails, on the other hand, is like a prefab house where workers pour a foundation, set the house up, and then leave you to add the drywall, siding, windows, and roof. If you need a new component for your prefab house, a sales representative is standing by to help immediately ship you what you need.</p>
<h3>Generators</h3>
<p>To extend the previous metaphor, generators are like sales representatives that allow you to place orders for new aspects of your site.  To create all the erb templates (the default templeting language for Rails), controller methods, model, database migrations, routes, and tests for a new project with a single line, you might run something like the following:</p>
<pre class="brush: ruby;">
script/generate scaffold topic title:string description:text
</pre>
<p>I moved away from using scaffolding pretty quickly, but it does provide a nice starting point for new programmers to build interactions with data models.</p>
<h3>Templates</h3>
<p>The default templating engine in Rails is <a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/">erb</a> which provides a convenient method for generating views of  your models. One of erb&#8217;s most important features is the use of &#8220;partials,&#8221; pieces of code that are used in multiple views by calling the render method. I often replicated this behavior in PHP by calling an include somewhere in a view.</p>
<h3>ActiveRecord</h3>
<p>The key to database interactions in Rails is ActiveRecord. As an SQL expert, I have to admit this part of the Rails framework drove me a bit batty at first, but then again I&#8217;ve been writing SQL for over 10 years (my colleagues often roll their eyes when I start writing it with relational algebra nomenclature), so allowing a framework to abstract this particular piece took some getting used to. If you&#8217;re new to programming, though, this means you don&#8217;t have to learn SQL but instead can use Ruby-style syntax to interact with your database without necessarily needing to care what your <a href="http://en.wikipedia.org/wiki/Relational_database_management_system">RDBMS</a> back-end happens to be.</p>
<p>Take this example of looking up a book review where you have both a &#8220;book&#8221; and &#8220;review&#8221; table. In PHP you would do something like this (this snip will only work with a MySQL connection but has some sub-selection stuff going on):</p>
<pre class="brush: php;">
function query($sql)
{
    global $conn;
    return mysql_query($sql, $conn);
}

function recent_reviews($count)
{
    $query = query(sprintf('SELECT b.book_title, r.review_id, r.created_at, r.id, review_counter.review_total
        FROM reviews r, books b,
            (SELECT count(*) AS review_total FROM reviews) AS review_counter
        WHERE r.book_id = b.book_id
        ORDER BY created_at DESC
        LIMIT %d', $count);

    return $query
}

print_r(recent_reviews(5));
</pre>
<p>Now, for the ActiveRecord equivalent:</p>
<pre class="brush: ruby;">
reviews = Review.find(:limit =&gt; 5, <img src='http://www.scholarslab.org/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder =&gt; &quot;created_at DESC&quot;);
puts reviews.inspect
</pre>
<p>Because of the way in which ActiveRecord sets up its model associations, you&#8217;ll have access to the different name scopes to print out the same information, just in far less code. However, if you really want to, you can pass your SQL to get more granular control over the syntax:</p>
<pre class="brush: ruby;">
reviews = Review.find_by_sql(&quot;SELECT b.book_title, r.review_id, r.created_at, r.id, review_counter.review_total
        FROM reviews r, books b,
            (SELECT count(*) AS review_total FROM reviews) AS review_counter
        WHERE r.book_id = b.book_id
        ORDER BY created_at DESC
        LIMIT ?&quot;, count);
</pre>
<p>One of the real beauties of the ActiveRecord methods is that as long as you&#8217;re using the generic ActiveRecord syntax, your data persistence layer can be pretty much any RDBMS and be changed with a couple lines in the configuration file. The trade-off however, is that you lose a few things and can make slightly more work for yourself than you might anticipate. One important caveat is that ActiveRecord doesn&#8217;t create foreign keys when you set up reference fields. This is actually by design as it&#8217;s using an object-oriented idiom (an object should validate the presence of another, without the underlying persistence layer enforcing any type of constraint), but I find myself adding these in to ensure that the RDBMS takes advantage of the pre-calculated indexes to improve overall performance.</p>
<p>I should also mention that I think the ActiveRecord model has some real limitations. As you develop your models, you will most like be tweaking its fields, which in turn requires new migrations, and you may forget which fields are actually in your models. There are plugins that help with this, but you do need to take additional steps to have this information placed somewhere convenient (I use a pre-commit git hook that calls the <a href="http://github.com/ctran/annotate_models">annotate gem</a> to dynamically annotate my model schemas).</p>
<h3>Security</h3>
<p>You&#8217;ll notice in the last examples I was doing some funny stuff in both the PHP and Ruby examples to protect against <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL injection attacks</a>. If you&#8217;re using the ActiveRecord methods of addressing objects, Rails will take care of this for you. If you&#8217;re using PHP, you&#8217;ll either need to do this yourself (sprintf is commonly used) or rely on a framework to parametrize your statements (you don&#8217;t want someone deleting everything in your database).</p>
<p>You also need to protect yourself from <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">Cross-site Scripting Attacks</a> (XSS) by escaping HTML from fields with dynamic content. erb has a helper function html_escape (h is the shorthand) which escapes this data. In Rails 3, this will change slightly and erb will automatically html_escape model output unless you explicitly tell it not to escape the field. One less thing to remember!</p>
<h3>Testing</h3>
<p>Testing is important, and I try to preach its virtues every chance I get. After finishing a project, the typical programmer won&#8217;t touch the code again until the application breaks. Good testing will save you (or the person that inherits the code) a lot of time discovering exactly what broke the application.</p>
<p>Let&#8217;s face it: testing is a pain in PHP, and I rarely see it done well. What I&#8217;ve really enjoyed about Ruby development is the fact that no matter how you code there is an appropriate testing framework available (I use <a href="http://rspec.info/">rspec</a>). There&#8217;s a strong emphasis on not only unit testing, but also integration and acceptance testing. There are also libraries that give you an idea of how well your <a href="http://github.com/relevance/rcov">code is tested</a>, something I sorely missed from my Java coding endeavors. One other huge plus is that every gem on the <a href="http://www.rubygems.org">rubygems.org</a> site includes test-coverage metrics to give you an idea of how well the code you want to install is tested.</p>
<p>PHP also has testing frameworks with <a href="http://www.phpunit.de/">PHPUnit</a> and <a href="http://code.google.com/p/phpspec/">PHPSpec</a> being rather popular. I won&#8217;t say too much about the PHP testing frameworks other than to say that there are analogous frameworks for writing and running tests in PHP and Ruby. However, I&#8217;ve noticed a slightly more concerted effort to think through the inclusion of the tools in Ruby and their integration into the coding workflow than I&#8217;ve experienced with PHP. With the latter language, I&#8217;ve often fell in to the trap of writing the code, getting it to where I want it, and then, really as an afterthought, writing basic unit tests to get rather skimpy code coverage.</p>
<p>As a case in point, a mantra in Rails development is <a href="http://rubyhoedown2008.confreaks.com/05-bryan-liles-lightning-talk-tatft-test-all-the-f-in-time.html">TATFT</a>.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="400" height="302" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://vimeo.com/moogaloop.swf?clip_id=1534976&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" /><embed type="application/x-shockwave-flash" width="400" height="302" src="http://vimeo.com/moogaloop.swf?clip_id=1534976&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=&amp;fullscreen=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p><a href="http://vimeo.com/1534976">BryanL on TATFT</a> from <a href="http://vimeo.com/bryanl">Bryan Liles</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
<h2>Deployment</h2>
<p>Two typical objections raised when contemplating Ruby development are that &#8220;Ruby doesn&#8217;t scale&#8221; and that server setup is a real pain. These are valid concerns, but as with many open source projects with a large number of fanatical supporters, the Ruby community has steadily made improvements in these areas. Actually, for the vast majority of our readership, these issues can be filed away in the solved category.</p>
<h3>Scaling</h3>
<p>I&#8217;ve always found objections to scaling a bit troubling. Scaling is one of those over-used terms that means different things to different people, but most of the &#8220;Rails doesn&#8217;t scale&#8221; comes from Twitter&#8217;s experience with the framework. They found, as they scaled horizontally (adding more servers) to handle loads of 11,000+ requests per second, that a bottleneck existed at the data persistence level as Rails doesn&#8217;t, by default, provide a mechanism to to address multiple databases. Twitter has since moved parts of their code base to <a href="http://www.scala-lang.org/">Scala</a> but has retained the majority of their code in Rails and has developed some rather ingenious messaging capabilities to talk to the appropriate abstraction layers that one needs in very large enterprise applications.</p>
<p>While Twitter shows that Rails is capable of scaling (with lots of work), quite honestly the likelihood of any of our applications needing this level of engineering is slim. I will say, however, that there are relatively simple methods of scaling with your infrastructure should you start running into performance issues. We have, for example, an application written in pure Ruby on Rails deployed as a Tomcat application (the details of which are completely outside the scope of this article, but the application gets all the benefits of an Enterprise class Java environment with the ease of Rails development).</p>
<h2>Server Support</h2>
<p>The Ruby language is included in most (if not all) modern Linux package systems and makes installation a snap. The other &#8220;major&#8221; piece of software you&#8217;ll need is RubyGems (a package manager for Ruby libraries), which is also generally available as a managed package.</p>
<blockquote><p><strong>Note</strong>: There is a major change occurring with the development of Rails 3. Rails is moving from a system of system-wide gems to application-level gems with the introduction of <a href="http://gembundler.com/">GemBundler</a>. This approach is a more stable method of deploying application requirements which not only allows you to ensure that application libraries are properly resolved, but also provide better granular control over which libraries are deployed in specific contexts.</p></blockquote>
<p>There was a time where deploying Rails applications was a real bear. Then along came <a href="http://www.modrails.com/">Phusion Passenger</a> (aka mod_rails). This allows you to run Rails (actually any Rack-based application) through Apache and Nginx without any other port management, service process monitoring, file cleanup, etc. As long as Apache is running, so is your Rails app!</p>
<h2>Community of Support</h2>
<p>The Rails community is pretty great in getting folks off the ground. As with any technology there are a fair number of curmudgeons, but leaders in the community as quick to remind people to be nice (see Yahuda Katz&#8217;s <a href="http://yehudakatz.com/2010/02/09/the-blind-men-and-the-elephant-a-story-of-noobs/">The Blind Men and the Elephant: A Story of Noobs</a>). There are several corporations backing Rails development (<a href="http://www.engineyard.com">EngineYard</a> is a big one) and when the Google Summer of Code for Rails program wasn&#8217;t continued, the Rails community was able to raise $100,000 in three days to support a <a href="http://rubysoc.org/">Ruby Summer of Code</a>.</p>
<p>There are a number of really good podcasts (<a href="http://ruby5.envylabs.com/">Ruby5</a> and <a href="http://5by5.tv/rubyshow">The Ruby Show</a> are good), vodcasts (<a href="http://railscasts.com/">Railscasts</a>), tutorial sites (<a href="http://asciicasts.com/">ACSIIcasts</a>), blogs (<a href="http://www.railsdispatch.com/">RailsDispatch</a>, <a href="http://thoughtbot.com/">ThoughtBot</a>, <a href="http://www.engineyard.com/blog/">EngineYard</a>), open source projects (lots on <a href="http://www.github.com">github</a>), open source books (<a href="http://www.railstutorial.org/book">Rails Tutorials</a>), and some really good reference books from <a href="http://pragprog.com/">The Pragmatic Programmers</a>. There&#8217;s even some humor&#8230;</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="480" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/p5EIrSM8dCA&amp;hl=en_US&amp;fs=1&amp;" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="480" height="385" src="http://www.youtube.com/v/p5EIrSM8dCA&amp;hl=en_US&amp;fs=1&amp;" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<h2>Summary</h2>
<p>As much as it drives language purists crazy when I say it, there&#8217;s nothing that you can do in Ruby that you can&#8217;t replicate in PHP (and vice-versa). In my experience, getting people set up with a functioning web application is far easier with Ruby than it is with PHP (and less prone to <a href="http://en.wikipedia.org/wiki/Spaghetti_code">spaghetti code</a>), and the deployment options make Ruby (plus a framework) a great starting point for new programmers to get their feet wet with web application development (check out <a href="http://www.heroku.com">Heroku</a>). If you&#8217;re an experienced developer, does it make sense to drop PHP and rewrite your code base? Absolutely not. However, at some point, you will be faced with the prospect of needing to migrate a legacy application where Ruby may make a lot of sense. As someone who has spent quite a bit of time de-tangling spaghetti code from Perl CGI and mixed HTML and PHP pages, I&#8217;m hoping that the people that will eventually be migrating my Ruby code will not need to perform the level of coding archaeology we&#8217;ve needed to perform.</p>
<p>Like most things in life, choosing the correct tool for the job needs some careful consideration and planning. Ruby makes a lot of sense for getting applications off the ground quickly and reinforcing good practices like testing, code separation, and readability that I find important in forming new digital humanities programmers. Web development over the last decade has become exceptionally complex (AJAX, web services, web standards, multiple browsers, etc.) and the real hope is that by using Ruby and Rails as an approach, people will be inspired to continue down a development path to both enrich their own scholarship and impact the larger digital humanities community without becoming frustrated by syntax. This is a bit of an experiment which we and other digital humanities shops are undertaking, and in which we&#8217;re inviting everyone to participate.  No matter the language, we should all be engaged in teaching best practices in project design and management, in software development techniques, in the construction of usable and elegant interfaces, and in the application of these things to humanities scholarship, through which everyone wins!</p>
<h2>Other Resources</h2>
<ul>
<li><a href="http://railsforphp.com/">Rails for PHP Developers</a></li>
<li><a href="http://www.oreillynet.com/ruby/blog/2007/09/7_reasons_i_switched_back_to_p_1.html">7 Reason I switched back to PHP after 2 years on Rails</a></li>
<li><a href="http://guides.rubyonrails.org/">RubyGuides</a></li>
<li><a href="http://www.jruby.org/">JRuby</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/slab-code/why-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Julie Meloni: N-dimensional Archives</title>
		<link>http://www.scholarslab.org/podcasts/julie-meloni-n-dimensional-archives/</link>
		<comments>http://www.scholarslab.org/podcasts/julie-meloni-n-dimensional-archives/#comments</comments>
		<pubDate>Fri, 07 May 2010 20:03:11 +0000</pubDate>
		<dc:creator>ronda</dc:creator>
				<category><![CDATA[Podcasts]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=805</guid>
		<description><![CDATA[Julie Meloni, Jerome McGann, and Bethany Nowviskie discuss ways of reconsidering the multivalent cultural record in a digital age

]]></description>
			<content:encoded><![CDATA[<p>Julie Meloni, Jerome McGann, and Bethany Nowviskie discuss ways of reconsidering the multivalent cultural record in a digital age</p>
<p><em></em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/podcasts/julie-meloni-n-dimensional-archives/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://deimos3.apple.com/WebObjects/Core.woa/FeedEnclosure/virginia-public.2014484138.02014484145.3871948813/enclosure.mp3" length="63833755" type="audio/mpeg" />
		</item>
		<item>
		<title>Introducing DAVILA</title>
		<link>http://www.scholarslab.org/digital-humanities/introducing-davila/</link>
		<comments>http://www.scholarslab.org/digital-humanities/introducing-davila/#comments</comments>
		<pubDate>Fri, 07 May 2010 19:10:46 +0000</pubDate>
		<dc:creator>Jean Bauer</dc:creator>
				<category><![CDATA[Digital Humanities]]></category>
		<category><![CDATA[Grad Fellows]]></category>
		<category><![CDATA[Visualization and Data Mining]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=732</guid>
		<description><![CDATA[
Jean Bauer, former Scholars&#8217; Lab Graduate Fellow in Digital Humanities announces: &#8220;I have just released my first open source project.  HUZZAH!&#8221;
DAVILA is a database schema visualization/annotation tool that  creates “humanist readable” technical diagrams.  It is written in Processing with the toxiclibs physics  library and released under GPLv3.  DAVILA takes in [...]]]></description>
			<content:encoded><![CDATA[<div>
<p>Jean Bauer, former Scholars&#8217; Lab Graduate Fellow in Digital Humanities announces: &#8220;I have just released my first open source project.  HUZZAH!&#8221;</p>
<p>DAVILA is a database schema visualization/annotation tool that  creates “humanist readable” technical diagrams.  It is written in <a href="http://processing.org/" target="_blank">Processing</a> with the <a href="http://toxiclibs.org/" target="_blank">toxiclibs</a> physics  library and released under GPLv3.  DAVILA takes in the database’s schema  and a pipe separated customization file and uses them to produce an  interactive, color-coded, annotated diagram similar in format to UML.   There are many applications that will create technical diagrams based on  database schema, but as a digital humanist I require more than they can  provide.  <span id="more-732"></span></p>
<p>Technical diagrams are wonderfully compact ways of conveying  information about extremely complex systems.  But they only work for  people who have been trained to read them.  If you design a database for  a historian, and then hand him or her a basic E-R or UML diagram, you  will end up explaining the diagram’s nomenclature before you can talk  about the database (and oftentimes you run out of time before getting  back to the research question underlying the database).  This removes  the major advantage of technical diagrams and can also create an  unnecessary divide between the technical and non-technical members of a  digital humanities development team.</p>
<p>I have become fascinated by how documenting a project (either in  development or after release) can build community.  I’m not just talking  about user generated documentation (ala wikis), but rather the feeling  created by a diagram or README file that really takes the time to  explain how the software works and why it works the way it does.  There  is a generosity and even warmth that comes from thoughtful, helpful  documentation, just as inadequate documentation can make someone feel  stupid, slighted, or unwanted as a user/developer.  I will be writing on  this topic more in the months to come (perhaps leading up to an  article).  In the meantime, check out DAVILA and let me know what you  think.</p>
<p>Project homepage: <a href="http://www.jeanbauer.com/davila.html" target="_blank">http://www.jeanbauer.com/davila.html</a></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/digital-humanities/introducing-davila/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GIS: The (rare) Tartan-Plaid Point Dispersion Problem</title>
		<link>http://www.scholarslab.org/geospatial-and-temporal/gis-the-rare-tartan-plaid-point-dispersion-problem/</link>
		<comments>http://www.scholarslab.org/geospatial-and-temporal/gis-the-rare-tartan-plaid-point-dispersion-problem/#comments</comments>
		<pubDate>Fri, 07 May 2010 19:07:20 +0000</pubDate>
		<dc:creator>Dave Richardson</dc:creator>
				<category><![CDATA[Geospatial and Temporal]]></category>
		<category><![CDATA[gis]]></category>
		<category><![CDATA[points]]></category>
		<category><![CDATA[problem]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=535</guid>
		<description><![CDATA[Have you ever wondered what would happen to your map of points if while converting your coordinates from latitude/longitude in degrees, minutes, seconds (DMS) to decimal degrees (DD) you messed up the math?  Ever seen a weird tartan-like plaid pattern emerge on your map from points that were suppose to be uniformly spread out over [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever wondered what would happen to your map of points if while converting your coordinates from latitude/longitude in degrees, minutes, seconds (DMS) to decimal degrees (DD) you messed up the math?  Ever seen a weird tartan-like plaid pattern emerge on your map from points that were suppose to be uniformly spread out over the known extent?  Or wonder why coordinates are much more commonly stored as decimal degrees by computer GIS applications instead of the degrees-minutes-seconds most of us learn growing up?  If so, this blog entry from the Scholars’ Lab at the University  of Virginia Library is for you! <span id="more-535"></span></p>
<p>First a little digression to explain latitude and longitude, and why computer GISs generally prefer decimal degrees when expressing lat/lon as a coordinate pair.</p>
<p>Latitude and Longitude is a spherical coordinate system for describing location upon a sphere (or upon an object that’s approximately a sphere, like the Earth).  Just as there are 360 degrees in a circle, there are 360 degrees of longitude (numbered 180 W (-180) to 0 to 180 E (+180) on either side of the Greenwich Prime Meridian) and 360 degrees of latitude (numbered 90 S (-90) to 0 to 90 N (+90) from the south Pole to the Equator (the Prime Parrallel, so to speak) to the North Pole&#8230; and back again on the other side of the globe, to complete the circle).  Each degree can be subdivided into 60 minutes, and each minute subdivided into 60 seconds.  Further subdivision of seconds is expressed as fractions or decimals.  Thus you could express the geographic location of the Scholars’ Lab at UVA as being at 38º 02’ 12.3540” N, 78 º 30’ 19.7928” W (or +38º 2’ 12.3540”, -78 º 30’ 19.7928”).</p>
<p>Computer GIS programs all want the northing and easting coordinate pair saved as just two numbers (one number for latitude, one number for longitude) instead of three different fields to contain the degrees, minutes, and seconds for latitude and another three fields for longitude.  This makes it much easier for the computer to plot location.  Many GIS programs also prefer the coordinates to be ordered longitude, latitude since that mimics X, Y coordinates.  Since there are 60 minutes in a degree and 60 seconds in a minute (or 3600 seconds in a degree [60 x 60]), you could write the location of the Scholars’ Lab as -78 – (30/60) – (19.7928/3600), 38 + (02/60) + (12.3540/3600) which is -78.505498°, 38.036765° in decimal degrees.</p>
<p>Now back to the emergent tartan-plaid problem.  What would happen if instead of converting to decimal degrees, you simple wrote out the degrees-minutes-seconds numbers in the format DD.MMSSssss ?  The Scholars Lab location would become -78.30197928, 38.02123540.  But the computer GIS would still interpret this as decimal degrees, and would compress all points falling within a 1&#215;1 degree box into just the first 6/10ths x 6/10ths of the box, with a gap without points filling the rest of the box.  Spread over a large region, this would result in a tartan plaid-like pattern emerging.</p>
<p>So what is supposed to look like this:</p>
<p><a rel="attachment wp-att-537" href="http://www.scholarslab.org/geospatial-and-temporal/gis-the-rare-tartan-plaid-point-dispersion-problem/attachment/tartan2/"><img class="alignnone size-medium wp-image-537" src="http://www.scholarslab.org/wp-content/uploads/2010/01/tartan2-300x133.jpg" alt="tartan example 2" width="300" height="133" /></a></p>
<p>Would end up looking like this:</p>
<p><a rel="attachment wp-att-536" href="http://www.scholarslab.org/geospatial-and-temporal/gis-the-rare-tartan-plaid-point-dispersion-problem/attachment/tartan1/"><img class="alignnone size-medium wp-image-536" src="http://www.scholarslab.org/wp-content/uploads/2010/01/tartan1-300x133.jpg" alt="tartan example 1" width="300" height="133" /></a></p>
<p>And both the correct and incorrect versions together:</p>
<p><a rel="attachment wp-att-538" href="http://www.scholarslab.org/geospatial-and-temporal/gis-the-rare-tartan-plaid-point-dispersion-problem/attachment/tartan3/"><img class="alignnone size-medium wp-image-538" src="http://www.scholarslab.org/wp-content/uploads/2010/01/tartan3-300x133.jpg" alt="tartan example 3" width="300" height="133" /></a></p>
<p>Not that this is a common mistake people using GIS make by any stretch, but when someone has a question about why their points are all coming out misaligned with strange empty striping patterns, it can take a little while to deduce what’s going on if you’ve never seen the results of such a mistake before.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/geospatial-and-temporal/gis-the-rare-tartan-plaid-point-dispersion-problem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automating Omeka Deployment with Capistrano</title>
		<link>http://www.scholarslab.org/slab-code/automating-omeka-deployment-with-capistrano/</link>
		<comments>http://www.scholarslab.org/slab-code/automating-omeka-deployment-with-capistrano/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 23:53:25 +0000</pubDate>
		<dc:creator>Wayne Graham</dc:creator>
				<category><![CDATA[SLab Code]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[omeka]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=660</guid>
		<description><![CDATA[If you&#8217;ve done much web development, you&#8217;ll know that deploying applications can be a real pain. Typically you get some code (like Omeka), FTP it to your server, run the install, then go grab some plugins and themes and FTP them to your server. If you&#8217;re a bit more sophisticated, you may have put this [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve done much web development, you&#8217;ll know that deploying applications can be a real pain. Typically you get some code (like Omeka), FTP it to your server, run the install, then go grab some plugins and themes and FTP them to your server. If you&#8217;re a bit more sophisticated, you may have put this in to an source code management (SCM) system like <a href="http://git-scm.com/">git</a>, <a href="http://mercurial.selenic.com/">mercurial</a>, or <a href="http://subversion.apache.org/">subversion</a>, which then changes your workflow to editing on your local machine, committing the changes to your SCM, logging on to the command line interface for your server, running an update on the code, praying nothing breaks; if it does, you then try to roll back to a working version (you remembered to run svn info on the code before updating so you know what number to go back to). Even if everything goes swimmingly, that&#8217;s a lot of steps and way more applications than I like to fool with, and since it&#8217;s essentially doing the same thing over and over again, wouldn&#8217;t it be nice to automate this process?   <span id="more-660"></span></p>
<p>Enter <a href="http://www.capify.org/index.php/Capistrano">Capistrano</a>&#8230;If you&#8217;ve not used this before, essentially this automates the deployment of web applications to your server environment.  It&#8217;s written in Ruby, but allows you to deploy ANY type of web application (we use it for Cocoon, Rails, Java, and PHP applications in the Scholars&#8217; Lab). If you&#8217;ve got a larger shop, you may also take a look at a web interface called <a href="http://labs.peritor.com/webistrano">Webistrano</a> which allows non-programmer types to deploy software through a web interface.</p>
<p>To show off the power of this software, I thought I&#8217;d write up how we use capistrano to deploy Omeka in various environments. The setup can be a little complex, but there are some good tutorials for getting started (see <a href="http://net.tutsplus.com/tutorials/ruby/setting-up-a-rails-server-and-deploying-with-capistrano-on-fedora-from-scratch/">Setting up a Rails Server and Deploying with Capistrano on Fedora from Scratch</a> and the <a href="http://www.capify.org/index.php/Getting_Started">Capistrano Getting Started</a>). The following code snips assume you have successfully installed capistrano and use Subversion as your SCM (if you need SVN hosting, you can start a new project on <a href="http://code.google.com/hosting/createProject">Google Code</a>; you can also use <a href="https://github.com/">Github</a> if you declare the git scm in the code).</p>
<p>The first step in getting your Omeka project automated for capistrano is ensuring both the capistrano and railsless-deploy gems are installed (if you&#8217;re not a ruby-ist, <a href="http://docs.rubygems.org/read/book/1">gem</a> is a package manager for Ruby applications and libraries):</p>
<pre class="brush: bash;">
sudo gem install capistrano railsless-deploy
</pre>
<p>Capistrano installs a new command on your system called &#8220;capify&#8221; which sets up the boilerplate for capistrano. Just execute the capify script in your project directory:</p>
<pre class="brush: bash;">
cd /path/to/project/trunk
capify .
</pre>
<p>This will create two files, Capfile in your root directory and a config/deploy.rb. You&#8217;ll need to edit the Capfile ever so slightly to add the requirement for the railsless-deploy gem. It should read as follows:</p>
<pre class="brush: ruby;">
load 'deploy' if respond_to?(:namespace) # cap2 differentiator
# Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }

require 'rubygems'
require 'railsless-deploy'
load    'config/deploy'
</pre>
<p>Now we just need to do some setup in the config/deploy.rb file to tell capistrano about Omeka. This is where you need to know a little about how your server is set up and you may need to slightly change your server set up in order to use capistrano. The way capistrano works is that it creates a releases directory on your path that holds &#8220;deployments&#8221; of you project. The latest version of the project is then symlinked the project directory into the releases. This allows you to very quickly undo a deployment that goes awry.</p>
<p>As an example, we deploy projects to /usr/local/projects, so our omeka project would get deployed to /usr/local/projects/omeka. Capistano will create a few directories in /usr/local/projects/omeka:</p>
<ul>
<li><strong>releases</strong> (timestamped directories of your application)</li>
<li><strong>shared</strong> (for log files, SCM cache, files you don&#8217;t want to be overwritten)</li>
<li><strong>current</strong> (symlink to latest directory in the releases directory)</li>
</ul>
<p>If you&#8217;re setting up Omeka, you will need to redirect the base Directory to the &#8220;current&#8221; symlink. Here&#8217;s the vhost entry we use for Omeka as an example (this is an Ubuntu server; you may need to change the log file path if you are deploying to another operating system).</p>
<pre class="brush: bash;">
&lt;VirtualHost *:80&gt;
ServerName your.server.org
DocumentRoot /usr/local/projects/omeka/current/
&lt;Directory &quot;/usr/local/projects/omeka/current&quot;&gt;
Options FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
&lt;/Directory&gt;

ErrorLog /var/log/apache2/omeka_error.log
TransferLog /var/log/apache2/omeka_access.log
&lt;/VirtualHost&gt;
</pre>
<p>Now, to edit the config/deploy.rb file to set things up for automated deployments.</p>
<pre class="brush: ruby;">
# You must always specify the application and repository for every recipe. The
# repository must be the URL of the repository you want this recipe to
# correspond to. The deploy_to path must be the path on each machine that will
# form the root of the application path.

set :application, 'omeka'
set :repository, 'http://your.svn.path/repo/trunk'

set :deploy_to, &quot;/usr/local/projects/#{application}&quot;
set :deploy_via, :remote_cache
set :user, 'deployer'
set :runner, user
set :run_method, :run

default_run_options[:pty] = true

ssh_options[:username] = user
ssh_options[:host_key] = 'ssh-dss'
ssh_options[:paranoid] = false

role :app, 'www.coolomekaapp.org'
role :web, 'www.coolomekaapp.org'
role :db, 'www.coolomekaapp.org'

# ===============
# Custom Tasks
# ===============
namespace :deploy do
desc 'Make sure the archives directory has the proper permissions'
task :chmod_archive_dir, :except=&gt;{:no_release =&gt; true} do

run &quot;chmod g+rw #{current_path}/archives&quot;
end
desc 'Sets up the intitial db.ini config'
task :upload_database_config, :except=&gt;{:no_release =&gt; true} do
db_config = &lt;&lt;-INI
[database]
host     = &quot;your.db.host&quot;
username = &quot;db_user&quot;
password = &quot;db_password&quot;
name     = &quot;db_name&quot;
prefix   = &quot;omeka_&quot;
;port     = &quot;&quot;
INI

put db_config, &quot;#{current_path}/db.ini&quot;

end

desc 'Move archives directory so it doesn\'t get overwritten during deployments'
 task :move_archive_dir, :except=&gt;{:no_release =&gt; true} do
 run &quot;mv #{current_path}/archives #{shared_path}&quot;
 end

 desc 'Just svn up the directory'
 task :svn_up, :except =&gt; {:no_release =&gt; true} do
 run &quot;svn up #{current_path}&quot;
 end

 desc 'Link archives folder to shared directory'
 task :link_archives_dir, :except=&gt;{:no_release =&gt; true} do
 run &quot;cd #{current_path} &amp;&amp; ln -snf #{shared_path}/archives archives&quot;
 end

end

# ======================
# Task Event Hooks
# ======================

after 'deploy:symlink', 'deploy:upload_database_config', 'deploy:link_archives_dir'
after 'deploy:cold', 'deploy:chmod_archives_dir', 'deploy:move_archives_dir'
after 'deploy', 'deploy:cleanup'
</pre>
<p>Ok, there&#8217;s a lot going on here. I&#8217;ll briefly explain what&#8217;s going on, but there should be enough here for you to start hacking. But let&#8217;s see what tasks capistrano know about and you can call. If you are still in your project directory, just type cap -T to list all the capistrano tasks. Your output should look similar to this:</p>
<pre class="brush: bash;">
cap deploy                        # Deploys your project.
cap deploy:check                  # Test deployment dependencies.
cap deploy:chmod_archive_dir      # Make sure the archives directory has the ...
cap deploy:cleanup                # Clean up old releases.
cap deploy:cold                   # Deploys and starts a `cold' application.
cap deploy:migrate                # Run the migrate rake task.
cap deploy:migrations             # Deploy and run pending migrations.
cap deploy:pending                # Displays the commits since your last deploy.
cap deploy:pending:diff           # Displays the `diff' since your last deploy.
cap deploy:restart                # Restarts your application.
cap deploy:rollback               # Rolls back to a previous version and rest...
cap deploy:rollback:code          # Rolls back to the previously deployed ver...
cap deploy:setup                  # Prepares one or more servers for deployment.
cap deploy:start                  # Start the application servers.
cap deploy:stop                   # Stop the application servers.
cap deploy:symlink                # Updates the symlink to the most recently ...
cap deploy:update                 # Copies your project and updates the symlink.
cap deploy:update_code            # Copies your project to the remote servers.
cap deploy:upload                 # Copy files to the currently deployed vers...
cap deploy:upload_database_config # Sets up the intitial db.ini config
cap deploy:web:disable            # Present a maintenance page to visitors.
cap deploy:web:enable             # Makes the application web-accessible again.
cap invoke                        # Invoke a single command on the remote ser...
cap log:tail_log                  # Tail the rails log file
cap shell                         # Begin an interactive Capistrano session.

Some tasks were not listed, either because they have no description,
or because they are only used internally by other tasks. To see all
tasks, type `cap -vT'.

Extended help may be available for these tasks.
Type `cap -e taskname' to view it.
</pre>
<p>To use a specific capistrano task, you just type the command listed. But let&#8217;s get back to the actual script and go over that briefly. Part of the installation process of Omeka requires you to reset the permissions of the archives directory. This is handled by the chmod_archive_dir. However, because of the way that capistrano deploys applications, the archives folder would get overwritten in every deployment. To get around this, we move the archives directory to the shared folder, then create a symlink from the current directory to the shared/archives directory.</p>
<p>There&#8217;s a task to upload_database_config that you can have in your cap script (we deploy out of private repos), but if you&#8217;re deploying out of a public repo, you may want to just put the db.ini file on the server in the shared directory and symlink it into the current_path. Lastly, there are times where you just need to do an &#8220;svn up&#8221; (or git pull) to update something small and not need to do a full deployment. This is where the cap deploy:svn_up helps out&#8230;.guess what it does <img src='http://www.scholarslab.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Capistrano also provides task even hooks to execute specific tasks after specific events. In this script, when you do a cold deployment (when you are setting things up for the first time), the script will change the permissions on the archives directory, then move the archives directory to the shared directory. When you do a normal deploy (after the directory has gotten a proper symlink), the script will upload the database config, then symlink the archives directory and run a cleanup (keep the last 5 versions you deployed).</p>
<p>While there&#8217;s still a bit of up-front set up to do on your server, capistrano significantly speeds up your ability to to consistently deploy software, quickly roll-back if (that changes to &#8220;when&#8221;, if you write code long enough) problems occur, and reinforces a development process that involves SCM!</p>
<h2>Resources</h2>
<ul>
<li><a href="http://www.capify.org/index.php/Capistrano">Capistrano</a></li>
<li><a href="http://www.jonmaddox.com/2006/08/16/automated-php-deployment-with-capistrano/">Automated PHP Deployment with Capistrano</a></li>
<li><a href="http://github.com/leehambley/railsless-deploy">Railsless-deploy</a></li>
<li><a href="http://www.capify.org/index.php/Tutorials">Capistrano Tutorials</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/slab-code/automating-omeka-deployment-with-capistrano/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Omeka Timeline Plugin</title>
		<link>http://www.scholarslab.org/slab-code/omeka-timeline-plugin/</link>
		<comments>http://www.scholarslab.org/slab-code/omeka-timeline-plugin/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 19:19:44 +0000</pubDate>
		<dc:creator>Wayne Graham</dc:creator>
				<category><![CDATA[SLab Code]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[omeka]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[timeline]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=605</guid>
		<description><![CDATA[As part of our ongoing efforts on our Neatline grant, we needed to include a way of displaying temporal information and interacting with other data stored in Omeka. Just about the time we were starting to write this code, CHNM announced their Plugin Rush which pays an honorarium to give folks some incentive to pitch in and develop a plugin or two. Since we were going to develop the plugin anyway, we're donating this back to the Omeka project, but we thought this might be a good opportunity to talk a little more about the development cycle for Omeka plugins, and hopefully inspire others to get involved.]]></description>
			<content:encoded><![CDATA[<p>As part of our ongoing efforts on our <a href="http://www.neatline.org">Neatline</a> grant, we needed to include a way of displaying temporal information and interacting with other data stored in Omeka. Just about the time we were starting to write this code, CHNM announced their <a href="http://omeka.org/blog/2010/02/18/plugin-rush-2010/">Plugin Rush</a> which pays an honorarium to give folks some incentive to pitch in and develop a plugin or two. Since we were going to develop the plugin anyway, we&#8217;re donating this back to the Omeka project, but we thought this might be a good opportunity to talk a little more about the development cycle for Omeka plugins, and hopefully inspire others to get involved.  <span id="more-605"></span></p>
<p>The specifications for the <a href="http://omeka.org/c/index.php/Plugin_Rush_2010#Timeline_.281.1-1.0.29">Timeline plugin</a> are wonderfully documented and explained on the Omeka wiki. This actually illustrates a great practice that is all too often ignored&#8230;explicitly stating what some software should do. Taking the time to think through the &#8220;what&#8221; a piece of software should do will save  you time in the long run as it forces you to think about how everything fits together, alleviating ambiguity and allowing you to focus on the task at hand.</p>
<p>For this specification, there were two requirements:</p>
<ul>
<li>The plugin should create a helper function for creating a <a href="http://www.simile-widgets.org/timeline/">SIMILE  Timeline</a> widget from an array of items.  The helper function should allow you to  specify which metadata elements the time data should come from, as well  as the element that specifies the caption (by default, the Dublin Core  Title element).</li>
<li> The timeline should allow for time intervals (start and end dates) and points in  time (singe date).</li>
</ul>
<p>While there are two requirements, it&#8217;s a good idea to break this us a little more into individual (atomic) tasks. First, we need to take a look at the <a href="http://code.google.com/p/simile-widgets/wiki/Timeline">SIMILE Timeline Widget documentation</a>. Taking a quick look at their <a href="http://code.google.com/p/simile-widgets/wiki/Timeline_GettingStarted">Getting Started</a> guide, this seems pretty straight forward</p>
<ol>
<li> <a href="http://code.google.com/p/simile-widgets/wiki/Timeline_GettingStarted#Step_1._Link_to_the_API">Include the Timeline javascript</a></li>
<li>Create a div container in the HTML view (e.g. &lt;div id=&#8221;timeline&#8221;&gt;&lt;/div&gt;</li>
<li>Format the items from Omeka as <a href="http://code.google.com/p/simile-widgets/wiki/Timeline_GettingStarted#Step_5._Add_Events">Timeline Events</a></li>
<li>Add the Timeline.create() call to the Omeka HTML view</li>
</ol>
<p>The specification states that this needs to be a helper function. If you&#8217;re not familiar with this term, a helper function is a block of code that does some of the computation for another piece of code. In many frameworks, helper functions aren&#8217;t actual objects, but pieces of procedural code that can be accessed from across the application that help add functionality that isn&#8217;t exactly proper to place in a model or controller; essentially these are statically accessible functions (in coding terms) that can be called from properly instantiated objects (in this case a view).</p>
<p>Now that we have good idea of what the code should do, let&#8217;s turn to some actual code. Omeka uses the <a href="http://framework.zend.com/">Zend Framework</a> to keep from doing a lot of repetitive programming, so most of the syntax of what we need to do is driven by how Zend handles PHP. On top of the Zend Framework, Omeka implements its own plugin infrastructure, so there are a few things we need to take in to account in our design.</p>
<p>The Zend Framework is a <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">model-view-controller (MVC) framework</a> designed to organize code for maintainability and DRY-ness (<a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">Don&#8217;t Repeat Yourself</a>). One the the hallmarks of most MVC applications is its physical separation of files and functionalities. In the case of Omeka plugins, the hierarchy is generally split into model, view, controller, and tests directory. For the Timeline plugin, since we are developing a helper function, we use a slightly modified directory structure:</p>
<pre class="brush: bash;">
Timeline
|__helpers
|__tests
|__views
</pre>
<p>We also need some mechanism to tell Omeka about a plugin. This metadata is currently provided in a file called plugin.ini. This file is pretty straight forward, but  let&#8217;s go over it briefly:</p>
<pre class="brush: php;">

[info]
name=&quot;Timeline&quot;
author=&quot;Scholars' Lab&quot;
description=&quot;SIMILE Timeline for Omeka&quot;
link=&quot;http://omeka.org/codex/Plugins/Timeline&quot;
omeka_minimum_version=&quot;1.0&quot;
omeka_tested_up_to=&quot;1.2&quot;
version=&quot;1.1&quot;
tags=&quot;Timeline, simile, chronology, time, temporal&quot;
</pre>
<p>This file is what the Omeka admin interface uses to display information about your plugin. Two things that may not be initially obvious are the<strong> omeka_minimimum_version</strong> and <strong>omeka_tested_up_to</strong> lines. One fact you&#8217;ll learn about software development, especially with API development, is as projects mature, the needs of the API grow along with them. You want to be able to mitigate potential issues should the plugin API change by explicitly setting the minimum revision number that your plugin is tested against (you can get older revisions from the SVN tags repo at <a href="https://omeka.org/svn/tags/">https://omeka.org/svn/tags/</a>).</p>
<blockquote><p><strong>Note:</strong> you can run multiple versions of Omeka on your machine for testing by checking out separate versions of the software in you web tree. For instance, you can have <strong>localhost/omeka1.0</strong>, <strong>localhost/omeka1.1</strong>, <strong>localhost/omeka_trunk</strong>. Setting this up is beyond the scope of this post (be sure to set up separate databases), but if you have questions, leave a comment.</p></blockquote>
<p>The next thing we need to do is tell Omeka what to do with our plugin. The top-level plugin.php file contains instructions (<a href="http://omeka.org/codex/Plugin_API/Hooks">hooks</a>) to tell the Admin interface what to do when a user installs or uninstalls the plugin. This is where we let Omeka know that items tagged with &#8220;Timeline&#8221; should use the Timeline Plugin, to set up some logging to help us debug when something goes wrong, and some default <a href="http://omeka.org/codex/Plugin_API/Hook/define_routes">routes</a> to help make &#8220;pretty&#8221; URLs.</p>
<p>Now, with all the preliminary setup taken care of, now we can start developing the helper function. First, let&#8217;s examine the Controller which tells Omeka what to do when an action is requested by the framework. This is actually a fairly straight forward:</p>
<pre class="brush: php;">

&lt;?php
class Timeline_TimelinesController extends Omeka_Controller_Action

{
	private $logger;

	public function init()
	{
		$this-&gt;_modelClass = 'Item';
		$writer = new Zend_Log_Writer_Stream(LOGS_DIR . DIRECTORY_SEPARATOR . &quot;timeline.log&quot;);
		$this-&gt;logger = new Zend_Log($writer);
	}

	public function showAction()
	{
		$this-&gt;view-&gt;item = $this-&gt;findById();
	}

}
</pre>
<p>Let&#8217;s go over briefly what&#8217;s going on here. There are some semantics in the way in which these Controller objects are named which are inherited from the way in which Zend handles Controllers. The <strong>Timeline_TimelinesController</strong> follows the convention of the &#8220;package&#8221; (the plugin) name, underscore, plural controller name (to handle multiple controllers), and finally &#8220;Controller&#8221; (which explicitly tells a programmer what function the Object performs). Because this is a Framework, we also want to be able to inherit a lot of behaviors without needing to code them ourselves, which is handled by the &#8220;extends Omeka_Controller_Action&#8221; (this is the base <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> class for Omeka which overrides and extends the <a href="http://framework.zend.com/manual/en/zend.controller.action.html">Zend_Controller_Action</a> object). The &#8220;important&#8221; part of the Controller code is really the showAction function which sets a variable named &#8220;item&#8221; in the view which contains a reference to the ID of an Omeka object. The rest just sets up a logger to keep track of what&#8217;s going on.</p>
<blockquote><p><strong>Note</strong>: If you run in to problems with this plugin, it is most likely related to logging. For more on this, see the documentation on <a href="http://omeka.org/codex/Retrieving_error_messages">Retrieving Error Messages</a>.</p></blockquote>
<p>Now we can get into the guts of the actual helper function. When you boil down the code, most of this is JavaScript with some strategically placed PHP. What we did is create a helper function named &#8220;createTimeline&#8221; which actually does the work for us. This takes two required items, a div reference to associate the Timeline on your page, and an array of Omeka Items with which to populate the Timeline.</p>
<pre class="brush: php;">
function createTimeline($div, $items = array(), $captionElementSet = &quot;Dublin Core&quot;, $captionElement =  &quot;Title&quot;, $dateElementSet = &quot;Dublin Core&quot;, $dateElement =  &quot;Date&quot; ) {
		echo js(&quot;prototype&quot;);
		global $mets;
		$mets = array($captionElementSet, $captionElement, $dateElementSet, $dateElement);
		?&gt;
		&lt;!--  we have to load the script in this funny way because we need to get the tag into the head of the doc
			because of the the funky way Simile Timeline loads its sub-scripts  --&gt;
		&lt;script type=&quot;text/javascript&quot;&gt;
			scripttag = document.createElement(&quot;script&quot;);
			scripttag.src = &quot;http://static.simile.mit.edu/timeline/api-2.3.0/timeline-api.js?bundle=false&quot;;
			scripttag.type = &quot;text/javascript&quot;;
			$$(&quot;head&quot;)[0].insert(scripttag);

			if (typeof(Omeka) == &quot;undefined&quot;) {
				Omeka = new Object();
			}

			if (!Omeka.Timeline) {
				Omeka.Timeline = new Object();
			}

		&lt;/script&gt;

		&lt;script type=&quot;text/javascript&quot; defer=&quot;defer&quot;&gt;
			Omeka.Timeline.timelinediv = $(&quot;&lt;?php echo $div;?&gt;&quot;);

			Omeka.Timeline.events = [
			&lt;?php
				function event_to_json($item) {
					global $mets;
					return &quot;{ 'title' : '&quot; . getMet($item, $mets[0], $mets[1]) . &quot;',
					'start' : '&quot; . getMet($item, $mets[2], $mets[3]) . &quot;',
					'description' : '&quot; . getMet($item, &quot;Dublin Core&quot;, &quot;Description&quot;) . &quot;',
					'durationEvent':false }&quot;;
				}
				echo implode(',',array_map('event_to_json', $items));
				?&gt;
				];

		&lt;/script&gt;
		&lt;?php
	     echo js(&quot;createTimeline&quot;);
		?&gt;
		&lt;script type=&quot;text/javascript&quot;&gt;
			Event.observe(window, 'load', onLoad);
			Event.observe(document.body, 'resize', onResize);
		&lt;/script&gt;

		&lt;?php
}
</pre>
<p>There&#8217;s a lot going on here, and there is a mix of PHP in the JavaScript. The first thing is making sure the prototype.js library is included, then declaring a variable named &#8220;mets&#8221; in the <a href="http://php.net/manual/en/language.variables.scope.php">global scope</a> (to make it available to other variable scopes). After we&#8217;ve declared $mets, get in to the JavaScript to include on the page and introducing a new JavaScript <a href="http://en.wikipedia.org/wiki/Namespace_%28computer_science%29">Namespace</a> (Omeka.Timeline) which allows you to extend this code in other views.</p>
<p>The second script block actually formats Omeka items that you&#8217;ve called as Timeline Events in the <a href="http://www.json.org/">JSON</a> format calling a helper method we also include in the code:</p>
<pre class="brush: php;">
function getMet($item, $elementSet, $element) {
	 $tmp = $item-&gt;getElementTextsByElementNameAndSetName($element, $elementSet);
	 return addslashes( $tmp[0]-&gt;text ) ;
}
</pre>
<p>This function returns the metadata for an Omeka item, which is then used the createTimeline&#8217;s sub-method of event_to_json to properly construct an event for Timeline. After all the JSON strings are created, we &#8220;glue&#8221; all the array elements with a comma with the <a href="http://php.net/manual/en/function.implode.php">implode</a> function.</p>
<p>As you can see, not a lot of code actually needs to be written to add functionality to Omeka. With a little research, and some pointers on syntax, extending Omeka can be done quite quickly and doesn&#8217;t require a degree in computer science. If you&#8217;re interested in getting started on a plugin, I highly recommend the <a href="http://groups.google.com/group/omeka-dev">Omeka dev list</a>; the community is growing and questions are answered quickly (usually by folks on the Omeka development team) and is a great way to learn about the technical issues surrounding developing software using the Omeka platform.</p>
<h2>Resources</h2>
<ul>
<li><a href="http://omeka.org/codex/Plugin_API">Omeka Plugin API</a></li>
<li><a href="http://groups.google.com/group/omeka-dev">Omeka Developer List</a></li>
<li><a href="https://addons.omeka.org/svn/plugins/Timeline/trunk/">Timeline Source Code</a></li>
<li><a href="http://omeka.org/codex/Plugins/Timeline">Timeline Documentation</a></li>
<li><a href="http://framework.zend.com/">Zend Framework</a></li>
<li><a href="http://framework.zend.com/manual/en/">Zend Framework Documentation</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/slab-code/omeka-timeline-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scholars&#8217; Lab Newsletter</title>
		<link>http://www.scholarslab.org/announcements/scholars-lab-newsletter/</link>
		<comments>http://www.scholarslab.org/announcements/scholars-lab-newsletter/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 19:28:19 +0000</pubDate>
		<dc:creator>ronda</dc:creator>
				<category><![CDATA[Announcements]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=680</guid>
		<description><![CDATA[We&#8217;re pleased to announce that the inaugural issue of our monthly newsletter is now available for download. The newsletter will highlight projects currently in progress in the Scholars&#8217; Lab, report on professional activities of the Scholars&#8217; Lab staff, and list monthly events. If you have suggestions for projects that you&#8217;d like to see highlighted in [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re pleased to announce that the inaugural issue of our monthly newsletter is now available for download. The newsletter will highlight projects currently in progress in the Scholars&#8217; Lab, report on professional activities of the Scholars&#8217; Lab staff, and list monthly events. If you have suggestions for projects that you&#8217;d like to see highlighted in future newsletters, please email me at <a class="superLinkifier" href="mailto:rag9b@virginia.edu">rag9b@virginia.edu</a>.</p>
<p style="padding-left: 30px;"><a rel="attachment wp-att-678" href="http://www.scholarslab.org/announcements/scholars-lab-newsletter/attachment/2010april/">Scholars&#8217; Lab News for April 2010 (PDF version)</a></p>
<p style="padding-left: 30px;"><a rel="attachment wp-att-679" href="http://www.scholarslab.org/announcements/scholars-lab-newsletter/attachment/2010april-2/">Scholars&#8217; Lab News April 2010 (text-only version)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/announcements/scholars-lab-newsletter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mr. Voronoi, meet the US state boundaries</title>
		<link>http://www.scholarslab.org/geospatial-and-temporal/mr-voronoi-meet-the-us-state-boundaries/</link>
		<comments>http://www.scholarslab.org/geospatial-and-temporal/mr-voronoi-meet-the-us-state-boundaries/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 18:57:34 +0000</pubDate>
		<dc:creator>kgj3t</dc:creator>
				<category><![CDATA[Geospatial and Temporal]]></category>
		<category><![CDATA[Visualization and Data Mining]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=609</guid>
		<description><![CDATA[In the Scholars&#8217; Lab we are working with remarkably detailed datasets showing changes to US political boundaries over time.  We&#8217;ve all been fascinated with visualizations where the familiar outlines of the US states emerge from thousands of boundary changes to their underlying counties over the last few hundred years.  Did you know Virginia once spanned [...]]]></description>
			<content:encoded><![CDATA[<p>In the Scholars&#8217; Lab we are working with remarkably detailed datasets showing changes to US political boundaries over time.  We&#8217;ve all been fascinated with visualizations where the familiar outlines of the US states emerge from thousands of boundary changes to their underlying counties over the last few hundred years.  Did you know Virginia once spanned from the Atlantic Ocean to the Mississippi River?</p>
<p><a rel="attachment wp-att-634" href="http://www.scholarslab.org/geospatial-and-temporal/mr-voronoi-meet-the-us-state-boundaries/attachment/virginiatomiss/"><img class="alignnone size-full wp-image-634" src="http://www.scholarslab.org/wp-content/uploads/2010/03/VirginiaToMiss.png" alt="Virginia" width="476" height="343" /></a></p>
<p>We&#8217;re developing a new web-based tool for visualizing these historic boundary changes and it&#8217;s nearly ready for prime time.  We&#8217;ll  announce the beta release here soon.</p>
<p>So with the knowledge that US state boundaries have already been subject to drastic change over time, let&#8217;s have some fun with geographic information systems to visualize drastic mathematically-induced changes to those familiar US state boundaries.</p>
<p>For our experiment, let&#8217;s keep all our current state capital cities right where they are since they are laden with the necessary infrastructure of government.  But we&#8217;ll move the state boundary lines <a href="http://mathworld.wolfram.com/VoronoiDiagram.html" target="_blank">Voronoi-style</a> so anywhere you travel in each of our new states you&#8217;ll be closer to the state capital than any other state capital.  In other words, when you&#8217;re standing anywhere inside our newly outlined Virginia, you will always be closer to the Virginia state capital, Richmond, than any other state capital.  That seems very efficient.  Let&#8217;s have a look.</p>
<p><a rel="attachment wp-att-626" href="http://www.scholarslab.org/geospatial-and-temporal/mr-voronoi-meet-the-us-state-boundaries/attachment/usanow2/"><img class="alignnone size-large wp-image-626" src="http://www.scholarslab.org/wp-content/uploads/2010/03/USAnow2-1024x651.png" alt="US States with capitals" width="470" height="298" /></a></p>
<p>Here&#8217;s that familiar grade-school wall map of the lower 48 US states and their capital cities.   Now let&#8217;s tweak the map with GIS software to reconfigure the states, Voronoi-style.</p>
<p><a rel="attachment wp-att-629" href="http://www.scholarslab.org/geospatial-and-temporal/mr-voronoi-meet-the-us-state-boundaries/attachment/usathen2/"><img class="alignnone size-large wp-image-629" src="http://www.scholarslab.org/wp-content/uploads/2010/03/USAthen2-1024x655.png" alt="US Voronoi states with capitals" width="470" height="300" /></a></p>
<p>Wow, what a difference Voronoi makes.</p>
<p>Let&#8217;s measure just how much the states have changed in our new layout.   In absolute terms, Utah and New Mexico make the biggest land grabs while Texas and California lose the most real estate.  But as a percentage of their current area, Rhode Island is the big winner ballooning in size by over 240% while Massachusetts shrinks 60%.</p>
<p>To visualize the state-by-state changes, Todd Burks from neighboring Clemons Library overlayed the two maps.</p>
<p><a rel="attachment wp-att-729" href="http://www.scholarslab.org/geospatial-and-temporal/mr-voronoi-meet-the-us-state-boundaries/attachment/toddmashup/"><img class="alignnone size-large wp-image-729" src="http://www.scholarslab.org/wp-content/uploads/2010/03/ToddMashup-1024x655.jpg" alt="" width="470" height="300" /></a></p>
<p>Intrigued?  <a href="http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?id=1349&amp;pid=1347&amp;topicname=Create_Thiessen_Polygons_%28Analysis%29" target="_blank">Read more</a> about Voronoi and Thiessen polygon GIS techniques.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/geospatial-and-temporal/mr-voronoi-meet-the-us-state-boundaries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Digital Therapy: Cesaire and Hawthorne</title>
		<link>http://www.scholarslab.org/podcasts/digital-therapy-cesaire-and-hawthorne/</link>
		<comments>http://www.scholarslab.org/podcasts/digital-therapy-cesaire-and-hawthorne/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 17:17:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Podcasts]]></category>
		<category><![CDATA[speaker series]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=574</guid>
		<description><![CDATA[Graduate students Alex Gil and Ryan Cordell present their recent work on  digital editions of works by Nathaniel Hawthorne and Aimé Césaire.
]]></description>
			<content:encoded><![CDATA[<p>Graduate students Alex Gil and Ryan Cordell present their recent work on  digital editions of works by Nathaniel Hawthorne and Aimé Césaire.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/podcasts/digital-therapy-cesaire-and-hawthorne/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://deimos3.apple.com/WebObjects/Core.woa/FeedEnclosure/virginia-public.2014484138.02014484145.3390392681/enclosure.mp3" length="60383965" type="audio/mpeg" />
<enclosure url="http://deimos3.apple.com/WebObjects/Core.woa/FeedEnclosure/virginia-public.2014484138.02014484145.3390392681/enclosure.mp3" length="60383965" type="audio/mpeg" />
		</item>
		<item>
		<title>More on Pandora:  genres, genomes, and musical taste&#8230;</title>
		<link>http://www.scholarslab.org/digital-humanities/more-on-pandora-genres/</link>
		<comments>http://www.scholarslab.org/digital-humanities/more-on-pandora-genres/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 14:39:52 +0000</pubDate>
		<dc:creator>jbk3y</dc:creator>
				<category><![CDATA[Digital Humanities]]></category>
		<category><![CDATA[Visualization and Data Mining]]></category>
		<category><![CDATA[Add new tag]]></category>

		<guid isPermaLink="false">http://scholarslab.lib.virginia.edu/?p=76</guid>
		<description><![CDATA[
Hello. In my last blog, I began my discussion of Pandora.com, the streaming audio website which offers a new kind of web radio to listeners. Enter a “seed” song into Pandora’s search engine, and the site will create a streaming “station” composed of songs that resemble your seed song. This process is powered by the [...]]]></description>
			<content:encoded><![CDATA[<p><!--StartFragment--></p>
<p class="MsoNormal">Hello.<span> </span>In my last blog, I began my discussion of <a href="http://www.pandora.com" target="_blank">Pandora.com</a>, the streaming audio website which offers a new kind of web radio to listeners.<span> </span>Enter a “seed” song into Pandora’s search engine, and the site will create a streaming “station” composed of songs that resemble your seed song.<span> </span>This process is powered by the Music Genome Project, a massive research endeavor which began in the early 2000s and is based out of the company’s Oakland, California headquarters.</p>
<p class="MsoNormal">How is Pandora’s song-recommendation engine different than web radio platforms that came before it?<span> </span>Well, the majority of other online radio stations, such as last.fm, operate off a system called collaborative filtering.<span> </span>What is collaborative filtering?<span> </span>In layperson’s terms, collaborative filtering involves matching one user’s taste to another’s (or a series of other people).<span> </span>On a site like <a href="last.fm" class="broken_link">last.fm</a>, over time a user amasses a playlist of songs they’ve expressed a preference for—a sort of musical taste profile.<span> </span>Last.fm’s search tools automatically identify other users with whom your tastes seem to overlap, and uses this information to power “radio” stations you can stream on the site.<span> </span>The process is pretty simple, and <a href="http://www.wired.com/culture/lifestyle/news/2003/07/59522">based on personal intuition and the data existing users have already entered into the system</a>.<span> </span>Collaborative filtering powers aspects of many media websites, such as Amazon.com’s personal recommendation feature for shoppers.</p>
<p class="MsoNormal"><span id="more-76"></span>It does have some limitations for online radio listeners, however.<span> </span>As Pandora’s founder Tim Westergren pointed out in a 2006 interview with Leo Laporte and Amber MacArthur, collaborative filtering-powered online radio stations have a tendency to only recommend what is broadly popular in contemporary pop music.<span> </span>While independent-label music certainly has a strong presence on last.fm, a quick scan of various users’ profiles on the site may suggest that Westergren has a point.<span> </span>Even among “indie” users on last.fm, there’s a whole lot of Death Cab for Cutie and Modest Mouse ruling the playlists (nothing against either of these bands).<span> </span>Collaborative filtering doesn’t necessarily ensure that the site’s users will discover truly obscure stuff they hadn’t heard of before.<span> </span>And in keeping with my interest in genre boundaries vis-à-vis Internet radio, in interviews Westergren has attributed the problem to the mainstream music business’ interest in keeping consumers bracketed into genre-specific niches.<span> </span>In the aforementioned chat with Laporte and MacArthur, Westergren cited the <a href="http://twit.tv/itn6" target="_blank">“age-old problem in the music industry”</a> wherein a tiny percentage of music released by a given label typically accounts for nearly all its sales—a problem codified by genre boundaries.</p>
<p class="MsoNormal">Pandora, through its Music Genome Project, aims to circumvent this problem, by offering its users a new kind of recommendation engine.<span> </span>As I mentioned in my earlier post, the Music Genome is a systematic endeavor to deconstruct and analyze individual pop songs using over 400 “musical attributes” that the company has identified.<span> </span>These attributes include everything from tempo, to vocal timbre, to harmonic movement—even sound production aspects like echo and reverb.<span> </span>In other words, it is essentially a musicological approach in the strictest sense of the word.<span> </span>The focus is on sound itself, rather than a band’s cultural associations with other bands (as is the case in collaborative filtering).<span> </span>Indeed, Westergren bragged in the aforementioned interview that “when we recommend to you a piece of music, we don’t even <em>know</em><span> how popular it is.”<span> </span></span></p>
<p class="MsoNormal">Instead, what the Music Genome Project entails is the company’s roughly fifty analysts sitting down in the Oakland, CA headquarters and methodically tagging a given song using these 400+ attributes.<span> </span>Westergren has described the process in ways akin to the scientific method, noting that a percentage of songs the analysts deconstruct are reviewed twice for quality.<span> </span>The songs, categorized by attributes, are added to the Project’s over 500,000 songs (and counting) accumulating in the company’s database.<span> </span>Songs sharing a similar musical “DNA” are then automatically matched and linked by Pandora’s search engine when you enter in a “seed” song.<span> </span>Westergren has called the Genome “kind of like a musical taxonomy,” and I don’t think this language is accidental.<span> </span>As Fabian Holt has pointed out about musical genres, “Discourse on the temporal dimensions of categories is saturated with organicist metaphors, as in discussions of how genres are <em>born</em><span>, how they </span><em>grow</em><span>, </span><em>mature</em><span>, </span><em>branch off</em><span>, </span><em>explode</em><span>, and </span><em>die</em><span>.”1<span> </span>Even though Pandora in fact aims to get </span><em>around</em><span> genre, it seems to me that this biologic language informs the company’s mission and direction.<br />
</span></p>
<p class="MsoNormal">In any case, as a Pandora user, I have often benefited from the happy accidents occasioned by the way the Music Genome Project works.<span> </span>For instance, I entered in Pandora as a &#8220;seed&#8221; Bob Dylan&#8217;s song &#8220;Tonight I&#8217;ll Be Staying Here With You&#8221;, a lilting, mid-tempo country-rock stroll.<span> </span>The Genome built a streaming station for me that included folk-rocky chestnuts by relatively obscure ‘60s and ‘70s groups like UFO and Earth Opera.<span> </span>It&#8217;s likely that I would not have heard about these groups without Pandora, or at least that I would&#8217;ve heard about them years from now in another context.<span> </span>In this regard, it seems that Westergren does have something to boast about regarding his claim that Pandora&#8217;s search engine connects listeners with &#8220;invisible&#8221; music in a way that mainstream, genre-bound, multinational music corporations just can&#8217;t.</p>
<p class="MsoNormal">On the other hand, there are several notable gaps in the logic and execution of Pandora and the Music Genome Project model.<span> </span>The first gap I feel compelled to point out is a very practical one.<span> </span>Returning to my example of the station based around &#8220;Tonight I&#8217;ll Be Staying Here With You,&#8221; Pandora is skilled in giving a user a lot of what they like.<span> </span>Enter in a twangy rock song like Dylan’s and you’ll get a station with loads of twangy rock songs.<span> </span>But there can be too much of a good thing; namely, I find homogeneity of songs’ <em>tempo</em><span> an issue on Pandora stations.<span> </span>“Tonight I’ll Be Staying Here With You” is a bit plodding, and I’ve found that over a few hours of playing this station, I mostly get one plodding song after the next.<span> </span>This can be useful in terms of finding hidden gems, but makes for monotonous, even frustrating listening over a span of a few hours. </span></p>
<p class="MsoNormal">I do know that Pandora makes much of its “Thumbs Up/Thumbs Down” feature, which allows the user to indicate her or his preference for a given song.<span> </span>Pandora’s algorithms will adjust the playlist’s direction (ever so slightly) upon a “Thumbs Down” for a song you don’t care for.<span> </span>In a 2006 interview with the <em>New York Times</em><span>, Westergren describes this feature as <a href="http://www.nytimes.com/2006/09/03/arts/music/03leed.html?_r=1&amp;pagewanted=all">a concession to human subjectivity</a> (within an otherwise “objective” platform), and I agree.<span> </span>The “Thumbs Up/Thumbs Down” feature requires active listening and participation on the user’s part—generally a good thing, I’ll admit.<span> </span>But what if I want to just sit back with a cold beverage and let the music play?<span> </span>The Genome’s platform, as it currently works, seems unable to deliver the ebbs and flows in tempo and musical texture which I enjoy in a good mixtape or college radio show.</span></p>
<p class="MsoNormal">These kind of practical gaps in Pandora’s service point me toward a larger theoretical problem worth discussing. <span> </span>In its insistence upon musical sound as <em>the</em><span> key ingredient for making song recommendations, the Music Genome Project willingly suspends belief in some basic social facts about the way music works.<span> </span>Music is undeniably social, cultural, and political.<span> </span>It’s the soundtrack to our lives as we dance, eat dinner, exercise, commute to work, fall in love, and so on.<span> </span>Music blasts out of loudspeakers at political rallies.<span> </span>We argue with friends over drinks about the relative merit of this or that musical group.<span> </span>And music is always part of a commercial marketplace, even in this age of file-sharing.<span> </span>Given all this, I find Westergren’s claim that a band’s marketplace popularity is <a href="http://twit.tv/itn6">“completely irrelevant to what we do”</a> a wee bit disingenuous, or at the very least requiring a willing suspension of disbelief regarding music’s social and marketplace role.</span></p>
<p class="MsoNormal">The Music Genome Project’s near-exclusive focus on sound itself, coupled with its organicist rhetoric regarding “musical DNA”, seems to suggest the company believes it can map out music in its totality—that it can “crack the code” of music, so to speak.<span> </span>As an aspiring musicologist, this reminds me a bit of another massive scholarly endeavor which worked toward a similar goal of cataloging music:<span> </span>Alan Lomax’s Cantometrics project.<span> </span>Developed by Lomax in the late 1950s and into the ‘60s, Cantometrics was a project wherein Lomax and several co-researchers analyzed the performance styles of (mostly traditional “folk”) songs from hundreds of different cultures around the world, tagging them with a variety of traits.<span> </span>These performance traits, such as vocal timbre, were organized into a computerized system wherein elements of the different musics could be compared.<span> </span>Lomax made the bold claim that one could draw conclusions about the social structure of a given society based on some of these performance traits (societies noted for a certain style of singing were sexually repressive, for instance).<span> </span>Of course, this claim was quite controversial, and has been challenged by other scholars since as overly reductive and essentialist.<span> </span>Fortunately, the Music Genome Project doesn’t attempt to make the connection between music and social structures the way Cantometrics did; indeed, as I said, the Genome Project’s rhetoric seems to <em>deny</em><span> aspects of the social world, if anything.</span></p>
<p class="MsoNormal">However, in the desire to systematically categorize and compare different aspects of music, one could say that the Genome Project and Cantometrics spring from a shared wellspring of human curiosity.<span> </span>One issue with this categorizing mission, though, is the problem of sample size.<span> </span>Lomax’s research was criticized for not casting a broad enough net in collecting these comparable performance traits.<span> </span>One could ask similar questions about the Music Genome Project’s scope.<span> </span>As I mentioned, the company’s website points out that its database currently features over 500,000 songs, and counting.<span> </span>This seems like a lot, but how useful is that number, when one considers the thousands and thousands of songs which are released commercially every year?<span> </span>And how can one ensure that multiple varieties, styles, and (yes, even) genres of music are adequately represented within those 500,000 songs?</p>
<p class="MsoNormal">Additionally, Pandora shares potentially problematic assumptions with Cantometrics regarding humans’ ability to fully categorize and catalog the world, to reduce music to its essence.<span> </span>This descends from the Enlightenment idea that our natural world is fully knowable through empirical and objective observation.<span> </span>That bedrock assumption has been the basis for the natural sciences, and one can see its influence on a project like Alan Lomax’s.<span> </span>The problem is:<span> </span>while an empirical observation approach might work well for classifying different varieties of tree frogs, when one wades into the murky waters of human behavior, it’s a lot more difficult to claim objectivity.<span> </span>Indeed, for myself and for a growing number of musicologists and humanities scholars more broadly, it is basically impossible to claim objectivity in one’s understanding of the world.</p>
<p class="MsoNormal">This is not to say that Pandora explicitly makes a claim of total objectivity, on their website or elsewhere.<span> </span>But as with Cantometrics, the fact that the company breaks songs down into discrete components and then makes comparisons and connections based on those components suggests that they believe music is knowable in some objective way.<span> </span>Pandora hasn’t made public a list of its over 400 “musical attributes”, but <a href="http://blog.pandora.com/faq/#92">shares a handful of them</a> on their website’s Frequently Asked Questions page.<span> </span>Some of the attributes they share make a lot of sense, and could even be called “objective”:<span> </span>major or minor key tonality, for instance.<span> </span>But consider an attribute like “headnodic beats”:<span> </span>in its FAQ entry, Pandora’s analysts admit they created the term themselves (it describes hip-hop beats which are strong, but not forceful enough to dance to).<span> </span>Given that probably almost no one outside of the Pandora offices uses this term, it can’t reasonably be called objective.<span> </span>This is not to say that an identification of some subjectivity within Pandora’s research model makes the whole enterprise come crashing down.<span> </span>Rather, I just wish to point out that while company prides itself on the cold objectivity of a computer algorithm choosing your music for you, human beings with subjective viewpoints created the components which power that algorithm.</p>
<p class="MsoNormal">Related to this, both Pandora and Cantometrics raise questions regarding musical gatekeepers, tastemakers, and their authority.<span> </span>Indeed, as ethnomusicologist Steven Feld has mused in response to Lomax’s work, “What are the sources of authority, wisdom, and legitimacy about sounds and music?<span> </span>Who can know about sound?<span> </span>Is musical knowledge public, private, ritual, esoteric?”.2<span> </span>Many researchers of pop music, pop culture, and genre agree that this issue of <em>who</em><span> is doing the classifying, categorizing, and ranking is a really important question.<span> </span>For instance, snobby clerks at your local independent record store may decide that Gillian Welch’s music belongs in the “folk” rather than “rock” section of the store.<span> </span>But where does the authority behind their judgment come from?  <span> </span>Their judgment is informed by their life experiences and backgrounds as (mostly) well-educated middle-class white males.</span></p>
<p class="MsoNormal">These gatekeepers’ judgments are also informed by a deep knowledge of various musical genres:<span> </span>the ability to distinguish glam from punk from grunge, and so on.<span> </span>Since Pandora’s fifty music analysts perform a similar function, I find this aspect of their job paradoxical:<span> </span>though the company seems to pride itself on getting beyond musical genre, these analysts must be extremely well-versed in genre in order to do their jobs well.<span> </span>In a recent video post on Pandora’s blog, Westergren states that the purpose of the Music Genome Project is ultimately to connect musicians with audiences, in ways the traditional music business can’t.3<span> </span>This is notably egalitarian rhetoric; it works off the assumption that consumers and musicians are empowered enough to seek each other out, and that they don’t need tastemakers dictating what music they should like.</p>
<p class="MsoNormal">As I noted above, however, the computerized system that listeners use to connect with musicians is designed and maintained by a group of (relatively) elite tastemakers.<span> </span>And in Westergren’s public statements about these analysts’ qualifications, I read a certain degree of anxiety over what kind of authority is vested in that role of analyst.<span> </span>In his 2006 interview with Leo Laporte and Amber MacArthur, Westergren pointed out that while all their analysts are regularly-gigging musicians, in order to carry out the depth of analysis required for the Music Genome Project, one really “need[s] an academic background”.<span> </span>Thus, in addition to being a working musician, an analyst employed by Pandora also needs at least a four-year undergraduate degree in music theory.<span> </span></p>
<p class="MsoNormal">On a practical level, this makes a lot of sense to me.<span> </span>If you’re going to employ folks to analyze songs for you, wouldn’t you want them to have an understanding of musical principles on several different levels?<span> </span>On the other hand, on a theoretical level, Pandora’s insistence on both “street” and “book” smarts from its analysts demonstrates an unresolved subliminal conflict over whether &#8220;brains and corporate no-how&#8221; or &#8220;gut, ‘Id’ feelings&#8221; are what shape the music we listen to.<span> </span>Thus, in this way, Pandora and the Music Genome Project struggle with these issues of taste and knowledge hierarchies just like other public pop prognosticators, even as their seemingly objective research platform denies this social fact.</p>
<p class="MsoNormal">This may read as though I am beating up on Pandora, but I hope the position I’m staking out is subtler than that.<span> </span>Rather, I have simply been attempting to point out some slight contradictions of logic within the Music Genome Project’s overall research platform.<span> </span>On a practical, user’s level, I enjoy the site.<span> </span>And to be fair to Pandora’s employees, on a certain level they seem to recognize the issues I am brining up here.<span> </span>For instance, in a recent post on Pandora’s official blog by one of its music analysts, Michael Zapruder likens evaluating songs to judging a baby beauty contest, and then points out,</p>
<p class="MsoNormal">&#8220;<em>The idea that all music is equal and deserves equal rights is somehow fundamentally a democratic idea; as is the corresponding idea that the public, and not some small cadre of experts, is the best judge of musical quality.<span> </span>But the fact that some music not only attracts more listeners, but also seems to mean more to more people over a longer period of time, indicates that there is actually something fundamentally unequal about music as well</em>.&#8221;4</p>
<p class="MsoNormal">In other words, perhaps this issue of taste isn’t an “either/or” problem, but rather a “both/and” one.<span> </span>And by its nature, it’s most likely a problem with no definitive answer.</p>
<p class="MsoNormal">It seems that in his blog entry, Pandora employees like Zapruder are trying to find a <em>practical</em><span>, everyday way of working around and through this problem—and I can’t fault them for that.<span> </span>Certainly, the academic in me bristles when I see Pandora present something like “headnodic beats” as some kind of objective criteria for judging music.<span> </span>But on a practical level, it seems that these classifications, even if they’re vague (such as<span> </span>“vinyl ambience,” or what have you) are perhaps vague at least partly in the service of the </span><em>listener’s</em><span> experience—of trying to match users to interesting new music.<span> </span>It doesn’t seem that the point of the Genome is to categorize musical attributes simply for the sake of categorization.<span> </span>Rather, the point seems to be to put that information to use, making musical connections for the listener.<span> </span>So perhaps it’s a utilitarian reason why the Music Genome cuts certain logical corners on the “objective vs. subjective” question.</span></p>
<p class="MsoNormal">Ultimately, Pandora’s service rests upon the assumption that sound itself is the only aspect which really matters when analyzing different forms of music.<span> </span>It assumes that sound automatically trumps the sociocultural boundaries of genre, taste, and marketplace.<span> </span>This isn&#8217;t true, of course:<span> </span>in the real world we live in, rhetoric surrounding genre and taste guide the musical choices we all make, from Walmart AC/DC lovers to bebop nerds.<span> </span>But the Music Genome Project’s fiction regarding the supremacy of sound is an important, if very one-sided, position to have out there in the world.<span> </span>In fact, it’s almost counter-cultural in a way, because journalists and advertisers often focus so much on <em>image</em><span> when considering contemporary pop music.<span> </span>Pandora’s vision is a kind of imagined musical utopia, making a particularly 21st-century-specific stand for the importance of musical sound—a stand made possible by the shared </span><em>cultural</em><span> resource of the Internet.</span></p>
<p class="MsoNormal">Finally, closing with an idea my professor Fred Maus pointed out to me, when you&#8217;re confronted with enjoying a song you didn&#8217;t think you would like on Pandora (you enter in a Turbonegro song as your “seed” and are rewarded with a Poison song, for example), that tells us something important about genre boundaries.<span> </span>Your bemusement proves that musical genres exist.<span> </span>They&#8217;re cultural; they don&#8217;t hold up to objective scrutiny.<span> </span>And they&#8217;re based on something more than just musical sound; they&#8217;re built around assumptions that have to do with hierarchies of taste and class.<span> </span>Thus, paradoxically, we can learn quite a bit about the rules of genre from a website devoted to transcending those rules.</p>
<div>
<hr size="1" />
<div>
<p class="MsoFootnoteText">
</div>
<div>
<p class="MsoNormal">1  Holt, Fabian.<span> </span><em>Genre in Popular Music</em><span>.<span> </span>Chicago:<span> </span>University of Chicago Press, 2007.<span> </span></span>Pg. 14.</p>
<p class="MsoFootnoteText">2  Feld, Steven.<span> </span>“Sound Structure as Social Structure.”<span> </span><em>Ethnomusicology</em><span>, Vol. 28. No. 3 </span>(Sept. 1984), pp. 383-409.</p>
<p class="MsoFootnoteText">3  http://blog.pandora.com/pandora/archives/2009/03/index.html<span> </span>March 15, 2009 entry.</p>
<p class="MsoFootnoteText">4  http://blog.pandora.com/pandora/archives/2009/02/index.html      February 25, 2009 entry.</p>
</div>
<div>
<p class="MsoFootnoteText">
</div>
</div>
<p><!--EndFragment--></p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/digital-humanities/more-on-pandora-genres/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lisa Rosner: the Anatomy Murders</title>
		<link>http://www.scholarslab.org/podcasts/lisa-rosner-the-anatomy-murders/</link>
		<comments>http://www.scholarslab.org/podcasts/lisa-rosner-the-anatomy-murders/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 17:30:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Podcasts]]></category>
		<category><![CDATA[speaker series]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=579</guid>
		<description><![CDATA[Up the close
And down the stair
Visualizing the worlds
Of Burke and Hare


]]></description>
			<content:encoded><![CDATA[<p><em>Up the close<br />
And down the stair<br />
Visualizing the worlds<br />
Of Burke and Hare</em></p>
<p><em><br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/podcasts/lisa-rosner-the-anatomy-murders/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
<enclosure url="http://deimos3.apple.com/WebObjects/Core.woa/FeedEnclosure/virginia-public.2014484138.02014484145.3381074823/enclosure.mp3" length="62320365" type="audio/mpeg" />
<enclosure url="http://deimos3.apple.com/WebObjects/Core.woa/FeedEnclosure/virginia-public.2014484138.02014484145.3381074823/enclosure.mp3" length="62320365" type="audio/mpeg" />
		</item>
		<item>
		<title>The 1907 Massie map of Albemarle Co.</title>
		<link>http://www.scholarslab.org/geospatial-and-temporal/the-1907-massie-map-of-albemarle-co-is-now-in-the-portal/</link>
		<comments>http://www.scholarslab.org/geospatial-and-temporal/the-1907-massie-map-of-albemarle-co-is-now-in-the-portal/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 20:11:57 +0000</pubDate>
		<dc:creator>Dave Richardson</dc:creator>
				<category><![CDATA[Geospatial and Temporal]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[albemarle county]]></category>
		<category><![CDATA[historic]]></category>
		<category><![CDATA[map]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=462</guid>
		<description><![CDATA[While going through our archives of scanned maps, we recently ran across a copy of  Frank A. Massie’s 1907 “A new and historical map of Albemarle County, Virginia” [Special Collections, University of Virginia Library], commonly referred to as the Massie map,  which contains a wealth of detailed historical information for the county in [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_482" class="wp-caption alignright" style="width: 119px"><a rel="attachment wp-att-482" href="http://www.scholarslab.org/geospatial-and-temporal/the-1907-massie-map-of-albemarle-co-is-now-in-the-portal/attachment/massie1907_thumb500-2/"><img class="size-full wp-image-482" src="http://www.scholarslab.org/wp-content/uploads/2010/01/Massie1907_thumb500.jpg" alt="The 1907 Massie Map of Albemarle Co., VA" width="109" height="150" /></a><p class="wp-caption-text">The 1907 Massie Map of Albemarle Co., VA</p></div>
<p>While going through our archives of scanned maps, we recently ran across a copy of  <strong>Frank A. Massie’s 1907 “A new and historical map of Albemarle County, Virginia” </strong>[Special Collections, University of Virginia Library], commonly referred to as the Massie map,  which contains a wealth of detailed historical information for the county in which the University of Virginia sits.</p>
<p><span id="more-462"></span>After obtaining a more recent scan of the map from Special Collections and Andrew Curly (of the Library’s Digital Production Services), we georectified the digital map and added it to our <a href="http://lat.lib.virginia.edu:8080/geonetwork/">geospatial data portal</a>.  Accessing the map through our portal (<a href="http://lat.lib.virginia.edu:8080/geonetwork/srv/en/metadata.show?id=544&amp;currTab=simple">here</a> or<a href="http://geoportal.scholarslab.org/item/544"> here</a>) allows you to not only view the map at high resolution in your browser, but also to <a href="http://lat.lib.virginia.edu:8080/geoserver/wms/kml_reflect?layers=Massie:Massie1907_2483">view the Massie map in Google Earth</a>, as well as being able to overlay the Massie map over other base maps and other geospatial data layers (for example, by making a WMS call to our portal’s server from your desktop GIS; or by pulling the Massie map into your webpage-embedded dynamic map using <a href="http://openlayers.org/">Open Layers</a>).</p>
<p>Among the many interesting historical features on the maps, are the locations of:</p>
<ul>
<li>The residences and named estates of prominent county landowners, including the oldest house in the county, plus various churches and schools, numerous dams, mills, and quarries, and local geologic and mineral resources;</li>
<li>Where Revolutionary war prisoners where held (the Barracks that held Hessian troops and from which Barracks Road was named, as well as where Baron and Baroness de Reidesel resided) plus old militia rendezvous points;</li>
<li>Routes and encampments of various military campaigns (notably those of British Lieutenant Colonel Banastre Tarleton’s 1781 raid on Charlottesville and Gov. Thomas Jefferson’s subsequent flight, General T. J. “Stonewall” Jackson’s Confederate Army’s march in 1862, General George A. Custer’s unsuccessful Union Army raid in 1864, and General Philip Sheridan’s Union Army’s march in 1865 along with locations of many of the mills and bridges Sheridan had destroyed);</li>
<li>Existing and proposed rail lines of many now-nonexistent railroads;</li>
<li>Locations where various murders and river drownings occurred.</li>
</ul>
<p>Additionally, the map contains tables showing city and county data from the 1900 census and a 1906 household survey (listing, among other things: total property values and taxes; numbers of livestock (1000’s of cattle, horses, hogs, and sheep, but only 24 goats!), wagons, watches, clocks, sewing machines, and pianos; number of manufacturers with their capital, number employees, and total wages; farm acreage; and enrollment figures for the white and colored public schools.</p>
<p>There’s also an inset showing the major rail lines and railroad junctions for the state of Virginia.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/geospatial-and-temporal/the-1907-massie-map-of-albemarle-co-is-now-in-the-portal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculating county-to-county distances with GIS</title>
		<link>http://www.scholarslab.org/geospatial-and-temporal/calculating-county-to-county-distances-with-gis/</link>
		<comments>http://www.scholarslab.org/geospatial-and-temporal/calculating-county-to-county-distances-with-gis/#comments</comments>
		<pubDate>Thu, 07 Jan 2010 20:40:08 +0000</pubDate>
		<dc:creator>kgj3t</dc:creator>
				<category><![CDATA[Geospatial and Temporal]]></category>
		<category><![CDATA[ESRI]]></category>
		<category><![CDATA[gis]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=442</guid>
		<description><![CDATA[In the Scholars&#8217; Lab we recently worked with a researcher whose study areas focused on several groups of US counties.  Of interest was the distance from every county within a group to every other county in that same group. We used geographic information systems (GIS) software to calculate these distances.
GIS software creates, manages, analyzes, [...]]]></description>
			<content:encoded><![CDATA[<p>In the Scholars&#8217; Lab we recently worked with a researcher whose study areas focused on several groups of US counties.  Of interest was the distance from every county within a group to every other county in that same group. We used geographic information systems (GIS) software to calculate these distances.</p>
<p><span id="more-442"></span>GIS software creates, manages, analyzes, and visualizes geographically referenced data.  Environmental Systems Research Institute (ESRI) in Redlands, California, produces ArcGIS desktop, a GIS software suite.  The following examples use ArcGIS ArcMap software version 9.3.1 at the ArcInfo product level.  Instructions for accessing GIS software at the University of Virginia are here: <a href="http://guides.lib.virginia.edu/gis">http://guides.lib.virginia.edu/gis</a>.  If you are not affiliated with UVA, contact your local IT support person or ESRI for information on accessing this GIS software.</p>
<p><strong>Calculating polygon centroids</strong> – When working with polygon features (like county boundaries) in GIS it is often necessary to locate the geographic center or centroid of each polygon as a point feature.  In ESRI’s ArcGIS desktop software the ‘Feature To Point’ tool creates polygon centroids.</p>
<p><a rel="attachment wp-att-449" href="http://www.scholarslab.org/geospatial-and-temporal/calculating-county-to-county-distances-with-gis/attachment/featuretopoint-2/"><img class="alignnone size-full wp-image-449" src="http://www.scholarslab.org/wp-content/uploads/2010/01/FeatureToPoint1.jpg" alt="" width="526" height="560" /></a></p>
<p>For more information see the ArcGIS online help for the ‘Feature To Point’ tool:</p>
<p><a href="http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?id=1798&amp;pid=1790&amp;topicname=Feature_To_Point_%28Data_Management%29">http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?id=1798&amp;pid=1790&amp;topicname=Feature_To_Point_%28Data_Management%29</a></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong>Creating a point distance table</strong> – Given a set of point features, GIS software can calculate the straight-line distance from each point in the set to every other point in the set.   The output distance table contains one row for each point-to-point combination along with the calculated distance.  In ESRI’s ArcGIS desktop software the ‘Point Distance’ tool creates a point distance table.</p>
<p><a rel="attachment wp-att-454" href="http://www.scholarslab.org/geospatial-and-temporal/calculating-county-to-county-distances-with-gis/attachment/pointdistance/"><img class="alignnone size-full wp-image-454" src="http://www.scholarslab.org/wp-content/uploads/2010/01/PointDistance.jpg" alt="Point Distance" width="526" height="486" /></a></p>
<p>For more information see the ArcGIS online help for the Point Distance tool: <a href="http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?id=1353&amp;pid=1347&amp;topicname=Point_Distance_%28Analysis%29">http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?id=1353&amp;pid=1347&amp;topicname=Point_Distance_%28Analysis%29</a></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong>Example using the ‘Feature To Point’ and ‘Point Distance’ tools – </strong>Given a polygon dataset representing boundaries of a group of US counties, calculate the distance between each county in the group and every other county in the group.</p>
<ol>
<li>After ensuring the county polygon boundary file is projected using a distance-preserving projection, select the county polygons for the study area.<a rel="attachment wp-att-456" href="http://www.scholarslab.org/geospatial-and-temporal/calculating-county-to-county-distances-with-gis/attachment/counties-2/"><img class="alignnone size-large wp-image-456" src="http://www.scholarslab.org/wp-content/uploads/2010/01/Counties1-1024x763.jpg" alt="" width="470" height="350" /></a></li>
<li>Convert the selected county polygons to county polygon centroid points using the ‘Feature To Point’ tool. <a rel="attachment wp-att-457" href="http://www.scholarslab.org/geospatial-and-temporal/calculating-county-to-county-distances-with-gis/attachment/countiescentroids/"><img class="alignnone size-large wp-image-457" src="http://www.scholarslab.org/wp-content/uploads/2010/01/CountiesCentroids-1024x763.jpg" alt="Counties with Centroids" width="470" height="350" /></a></li>
<li>Generate the point distance table for all county centroid points created in step 2 using the ‘Point Distance’ tool.  Distance is expressed in the linear unit of the input dataset, which is meters in our example.<a rel="attachment wp-att-459" href="http://www.scholarslab.org/geospatial-and-temporal/calculating-county-to-county-distances-with-gis/attachment/matrix-2/"><img class="alignnone size-full wp-image-459" src="http://www.scholarslab.org/wp-content/uploads/2010/01/Matrix1.jpg" alt="" width="237" height="263" /></a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/geospatial-and-temporal/calculating-county-to-county-distances-with-gis/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Large Files and Omeka</title>
		<link>http://www.scholarslab.org/slab-code/large-files-and-omeka/</link>
		<comments>http://www.scholarslab.org/slab-code/large-files-and-omeka/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 19:40:05 +0000</pubDate>
		<dc:creator>Wayne Graham</dc:creator>
				<category><![CDATA[SLab Code]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=376</guid>
		<description><![CDATA[This issue came up for a friend of the Scholars&#8217; Lab today on Twitter, but it&#8217;s hard to answer in 140 characters. It&#8217;s a question about allowing for larger file sizes in Omeka and there are a few ways to handle this.  (Because we want our new blog to be a combination of thoughtful [...]]]></description>
			<content:encoded><![CDATA[<p>This issue came up for a friend of the Scholars&#8217; Lab today on Twitter, but it&#8217;s hard to answer in 140 characters. It&#8217;s a question about allowing for larger file sizes in Omeka and there are a few ways to handle this.  (Because we want our new blog to be a combination of thoughtful essays on digital scholarship and quick answers to real-world technical problems, I thought I&#8217;d post here.)</p>
<p>Since Omeka runs on PHP, this is actually a PHP configuration issue and not something you can currently tweak in Omeka. Basically, you just need to tell PHP to allow larger files sizes that are larger than the default. A very easy way to do this is to edit the .htaccess file that Omeka ships with along the following lines:</p>
<pre class="brush: bash;">
php_value upload_max_filesize 20971520
php_value post_max_size 20971520
</pre>
<p>I&#8217;ll note here that doing things this way only affects your Omeka project. Another way to go about this is to add the above to the Apache configuration that defines from where Omeka should be served. For example:</p>
<pre class="brush: bash;">

&lt;VirtualHost *:80&gt;

ServerName www.coolomeka.org
DocumentRoot /var/www/omeka

&lt;Directory &quot;/var/www/omeka&quot;&gt;
    Options FollwSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
&lt;/Directory&gt;

    ErrorLog logs/omeka_error_log
    TransferLog logs/omeka_transfer_log

    php_value upload_max_filesize 20M
    php_value post_max_size 20M
&lt;/VirtualHost&gt;
</pre>
<p>Lastly, you can edit the php.ini file (usually in /etc/php.ini or /etc/php5/apache2/php.ini). Just do a search in the file and change the following settings:</p>
<pre class="brush: bash;">
  memory_limit = 32M
  post_max_size = 20M
  upload_max_size = 20M
</pre>
<p>You typically don&#8217;t need to reload Apache (as long as you did not edit the Apache configuration file) to get these settings to work.</p>
<p>For more info on this, check out these resources</p>
<ul>
<li><a href="http://php.net/manual/en/ini.core.php">Description of core php.ini directives</a></li>
<li><a href="http://www.radinks.com/upload/config.php">PHP Upload Configuration</a></li>
<li><a href="http://www.developershome.com/wap/wapUpload/wap_upload.asp?page=php2">PHP Directives Related to (Large) File Upload</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/slab-code/large-files-and-omeka/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Neatline</title>
		<link>http://www.scholarslab.org/uncategorized/neatline/</link>
		<comments>http://www.scholarslab.org/uncategorized/neatline/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 21:08:14 +0000</pubDate>
		<dc:creator>Bethany</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.scholarslab.org/?p=362</guid>
		<description><![CDATA[I&#8217;ve called Neatline, the Digital Humanities Start-Up project Adam Soroka and I began developing in September, a &#8220;contribution to interpretive humanities scholarship in the visual vernacular.&#8221;
Huh?
This project will allow scholars (and other stewards of cultural heritage) to create Web-based geospatial and temporal visualizations that build on the rich EAD metadata libraries produce in describing their [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve called <a href="http://neatline.org/">Neatline</a>, the <a href="http://www.neh.gov/grants/guidelines/digitalhumanitiesstartup.html">Digital Humanities Start-Up</a> project Adam Soroka and I began developing in September, a &#8220;contribution to interpretive humanities scholarship in the visual vernacular.&#8221;</p>
<p>Huh?</p>
<p>This project will allow scholars (and other stewards of cultural heritage) to create Web-based geospatial and temporal visualizations that build on the rich <a href="http://www.archivists.org/saagroups/ead/index.html">EAD metadata</a> libraries produce in describing their archival collections and making them more discoverable &#8212; but the crucial twist is that we didn&#8217;t want to think of our Neatline visualizations as <em>products</em> of the metadata.  They&#8217;re not brain-dead algorithmic output or some kind of thoughtless expression of the archivist&#8217;s (nuanced, but necessarily broad) stance toward historical or literary documents of interest.  (Yes, I&#8217;m asking for it; bring it on!)  In other words, Neatline isn&#8217;t about the parsing of placenames and automated population of timelines with data.  Rather, we&#8217;ve conceived this tool (really, as development proceeds, this <em>approach</em>, because Neatline is emerging as an arrangement of instruments and an attitude toward their use) as a kind of <em>playspace for the scholarly interpretative act</em>.  In future posts, we&#8217;ll describe our development effort and I&#8217;ll delve a little into the conceptual background for Neatline in the <a href="http://iath.virginia.edu/time">Temporal Modelling</a> project I undertook several years ago with <a href="http://en.wikipedia.org/wiki/Johanna_Drucker">Johanna Drucker</a>.  </p>
<p>In the meantime, you can read about how we&#8217;re employing the <a href="http://omeka.org">Omeka</a> plugin framework as a way to handle GIS services for scanned historical maps on the ScholarsLab.org project pages for <a href="http://www.scholarslab.org/projects/neatline/">Neatline-in-progress</a> and our larger <a href="http://www.scholarslab.org/projects/omeka-plugins/">Omeka plugin work</a>, or you can check out our dedicated <a href="http://neatline.org">project blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.scholarslab.org/uncategorized/neatline/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
