<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Contour Line</title>
	<atom:link href="http://contourline.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://contourline.wordpress.com</link>
	<description>Surround and define the edges of a subject, giving it shape and volume</description>
	<lastBuildDate>Tue, 07 May 2013 20:53:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='contourline.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Contour Line</title>
		<link>http://contourline.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://contourline.wordpress.com/osd.xml" title="Contour Line" />
	<atom:link rel='hub' href='http://contourline.wordpress.com/?pushpress=hub'/>
		<item>
		<title>On data and versions of data</title>
		<link>http://contourline.wordpress.com/2013/04/21/on-data-and-versions-of-data/</link>
		<comments>http://contourline.wordpress.com/2013/04/21/on-data-and-versions-of-data/#comments</comments>
		<pubDate>Mon, 22 Apr 2013 02:59:13 +0000</pubDate>
		<dc:creator>jmarca</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://contourline.wordpress.com/?p=655</guid>
		<description><![CDATA[Craig pointed out that git may not be the best solution and alternatives could be considered.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=655&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>  Craig pointed out that git may not be the best solution and<br />
  <a href="http://opengeo.org/publications/distributedversioningimplement/">alternatives</a><br />
  <a href="http://off-scale.com/">could</a><br />
  <a href="http://stackoverflow.com/questions/6268628/git-a-large-data-set">be</a><br />
  <a href="http://git-annex.branchable.com/">considered</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/contourline.wordpress.com/655/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/contourline.wordpress.com/655/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=655&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://contourline.wordpress.com/2013/04/21/on-data-and-versions-of-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0304452093efd125e7dac9cab0d0be5e?s=96&#38;d=monsterid" medium="image">
			<media:title type="html">jmarca</media:title>
		</media:content>
	</item>
		<item>
		<title>Public Planning Models</title>
		<link>http://contourline.wordpress.com/2013/03/19/public-planning-models/</link>
		<comments>http://contourline.wordpress.com/2013/03/19/public-planning-models/#comments</comments>
		<pubDate>Tue, 19 Mar 2013 22:39:53 +0000</pubDate>
		<dc:creator>jmarca</dc:creator>
				<category><![CDATA[transportation]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://contourline.wordpress.com/?p=646</guid>
		<description><![CDATA[Craig and I just posted our entry into the Knight Newschallenge Lottery. It is called Public Planning Models, in a classic case of a working title ending up being the final title. The basic idea is that planning models are &#8230; <a href="http://contourline.wordpress.com/2013/03/19/public-planning-models/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=646&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Craig and I just posted <a href="https://www.newschallenge.org/open/open-government/submission/public-planning-models/" title="Public Planning Models" target="_blank">our entry into the Knight Newschallenge Lottery</a>.  It is called Public Planning Models, in a classic case of a working title ending up being the final title.  </p>
<p>The basic idea is that planning models are opaque and mysterious, and really buggy and error prone.  The problem isn&#8217;t the fault of the modelers or the model systems, but rather the lack of input data.  Consider that a planning model first tries to model today&#8217;s world, and then tries to model the future using that same model with extrapolated conditions.   There are two sources of error&#8212;the model of the present, and the extrapolation of that model into the future.</p>
<p>In a perfect, totalitarian state, the government would know everywhere you go, and all that information could be loaded into the model of the present.  Calibration would be simple, because every vehicle is already in the model, so of course it captures reality.  But even in a totalitarian, all-knowing state, predicting the future isn&#8217;t possible.  Trends reverse themselves, people pick up different habits, and technology happens, changing the way we do things.</p>
<p>We have been watching and participating in the evolution of planning models, in particular pushing for the adoption of activity-based models over trip-based models.  The big problem here is the burden of data collection, as well as the increased complexity of the model framework.  Activity-based models are being incrementally adopted because they are too complicated and cost too much money to deploy.</p>
<p>Public Planning Models takes a different approach.  Rather than trying to come up with better data collection processes and better modeling techniques, we thought it would be better to try to expose the full ugliness of current planning models to the public.  This serves three purposes.  First, people can see just how weak many of the fundamental assumptions in these models are.  Second, everybody can take a look at the model system and suggest corrections and improvements, in the spirit of crowd-sourcing the model calibration step.  And third, exposing the models and the applications of those models will give people an incentive to become more involved.  That involvement can run the gamut from simply providing a few days worth of travel and activity data to the model&#8217;s input data set, to taking the model system itself and playing around with alternate planning scenarios.  </p>
<p>Anyway, take a look at our <a href="https://www.newschallenge.org/open/open-government/submission/public-planning-models/" title="Public Planning Models" target="_blank">proposal</a>, add comments, and if you know one of the judges, put in a good word for our efforts.  There are tons of submissions, and all of the ones I&#8217;ve read so far look pretty good.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/contourline.wordpress.com/646/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/contourline.wordpress.com/646/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=646&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://contourline.wordpress.com/2013/03/19/public-planning-models/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0304452093efd125e7dac9cab0d0be5e?s=96&#38;d=monsterid" medium="image">
			<media:title type="html">jmarca</media:title>
		</media:content>
	</item>
		<item>
		<title>CouchDB and Erlang</title>
		<link>http://contourline.wordpress.com/2013/03/01/couchdb-and-erlang/</link>
		<comments>http://contourline.wordpress.com/2013/03/01/couchdb-and-erlang/#comments</comments>
		<pubDate>Fri, 01 Mar 2013 23:00:17 +0000</pubDate>
		<dc:creator>jmarca</dc:creator>
				<category><![CDATA[couchdb]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://contourline.wordpress.com/?p=630</guid>
		<description><![CDATA[Typical left-field introduction As far as I understand it, the ability to run Erlang views natively is likely to be removed in the future because it does not offer any sandboxing of the content, and so the view can execute &#8230; <a href="http://contourline.wordpress.com/2013/03/01/couchdb-and-erlang/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=630&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h2>Typical left-field introduction</h2>
<p>As far as I understand it, the ability to run Erlang views natively is likely to be removed in the future because it does not offer any sandboxing of the content, and so the view can execute arbitrary commands on the server. So Erlang views are likely to go away.</p>
<h2>Problem: big docs crash JSON.parse()</h2>
<p>That said, I have a use case for Erlang views. <span id="more-630"></span> I have a database with two really large documents. They are TopoJSON documents of a 4km grid overlaid on California. One grid is in the original projection, and the other is reprojected as best as I can manage to SRID:4326. Both files are about 3.4MB, and apparently they cause intermittent problems for the JS view engine in CouchDB. I can&#8217;t quite nail down the issue enough to file a bug report, but if the docs are in there any view can fail. If I delete the TopoJSON docs and then put them back again, views will sometimes pass, but my suspicion is that the fail is due to a very large block of docs getting sent to the view engine that includes the TopoJSON files&#8230;the RAM required to parse the JSON is more than the server has available. My guess is that the reason it works when the TopoJSON files are deleted then re-inserted is that they are processed by themselves, or with a much smaller batch of other docs.</p>
<p>Regardless, the issue definitely comes about due to marshalling the data from Erlang to JS and then breaking it up using JSON.parse (that is what the crash dump says). So, I put together a super simple Erlang view, and it passed just fine, while the equivalent JS view failed. Problem solved (at least until the CouchDB devs pull the trigger on stripping out Erlang views).</p>
<h2>But now I have new problems&#8230;</h2>
<p>While I&#8217;m good with JavaScript, I&#8217;m about as clueless with Erlang as I am helping my daughters buy ballet leotards. But I found out a couple of things that I want to write down here.</p>
<p>First, due to a <a href="http://wiki.apache.org/couchdb/EnableErlangViews">few</a> <a href="http://stackoverflow.com/a/2422631">helpful</a> <a href="http://jamietalbot.com/2010/03/18/handling-json-objects-in-couchdb-native-erlang-views/">resources</a> on the internet, I was able to get a simple view going. A typical record looks like this:</p>
<pre class="brush: jscript; title: ; notranslate">
{
   &quot;_id&quot;: &quot;129_160_2007-01-01 00:00&quot;,
   &quot;_rev&quot;: &quot;2-4f3364efb916a4979dc4efe13bc667d1&quot;,
   &quot;geom_id&quot;: &quot;129_160&quot;,
   &quot;i_cell&quot;: 129,
   &quot;j_cell&quot;: 160,
   &quot;data&quot;: [
       &quot;2007-01-01 00:00&quot;,
       &quot;280&quot;,
       23153.13,
       184.23,
       458.45,
       0.03,
       73.48,
       46.72,
       5.04,
       61.33,
       13.28,
       2.03,
       52.24,
       13.08,
       52.31,
       2,
       &quot;400338&quot;,
       &quot;401512&quot;
   ],
   &quot;aadt_frac&quot;: {
       &quot;n&quot;: 0.02204350388061379,
       &quot;hh&quot;: 0.029391644125345406,
       &quot;not_hh&quot;: 0.024323281333117733
   }
}
</pre>
<p>didn&#8217;t have much hope because I didn&#8217;t know what would happen if I tried to split a string on a token that wasn&#8217;t in the string<br />
I wanted a view that would highlight the documents that had abnormally high values for <code>aadt_frac.n</code>. In JavaScript, that is easy, but as I said, JavaScript failed me. In Erlang, how would one access the internal members of the JSON object? The answer is below.</p>
<pre class="brush: erlang; title: ; notranslate">
fun({Doc}) -&gt;
  A = couch_util:get_value(&lt;&lt;&quot;aadt_frac&quot;&gt;&gt;, Doc),
  case A of
    undefined -&gt;
          ok;
    _ -&gt;
      G = couch_util:get_value(&lt;&lt;&quot;geom_id&quot;&gt;&gt;, Doc),
      {[{&lt;&lt;&quot;n&quot;&gt;&gt;, N},{&lt;&lt;&quot;hh&quot;&gt;&gt;, Hh},{&lt;&lt;&quot;not_hh&quot;&gt;&gt;, Nhh}]} = A,
      if
         N &gt; 0.5 -&gt; Emit(G,N),
                    true;
         true -&gt; true
      end
  end
end.
</pre>
<p>Apparently CouchDB provides a namespace for some Erlang utilities, and one of those will get a value out of a JSON record. That is what the first line is doing: <code>A = couch_util:get_value(&lt;&lt;"aadt_frac"&gt;&gt;, Doc)</code> extracts the &#8216;aadt_frac&#8217; value from the document and stores it in the variable <code>A</code>. Apparently Erlang variables need to be Capitalized, which was weird and may not be true.</p>
<p>I learned about case statements from the <a href="http://www.erlang.org/doc/getting_started/seq_prog.html#id66136">Erlang User&#8217;s Guide</a>, with a little more help from the two examples in the CouchDB wiki page. If <code>A</code> is undefined, then skip the doc. If it is defined, then I have to extract its contents. The line <code>{[{&lt;&lt;"n"&gt;&gt;, N},{&lt;&lt;"hh"&gt;&gt;, Hh},{&lt;&lt;"not_hh"&gt;&gt;, Nhh}]} = A</code> does this, following the advice from <a href="http://stackoverflow.com/a/2422631" rel="nofollow">http://stackoverflow.com/a/2422631</a>. The last if statement simply checks if <code>N</code> is greater than 0.5, and if it is, it will emit the grid&#8217;s geometry id and the value of <code>N</code>.</p>
<p>This view worked great, and pointed up about 20 or so locations and times with outrageously high values for n, hh, and not_hh. I dealt with these issues in my code, and created new versions of the documents, and then dove into some modeling in R.</p>
<p>My goal is to build a spatial model of these variables for places where I have no data measurements and save the estimates into the same CouchDB, filling in all the empty grid cells. Unfortunately, my first attempt failed&#8212;my code had a bug and I wrote blank entries for the aadt_frac record. Luckily I only messed up on a single month for a very small section. Unfortunately, that was still 200,000+ documents I now needed to delete.</p>
<p>The first step was to find these documents using a view. Javascript was out stil, but because I had learned me some Erlang, I could write the following simple view:</p>
<pre class="brush: erlang; title: ; notranslate">
fun({Doc}) -&gt;
        T = couch_util:get_value(&lt;&lt;&quot;ts&quot;&gt;&gt;, Doc),
        case T of
            undefined -&gt;  ok;
            _ -&gt;
                D = couch_util:get_value(&lt;&lt;&quot;data&quot;&gt;&gt;, Doc),
                case D of
                    undefined -&gt;
                        Emit(1,1);
                    _ -&gt;
                        ok
                end
        end
end.
</pre>
<p>Simple logic: if the document has a timestamp field, it is a document I want to consider (not a geometry file and not a design document), and if that file with a timestamp is missing a data field, then it needs to be deleted, so flag it by emitting something.</p>
<p>Now I bumped up against another problem with CouchDB&#8230;how to bulk delete documents. In SQL, I would write a query, verify that it was returning what I expected, double and triple check, and then drop those records from the table in a big query statement. In contrast, CouchDB speaks HTTP, and you must resort to DELETE requests, or POST to <code>_bulk_docs</code> with a list of document ids, revisions, and <code>_delete:true</code> fields. The view above is the first step. It allows me to gather up all of the document ids and revision numbers that I need to purge. The next step is to write code to bundle up those ids and revs, slap on the delete directive, and send the request to the CouchDB bulk_docs interface.</p>
<p>Ordinarily I just hack a little something out in whatever language I am using to get that job done. But I was working in R, and I hate using R for this sort of thing, so I turned to node.js, my hammer of choice these days. Because I&#8217;ve done this before, I decided to just write a self-contained package that will allow the deletion of every document that is emitted by a view. And I also wrote tests, to prove that it worked before I unleashed it on my 6GB database. The code is on <a href="https://github.com/jmarca/node_couch_view_deleter">github</a>. I ran it and deleted the problem docs. Problem solved.</p>
<h2>But now I have new problems&#8230;</h2>
<p>In the never ending saga of many mistakes that is my life, I fixed the aadt_frac generation code, but failed to notice and fix the fact that the <code>_id</code> values being generated by my R were broken, or rather, non existent. A big part of my work flow is knowing that I can query documents directly by their ids, and I just stored a bunch of documents with randomly generated UUIDs for ids. So I turned to Erlang and was faced with a new problem: I couldn&#8217;t simply rely on testing for undefined, because all documents have a valid id! Instead I needed to compare that id value against something. A new skill!</p>
<p>My first attempts, after a bit of searching around, failed miserably. A valid id is supposed to be the concatenation of the geom_id and the timestamp, with an underscore separating the two. What I needed was a way to test if the id looked like that. First I tried a split type approach, using the string:token function:</p>
<pre class="brush: erlang; title: ; notranslate">
[Icell,Jcell,Ts] = string:tokens(Id, &quot;_&quot;)
</pre>
<p>but that failed.  Actually it failed due to a syntax error higher up, but I abandoned the approach anyway&#8230;I was trying to split when I really just wanted to compare a substring, so I went with a different function.</p>
<pre class="brush: erlang; title: ; notranslate">
Id = couch_util:get_value(&lt;&lt;&quot;_id&quot;&gt;&gt;, Doc),
Gid = couch_util:get_value(&lt;&lt;&quot;geom_id&quot;&gt;&gt;, Doc),
case string:str(Id, Gid) of
    0 -&gt; Emit(2,1);
    _ -&gt; Emit(3,1)
end;
</pre>
<p>This one didn&#8217;t have a syntax error, but kept failing no matter how I prodded and poked. The logs said:</p>
<pre class="brush: erlang; title: ; notranslate">
** Reason for termination ==
** {function_clause,
       [{string,str,
            [&lt;&lt;&quot;b71476cb16533f8570ca909cad3a02dc&quot;&gt;&gt;,&lt;&lt;&quot;197_102&quot;&gt;&gt;],
            [{file,&quot;string.erl&quot;},{line,102}]},
        {erl_eval,do_apply,6,[{file,&quot;erl_eval.erl&quot;},{line,572}]},
        {erl_eval,expr,5,[{file,&quot;erl_eval.erl&quot;},{line,250}]},
        {couch_native_process,'-run/2-fun-0-',2,
...
</pre>
<p>&#8220;Hmm&#8221; I said to myself, &#8220;maybe these aren&#8217;t strings.&#8221; I mean, the data underneath them is a string, but that doesn&#8217;t mean Erlang thinks they are strings. So I revisited the CouchDB wiki page, and saw this snippet in the second filter:</p>
<pre class="brush: erlang; title: ; notranslate">
Values = binary:split(ValuesParam, &lt;&lt;&quot;,&quot;&gt;&gt;, [global]),
</pre>
<p>Armed with that, I went poking around the Erlang docs and found <a href="http://www.erlang.org/doc/man/binary.html#match-3"><code>binary:match</code></a>, and put together this bit that worked:</p>
<pre class="brush: erlang; title: ; notranslate">
Id = couch_util:get_value(&lt;&lt;&quot;_id&quot;&gt;&gt;, Doc),
Gid = couch_util:get_value(&lt;&lt;&quot;geom_id&quot;&gt;&gt;, Doc),
case binary:match(Id, Gid) of
    nomatch -&gt; Emit(2,1);
    _ -&gt; ok
end;
</pre>
<p>Once again, I had a view with lots of documents in it, so I passed it to my handy dandy node_couch_view_deleter program, and got rid of them all.</p>
<h2>Conclusion</h2>
<p>I&#8217;ve been telling my daughter to always write conclusions that conclude her papers. Of course I also tell her to write paragraphs with at least 5 sentences in them. Apparently I don&#8217;t follow my own advice.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/contourline.wordpress.com/630/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/contourline.wordpress.com/630/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=630&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://contourline.wordpress.com/2013/03/01/couchdb-and-erlang/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0304452093efd125e7dac9cab0d0be5e?s=96&#38;d=monsterid" medium="image">
			<media:title type="html">jmarca</media:title>
		</media:content>
	</item>
		<item>
		<title>Mode choice versus life cycle change</title>
		<link>http://contourline.wordpress.com/2013/02/11/mode-choice-versus-life-cycle-change/</link>
		<comments>http://contourline.wordpress.com/2013/02/11/mode-choice-versus-life-cycle-change/#comments</comments>
		<pubDate>Mon, 11 Feb 2013 21:08:54 +0000</pubDate>
		<dc:creator>jmarca</dc:creator>
				<category><![CDATA[bikes]]></category>
		<category><![CDATA[research]]></category>
		<category><![CDATA[transportation]]></category>

		<guid isPermaLink="false">http://contourline.wordpress.com/?p=614</guid>
		<description><![CDATA[During TRB I attended a presentation on the effect of life cycle changes on travel pattern characteristics. The presenter defined the usual life cycle changes (getting married, changing home location, having a child, etc) and set up a structural equations &#8230; <a href="http://contourline.wordpress.com/2013/02/11/mode-choice-versus-life-cycle-change/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=614&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>During TRB I attended a presentation on the effect of life cycle changes on travel pattern characteristics.  The presenter defined the usual life cycle changes (getting married, changing home location, having a child, etc) and set up a structural equations model to related these changes with the size of a person&#8217;s social network, the length (distance) and number of trips per day, the length (duration) and number of activities per day, and so on.</p>
<p>The work was interesting and got me thinking whether one could treat &#8220;being green&#8221; as a life cycle choice rather than as a mode choice.  In the usual mode choice context, <span id="more-614"></span>one considers each trip and weighs the costs and benefits of each mode.  In theory, each person will choose the mode that is best for her or him.  It is assumed that people are perfectly rational, and any differences in choices given apparently identical attribute sets is assigned to some unobservable error.  While this ignores the fact that people are pretty bad at making quick and accurate appraisals of the true costs and benefits of different modes, one could argue that even this fact is taken into account in that different people have different tolerance for spending time and effort searching for a better solution.  In the end, the random differences between people are presumed to come from some known distribution, and the modeling exercise estimates the relative weights of the observables (cost of bus, cost of transit, cost of biking, cost of walking, etc).  In the end, the analyst has a model that can estimate the answers to questions like how many former drivers would bike if bike travel times (or generalized cost) were decreased 1%. </p>
<p>Applying the idea of mode choice to my trip home today, in the mode choice modeling world my choices would consist of walking, biking, bus, and car, and most models would show that car is the hands-down winner in terms of high benefits and low costs.  This is in fact true for me too&#8212;I own a car, and I&#8217;m already paying taxes and insurance on it, and it is a fast and easy way to get around. The fact that I am going to choose to bicycle home this evening would be attributed to some unobserved randomness in how I personally evaluate those costs and benefits.</p>
<p>This isn&#8217;t what happens at all.  In reality, I have a beautiful Atlantis Rivendell sitting next to my desk in my office, and I am going to ride it home.  I chose a &#8220;bicycling lifestyle&#8221; quite a while ago, perhaps not even consciously, and so I generally choose bike first unless there is some major constraint which requires me to use a car.  Those constraints usually involve my wife and my children, or more accurately, when my lovely wife is out of town and I have run my children around to their after school activities. Which brings me to my real point of this post: bicycle choice is a life cycle stage for me, not a mode choice.  This stage or state is not one that my wife and children are in, and so whenever I have to participate in their daily activity patterns (ballet, piano, theater, etc), I am forced out of my bicycle life cycle state, and into a car life cycle state.</p>
<p>At the same TRB conference, I was looking for research in the domain of active transportation, or how and why people choose more active travel modes such as bicycling and walking.  This was inspired by my wife, who has a master&#8217;s degree in public health and told me that there was a growing interest in trying to use active transportation to combat serious health concerns like obesity and diabetes.  In a nutshell, people drive too much, and sit in front of the television too much, and modern humans are becoming fat slugs.  We didn&#8217;t evolve to be slugs, and so our bodies are not dealing well with this new set of circumstances.  One way to end the cycle is to &#8220;get&#8221; people to walk or bike more when they travel.</p>
<p>The trick is that the car is just so great at providing a low cost, high benefit transportation solution.  It is nearly impossible to identify a normal trip example in which driving loses out to walking or biking.  Cars have great roads and priority access at intersections and in parking lots, have super-fast top speeds, and plenty of hauling power.  So how can you expect someone who is overweight and diabetic to choose to walk to the supermarket (most likely across major roads and through a massive parking lot) to buy groceries?</p>
<p>In some places the &#8220;active life style&#8221; is most definitely imposed by the urban form, and driving to the market to do some shopping makes no sense at all.  For example, when I lived in Boston, the markets were tiny, and even if I did own a car I certainly wouldn&#8217;t have given up a parking spot just to spend 20 minutes looking for another one.  Instead, I shopped as I walked home each night as I passed different stores.  If I needed vegetables, I&#8217;d swing through Beacon Hill.  If I needed meats or cheeses, I&#8217;d go a block out of my way in the North End to the deli I liked.  Apparently, there are cities all over the world who are taking steps to try to make their urban environments more walkable, which at the same time will make them at least slightly less drivable.  I interpret this movement as trying to &#8220;get&#8221; people to be more active by trying to improve the benefits to costs ratio of active travel modes versus driving.  But the fact is you can&#8217;t make every city into Boston, and just a few short miles from where I lived in the North End, driving was the norm, not walking.</p>
<p>After that TRB session, I think there might be a different way to approach persuading people to choose active travel modes.  I think it is important to  view active travel as a life cycle change.  Choosing to walk or bike is going to have a drastic impact on every aspect of a person&#8217;s usual travel pattern, not just on a single trip.  This means that one who currently drives cannot simply pick any random trip in any random day and choose to perform that trip by bike or on foot.  Rather, the person will need to rearrange many activities in order to allow for the time and inconvenience of the non-motorized mode.  These secondary impacts are not trivial, and work against the active transportation choices.  Perhaps by viewing the choice of an active travel mode as a life cycle stage and by applying some of the same research tools we&#8217;ve applied to how more traditional life cycle changes affect travel patterns, we can devise ways to help people to shift to active transportation and lead healthier lives.  </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/contourline.wordpress.com/614/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/contourline.wordpress.com/614/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=614&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://contourline.wordpress.com/2013/02/11/mode-choice-versus-life-cycle-change/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0304452093efd125e7dac9cab0d0be5e?s=96&#38;d=monsterid" medium="image">
			<media:title type="html">jmarca</media:title>
		</media:content>
	</item>
		<item>
		<title>Tiptoe across the stream</title>
		<link>http://contourline.wordpress.com/2012/10/26/tiptoe-across-the-stream/</link>
		<comments>http://contourline.wordpress.com/2012/10/26/tiptoe-across-the-stream/#comments</comments>
		<pubDate>Fri, 26 Oct 2012 20:14:46 +0000</pubDate>
		<dc:creator>jmarca</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://contourline.wordpress.com/?p=602</guid>
		<description><![CDATA[I used streams in node.js last night. I can&#8217;t say I &#8220;get&#8221; them or that I am fluent in all use cases, but I can at least contribute one super basic use case that I couldn&#8217;t find explained anywhere. In &#8230; <a href="http://contourline.wordpress.com/2012/10/26/tiptoe-across-the-stream/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=602&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I used streams in node.js last night.  I can&#8217;t say I &#8220;get&#8221; them or that I am fluent in all use cases, but I can at least contribute one super basic use case that I couldn&#8217;t find explained anywhere.</p>
<p><span id="more-602"></span></p>
<p>In my application, I have a library that converts GeoJSON files into CSV files, dumping the geometry data and just preserving the properties.  Because that was one of the design criteria, the GeoJSON documents have buried in their &#8216;properties&#8217; hash a &#8216;header&#8217; object that I pull out and use as column headers, and a &#8216;data&#8217; object that is an array of data, matching the headers.</p>
<p>When I wrote the code, I wanted a streaming JSON parser, but I didn&#8217;t like the ones I tested, so instead I just parse the whole doc, find the header, find the data, and pass the result to the csv library.</p>
<p>Last night `npm install` on my laptop upgraded the csv library (<a href="http://www.adaltas.com/projects/node-csv" rel="nofollow">http://www.adaltas.com/projects/node-csv</a>) to 0.2.x, which brought with it a increased emphasis on streams along with some minor api changes.  I also was working on merging multiple files together, which meant I really wanted to stream the results as I completed each file.</p>
<p>But my problem was that I had no concept of how to write data to the csv stream and get it to work.  The examples and test cases all had things like </p>
<pre class="brush: jscript; title: ; notranslate">
csv()
.from.path(__dirname+'/columns.in', {
    columns: true
})
.to.stream(process.stdout, {
    columns: ['id', 'name'],
    end: false
})
</pre>
<p>But I wanted to write stuff over and over again.  I tried a minimal hacky fix by just piping one file at a time to the res stream, but somehow my code kept closing the stream.   After repeatedly re-reading the same passages over and over again, I finally figured out that what I wanted was the &#8220;.write()&#8221; method of the stream interface.  I want to call &#8220;csv.write(row)&#8221; when it is available, and then just let the csv do the piping to the res stream.  So I rewrote things a bit, and this is what I ended up with.</p>
<p>First, I create the csv writer.  Because this is an express web app, I want the output to go to the response object in the function call.  I did not set the &#8216;source&#8217; of the stream, because instead I am going to be writing that line by line.</p>
<pre class="brush: jscript; title: ; notranslate">
return function csv_formatter_service(req,res,next){
    var csv_writer = csv()
    csv_writer.pipe(res)
...
</pre>
<p>Then I do some uninteresting stuff in callbacks to get filenames that I want to concatenate, and then I do the following to actually do the CSV conversion:</p>
<pre class="brush: jscript; title: ; notranslate">
function(err,files){
    if(err) return next(err)
    res.writeHead(200, { 'Content-Type': 'text/csv' });
    // create a common builder so that I only dump one header row
    // and can number each record consecutively
    var builder = buildCSV({'columns':column_names}
                          ,function(err,rows){
                               // simple callback for builder, used for debugging mostly
                               if(err){return err;}
                               return null;
                           })
    // handy dandy async call makes sure that each file is processed consecutively
    // so that their output is not jumbled together on the stream
    async.forEachSeries(files
                       ,function(file,cb){
                            // eventually replace the read file with a streaming JSON parser
                            fs.readFile(file,'utf8', function(err,data){
                                // pass the data and csv_writer to the function 
                                // that parses the JSON
                                var err = builder(err,data,csv_writer)
                                // err is the output of the callback defined above (null or error)
                                cb(err);
                            })
                        }
                       ,function(err){
                            // simple placeholder callback for forEachSeries.  end the response
                            res.end(err)
                            return null
                        })
    // emacs complains if I don't return null, and anyway it is good practice
    return null
)
</pre>
<p>Now for the JSON parser code.  Whereas before I would parse the JSON doc, get an array of lines, and then create the csv() call with that array as the source, now I skip a step and just write each line to the csv writer object passed in.</p>
<pre class="brush: jscript; title: ; notranslate">
function buildCSV(options,cb){
    var header_row
    var column_names = options.columns ? options.columns : {}
    var total_data_idx = -1

    return function(err,doc,writestream){
        var fcoll = JSON.parse(doc)
        var features = fcoll.features;
        var rows = 0;
        var datacols=[];
        var features_length = features.length;
        // code to figure out the header row, then 
        if(header_row === undefined){
            header_row = _.map(['i','document'].concat(datacols)
                              ,function(key){
                                   return column_names[key] || key
                               })

            // Woo Hoo, just *write* data to the stream, and off it goes to the client!
            writestream.write(header_row)
            
        }
        // now process the data rows
        for (var i = 0; i &lt; features_length; i++){
            var props = features[i].properties;
            var datalen = props.data.length;
            if(props.data !== undefined &amp;&amp; Array.isArray(props.data) &amp;&amp; datalen){
                for (var dataidx = 0; dataidx &lt; datalen; dataidx++){
                    total_data_idx++
                    var width = props.data[dataidx].length
                    var entry = [total_data_idx,props.document]
                    entry = entry.concat(
                        datacols.map(function(key,idx){
                            if(props.data[dataidx] === undefined
                             || props.data[dataidx][idx] === undefined){
                                return '';
                            }else{
                                return props.data[dataidx][idx] ;
                            }
                        })
                    )

                    // Again, no fuss no muss no temporary arrays.  
                    // Just write to the stream and send the data on its way
                    writestream.write(entry)
                    rows++  // no, I'm not sure why I am tracking rows of data separately but whatever
                            // probably debugging cruft.
                }
            }else{
                // no data
                total_data_idx++  // even in the no data case, I send a row of commas, 
                                  // so increment the counter

               // record of empties, I choose you! 
               writestream.write([total_data_idx,props.docid]
                                                       .concat(
                                                           datacols.map(function(key){
                                                               // this map returns nothing, 
                                                               // to fill out the commas one per column
                                                               return ''; 
                                                           })
                                                       )
                                 );
 
            }
        }
        return cb(null,rows)
    };

</pre>
<p>And that is it, my minor revelation.  With streams, you can just write to them, and the data goes on its way.  In this case, the csv library has been set up to handle arrays and strings and such, so I can just write arrays.  Specifically, the docs state:</p>
<blockquote><p>
<code>write(data, [preserve])</code></p>
<p>
Implementation of the Writable Stream API with a larger signature. Data may be a string, a buffer, an array or an object.
</p>
<p>
If data is a string or a buffer, it could span multiple lines. If data is an object or an array, it must represent a single line. Preserve is for line which are not considered as CSV data.
</p>
</blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/contourline.wordpress.com/602/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/contourline.wordpress.com/602/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=602&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://contourline.wordpress.com/2012/10/26/tiptoe-across-the-stream/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0304452093efd125e7dac9cab0d0be5e?s=96&#38;d=monsterid" medium="image">
			<media:title type="html">jmarca</media:title>
		</media:content>
	</item>
		<item>
		<title>Tiger Shape Tech Docs, Appendix E:  Feature name types, now as CSV</title>
		<link>http://contourline.wordpress.com/2012/09/28/appendix-e-feature-name-types-now-as-csv/</link>
		<comments>http://contourline.wordpress.com/2012/09/28/appendix-e-feature-name-types-now-as-csv/#comments</comments>
		<pubDate>Fri, 28 Sep 2012 18:31:57 +0000</pubDate>
		<dc:creator>jmarca</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://contourline.wordpress.com/?p=594</guid>
		<description><![CDATA[What follows is appendix E of the TECHNICAL DOCUMENTATION: 2011 TIGER/Line Shapefiles Technical Documentation/prepared by the U.S. Census Bureau, 2011, available here It was sort of a pain to use emacs to make it csv, so I&#8217;m posting it.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=594&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>What follows is appendix E of the <strong>TECHNICAL DOCUMENTATION: 2011 TIGER/Line Shapefiles</strong><br />
Technical Documentation/prepared by the U.S. Census Bureau, 2011, available <a href="http://www.census.gov/geo/www/tiger/tgrshp2011/TGRSHP2011_TechDoc_E.pdf" title="Tiger Shape 2011 TechDoc Appx E">here</a>  It was sort of a pain to use emacs to make it csv, so I&#8217;m posting it.<br />
<span id="more-594"></span></p>
<pre class="brush: plain; title: ; notranslate">
Type code,Expanded full text,Display name abbreviation,Spanish,Translation,Prefix type,Suffix type
103,Academy,Acdmy,,,Y,Y
104,Acueducto,Acueducto,Yes,Aqueduct,Y,N
105,Aeropuerto,Aero,Yes,Airport,Y,N
106,Air Force Base,AFB,,,N,Y
107,Airfield,Airfield,,,N,Y
108,Airpark,Airpark,,,N,Y
109,Airport,Arprt,,,N,Y
110,Airstrip,Airstrip,,,N,Y
112,Alley,Aly,,,N,Y
115,Apartment Building,Apt Bldg,,,N,Y
116,Apartment Complex,Apt Complex,,,N,Y
117,Apartments,Apts,,,N,Y
118,Aqueduct,Aqueduct,,,N,Y
119,Arcade,Arc,,,Y,Y
121,Arroyo,Arroyo,Yes,Stream,Y,N
122,Assisted Living Center,Asstd Liv Ctr,,,N,Y
694,Assisted Living Facility,Asstd Liv Fac,,,N,Y
123,Autopista,Autopista,Yes,Expressway/Freeway,Y,N
124,Avenida,Ave,Yes,Avenue,Y,N
125,Avenue,Ave,,,Y,Y
126,Bahia,Bahía,Yes,Bay,Y,N
127,Bank,Bk,,,Y,Y
704,Base,Base,,,N,Y
128,Basin,Basin,,,N,Y
129,Bay,Bay,,,Y,Y
130,Bayou,Byu,,,Y,Y
131,Beach,Bch,,,N,Y
132,Bed and Breakfast,B and B,,,N,Y
136,Beltway,Beltway,,,N,Y
137,Bend,Bnd,,,N,Y
138,Bluff,Blf,,,N,Y
139,Boarding House,Brdng Hse,,,N,Y
140,Bog,Bog,,,N,Y
141,Bosque,Bosque,Yes,Forest,Y,N
142,Boulevard,Blvd,,,Y,Y
143,Boundary,Boundary,,,N,Y
146,Branch,Br,,,Y,Y
147,Bridge,Brg,,,N,Y
148,Brook,Brk,,,N,Y
149,Building,Bldg,,,Y,Y
150,Bulevar,Bulevar,Yes,Boulevard,Y,N
151,Bureau of Indian Affairs Highway,BIA Hwy,,,Y,N
152,Bureau of Indian Affairs Road,BIA Rd,,,Y,N
153,Bureau of Indian Affairs Route,BIA Rte,,,Y,N
154,Bureau of Land Management Road,BLM Rd,,,Y,N
696,Bypass,Byp,,,Y,Y
156,Calle,Cll,Yes,Street,Y,N
157,Calleja,Calleja,Yes,Narrow Street,Y,N
158,Callejón,Callejón,Yes,Alley,Y,N
159,Caminito,Cmt,Yes,Little Road,Y,N
160,Camino,Cam,Yes,Road/Way,Y,N
161,Camp,Cp,,,Y,Y
163,Campground,Cmpgrnd,,,N,Y
164,Campus,Cmps,,,N,Y
165,Canal,Cnl,,,Y,Y
172,Cano,Caño,Yes,Drain/Sewer,Y,N
166,Cantera,Cantera,Yes,Quarry/Gravel Pit,Y,N
167,Canyon,Cyn,,,Y,Y
168,Capilla,Capilla,Yes,Chapel,Y,N
169,Carretera,Carr,Yes,Road,Y,N
170,Causeway,Cswy,,,N,Y
171,Cayo,Cayo,Yes,Key,Y,N
173,Cementerio,Cem,Yes,Cemetery,Y,N
174,Cemetery,Cmtry,,,N,Y
175,Center,Ctr,,,Y,Y
176,Centro,Centro,Yes,Center,Y,N
177,Cerrada,Cer,Yes,Closed,Y,N
178,Chamber of Commerce,Cham of Com,,,N,Y
179,Channel,Chnnl,,,N,Y
180,Chapel,Cpl,,,Y,Y
181,Childrens Home,Childrens Home,,,N,Y
182,Church,Church,,,Y,Y
183,Circle,Cir,,,N,Y
234,Círculo,Cír,Yes,Circle,Y,N
184,City Hall,City Hall,,,N,Y
185,City Park,City Park,,,N,Y
186,Cliff,Clf,,,N,Y
187,Club,Clb,,,Y,Y
188,Colegio,Colegio,Yes,School,Y,N
189,College,Colg,,,Y,Y
190,Common,Cmn,,,N,Y
191,Commons,Cmns,,,Y,Y
192,Community Center,Community Ctr,,,N,Y
193,Community College,Community Colg,,,Y,Y
194,Community Park,Community Park,,,Y,Y
195,Complex,Complx,,,N,Y
197,Condominios,Condios,Yes,Condominiums,Y,N
198,Condominium,Condo,,,Y,Y
199,Condominiums,Condos,,,N,Y
201,Convent,Cnvnt,,,Y,Y
202,Convention Center,Convention Ctr,,,Y,Y
203,Corners,Cors,,,N,Y
204,Correctional Facility,Corr Faclty,,,N,Y
205,Correctional Institute,Corr Inst,,,N,Y
207,Corte,Corte,Yes,Court,Y,N
679,Cottage,Cottage,,,N,Y
208,Coulee,Coulee,,,N,Y
209,Country Club,Country Club,,,Y,Y
210,County Highway,Co Hwy,,,Y,N
211,County Home,Co Home,,,Y,Y
212,County Lane,Co Ln,,,Y,N
213,County Park,Co Park,,,N,Y
214,County Road,Co Rd,,,Y,N
215,County Route,Co Rte,,,Y,N
216,County State Aid Highway,Co St Aid Hwy,,,Y,N
217,County Trunk Highway,Co Trunk Hwy,,,Y,N
218,County Trunk Road,Co Trunk Rd,,,Y,N
219,Course,Crs,,,N,Y
220,Court,Ct,,,Y,Y
221,Courthouse,Courthouse,,,N,Y
222,Courts,Cts,,,N,Y
223,Cove,Cv,,,N,Y
225,Creek,Crk,,,N,Y
226,Crescent,Cres,,,N,Y
227,Crest,Crst,,,N,Y
228,Crossing,Xing,,,N,Y
229,Crossroads,Xroad,,,Y,Y
233,Cutoff,Cutoff,,,N,Y
235,Dam,Dm,,,N,Y
236,Delta Road,Delta Rd,,,Y,N
237,Department,Dept,,,Y,Y
238,Depot,Dep,,,N,Y
239,Detention Center,Detention Ctr,,,N,Y
240,District of Columbia Highway,DC Hwy,,,Y,N
241,Ditch,Ditch,,,Y,Y
242,Divide,Dv,,,N,Y
243,Dock,Dock,,,N,Y
244,Dormitory,Dormitory,,,N,Y
245,Drain,Drn,,,N,Y
246,Draw,Draw,,,N,Y
247,Drive,Dr,,,N,Y
248,Driveway,Driveway,,,Y,Y
249,Dump,Dump,,,N,Y
251,Edificio,Edif,Yes,Building,Y,N
252,Elementary School,Elem School,,,N,Y
253,Ensenada,Ensenada,Yes,Cove,Y,N
254,Entrada,Ent,Yes,Entrance,Y,N
256,Escuela,Escuela,Yes,School,Y,N
680,Esplanade,Esplanade,Yes,Esplanade,Y,Y
257,Estates,Ests,,,N,Y
260,Estuary,Estuary,,,N,Y
261,Expreso,Expreso,Yes,Expressway,Y,N
262,Expressway,Expy,,,Y,Y
263,Extension,Ext,,,Y,Y
264,Facility,Faclty,,,N,Y
265,Fairgrounds,Fairgrounds,,,N,Y
266,Falls,Fls,,,Y,Y
267,Farm,Frm,,,N,Y
268,Farm Road,Farm Rd,,,Y,N
269,Farm-to-Market Road,FM,,,Y,N
275,Fence Line,Fence Line,,,N,Y
276,Ferry Crossing,Ferry Crossing,,,Y,Y
277,Field,Fld,,,N,Y
278,Fire Control Road,Fire Cntrl Rd,,,Y,N
279,Fire Department,Fire Dept,,,N,Y
280,Fire District Road,Fire Dist Rd,,,Y,N
281,Fire Lane,Fire Ln,,,Y,N
282,Fire Road,Fire Rd,,,Y,N
283,Fire Route,Fire Rte,,,Y,N
284,Fire Station,Fire Sta,,,Y,Y
285,Fire Trail,Fire Trl,,,Y,N
286,Flowage,Flowage,,,N,Y
287,Flume,Flume,,,N,Y
288,Forest,Frst,,,N,Y
289,Forest Highway,Forest Hwy,,,Y,Y
290,Forest Road,Forest Rd,,,Y,N
291,Forest Route,Forest Rte,,,Y,N
292,Forest Service Road,FS Rd,,,Y,N
293,Fork,Frk,,,N,Y
294,Fort,Ft,,,Y,N
295,Four-Wheel Drive Trail,4WD Trl,,,Y,Y
296,Fraternity,Frtrnty,,,N,Y
297,Freeway,Fwy,,,N,Y
298,Garage,Grge,,,N,Y
299,Gardens,Gdns,,,N,Y
303,Glacier,Glacier,,,N,Y
304,Glen,Gln,,,N,Y
305,Golf Club,Golf Club,,,Y,Y
306,Golf Course,Golf Course,,,Y,Y
307,Grade,Grade,,,N,Y
309,Green,Grn,,,N,Y
310,Group Home,Group Home,,,N,Y
311,Gulch,Gulch,,,N,Y
312,Gulf,Gulf,,,Y,Y
313,Gully,Gully,,,N,Y
314,Halfway House,Halfway House,,,N,Y
315,Hall,Hall,,,N,Y
316,Harbor,Hbr,,,N,Y
317,Heights,Hts,,,N,Y
321,High School,High School,,,N,Y
322,Highway,Hwy,,,Y,Y
323,Hill,Hl,,,N,Y
324,Hollow,Holw,,,N,Y
325,Home,Home,,,Y,Y
326,Hospital,Hosp,,,Y,Y
327,Hostel,Hostel,,,N,Y
328,Hotel,Hotel,,,Y,Y
329,House,Hse,,,Y,Y
330,Housing,Hsng,,,Y,Y
332,Iglesia,Iglesia,Yes,Church,Y,N
333,Indian Route,Indian Rte,,,Y,N
334,Indian Service Route,Indian Svc Rte,,,Y,N
336,Industrial Park,Indl Park,,,N,Y
337,Inlet,Inlt,,,N,Y
338,Inn,Inn,,,Y,Y
339,Institute,Inst,,,Y,Y
340,Institution,Instn,,,N,Y
341,Instituto,Instituto,Yes,Institute,Y,N
342,Intermediate School,Inter School,,,N,Y
344,Interstate Highway,I-,,,Y,N
345,Isla,Isla,Yes,Island,Y,N
346,Island,Is,,,N,Y
347,Islands,Iss,,,Y,Y
348,Isle,Isle,,,Y,Y
349,Jail,Jail,,,N,Y
351,Jeep Trail,Jeep Trl,,,Y,Y
352,Junction,Junction,,,N,Y
353,Junior High School,Jr HS,,,N,Y
356,Kill,Kill,,,Y,Y
357,Lago,Lago,Yes,Lake,Y,N
358,Lagoon,Lagoon,,,N,Y
360,Laguna,Laguna,Yes,Lagoon,Y,N
361,Lake,Lk,,,Y,Y
362,Lakes,Lks,,,N,Y
363,Landfill,Lndfll,,,N,Y
364,Landing,Lndg,,,N,Y
365,Landing Area,Landing Area,,,Y,Y
366,Landing Field,Landing Fld,,,Y,Y
367,Landing Strip,Landing Strp,,,Y,Y
368,Lane,Ln,,,Y,Y
369,Lateral,Lateral,,,Y,Y
370,Levee,Levee,,,Y,Y
371,Library,Lbry,,,Y,Y
372,Lift,Lift,,,Y,Y
373,Lighthouse,Lighthouse,,,N,Y
374,Line,Line,,,Y,Y
376,Lodge,Ldg,,,N,Y
377,Logging Road,Logging Rd,,,Y,Y
378,Loop,Loop,,,Y,Y
379,Mall,Mall,,,Y,Y
380,Manor,Mnr,,,N,Y
381,Mar,Mar,Yes,Sea,Y,N
382,Marginal,Marginal,Yes,Service Road,Y,N
383,Marina,Mrna,,,N,Y
384,Marsh,Marsh,,,N,Y
385,Meadows,Mdws,,,N,Y
386,Medical Building,Medical Bldg,,,N,Y
387,Medical Center,Medical Ctr,,,Y,Y
388,Memorial,Meml,,,N,Y
389,Memorial Gardens,Memorial Gnds,,,N,Y
390,Memorial Park,Memorial Pk,,,N,Y
391,Mesa,Mesa,,,Y,Y
392,Middle School,Mid Schl,,,N,Y
393,Military Reservation,Mil Res,,,N,Y
394,Millpond,Millpond,,,N,Y
395,Mine,Mine,,,N,Y
396,Mission,Mssn,,,Y,Y
397,Mobile Home Community,Mobile Hm Cmty,,,Y,Y
398,Mobile Home Estates,Mobile Hm Est,,,Y,Y
399,Mobile Home Park,Mobile Hm Pk,,,Y,Y
400,Monastery,Monstry,,,Y,Y
401,Monument,Mnmt,,,N,Y
403,Mosque,Mosque,,,Y,Y
404,Motel,Mtl,,,Y,Y
405,Motor Lodge,Motor Lodge,,,N,Y
406,Motorway,Mtwy,,,N,Y
407,Mount,Mt,,,Y,Y
408,Mountain,Mtn,,,N,Y
411,Museum,Mus,,,Y,Y
412,National Battlefield,Natl Bfld,,,N,Y
413,National Battlefield Park,Natl Bfld Pk,,,N,Y
414,National Battlefield Site,Natl Bfld Site,,,N,Y
415,National Conservation Area,Natl Cnsv Area,,,N,Y
416,National Forest,Natl Forest,,,N,Y
417,National Forest Development Road,Nat For Dev Rd,,,Y,N
419,National Grasslands,Natl Grsslnds,,,N,Y
420,National Historic Site,Natl Hist Site,,,N,Y
421,National Historical Park,Natl Hist Pk,,,N,Y
422,National Lakeshore,Natl Lkshr,,,N,Y
423,National Memorial,Natl Meml,,,N,Y
424,National Military Park,Natl Mil Pk,,,N,Y
425,National Monument,Natl Mnmt,,,N,Y
426,National Park,Natl Pk,,,N,Y
427,National Preserve,Natl Prsv,,,N,Y
428,National Recreation Area,Natl Rec Area,,,N,Y
429,National Recreational River,Natl Rec Riv,,,N,Y
430,National Reserve,Natl Resv,,,N,Y
431,National River,Natl Riv,,,N,Y
432,National Scenic Area,Natl Sc Area,,,N,Y
433,National Scenic River,Natl Sc Riv,,,N,Y
435,National Scenic Riverways,Natl Sc Rvrwys,,,N,Y
436,National Scenic Trail,Natl Sc Trl,,,N,Y
437,National Seashore,Natl Shr,,,N,Y
438,National Wildlife Refuge,Natl Wld Rfg,,,N,Y
439,Navajo Service Route,Navajo Svc Rte,,,Y,N
440,Naval Air Station,Naval Air Sta,,,N,Y
442,Nursing Home,Nurse Home,,,N,Y
444,Ocean,Ocean,,,N,Y
445,Oceano,Océano,Yes,Ocean,Y,N
446,Office,Ofc,,,Y,Y
447,Office Building,Office Bldg,,,N,Y
449,Office Park,Office Park,,,N,Y
698,Orchard,Orchard,,,N,Y
451,Orchards,Orchrds,,,N,Y
452,Orphanage,Orphanage,,,N,Y
453,Outlet,Outlet,,,N,Y
454,Oval,Oval,,,N,Y
455,Overpass,Opas,,,N,Y
456,Parish Road,Parish Rd,,,Y,N
457,Park,Park,,,N,Y
458,Park and Ride,Park and Ride,,,N,Y
460,Parkway,Pkwy,,,N,Y
706,Parq,Parq,Yes,Park,Y,N
461,Parque,Parque,Yes,Park,Y,N
462,Pasaje,Pasaje,Yes,Passage,Y,N
463,Paseo,Pso,Yes,Path,Y,N
464,Pass,Pass,,,Y,Y
465,Passage,Psge,,,Y,Y
466,Path,Path,,,N,Y
682,Pavilion,Pavilion,,,N,Y
467,Peak,Peak,,,N,Y
705,Penitentiary,Penitentiary,,,N,Y
468,Pier,Pier,,,Y,Y
469,Pike,Pike,,,N,Y
470,Pipeline,Pipeline,,,N,Y
472,Place,Pl,,,N,Y
473,Placita,Pla,Yes,Little Plaza,Y,N
474,Plant,Plnt,,,N,Y
683,Plantation,Plantation,,,N,Y
475,Playa,Playa,Yes,Beach,Y,N
476,Playground,Playground,,,N,Y
477,Plaza,Plz,,,Y,Y
478,Point,Pt,,,Y,Y
479,Pointe,Pointe,,,N,Y
480,Police Department,Police Dept,,,Y,Y
481,Police Station,Police Station,,,Y,Y
482,Pond,Pond,,,Y,Y
483,Ponds,Ponds,,,N,Y
485,Port,Prt,,,Y,Y
486,Post Office,Post Office,,,N,Y
487,Power Line,Power Line,,,N,Y
691,Power Plant,Power Plant,,,N,Y
488,Prairie,Pr,,,N,Y
489,Preserve,Preserve,,,N,Y
491,Prison,Prison,,,N,Y
690,Prison Farm,Prison Farm,,,N,Y
685,Promenade,Promenade,,,N,Y
492,Prong,Prong,,,N,Y
494,Puente,Puente,Yes,Bridge,Y,N
495,Quadrangle,Quadrangle,,,N,Y
496,Quarry,Quar,,,N,Y
686,Quarters,Quarters,,,N,Y
497,Quebrada,Qbda,Yes,Creek,Y,N
499,Race,Race,,,N,Y
501,Rail,Rail,,,N,Y
502,Rail Link,Rail Link,,,Y,Y
504,Railnet,Railnet,,,N,Y
505,Railroad,RR,,,N,Y
506,Railway,Rlwy,,,N,Y
507,Ramal,Ramal,Yes,Short Street,Y,N
508,Ramp,Ramp,,,N,Y
510,Ranch Road,Ranch Rd,,,Y,N
511,Ranch to Market Road,RM,,,Y,N
512,Rancho,Rch,Yes,Ranch/Farm,Y,N
513,Ravine,Ravine,,,N,Y
514,Recreation Area,Rec Area,,,N,Y
515,Reformatory,Reformatory,,,N,Y
516,Refuge,Refuge,,,N,Y
518,Regional Park,Regional Pk,,,N,Y
519,Reservation,Reservation,,,N,Y
520,Reservation Highway,Resvn Hwy,,,Y,N
521,Reserve,Resv,,,N,Y
522,Reservoir,Reservoir,,,Y,Y
524,Residence Hall,Res Hall,,,N,Y
525,Residencial,Residencial,Yes,Public Housing Project,Y,N
526,Resort,Resrt,,,N,Y
688,Rest Home,Rest Home,,,N,Y
527,Retirement Home,Retirement Hme,,,N,Y
528,Retirement Village,Retirement Vlg,,,N,Y
529,Ridge,Rdg,,,N,Y
543,Rio,Río,Yes,River,Y,N
530,River,Riv,,,N,Y
531,Road,Rd,,,Y,Y
533,Roadway,Roadway,,,N,Y
535,Rock,Rock,,,Y,Y
536,Rooming House,Rooming Hse,,,N,Y
537,Route,Rte,,,Y,Y
538,Row,Row,,,Y,Y
539,Rue,Rue,,,Y,Y
540,Run,Run,,,N,Y
541,Runway,Runway,,,Y,Y
542,Ruta,Ruta,Yes,Route,Y,N
498,RV Park,RV Park,,,N,Y
545,Sanitarium,Sanitarium,,,N,Y
546,School,Schl,,,Y,Y
549,Sea,Sea,,,Y,Y
550,Seashore,Seashore,,,N,Y
552,Sector,Sec,Yes,Sector,Y,N
553,Seminary,Smry,,,Y,Y
554,Sendero,Sendero,Yes,Foot Path,Y,N
555,Service Road,Svc Rd,,,Y,Y
556,Shelter,Shelter,,,N,Y
558,Shop,Shop,,,N,Y
699,Shopping Center,Shopping Ctr,,,N,Y
560,Shopping Mall,Shopping Mall,,,N,Y
700,Shopping Plaza,Shopping Plz,,,N,Y
703,Site,Site,,,N,Y
564,Skyway,Skwy,,,Y,Y
565,Slough,Slough,,,N,Y
566,Sonda,Sonda,Yes,Sound,Y,N
567,Sorority,Sorority,,,Y,Y
568,Sound,Snd,,,Y,N
569,Spa,Spa,,,Y,Y
570,Speedway,Speedway,,,Y,Y
571,Spring,Spg,,,N,Y
572,Spur,Spur,,,Y,Y
573,Square,Sq,,,Y,Y
575,State Beach,State Beach,,,N,Y
577,State Forest,State Forest,,,N,Y
578,State Forest Service Road,St FS Rd,,,Y,N
579,State Highway,State Hwy,,,Y,N
580,State Hospital,State Hospital,,,Y,Y
581,State Loop,State Loop,,,Y,N
582,State Park,State Park,,,N,Y
584,State Prison,State Prison,,,N,Y
585,State Road,State Rd,,,Y,N
586,State Route,State Rte,,,Y,N
588,State Spur,State Spur,,,Y,N
589,State Trunk Highway,St Trunk Hwy,,,Y,N
591,Station,Sta,,,N,Y
592,Strait,Strait,,,Y,Y
593,Stravenue,Stra,,,N,Y
594,Stream,Strm,,,N,Y
595,Street,St,,,N,Y
596,Strip,Strip,,,Y,Y
599,Swamp,Swamp,,,N,Y
600,Synagogue,Synagogue,,,Y,Y
601,Tank,Tank,,,N,Y
603,Temple,Tmpl,,,Y,Y
604,Terminal,Trmnl,,,N,Y
605,Terrace,Ter,,,Y,Y
687,Thoroughfare,Thoroughfare,,,N,Y
607,Toll Booth,Toll Booth,,,Y,Y
701,Toll Road,Toll Rd,,,N,Y
610,Tollway,Tollway,,,N,Y
611,Tower,Twr,,,Y,Y
612,Town Center,Town Ctr,,,Y,Y
613,Town Hall,Town Hall,,,N,Y
614,Town Highway,Town Hwy,,,Y,N
615,Town Road,Town Rd,,,Y,N
616,Towne Center,Towne Ctr,,,Y,Y
617,Township Highway,Twp Hwy,,,Y,N
618,Township Road,Twp Rd,,,Y,N
619,Trace,Trce,,,N,Y
620,Track,Trak,,,Y,Y
621,Trafficway,Trfy,,,N,Y
622,Trail,Trl,,,Y,Y
623,Trailer Court,Trailer Ct,,,N,Y
624,Trailer Park,Trailer Pk,,,N,Y
628,Transmission Line,Trans Ln,,,N,Y
702,Treatment Plant,Trmt Plant,,,Y,Y
630,Tribal Road,Tribal Rd,,,Y,N
632,Trolley,Trolley,,,Y,Y
633,Truck Trail,Truck Trl,,,Y,Y
636,Túnel,Túnel,Yes,Tunnel,Y,N
634,Tunnel,Tunl,,,Y,Y
635,Turnpike,Tpke,,,N,Y
637,Underpass,Upas,,,Y,Y
642,Universidad,Universidad,Yes,University/College,Y,N
643,University,Univ,,,Y,Y
638,US Forest Service Highway,USFS Hwy,,,Y,N
639,US Forest Service Road,USFS Rd,,,Y,N
640,US Highway,US Hwy,,,Y,N
641,US Route,US Rte,,,Y,N
644,Valley,Vly,,,N,Y
645,Vereda,Ver,Yes,Path,Y,N
655,Via,Via,Yes,Way,Y,N
646,Viaduct,Viaduct,,,N,Y
647,View,Vw,,,N,Y
648,Villa,Villa,,,Y,Y
649,Village,Vlg,,,Y,Y
650,Village Center,Village Ctr,,,Y,Y
697,Vineyard,Vineyard,,,N,Y
652,Vineyards,Vineyards,,,N,Y
654,Vista,Vis,,,Y,Y
656,Walk,Walk,,,N,Y
657,Walkway,Walkway,,,N,Y
659,Wash,Wash,,,N,Y
660,Waterway,Waterway,,,N,Y
661,Way,Way,,,N,Y
663,Wharf,Wharf,,,N,Y
665,Wild and Scenic River,Wld n Snc Riv,,,N,Y
664,Wild River,Wild River,,,N,Y
666,Wilderness,Wilderness,,,N,Y
667,Wilderness Park,Wilderenss Pk,,,N,Y
668,Wildlife Management Area,Wldlf Mgt Area,,,N,Y
669,Winery,Winery,,,Y,Y
672,Yard,Yard,,,N,Y
673,Yards,Yards,,,Y,Y
670,YMCA,YMCA,,,Y,Y
671,YWCA,YWCA,,,Y,Y
675,Zanja,Zanja,Yes,Ditch,Y,N
676,Zoo,Zoo,,,Y,Y
</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/contourline.wordpress.com/594/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/contourline.wordpress.com/594/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=594&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://contourline.wordpress.com/2012/09/28/appendix-e-feature-name-types-now-as-csv/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0304452093efd125e7dac9cab0d0be5e?s=96&#38;d=monsterid" medium="image">
			<media:title type="html">jmarca</media:title>
		</media:content>
	</item>
		<item>
		<title>Using superagent to authenticate a user-agent in node.js, plus a bonus bug!</title>
		<link>http://contourline.wordpress.com/2012/09/20/using-superagent-to-authenticate-a-user-agent-in-node-js/</link>
		<comments>http://contourline.wordpress.com/2012/09/20/using-superagent-to-authenticate-a-user-agent-in-node-js/#comments</comments>
		<pubDate>Fri, 21 Sep 2012 04:36:53 +0000</pubDate>
		<dc:creator>jmarca</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://contourline.wordpress.com/?p=587</guid>
		<description><![CDATA[Summary This post describes how I use the superagent library to test access to restricted resources on my web server. This is something that I found to take a bit more effort than I expected, so I thought I&#8217;d write &#8230; <a href="http://contourline.wordpress.com/2012/09/20/using-superagent-to-authenticate-a-user-agent-in-node-js/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=587&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<h1>Summary</h1>
<p>This post describes how I use the <a href="http://visionmedia.github.com/superagent">superagent</a> library to test access to restricted resources on my web server. This is something that I found to take a bit more effort than I expected, so I thought I&#8217;d write this up for the greater good.</p>
<h1>Context</h1>
<p>I am running a website in which some resources are open to the internet, while others require authentication versus our <a href="http://www.cas.jasig.org/cas">CAS</a> server.</p>
<p>I have been logging into the CAS server using <a href="https://github.com/mikeal/request">request</a>.  But in the interest of trying out different libraries and all that, I decided to rewrite my<br />
method using superagent.</p>
<p>I need to log into the CAS server from node.js because I am writing tests that verify that the protected resources are hidden to non-authenticated users, and available to authenticated ones.<span id="more-587"></span></p>
<h1>Plot development</h1>
<p>When I first tried superagent, it didn&#8217;t have any way to accept and keep cookies.  Or rather, perhaps it did but it wasn&#8217;t documented. Now it is documented in <a href="https://github.com/visionmedia/superagent#persisting-an-agent-with-cookies-ie-sessions">the github readme</a>. That code is reproduced below:</p>
<pre class="brush: jscript; title: ; notranslate">
var superagent = require('superagent');
var user1 = superagent.agent();
user1
  .post('http://localhost:4000/signin')
  .send({ user: 'hunter@hunterloftis.com', password: 'password' })
  .end(function(err, res) {
    // user1 will manage its own cookies
    // res.redirects contains an Array of redirects
  });
</pre>
<p>My situation is slightly more complicated.  First, the CAS server expects to interact with a human on a web page, so it buries secret messages in the form fields in the generated login page.  For example:</p>
<pre class="sourceCode html"><code class="sourceCode html"><span class="kw">&lt;input</span><span class="ot"> type=</span><span class="st">&quot;hidden&quot;</span><span class="ot"> value=</span><span class="st">&quot;e1s1&quot;</span><span class="ot"> name=</span><span class="st">&quot;lt&quot;</span><span class="kw">&gt;</span>
<span class="kw">&lt;input</span><span class="ot"> type=</span><span class="st">&quot;hidden&quot;</span><span class="ot"> value=</span><span class="st">&quot;submit&quot;</span><span class="ot"> name=</span><span class="st">&quot;_eventId&quot;</span><span class="kw">&gt;</span></code></pre>
<p>Even more irritating, the CAS server implementation that we are running apparently only responds to known user agents.  It plays nicely with Firefox and curl, but it pukes and throws an error when<br />
confronted with node.js libraries such as request or superagent.  So one has to remember to lie about the user agent. </p>
<h1>Rising action</h1>
<p>The first step is to get the login page, as performed by the following code block</p>
<pre class="brush: jscript; title: ; notranslate">
var ua = superagent.agent()
ua.get(casurl)
  .set('User-Agent','Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0')
  .end(_login_handler(ua,function(err,res){
                         if(err) return callback(err)
                         var success_reged=/Log In Successful/i;
                         if(success_regex.test(res.text)){
                             return callback()
                         }else{
                             return callback(new Error('CAS login failed'))
                         }
                      })
      )
</pre>
<p>The login page itself is passed to the function generated by the call to <code>_login_handler()</code>, which is reproduced below.  In this case, I am setting up a test, so I know the user and the user&#8217;s password, defined by <code>cas_user</code> and <code>cas_pass</code>.</p>
<pre class="brush: jscript; title: ; notranslate">
function _login_handler(ua,callback){
    return function(err,res){
        if(err) return callback(err)
        // parse the body for the form url, with the correct jsessionid
        var form_regex = /id=&quot;fm1&quot;.*action=&quot;(.*)&quot; method=&quot;post&quot;/;
        var result = form_regex.exec(res.text)
        var url='https://'+cashost+result[1]

        var form={'username':cas_user
                  ,'password':cas_pass
                  ,'submit':'LOGIN'
                  }

        // scrape hidden input values
        var name_regex = /name=&quot;(.*?)&quot;/
            var value_regex = /value=&quot;(.*?)&quot;/
            var hidden_regex = /&lt;input.*type=&quot;hidden&quot;.*?&gt;/g
        while ((result = hidden_regex.exec(res.text)) !== null)
        {
            var n = name_regex.exec(result[0])
            var v = value_regex.exec(result[0])
            form[n[1]]=v[1]
        }
        // ready to post
        ua.post(url)
        .type('form')
        .set('User-Agent','Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0')
        .send(form)
        .end(callback)
        return null
    }
}
</pre>
<p>I glossed over the tricky bits that had me stuck through a bunch of tweak-try-fail iterations.  First, every time the agent is used to make a request, the CAS server must be sent the fake user agent header.</p>
<pre class="brush: jscript; title: ; notranslate">
ua.get(casurl)
  .set('User-Agent','Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0')
// ...
// ...
ua.post(url)
  .type('form')
  .set('User-Agent','Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0')
</pre>
<p>Second, superagent must be told to send the hashref of data as text, not as JSON.  This wrinkle I missed entirely until I started reading the <a href="http://visionmedia.github.com/superagent/#get-requests">superagent docs</a> carefully.  The docs clearly state that the default POST transport is JSON:</p>
<blockquote><p>&#8220;Since JSON is undoubtably the most common, it’s the default!&#8221;
</p></blockquote>
<p>The next paragraph down in the docs explains the use of the <code>.type('form')</code> options:</p>
<blockquote><p>To send the data as application/x-www-form-urlencoded simply invoke .type() with “form”, where the default is “json”. This request will POST the body “name=tj&amp;pet=tobi”.
</p></blockquote>
<p>The second call above uses this option to post the login credentials and hidden fields to the CAS server.</p>
<p>With that, if the credentials are correct, the user agent will have an established session with the CAS server that can be verified by each of the web hosts using the CAS authentication system.</p>
<h1>Conflict</h1>
<p>But merely logging in to the CAS server and establishing a session with it is only half of the story.  The main feature that CAS supports is single sign on.  This is achieved in practice as follows.  First, a user logs on to the CAS system somehow.  Then the user agent visits a CAS-protected website.  This website redirects the incoming request to the CAS server, with a query parameter called &#8220;service&#8221;.  If the user agent is already logged in to the CAS server, then the server returns the user to the url defined in the &#8220;service&#8221; query parameter, along with a one-time-use ticket.  The CAS-protected webservice then checks this ticket by sending a request directly to the CAS server to verify that the service ticket it just received from the incoming request is valid.  If it is valid, then the user agent is considered to be an authenticated user.</p>
<p>Unfortunately, this is when I found a bug in SuperAgent that is not present in <a href="https://github.com/mikeal/request">request</a>, and to try to fill the open source bargain, I created a <a href="https://gist.github.com/3764079">test case</a> and opened a <a href="https://github.com/visionmedia/superagent/issues/119">bug report</a>.  I also tried to fix it myself, but it wasn&#8217;t quite as simple as I thought.  Merely copying the headers during the redirect doesn&#8217;t solve the issue.</p>
<h1>Conclusion</h1>
<p>In true postmodern fiction style, there is no real end to this story.  It works to log in to CAS, but it doesn&#8217;t work to establish an authenticated session with a CAS-protected website.  As very similar code works fine using Request, I am returning to using that code, and will perhaps be writing another, similar blog post in the future containing that code.</p>
<h1>Appendix</h1>
<p>For completeness, the chain of functions I use are reproduced below.</p>
<pre class="brush: jscript; title: ; notranslate">
function _login_handler(ua,callback){
    return function(err,res){
        if(err) return callback(err)
        // parse the body for the form url, with the correct jsessionid
        var form_regex = /id=&quot;fm1&quot;.*action=&quot;(.*)&quot; method=&quot;post&quot;/;
        var result = form_regex.exec(res.text)
        var url='https://'+cashost+result[1]

        var form={'username':cas_user
                  ,'password':cas_pass
                  ,'submit':'LOGIN'
                  }

        // scrape hidden input values
        var name_regex = /name=&quot;(.*?)&quot;/
            var value_regex = /value=&quot;(.*?)&quot;/
            var hidden_regex = /&lt;input.*type=&quot;hidden&quot;.*?&gt;/g
        while ((result = hidden_regex.exec(res.text)) !== null)
        {
            var n = name_regex.exec(result[0])
            var v = value_regex.exec(result[0])
            form[n[1]]=v[1]
        }
        // ready to post
        ua.post(url)
        .type('form')
        .set('User-Agent','Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0')
        .send(form)
        .end(callback)
        return null
    }
}


function cas_login_function(ua,callback){

             console.log('hitting '+casurl)

             ua.get(casurl)
             .set('User-Agent','Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/12.0')
             .end(_login_handler(ua
                              ,function(err,res){
                                   if(err) return callback (err)
                                   var success_regex = /Log In Successful/i;
                                   if(success_regex.test(res.text)){
                                       return callback()
                                   }else{
                                       return callback(new Error('CAS login failed'))
                                   }
                               }) )
             return null
         }

// ...

describe('get files with login',function(){
    var agent =  superagent.agent()
    before(function(done){
        cas_login_function(agent,function(err){
            if(err) throw new Error(err)
            done()
        })
    })
    // in all of the following tests, agent is logged in to CAS
    it('should get index.html from /protected_resource'
      ,function(done){
           agent
           .get(rooturl+'/protected_resource')
           .end(function(err,res){
               if(err) return done(err)
               res.ok.should.be.true;
               ...
               return done()
           })
    })
})

</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/contourline.wordpress.com/587/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/contourline.wordpress.com/587/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=587&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://contourline.wordpress.com/2012/09/20/using-superagent-to-authenticate-a-user-agent-in-node-js/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0304452093efd125e7dac9cab0d0be5e?s=96&#38;d=monsterid" medium="image">
			<media:title type="html">jmarca</media:title>
		</media:content>
	</item>
		<item>
		<title>Thinking about data and time</title>
		<link>http://contourline.wordpress.com/2012/09/13/thinking-about-data-and-time/</link>
		<comments>http://contourline.wordpress.com/2012/09/13/thinking-about-data-and-time/#comments</comments>
		<pubDate>Fri, 14 Sep 2012 00:19:08 +0000</pubDate>
		<dc:creator>jmarca</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://contourline.wordpress.com/?p=585</guid>
		<description><![CDATA[Half baked post here, mostly just a note to self. I want to store data and time together, like in the description of Datomic. In face I *have* been doing this for some time, but I want to be more &#8230; <a href="http://contourline.wordpress.com/2012/09/13/thinking-about-data-and-time/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=585&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Half baked post here, mostly just a note to self.</p>
<p><span id="more-585"></span></p>
<p>I want to store data and time together, like in the description of Datomic.  In face I *have* been doing this for some time, but I want to be more formal about it.  </p>
<p>First, all my attempts within PostgreSQL suck.  I end up with massive tables that need to be reduced after the fact and that don&#8217;t really do what I want.</p>
<p>CouchDB&#8217;s document approach is interesting, in that you can store time<br />
stamp in the doc, and/or use the timestamp as part of the doc id, but<br />
it is also annoying&#8230;for a case like vds, I just want to record that<br />
the detector started at some point and stopped at some other point,<br />
but since the stop isn&#8217;t announce, I need to record every time the<br />
detector </p>
<p>Suppose I have a batch of VDS detectors, announced by a file that says that as of that day, all of those detectors are on.  So the next time a new file is received, only the detectors in the file are still on, all the ones not in the file are implicitly off.</p>
<p>But if I am also storing data from all of those detectors at the same time, then in theory at least I should know whether or not the detector is on for any given day.  </p>
<p>Okay, but what about the other metadata, like the segment length, that might change based on other changes in the system but that leave the core facts about the detector (it is on the freeway, at a point in space, collecting data for a bucha lanes) intact?  Those facts need to be written down each time they change, and if there isn&#8217;t a new entry in the new detector listing, then that means that the detector is off and the last state is the penultimate state, and the last day that the detector might have been active and with characteristics is the last day it collected data.</p>
<p>I&#8217;m trying to talk myself out of having to write a date stamp to &#8220;all the detectors not in this file that do not yet have a final active date&#8221;, which seems stupid and inefficient.  And I don&#8217;t think I have to do that.  The facts as of the last update are true until those facts are changed.  The fact that the detector is not in the new detector list is irrelevant because I know that it isn&#8217;t collecting data anymore.</p>
<p>To get the descriptive facts about a detector for a particular day&#8217;s data, all I need to do is get the document from the detector state db that is less than or equal to the day in question.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/contourline.wordpress.com/585/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/contourline.wordpress.com/585/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=585&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://contourline.wordpress.com/2012/09/13/thinking-about-data-and-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0304452093efd125e7dac9cab0d0be5e?s=96&#38;d=monsterid" medium="image">
			<media:title type="html">jmarca</media:title>
		</media:content>
	</item>
		<item>
		<title>Change is good</title>
		<link>http://contourline.wordpress.com/2012/09/06/change-is-good/</link>
		<comments>http://contourline.wordpress.com/2012/09/06/change-is-good/#comments</comments>
		<pubDate>Fri, 07 Sep 2012 05:22:24 +0000</pubDate>
		<dc:creator>jmarca</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://contourline.wordpress.com/?p=582</guid>
		<description><![CDATA[I am super excited by the fact that California has almost approved the use of Google&#8217;s driverless cars on the streets, and I hope the bill gets signed into law.  My excitement has nothing to do with wanting to own &#8230; <a href="http://contourline.wordpress.com/2012/09/06/change-is-good/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=582&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I am super excited by the fact that California has almost approved the use of Google&#8217;s driverless cars on the streets, and I hope the bill gets signed into law.  My excitement has nothing to do with wanting to own one of these cars, and everything to do with studying the impact on traffic.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/contourline.wordpress.com/582/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/contourline.wordpress.com/582/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=582&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://contourline.wordpress.com/2012/09/06/change-is-good/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0304452093efd125e7dac9cab0d0be5e?s=96&#38;d=monsterid" medium="image">
			<media:title type="html">jmarca</media:title>
		</media:content>
	</item>
		<item>
		<title>Reduced parking requirements article</title>
		<link>http://contourline.wordpress.com/2012/08/15/reduced-parking-requirements-article/</link>
		<comments>http://contourline.wordpress.com/2012/08/15/reduced-parking-requirements-article/#comments</comments>
		<pubDate>Wed, 15 Aug 2012 17:16:13 +0000</pubDate>
		<dc:creator>jmarca</dc:creator>
				<category><![CDATA[bikes]]></category>
		<category><![CDATA[transportation]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://contourline.wordpress.com/?p=578</guid>
		<description><![CDATA[There is an article in today&#8217;s LA Times that talks about a move to reduce the parking requirements of various kinds of retail. This is very interesting and could begin to push people to reduce driving. In parallel, there are &#8230; <a href="http://contourline.wordpress.com/2012/08/15/reduced-parking-requirements-article/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=578&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>There is an <a href="http://www.latimes.com/news/local/la-me-0815-parking-ordinance-20120815,0,2276469.story">article</a> in today&#8217;s LA Times that talks about a move to reduce the parking requirements of various kinds of retail.  This is very interesting and could begin to push people to reduce driving.  In parallel, there are a few laws on the books in California that require denser development in order to reduce greenhouse gas emissions.  Now denser development by itself will not reduce greenhouse gas emissions, and may in fact make things worse if everybody keeps driving to exactly what they do now (imagine&#8230;more destinations crammed into a smaller space means more cars on the same streets means more traffic means more emissions).  But, if denser development is paired with reduced parking requirements, there is even more incentive to leave the car home for a trip or two (as there will be nowhere to park it when you get there).<br />
<span id="more-578"></span><br />
The <em>problem</em> with the car is that it is pretty excellent.  In order to get people to substitute some walking and biking for a car trip, the car choice will have to suck a lot more than it currently does.  That can only be accomplished in a few ways: raise the cost or scarcity of parking, toll travel on the roads, raise the price of fuel, or reduce the supply of roadway.  But making driving a little bit worse that it is now won&#8217;t cut it, because here in Southern California all other modes of travel are a lot worse.</p>
<p>I bicycle to work every day, except for the occasional day here or there, and I fully realize how limiting bicycling is.  In a car I would think nothing of making a side trip to the store on the way home, or performing other household errands.  But on a bike, even with an excellent <a href="http://www.rivbike.com" target='rivbike'>Atlantis</a> with racks and bags, running to the store will add 30 minutes of travel time, plus add extra weight that my legs have to propel.  Cars are better, faster, and cheaper for commuting to work, but I prefer to get exercise (and basically I&#8217;m stubborn and have a high tolerance for pain).  </p>
<p>For short trips near our house, the bike should be excellent.  My kids go to school about a mile and a half from our house, and there are restaurants and shops well within a mile of us.  But where I live (Costa Mesa, in Orange County, CA), the parking lots and streets are so heavily car-oriented that my kids are afraid to cross the two major streets that close off our subdivision.  </p>
<p>For example, Google Maps informs me that just 1.6 miles from my house there is a super awesome coffee bar (<a href="http://www.portolacoffeelab.com/" target='portola'>Portola Coffee</a>) right next to a gelato place and some of the best pastries in Orange County.  The problem is that the 1.6 mile route requires cycling on <a href="http://goo.gl/maps/05C0e" target='yuck'>Harbor Boulevard </a>for most of the way.  There is a handy bike path along a flood control channel that we can use, but then the trip becomes 3.1 miles!  Double the distance on a bike is difficult, and a strong disincentive when compared to the fast, easy, cheap, and efficient automobile.  Even bribery with ice cream or pastries won&#8217;t work more than once a month.</p>
<p>Reducing parking requirements is a good baby step towards reducing the relative superiority of the automobile.  I&#8217;m pretty happy that is finally happening, but not much is going to change with respect to emissions and parking lot oriented development without a lot more parallel measures and a lot more citizen led initiatives.  If people are happy in their cars, plain old traffic and difficult parking conditions here and there isn&#8217;t going to get them to walk or bike. I&#8217;m interested to see how OCTA, SCAG, and so on, will increase development density in the coming years.</p>
<p>(And I&#8217;d still like to do some bike touring closer to home than Amsterdam.)</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/contourline.wordpress.com/578/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/contourline.wordpress.com/578/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=contourline.wordpress.com&#038;blog=718724&#038;post=578&#038;subd=contourline&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://contourline.wordpress.com/2012/08/15/reduced-parking-requirements-article/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/0304452093efd125e7dac9cab0d0be5e?s=96&#38;d=monsterid" medium="image">
			<media:title type="html">jmarca</media:title>
		</media:content>
	</item>
	</channel>
</rss>
