<?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>GeoIQ Developer</title>
	<atom:link href="http://developer.geoiq.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://developer.geoiq.com</link>
	<description>GeoIQ Developer site</description>
	<lastBuildDate>Mon, 14 Nov 2011 18:22:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Now with New! Improved! Faster! Intersections!</title>
		<link>http://developer.geoiq.com/blog/2011/11/14/now-with-new-improved-faster-intersections/</link>
		<comments>http://developer.geoiq.com/blog/2011/11/14/now-with-new-improved-faster-intersections/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 13:23:31 +0000</pubDate>
		<dc:creator>Tim Waters</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://developer.geoiq.com/?p=1460</guid>
		<description><![CDATA[<p></p> <p>Some of you were noticing that the Intersection analysis was a bit slow and we noticed that it was using quite a lot of memory &#8211; the larger the dataset, the worse it performed. We tackled this head on and have rolled out a much better algorithm, which, I&#8217;ve measured as being between 7 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://developer.geoiq.com/wp-content/uploads/2011/11/ref.intersect.png" alt="" title="intersect" width="64" height="64" class="alignnone size-full wp-image-1461" /></p>

<p>Some of you were noticing that the Intersection analysis was a bit slow and we noticed that it was using quite a lot of memory &#8211; the larger the dataset, the worse it performed. We tackled this head on and have rolled out a much better algorithm, which, I&#8217;ve measured as being between 7 to 10 times quicker! It&#8217;s much more zippier now.</p>

<p>The Intersection analysis determines all the locations where one data set overlaps another data set on the map.</p>

<p>For instance you have some areas representing counties and areas representing the pollution plume, that crosses the counties by performing an intersection analysis, you can get new unique areas that represent the bits of counties that are under the pollution plume. It&#8217;s pretty powerful.    </p>

<p>Or you might want to see all the Coffee Shops that overlap with the &#8220;.75 mile buffer of Metro stations&#8221; data set. To run this analysis once you have selected &#8220;2008 usa starbucks locations&#8221; then click &#8220;select second data set&#8221; and search for metro and add &#8220;Dataset from DC Metros Stations with a .75 mile buffer&#8221;. </p>



<p>How we do it? We basically only calculate the intersection of the features if they share the same area.</p>

<p>For the geo-techies amongst you, the procedure goes we use goes as follows:</p>

<p>1. create spatial index for  dataset 1 features<br />
2. loop over dataset 2 features<br />
3. when current dataset 2  feature intersects with dataset 1 index, then<br />
4. for all the features that are intersected, get the intersection<br />
5. if there&#8217;s any errors, try to fix them<br />
6. rinse, repeat</p>


<p> </p>]]></content:encoded>
			<wfw:commentRss>http://developer.geoiq.com/blog/2011/11/14/now-with-new-improved-faster-intersections/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Leaflet &amp; GeoCommons JSON</title>
		<link>http://developer.geoiq.com/blog/2011/10/31/leaflet-geocommons-json/</link>
		<comments>http://developer.geoiq.com/blog/2011/10/31/leaflet-geocommons-json/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 12:18:02 +0000</pubDate>
		<dc:creator>Tim Waters</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://developer.geoiq.com/?p=1344</guid>
		<description><![CDATA[<p>Hi, in this quick tutorial we will have a look at a new JavaScript mapping library, <a href="http://leaflet.cloudmade.com/">Leaflet</a> using it to help load JSON features from a <a href="http://geocommons.com/">GeoCommons</a> dataset. We will add our <a href="http://developer.geoiq.com/tools/acetate/">Acetate</a> tile layer to the map, and use the cool API feature filtering functionalities to get just the features we [...]]]></description>
			<content:encoded><![CDATA[<p>Hi, in this quick tutorial we will have a look at a new JavaScript mapping library, <a href="http://leaflet.cloudmade.com/">Leaflet</a> using it to help load <span class="caps">JSON </span>features from a <a href="http://geocommons.com/">GeoCommons</a> dataset. We will add our <a href="http://developer.geoiq.com/tools/acetate/">Acetate</a> tile layer to the map, and use the cool <span class="caps">API </span>feature filtering functionalities to get just the features we want from the server, show them on a Leaflet map, add popups to the features, style the features according to what the feature is, and add some further interactivity. This blog follows up from two posts on my personal blog, showing GeoCommons features with <a href="http://thinkwhere.wordpress.com/2011/06/26/geocommons-geojson-in-openlayers/">OpenLayers</a> and <a href="http://thinkwhere.wordpress.com/2011/08/02/pubs-in-england-how-to-do-it-with-polymaps-and-geocommons-filters/">with Polymaps</a>. </p>

<p><img src="http://developer.geoiq.com/wp-content/uploads/2011/10/e32595ad444b71a872817e01a0f9758a.png" alt="" title="Leaflet with geoiq geocommons geojson" width="710" height="531" class="alignnone size-full wp-image-1345" /></p>

<p>The dataset we will use is <a href="http://geocommons.com/overlays/168923">Leeds Buildings 2011</a>  &#8211; it&#8217;s shows all the buildings in the District of Leeds, <span class="caps">UK, </span>that were in the OpenStreetMap database as of July 2011. I made it from the England shapefile export from <a href="http://www.geofabrik.de">GeoFabrik.de</a>, and can highly recommend checking out the download pages at <a href="http://www.geofabrik.de/data/download.html">GeoFabrik</a> if you want to play with some OpenStreetMap data yourself. </p>

<p>Leaflet is a modern, lightweight <span class="caps">BSD</span>-licensed JavaScript library for making tile-based interactive maps for both desktop and mobile web browsers, developed by CloudMade. I think it&#8217;s pretty nice, and they have <a href="http://leaflet.cloudmade.com/examples.html">some good examples</a>. I&#8217;d be interested to hear if you can view this map with mobile devices.</p>

<br /><br />
<h3> Get Leaflet. </h3>

<p>First go ahead an get Leaflet from <a href="http://leaflet.cloudmade.com/">http://leaflet.cloudmade.com/</a>. Make sure you add on your page the link to the correct js file in the dist directory.</p>

<br /><br />
<h3> Make a Map </h3>

<p>We set up everything on the init function called by the body onload event.  <code>var myMap = new L.Map('map');</code> sets everything up with a div in the body with the id as &#8220;map&#8221; <code>&lt;div id=&quot;map&quot; style=&quot;height: 90%;&quot;&gt;&lt;/div&gt; </code></p>

<br /><br />
<h3> Add Acetate tile layer</h3>

<p>Acetate is the result of GeoIQ&#8217;s set of Mapnik stylesheets and algorithms to create good quality basemaps especially for overlaying data on top.<br />
It&#8217;s a tile layer, and tile layers are usually defined according to the <span class="caps">ZXY </span>scheme.  An example tile <span class="caps">URL </span>would be http://a2.acetate.geoiq.com/tiles/acetate/13/4059/2638.png</p>



<pre><code>var acetateUrl =  'http://{s}.acetate.geoiq.com/tiles/acetate/{z}/{x}/{y}.png';
var acetateAttrib = '2011 GeoIQ &amp;#038; Stamen, Data from OSM and Natural Earth';
var acetate = new L.TileLayer(acetateUrl, {maxZoom: 18, attribution: acetateAttrib, subdomains: ['a1', 'a2', 'a3']});
</code></pre>



<p>The first line, we define the pattern for Leaflet to understand. The second line defines the attribution to show with the layer, and the last line, creates the TileLayer and passed in some options, the main thing here is the use of the {s} variable in the url and the subdomains option. {s} will be replaced with a1, a2 or a3, to create a proper image, like above.</p>



<pre><code>var leeds = new L.LatLng(53.796, -1.551);
myMap.setView(leeds, 14).addLayer(acetate);
</code></pre>



<p>Now we create a LatLng object, centred over Leeds, <span class="caps">UK, </span>and then set the view for the map, and method chain adding the acetate layer to it. Once you&#8217;ve done this, you will actually see a map!</p>

<br /><br />
<h3> GeoiQ Features <span class="caps">API </span>&#038; Get <span class="caps">JSON</span> Features </h3>

<p>The <a href="http://geocommons.com/help/REST_API#Features-API">features <span class="caps">REST API</span></a> allows a developer to get all the features within a radius, specifying the lat lon of the centre of the radius and the distance.</p>


<pre><code>var geojsonLayer = new L.GeoJSON();

var url = &quot;http://geocommons.com/datasets/168923/features.json?lat=53.796&amp;amp;lon=-1.551&amp;amp;radius=3&amp;amp;callback=?&quot;; 

jQuery.getJSON(url, function(data){
	jQuery.each(data, function(i,f) {
		f.properties = {name: f.name, osm_id: f.osm_id, type: f.type};
		f.type = &quot;Feature&quot;;
		// Now Push into geojson layer each feature
		geojsonLayer.addGeoJSON(f);
	});
});

myMap.addLayer(geojsonLayer);</code></pre>



<p><em>lat=53.796&amp;lon=-1.551&amp;radius=3</em> Is our spatial filtering. It says, given a point at Lat 53.796 and Lon -1.551, give me all the features within a radius of 3KM. Interestingly, we can also use the units param to specify the units of distance, if you like your imperial units!</p>

<p>I&#8217;m using JQuery here, as it&#8217;s got some nice helpers. This grabs the <span class="caps">JSON, </span>and loops over the features, adding features to the geojson layer. Using the addGeoJSON method call.</p>

<p>Did you know that the features <span class="caps">API </span>also has the ability to filter by many different ways, for example by polygon, and by buffered polygon? <code> polygon=-77,34,-78.5,34.5,-82,32,-79,30,-77,34&amp;amp;radius=100</code>. I particularly like the filter functionality. In our example, we could have just filtered the map to just show hospital buildings.<br />
<code>http://geocommons.com/datasets/168923/features.json?filter[type][][equals]=hospital&amp;amp;callback=?</code></p>

<br /><br />
<h3> Add popup </h3>

<p>We have to use the featureparse event on the geojsonLayer, and specify this before any things are added to the map.</p>


<pre><code>geojsonLayer.on(&quot;featureparse&quot;, function (e) {
if (e.properties &amp;#038;&amp; e.properties.name){
   e.layer.bindPopup(e.properties.name +&quot;&lt;br /&gt;&quot;+e.properties.type);
}
</code></pre>



<p>The featureparse event is called just before features are added to the layer. Here it&#8217;s looking at the feature, and if it has a name in the properties, then to create a popup, showing the name and type </p>

<br /><br />
<h3> Add click handler </h3>

<p>We add a click handler within the same feature parse event handler. </p>



<pre><code>
if (e.properties &amp;#038;&amp; e.properties.osm_id) {
 e.layer.on('click', function(ee){
   Query(&quot;.info&quot;).html(&quot;&lt;a href='http://www.openstreetmap.org/browse/way/&quot; +
   e.properties.osm_id+&quot;'&gt;OSM ID: &quot;+e.properties.osm_id + &quot;&lt;/a&gt;&lt;em&gt; Name: &lt;/em&gt;&quot;+
   e.properties.name + &quot;  (&lt;em&gt;type: &lt;/em&gt;&quot; +e.properties.type+&quot;)&quot;);
 });
 }
</code></pre>



<p>Here, we use a bit of Jquery to update the value of a div with the details of the feature. It shows the osm id, and a link to the openstreetmap website for that feature, and some values.</p>

<br /><br />
<h3> Add categorical styling </h3>

<p>This bit is a bit more complex, but essentially, the <span class="caps">SVG </span>features are styled using <span class="caps">CSS, </span>and can be styled accordingly. Within the same featureparse event handler, again, set up before features are added to the layer, we look to see if the feature has a type (like, hospital, retail etc), and if it has, then it&#8217;s given a style. We only really change the style colour. </p>



<pre><code>
if (e.properties &amp;#038;&amp; e.properties.type &amp;#038;&amp; e.layer.setStyle){
      var color = &quot;#334DCC&quot;;
      var t = e.properties.type;
      var colormap = {
        &quot;hospital&quot;:&quot;#CC3399&quot;,
        &quot;residential&quot;:&quot;#CC6633&quot;,
        &quot;house&quot;:&quot;#CCB333&quot;,
        &quot;school&quot;:&quot;#99CC33&quot;,
        &quot;retail&quot;:&quot;#D864B1&quot;,
        &quot;commercial&quot;:&quot;#006600&quot;};
      
      color = colormap[t] || color;

 e.layer.setStyle({&quot;color&quot;:color,&quot;weight&quot;: 2,&quot;opacity&quot;: 1 });
}
</code></pre>



<br /><br />
<h3> Give it a go! </h3>

<p>Try out <a href="http://geothings.net/geoiq/geoiq_leaflet.htm">the playable demo</a>, and if you want you can <a href="https://gist.github.com/1327318">have a look at the code</a> too.<br />
All the code can be found here:<br />
And a playable dem</p>]]></content:encoded>
			<wfw:commentRss>http://developer.geoiq.com/blog/2011/10/31/leaflet-geocommons-json/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Lazy Developer’s Guide to Loading Datasets into GeoCommons</title>
		<link>http://developer.geoiq.com/blog/2011/10/28/the-lazy-developer%e2%80%99s-guide-to-loading-datasets-into-geocommons/</link>
		<comments>http://developer.geoiq.com/blog/2011/10/28/the-lazy-developer%e2%80%99s-guide-to-loading-datasets-into-geocommons/#comments</comments>
		<pubDate>Fri, 28 Oct 2011 13:06:49 +0000</pubDate>
		<dc:creator>semprebon</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://developer.geoiq.com/?p=1364</guid>
		<description><![CDATA[Loading KML Files So lets say you have a bunch of kml files you want to load into Geocommons. Of course, its fairly easy to load these through the web UI, but if you need to do this often enough, it would be nice to have a program to do it for you &#8211; after [...]]]></description>
			<content:encoded><![CDATA[<div>
<h2>Loading <span class="caps">KML</span> Files</h2>
So lets say you have a bunch of kml files you want to load into Geocommons. Of course, its fairly easy to load these through the web <span class="caps">UI, </span>but if you need to do this often enough, it would be nice to have a program to do it for you &#8211; after all, as <a href="http://en.wikipedia.org/wiki/Larry_Wall">Larry Wall</a> said, laziness is one of the <a href="http://c2.com/cgi/wiki?LazinessImpatienceHubris">three virtues</a> of great programmers.

<p><br />Frankly, its not exactly obvious from our <a href="http://developer.geoiq.com/api/"><span class="caps">API </span>documentation</a> what the best way to do this is. And if you aren&#8217;t familiar with Curl, the examples are probably not going to help you much, so I&#8217;ll be doing this code in Java. Of course, we here at GeoIQ are Ruby programmers, and thus have a natural disdain for anything to do with Java, so I&#8217;m probably losing serious Ruby street cred just posting this, but anything for the good of the cause. We will be using the occasionally obtuse Geocommons <span class="caps">REST API, </span>but I&#8217;ll try to steer you around some of the not so obvious pitfalls.</p>

<p>The basic idea of the program is that you would run it from the command line, passing in your login, password, and a directory. It then scans the directory for <span class="caps">KML </span>files and uploads them to geocommons. Fortunately, Java elegantly handled getting the files using a FileFilter:</p>


<pre><code>public class Loader {

    public static void main(String[] args) {
        for (String filePath: kmlFilesIn(dirPath)) {
            // load file here
        }
    }

    /**
     * Determines if file will be uploaded
     *
     * @param dirPath path to file
     * @return array of filenames for kml files in specified directory
     */
    private static String[] kmlFilesIn(String dirPath) {
        String[] filePaths = new File(dirPath).list(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.endsWith(&quot;.kml&quot;);
            }
        });
        if (filePaths == null) {
            throw new RuntimeException( &quot;Invalid directory: &quot; + dirPath);
        }
        return filePaths;
    }
}
</code></pre>


<code> </code><br />
<h2><span class="caps">POST</span>ing the file</h2>
So far, its pretty basic Java stuff. Lets start implementing the Loader itself. The first thing we need to do is submit a <span class="caps">POST </span>request to geocommons with our kml data. Looking at the <span class="caps">API </span>examples, there is nothing about sending kml. There is this cryptic curl example for csv:<br />
<br />

<pre><code>cat 98633.csv | curl -i -X POST -u &quot;username:password&quot; --data-binary @- -H &quot;Content-Type: text/csv&quot; http://geocommons.com/datasets.json</code></pre>

<p><br /><br />
You might think we could do something similar and send the raw kml data in the post with the content type set to &#8220;application/vnd.google-earth.kml+xml&#8221;, but I&#8217;m not sure this will work. Even if it did, as a general approach, it has some major shortcomings &#8212; for example, you can&#8217;t send any other data in the request. Instead, we will be sending the data as if it came from a form, with a Content Type of &#8220;multipart/form-data&#8221;. While it may be more complex at first, it can be used in virtually all cases where we are <span class="caps">POST</span>ing or <span class="caps">PUT</span>ing data to GeoCommons.</p>

<p>For some reason, multipart form data &Acirc;&nbsp;doesn&#8217;t seem to well supported in Java&#8217;s networking libraries (or Ruby&#8217;s, for that matter). The code to do format multi-part form data isn&#8217;t particularly hard to write, but can be a little tedious to get correct, particularly if you can&#8217;t see what&#8217;s happening on the server side. Instead we&#8217;ll be using the <a href="http://hc.apache.org/index.html">HttpComponents project</a> from Apache. You can download HttpCore and HttpClient (I got versions 4.1.3 and 4.1.2 respectively) <a href="http://hc.apache.org/downloads.cgi">from here</a>.</p>

<p>So, lets add a method to our class to post a file:</p>


<pre><code>/**
 * Posts a file to a given URL
 *
 * @param url URL string to post to
 * @param file file to post
 * @return location returned
 * @throws LoaderException if we don't get a good response from the server
 * @throws Exception if file fails to load
 */
private String post(String url, File file) throws IOException, LoaderException {
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost request = new HttpPost(url);
    MultipartEntity entity = new MultipartEntity();

    entity.addPart(&quot;dataset[kml]&quot;, new FileBody(file));
    request.setEntity(entity);
    HttpResponse response = httpclient.execute(request);
    if (response.getStatusLine().getStatusCode() == 201) {
        return response.getFirstHeader(&quot;Location&quot;).getValue();
    } else {
        throw new LoaderException(&quot;Failed to process file: &quot;
            + EntityUtils.toString(response.getEntity()));
    }
}
</code></pre>


<p><br />Basically, we create HttpClient and HttpPost objects, add our file, submit the request, and handle the response. In handling the response, we have a couple of options. When you <span class="caps">POST </span>a new object to GeoCommons, it should respond with a representation of the data posted (based on the extension you gave in the url, &#8220;json&#8221; in this case). I recommend in most cases getting your response as json, since it is handled more consistently across the GeoCommons <span class="caps">API.</span> In addition to the <span class="caps">JSON, </span>the response will have a <span class="caps">URL </span>in the &#8220;Location&#8221; header you can use as an <span class="caps">HTTP </span>end-point for further <span class="caps">REST </span>requests. Since 90% of the time we are going to need that <span class="caps">URL </span>for reasons that will be come obvious later, this method return the <span class="caps">URL </span>rather than parsing the <span class="caps">JSON </span>content.</p>

<p>You might be wondering what is in that <span class="caps">JSON </span>response:</p>


<pre><code>{ &quot;success&quot;: true, &quot;state&quot;: &quot;processing&quot;, &quot;id&quot;: 1234, &quot;title&quot;: &quot;myfile&quot;, &quot;desc&quot;: &quot;&quot; }</code></pre>

<p><br /><br />
The two important fields here are the id, which you are going to need to do things like add a dataset to a map, and the state, which will be described later. You can actually get the id from the <span class="caps">URL </span>in the location field (or vice-versa), since it would just be &#8220;http://geocommons.com/1234.json&#8221;.</p>

Unfortunately, if we try submitting this request, we will get a 401 &#8211; Not Authorized. Only registered users can upload data. We need to identify who we are before we can post a request.<br />
<br /><h2>Authenticating</h2>
There are a number of options for authenticating with GeoCommons. For now, we&#8217;ll be using Http Basic Authentication, because its easy to implement. Unfortunately, its not very secure. Maybe in some future blog post I&#8217;ll cover other authentication methods.

<p><br />HttpClient seems to have support for doing authentication, but after half an hour of searching the <a href="http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/index.html">JavaDocs</a>, reading the <a href="http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientAuthentication.java">examples</a>, and trying out code, I was unable to figure out how its supposed to work. Fortunately, all we really need to do for Basic Authentication is set &Acirc;&nbsp;a header in the request with the username and password encoded using <a href="http://en.wikipedia.org/wiki/Base64">Base64 encoding</a>, so we can skip all those confusing authentication classes and just do:</p>


<pre><code>/**
 * Add basic authentication header to request
 *
 * @param request
 */
private void addAuthentication(HttpRequestBase request) {
    String usernamePassword = login + &quot;:&quot; + password;
    String encodedUsernamePassword
 = DatatypeConverter.printBase64Binary(usernamePassword.getBytes());
    request.addHeader(&quot;Authorization&quot;, &quot;Basic &quot; + encodedUsernamePassword);
}
</code></pre>


<code> </code><br />
<h2>Waiting for Completion</h2>
The processing of an uploaded file can be a time-consuming process, particularly for large files. If the process takes too long, the Http server (Apache) will eventually time out the request. Rather than having clients keep the <span class="caps">HTTP </span>connection open, and risk a timeout, GeoCommons will in many cases process the file asynchronously. This means your <span class="caps">POST </span>request will come back with a response before the file has completed processing. Before you do anything else with that file (except maybe deleting it), you need to check to see if processing is complete. This is done by sending a <span class="caps">GET </span>request to the <span class="caps">URL </span>we got back from our post method.

<br />The response will be a <span class="caps">JSON </span>object, somewhat similar to the one we got back from the original <span class="caps">POST </span>request, but possibly with more fields in it. At this point, we are only interested in the state. For our purposes, there are four possible values:<br />
<br /><ul>
	<li>complete &#8211; we&#8217;re done with this file, and can move on</li>
	<li>processing &#8211; GeoCommons is still processing the file, we need to wait</li>
	<li>errored &#8211; Some unrecoverable error occurred; we&#8217;re done with the file, but should inform the user</li>
	<li>anything else &#8211; Geocommons stopped processing the file, and its now in some intermediate state waiting for further input.</li>
</ul>
For the &#8220;anything else&#8221; case, the files will show up in your &#8220;pending datasets&#8221; tab, waiting for you to enter more info (geocoding method, title, etc). For our purposes, we&#8217;ll treat this the same as &#8220;complete&#8221;, since this doesn&#8217;t happen as much with kml (they generally have all the metadata the system needs) and there isn&#8217;t much we can do anyway.

<p><br />Unfortunately, Java (at least as of version 1.6) doesn&#8217;t have a built in library for parsing <span class="caps">JSON, </span>but as usually, there are a ton of third party libraries that will do <span class="caps">JSON </span>just fine. Being a simple person, I ended up using <a href="http://code.google.com/p/json-simple/">json-simple</a>. You can download version 1.1 <a href="http://code.google.com/p/json-simple/downloads/list">from here</a>.</p>

<p>So, our code to check the state of the dataset looks like:</p>


<pre><code>/**
 * Checks the specified dataset url to see if the dataset has completed.
 *
 * @throws IOException in the unlike event that the response can't be processed
 * @throws LoaderException if we don't get a good response from the server or geocommons
 * has a problem with the file
 */
private boolean isComplete(String url) throws IOException, LoaderException {
    String datasetJson = get(url);
    JSONObject dataset = (JSONObject) JSONValue.parse(datasetJson);
    String state = (String) dataset.get(&quot;state&quot;);
    if (state.equals(&quot;errored&quot;)) {
        throw new LoaderException(&quot;Error processing file&quot;);
    }
    return !state.equals(&quot;processing&quot;);
}

/**
 * Sends a GET request to a URL, and returns the response body as a string
 *
 * @param url url to get
 * @return string representing the response content
 * @throws IOException in the unlikely event that the response body can't be processed
 * @throws LoaderException if we don't get a good response from the server
 */
private String get(String url) throws IOException, LoaderException {
    HttpClient httpclient = new DefaultHttpClient();
    HttpGet request = new HttpGet(url);
    addAuthentication(request);
     HttpResponse response = httpclient.execute(request);
     if (response.getStatusLine().getStatusCode() == 200) {
         return EntityUtils.toString(response.getEntity());
     } else {
         throw new LoaderException(
             &quot;Failed to get dataset: &quot; + UntityUtils.toString(response.getEntity()));
     }
}
</code></pre>


<p><br />We are sending the <span class="caps">GET </span>request, then parsing the response content as <span class="caps">JSON </span>and pulling out the &#8220;state&#8221; property.</p>

<p>Putting it all together, the loader will now load each file, wait until it finishes loading, then move on to the next</p>


<pre><code>/**
 * Loads multiple kml files to GeoCommons.
 *
 * This program will upload all kml files in the specified directory to geocommons.
 *
 * To run:
 *
 * java com.geoiq.Loader mylogin mypassword /dir/to/files
 */
package com.geoiq;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

import javax.xml.bind.DatatypeConverter;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

public class Loader {

    public static final String SITE_URL = &quot;http://geocommons.com&quot;;

    private String login;
    private String password;

    public Loader(String login, String password) {
        this.login = login;
        this.password = password;
    }

    /**
     * @param args command line arguments
     *
     * args[0] - geocommons login
     * args[1] - geocommons password
     * args[2] - directory
     */
    public static void main(String[] args) {
        String login = args[0];
        String password = args[1];
        String dirPath = args[2];

        Loader loader = new Loader(login, password);

        for (String filePath: kmlFilesIn(dirPath)) {
            loader.load(new File(dirPath, filePath));
        }
    }

    /**
     * Determines if file will be uploaded
     *
     * @param dirPath path to file
     * @return array of filenames for kml files in specified directory
     */
    private static String[] kmlFilesIn(String dirPath) {
        String[] filePaths = new File(dirPath).list(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                return name.endsWith(&quot;.kml&quot;);
            }
        });
        if (filePaths == null) {
            throw new RuntimeException( &quot;Invalid directory: &quot; + dirPath);
        }
        return filePaths;
    }

    /**
     * Loads the specified kml file to geocommons, tracking state until load completes
     *
     * @param file file to load
     */
    public void load(File file) {
        System.out.println(&quot;loading&quot; + file.getPath());
        try {
            String url = post(SITE_URL + &quot;/datasets.json&quot;, file);
            while (!isComplete(url)) {
                Thread.sleep(3000);
            }
        } catch (LoaderException e) {
            System.err.println(&quot;Failed to load &quot; + file.getPath());
                e.printStackTrace(System.err);
            } catch (IOException e) {
            System.err.println(&quot;Failed to load &quot; + file.getPath());
            e.printStackTrace(System.err);
        } catch (InterruptedException e) {
            System.err.println(&quot;Interrupted&quot;);
        }
    }

    /**
     * Checks the specified dataset url to see if the dataset has completed.
     *
     * @throws IOException in the unlike event that the response can't be processed
     * @throws LoaderException if we don't get a good response from the server or
     * geocommons has a problem with the file
     */
    private boolean isComplete(String url) throws IOException, LoaderException {
        String datasetJson = get(url);
        JSONObject dataset = (JSONObject) JSONValue.parse(datasetJson);
        String state = (String) dataset.get(&quot;state&quot;);
        if (state.equals(&quot;errored&quot;)) {
            throw new LoaderException(&quot;Error processing file&quot;);
        }
        return !state.equals(&quot;processing&quot;);
    }

    /**
     * Sends a GET request to a URL, and returns the response body as a string
     *
     * @param url url to get
     * @return string representing the response content
     * @throws IOException in the unlikely event that the response can't be processed
     * @throws LoaderException if we don't get a good response from the server
     */
    private String get(String url) throws IOException, LoaderException {
        HttpClient httpclient = new DefaultHttpClient();
        HttpGet request = new HttpGet(url);
        addAuthentication(request);
        HttpResponse response = httpclient.execute(request);
        if (response.getStatusLine().getStatusCode() == 200) {
            return EntityUtils.toString(response.getEntity());
        } else {
            throw new LoaderException(
                &quot;Failed to get dataset: &quot; + EntityUtils.toString(response.getEntity()));
        }
    }

    /**
     * Posts a file to a given URL using basic authentication
     *
     * @param url URL string to post to
     * @param file file to post
     * @return location returned
     * @throws LoaderException if we don't get a good response from the server
     * @throws Exception if file fails to load
     */
    private String post(String url, File file) throws IOException, LoaderException {
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost request = new HttpPost(url);
        addAuthentication(request);	 

        MultipartEntity entity = new MultipartEntity();
        entity.addPart(&quot;dataset[kml]&quot;, new FileBody(file));
        request.setEntity(entity);
        HttpResponse response = httpclient.execute(request);
        if (response.getStatusLine().getStatusCode() == 201) {
            return response.getFirstHeader(&quot;Location&quot;).getValue();
        } else {
            throw new LoaderException(
                &quot;Failed to process file: &quot; + EntityUtils.toString(response.getEntity()));
        }
    }

    /**
     * Add basic authentication header to request
     *
     * @param request
     */
    private void addAuthentication(HttpRequestBase request) {
        String usernamePassword = login + &quot;:&quot; + password;
        String encodedUsernamePassword
            = DatatypeConverter.printBase64Binary(usernamePassword.getBytes());
        request.addHeader(&quot;Authorization&quot;, &quot;Basic &quot; + encodedUsernamePassword);
    }

    /**
     * Exception thrown when geocommons doesn't behave as expected.
     */
    private static class LoaderException extends Exception {
        private static final long serialVersionUID = 1L;

        public LoaderException(String messge) {
            super(messge);
        }
    }
}
</code></pre>


</div>]]></content:encoded>
			<wfw:commentRss>http://developer.geoiq.com/blog/2011/10/28/the-lazy-developer%e2%80%99s-guide-to-loading-datasets-into-geocommons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GEOS &#8211; library for spatial magic</title>
		<link>http://developer.geoiq.com/blog/2011/06/15/geos-library-for-spatial-magic/</link>
		<comments>http://developer.geoiq.com/blog/2011/06/15/geos-library-for-spatial-magic/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 13:21:26 +0000</pubDate>
		<dc:creator>Tim Waters</dc:creator>
				<category><![CDATA[Analysis]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[geos]]></category>
		<category><![CDATA[jts]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[spatial]]></category>

		<guid isPermaLink="false">http://developer.geoiq.com/?p=1049</guid>
		<description><![CDATA[<p>We use <a href="http://trac.osgeo.org/geos/">GEOS</a> here in GeoIQ Towers, and love how powerful it is. If you are into your geospatial applications and you&#8217;ve never heard of it, you may well have heard of other applications that use it &#8211; such as <a href="http://www.postgis.org/">PostGIS</a>,  <a href="http://mapserver.org/">Mapserver</a>, <a href="http://grass.itc.it/">GRASS</a>, <a href="http://geodjango.org/">GeoDjango</a> and <a href="http://www.safe.com/">FME</a>. We use it [...]]]></description>
			<content:encoded><![CDATA[<p>We use <a href="http://trac.osgeo.org/geos/">GEOS</a> here in GeoIQ Towers, and love how powerful it is. If you are into your geospatial applications and you&#8217;ve never heard of it, you may well have heard of other applications that use it &#8211; such as <a href="http://www.postgis.org/">PostGIS</a>,  <a href="http://mapserver.org/">Mapserver</a>, <a href="http://grass.itc.it/">GRASS</a>, <a href="http://geodjango.org/">GeoDjango</a> and <a href="http://www.safe.com/">FME</a>. We use it a lot behind the scenes in our suite of geospatial analysis tools &#8211; <a href="http://blog.geoiq.com/2011/06/14/geoanalytics-for-the-masses/">tools that anyone can use</a> now on<a href="http://geocommons.com"> GeoCommons.com</a></p>
<p><img class="alignnone" src="http://tsusiatsoftware.net/jts/images/example-intersection.gif" alt="" width="192" height="166" /></p>
<p>It&#8217;s a C port of the <a href="http://sourceforge.net/projects/jts-topo-suite/">Java Topology Suite</a> but they both do the same things very well &#8211; basically they do spatial functions for processing geometries.</p>
<h2>What does it do?</h2>
<p>The kinds of things it can do include:</p>
<ul>
<li>Supports all OGC Geometry types, like Points, Polygons etc</li>
<li>Area calculations</li>
<li>Distance between geometries</li>
<li>Point in polygon calculations</li>
<li>Intersects, overlaps, touches, contains operations</li>
<li>Buffer, difference, union</li>
<li>Geometry simplification</li>
</ul>
<p>And we use it for pretty much all of the above!</p>
<h2>How to get it</h2>
<p>Since we use Ruby, we use the GEOS Ruby Bindings. I get mine from the <a href="https://launchpad.net/~ubuntugis">UbuntuGIS repository</a> and install the libgeos-ruby1.8 package (and the associated dependencies). I&#8217;m assuming you would know how to go ahead and get it.</p>
<p>You can also try out the <a href="https://github.com/dark-panda/ffi-geo">newer FFI bindings for GEOS</a> and let me know how you get on, and you can also use JTS with JRuby if you feel like it too!</p>
<h2>
<p><div class="wp-caption alignnone" style="width: 510px"><img src="http://farm6.static.flickr.com/5219/5533414164_18a97485ab.jpg" alt="" width="500" height="375" /><p class="wp-caption-text">Donut Photo by http://www.flickr.com/photos/amylovesyah/</p></div></h2>
<h2>How to use it</h2>
<h3>Donut Buffers</h3>
<p>Here&#8217;s a snippet of code that is used when you want to buffer a dataset.</p>
<pre>
<div>def buffer(feature, radius, min_radius=0.0)</div>
<div>   wkb_writer = Geos::WkbWriter.new
   wkb_reader = Geos::WkbReader.new

   geom =  wkb_reader.read_hex feature.geometry
   buffer_geom = geom.buffer(radius)

   if min_radius != 0.0
      hole_geom = geom.buffer(min_radius)
      buffer_geom = buffer_geom.difference(hole_geom)
   end

   feature.geometry = wkb_writer.write_hex buffer_geom
   feature</div>
<div>end</div>
</pre>
<p>Going through the code, the method takes in a feature object, which has a geometry attribute which in this case is in  the HEX WKB format  (01010000002FDD2406816154C0C66D3480B7A03B40 for example)</p>
<p>Geometries can be stored in many formats, and GEOS can read them. But the key bit is that we have to use a GEOS::WkbReader to read in a string object and convert it into a geometry.</p>
<p>POINT(-81.5235 27.6278) Would be the same point geometry but in Well Known Text, or WKT.</p>
<p>So, we read the geometry in, and convert it into a special GEOS object, ready to be worked upon.<br />
The next line down is where the buffer operation takes place.</p>
<blockquote>
<pre>buffer_geom = geom.buffer(radius)</pre>
</blockquote>
<pre><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 19px;">Pretty simple, eh?</span></pre>
<p>This makes a polygon around a buffer, with the radius variable as distance.</p>
<p>The next few lines are donut making &#8211; we see if the method was called with a min_radius value, buffer the same point but with the smaller radius and then do a difference operation on that!</p>
<blockquote>
<pre><span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px;">buffer_geom = buffer_geom.difference(hole_geom)</span></pre>
</blockquote>
<p>And the final of the method uses the geos wkb_writer to write back the new donuted geometry for that feature.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.geoiq.com/blog/2011/06/15/geos-library-for-spatial-magic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fusion Tables &amp; GeoCommons</title>
		<link>http://developer.geoiq.com/blog/2011/06/06/fusion-tables-geocommons/</link>
		<comments>http://developer.geoiq.com/blog/2011/06/06/fusion-tables-geocommons/#comments</comments>
		<pubDate>Mon, 06 Jun 2011 13:46:58 +0000</pubDate>
		<dc:creator>Chris Helm</dc:creator>
				<category><![CDATA[Data]]></category>

		<guid isPermaLink="false">http://developer.geoiq.com/?p=741</guid>
		<description><![CDATA[<p><a href="http://developer.geoiq.com/wp-content/uploads/2011/06/ft_to_gc.png" rel="lightbox[741]"></a></p> <p>We realized that this post was just too useful for only developers, so we <a href="http://blog.geoiq.com/2011/06/06/fusion-tables-geocommons/">moved it over to the main GeoIQ Blog</a>. </p> <p>I&#8217;ll be posting up some details on how the Fusion Tables adapter works under the hood in GeoIQ and how we can actually connect into a lot of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://developer.geoiq.com/wp-content/uploads/2011/06/ft_to_gc.png" rel="lightbox[741]"><img class="aligncenter size-full wp-image-991" src="http://developer.geoiq.com/wp-content/uploads/2011/06/ft_to_gc.png" alt="" width="378" height="57" /></a></p>
<p>We realized that this post was just too useful for only developers, so we <a href="http://blog.geoiq.com/2011/06/06/fusion-tables-geocommons/">moved it over to the main GeoIQ Blog</a>. </p>
<p>I&#8217;ll be posting up some details on how the Fusion Tables adapter works under the hood in GeoIQ and how we can actually connect into a lot of different API&#8217;s very easily with GeoIQ Connect!</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.geoiq.com/blog/2011/06/06/fusion-tables-geocommons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GeoCommons &#8217;2.0&#8242; &#8211; with more developer goodness</title>
		<link>http://developer.geoiq.com/blog/2011/05/31/geocommons-2-0-with-more-developer-goodness/</link>
		<comments>http://developer.geoiq.com/blog/2011/05/31/geocommons-2-0-with-more-developer-goodness/#comments</comments>
		<pubDate>Tue, 31 May 2011 13:09:44 +0000</pubDate>
		<dc:creator>Andrew Turner</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://developer.geoiq.com/?p=941</guid>
		<description><![CDATA[<p><a href="http://blog.geoiq.com/files/2011/05/home.slide_.20.jpg" rel="lightbox[941]"></a>Today we launched the major refresh of <a href="http://www.geocommons.com/" title="GeoCommons">GeoCommons</a> &#8211; essentially &#8220;2.0&#8243; as we were literally up to that version number anyways, but it also fits a lot of what we&#8217;ve done under the hood. I don&#8217;t want to give it all away &#8211; each of the team members will be sharing [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.geoiq.com/files/2011/05/home.slide_.20.jpg" rel="lightbox[941]"><img src="http://blog.geoiq.com/files/2011/05/home.slide_.20-tm.jpg" width="271" height="143" alt="home.slide.20.jpg" style="float:right; padding-top:5px; padding-bottom:5px; padding-left:5px;" /></a>Today we launched the major refresh of <a href="http://www.geocommons.com/" title="GeoCommons">GeoCommons</a> &#8211; essentially &#8220;2.0&#8243; as we were literally up to that version number anyways, but it also fits a lot of what we&#8217;ve done under the hood. I don&#8217;t want to give it all away &#8211; each of the team members will be sharing their own perspectives and insights into what they&#8217;ve accomplished &#8211; but there is a lot that has changed.</p>
<p>There are small touch-ups throughout the platform, <a href="http://developer.geoiq.com/blog/author/semprebon/" title="semprebon | GeoIQ Developer">Semprebon</a>&#8216;s preview images of datasets and maps, to larger capabilities such as data editing and versioning (did someone say &#8220;git for data?&#8221;). And clearly the most pronounced change was an entire rewrite of &#8220;the App formerly known as Maker&#8221; (TAFKAM) &#8211; simply put, our map visualization. We&#8217;re still using the very powerful and capable Flash engine, and <a href="http://www.geocomrade.com/" title="GeoComrade - maps, geo, web 4.0, motherland">Andrei</a> has performed some magic to render <b>a lot</b> of features (think 100&#8242;s of thousands) but we&#8217;ve moved the rest of our entire interface to JavaScript and HTML thanks to Derek. The benefit of that is that with our beta Polymaps support from <a href="http://developer.geoiq.com/blog/author/chris/" title="chris | GeoIQ Developer">Chris</a> you can now not only view maps on your iPad, but you can build visualizations and analyses on your iPad!</p>
<p>And lastly, but most importantly yet not nearly as noticeable, we&#8217;ve swapped out our infrastructure. Matt and Justin have raised GeoCommons completely to the cloud where we&#8217;re now able to easily scale out any piece of our infrastructure on demand. Combine that with <a href="http://developer.geoiq.com/blog/author/chippy/" title="chippy | GeoIQ Developer">Tim</a>&#8216;s work with our asynchronous processing we have truly brought geospatial data management, visualization and spatial analysis to the cloud &#8211; free for everyone to use.</p>
<p>Stay tuned for more details on these features I&#8217;ve mentioned, including some technical details on how we&#8217;ve scaled out our system to provide unique and capable data analysis to the web. And don&#8217;t think we&#8217;re stopping there &#8211; this new infrastructure has already enabled us to quickly add new features and tweaks. We&#8217;d love to hear your feedback, praise, or any issues you run into on <a href="http://getsatisfaction.com/geocommons" title="Get Satisfaction - People Powered Customer Service">our Community forum</a>. And if you&#8217;re a passionate GeoCommons user, a developer and want to work for a fun, dynamic, and exciting team &#8211; <a href="mailto:careers@geoiq.com">drop us a line</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.geoiq.com/blog/2011/05/31/geocommons-2-0-with-more-developer-goodness/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>JSConf 2011 in Review</title>
		<link>http://developer.geoiq.com/blog/2011/05/05/jsconf-2011-in-review/</link>
		<comments>http://developer.geoiq.com/blog/2011/05/05/jsconf-2011-in-review/#comments</comments>
		<pubDate>Thu, 05 May 2011 19:12:45 +0000</pubDate>
		<dc:creator>Chris Helm</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://developer.geoiq.com/?p=925</guid>
		<description><![CDATA[<p>This week my fellow GeoIQ engineer Derek Carter and I attended JSConf 2011 in Portland, OR. If you don&#8217;t know about this conference, and what it&#8217;s like, you should find out. It&#8217;s not like many other conferences out there. It gathers an impressive list of the some the world&#8217;s most forward thinking JavaScript experts. There&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>This week my fellow GeoIQ engineer Derek Carter and I attended JSConf 2011 in Portland, OR. If you don&#8217;t know about this conference, and what it&#8217;s like, you should find out.  It&#8217;s not like many other conferences out there. It gathers an impressive list of the some the world&#8217;s most forward thinking JavaScript experts. There&#8217;s a lot of fun to be had at JSConf and the organizers do a really good job of keeping the talks focused on very cutting edge topics. </p>
<p>There were several talks that were really great, and we were able to meet some truly amazing developers while we were there too. Here&#8217;s a short list of some of the talks and techs that I found to be interesting:</p>
<p>The first talk of the conference was really good. It was titled <a href="http://2011.jsconf.us/#/proposal/7edca1476b18fe06e50883702e26eafa">Bytes and Blobs</a> by the one and only David Flanagan, and it focused new HTML5/JS APIs for handle all sorts of binary data structures in the browser. Though its still early to start playing with, the raw file data API (which centers of passing around BLOBs) seems like it holds large amount of potential. Reading client-side files is just one of many features of this API, and one that could have a direct implication on the geo-spatial industry over the next years. Think about the ability to map data without having to actually upload it, or even doing format conversion in javascript without ever touching a server? interesting idea for sure. The entire group of these client-side binary data APIs was very impressive.</p>
<p>An early talk in the conference &#8220;B Track&#8221; was Tim Caswell on <strong>Node Powered Desktop Apps</strong>. A lot of people might ask &#8220;why JS on the desktop?&#8221; and this talk was a good introduction to a sub-theme of the conference: JavaScript everywhere. Why? cause JavaScript is clean, simple and becoming more and more engrained within every part of the web. It makes sense that more developers would be comfortable writing more backend applications in JS. So with the explosion of interest in Node.js people are really starting catch onto the idea that JS is not limited to just the browser and that it possesses some potent capabilities for app development in other areas. One of the libraries Tim mentioned and showed off was <a href="https://github.com/Tim-Smart/node-gtk">node-GTK</a> which is a node binding to libgtk &#8211; awesome. </p>
<p>Later on in the first day we saw Avni Kharti speak about <a href="http://2011.jsconf.us/#/proposal/6f23fd600302403a9f53e113900ea477">visualization tools on the web</a>. Her talk was okay, but was as close as anyone seemed to get to mentioning geo-spatial tools on the web. She focused on several tools and APIs that most geo geeks would be really familiar with (basically the Google toolkits like Google Maps and Fusion Tables). I was shocked she didn&#8217;t once mention GeoCommons in her talk, it truly and utterly shocking. Every downside of every tool in her talk is handled elegantly by GeoCommons. I made a point to tell her all about it afterward, and she admitted the next day that she wished she&#8217;d seen it before her talk. </p>
<p>The second to last talk of the conference was Brendan Eich &amp; Jeremy Ashkenas. Brendan is one the fathers of Javascript and gave a large audience a glimpse into some of the future features that we might expect in JS. There was strong theme of writing less code, and being more efficient in JS within his slides (and I was excited to the idea of list generators creep in there). Next Jeremy Ashkenas (creator of Backbone.js and CoffeeScript) gave a thorough talk on the concepts, benefits and features of CoffeeScript. It was great to see CoffeeScript in action and get a first hand description of how it works from the creator himself.   </p>
<p>Of course this is a very short list of only a few of the many awesome talks this year. I heard over and over again that people&#8217;s brains were exhausted from all the great new libs and ideas that were being talked about. Even though this was my first JSConf, I have a feeling it won&#8217;t be my last, and I am really looking forward to it next year. </p>
]]></content:encoded>
			<wfw:commentRss>http://developer.geoiq.com/blog/2011/05/05/jsconf-2011-in-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Portland GeoIQ HackDay!</title>
		<link>http://developer.geoiq.com/blog/2011/04/17/portland-geoiq-hackday/</link>
		<comments>http://developer.geoiq.com/blog/2011/04/17/portland-geoiq-hackday/#comments</comments>
		<pubDate>Sun, 17 Apr 2011 21:51:56 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[API]]></category>
		<category><![CDATA[hackday]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[portland]]></category>

		<guid isPermaLink="false">http://developer.geoiq.com/?p=921</guid>
		<description><![CDATA[Early next month is JSConf, which will be bringing some of our engineers to Portland.  We thought it would be a great time to meet-up with some of our Portland friends and show what we've been working on.  <a href="http://piepdx.com/">PIE</a> has been gracious enough to provide us with a space on Sunday afternoon May 1st from noon until 6pm]]></description>
			<content:encoded><![CDATA[<p>Early next month is JSConf, which will be bringing some of our engineers to Portland.  We thought it would be a great time to meet-up with some of our Portland friends and show what we&#8217;ve been working on.  <a href="http://piepdx.com/">PIE</a> has been gracious enough to provide us with a space on Sunday afternoon May 1st from noon until 6pm.  </p>
<p>We&#8217;ve recently added some new features to our JavaScript API as well as redone the documentation to make it easier to read.  Chris has been hacking on Node.js and Polymaps.  Derek&#8217;s been working on our charting ability with Raphael.  Come see what we&#8217;ve done and bring your own project ideas.</p>
<p>So <a href="http://geoiq.eventbrite.com/">sign-up</a> and see you there!</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.geoiq.com/blog/2011/04/17/portland-geoiq-hackday/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The GeoIQ on Ruby Nation</title>
		<link>http://developer.geoiq.com/blog/2011/04/05/the-geoiq-on-ruby-nation/</link>
		<comments>http://developer.geoiq.com/blog/2011/04/05/the-geoiq-on-ruby-nation/#comments</comments>
		<pubDate>Tue, 05 Apr 2011 22:51:01 +0000</pubDate>
		<dc:creator>semprebon</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://developer.geoiq.com/?p=918</guid>
		<description><![CDATA[It was a cold and rainy Friday morning when I headed out to Reston, Virginia for <a href="http://www.rubynation.org/">RubyNation</a>, a local ruby conference. Attending were hundreds of the Washington area’s finest ruby developers, as well as programmers from as far away as India. What follows are what I consider the highlights of the conference.</p> <p>The opening [...]]]></description>
			<content:encoded><![CDATA[<div>It was a cold and rainy Friday morning when I headed out to Reston, Virginia for <a href="http://www.rubynation.org/">RubyNation</a>, a local ruby conference. Attending were hundreds of the Washington area’s finest ruby developers, as well as programmers from as far away as India. What follows are what I consider the highlights of the conference.</p>
<p>The opening keynote by Ruby godfather <a href="http://pragdave.pragprog.com/">Dave Thomas</a> epitomized one trend I noticed, by not being about Ruby at all. In fact, out of 26 main talks at RubyNation (I didn&#8217;t count lightning talk sessions), only 11 were actually about Ruby. Has the rabid enthusiasm for ruby on rails finally abated? At least among the elite developers who actually take the time to attend conferences, this seems to be the case. There was speculation in the hallways as to which big-name ruby guru would be the first to break ranks. Talks by Aaron Bedra on <a href="http://clojure.org/">Clojure</a>, Jerry Cheung on <a href="http://nodejs.org/">Node,js</a>, and Blake Mizerany on, well, just about everything else, highlighted the advantages of avoiding ruby for tasks it isn’t particularly suited for: low-latency services, concurrency, analytical analysis, and more. Even Joe O’Brien’s talk on Ruby on Android was more about ruby’s failure as a viable Android programming language in comparison to the ruby-like <a href="http://www.mirah.org/">Mirah</a> programming language.</p>
<p>Of course, if you’re going to go all polyglot on your project, you need a way for those languages to intercommunicate. The preferred lingua franca, at least for lower-level integration, seemed to be the Java Virtual Machine, with <a href="http://www.jruby.org/">jRuby</a> getting several mentions and one full talk by Russ Olson.  Ben Scofield’s lecture on “Thinking Small”, on the other hand, dealt with integrating at a larger scale &#8211; in particular, with the value of creating a large system from many smaller, more focused services, communicating via databases and HTTP/REST. You know, we should really be doing more of that here at GeoIQ.</p>
<p>Second only to Ruby in conference air time, Javascript was well represented. In a pirate-themed talk complete with hats, patches and the shouting of “Arrrg!”, Chris Williams covered the history of JavaScript, from its humble and rushed beginnings to its current effort at world dominance, ending with his call for <a href="http://en.wikipedia.org/wiki/Google_bomb">google-bombing</a> to <a href="http://promotejs.com/">promote</a> good <a href="https://developer.mozilla.org/en/JavaScript">JS documentation.</a> The previously mentioned talk on Node.js covered the growing use of JS on the server, while Trotter Cachion’s talk on doing graphics in <a href="http://raphaeljs.com/">Raphaël </a>covered the client side. My favorite javascript alternative, <a href="http://jashkenas.github.com/coffee-script/">coffeescript</a>, seems to be getting some traction as well, with several mentions and one Lightning Talk.</p>
<p>Avdi Grimm gave an excellent talk on writing “Confident Code” which clearly spelled out how to make ruby more readable by structuring methods in 4 parts: Input,Work, Results, Errors. He also mention a number of neat techniques, like using Null Objects to eliminate nil checks, that I was not familiar with.</p>
<p>As usual, there were a sprinkling of talks on non-programing topics &#8211; David Keener’s on business models (money for code!), Keavy McMinn’s talk on training for an ironman triathlon (You think you have it bad?), and Dr. Nic  Williams closing keynote on ruby user groups (We need to talk) were all more or less successfully pitched as relevant to the ruby developer.</p>
<p>One reason I like going to conferences like RubyNation is to learn about new tools and even old tools that somehow escaped my notice. Some of the those that got my particular attention were <a href="http://www.mirah.org/">Mirah</a> (static ruby for jvm), <a href="http://code.google.com/p/protobuf/">Protocol Buffers</a> (cross-platform binary serialization), <a href="http://sass-lang.com/">Sass</a>/<a href="http://compass-style.org/">Compass</a> (programmable css), <a href="http://railsinstaller.org/">Rails Installer</a> (easy Rails for Windows), and <a href="http://raphaeljs.com/">Raphaël</a> (JS alternative to Flash or Canvas)</p>
<p>Of course, the main reason for a conference is to hang out with like-minded folks for stimulating conversations, and RubyNation didn&#8217;t disappoint, whether it was discussing the pros and cons of cross platform applications (Mac/iPhone users are picky, Linux users are happy to have any decent UI) or the best places to live outside the United States (Chile?). One of the great things about these smaller local programming conferences is that you end up knowing a lot more of the people. In all, a successful conference which can be summarized in one word: Arggg!</p></div>
]]></content:encoded>
			<wfw:commentRss>http://developer.geoiq.com/blog/2011/04/05/the-geoiq-on-ruby-nation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GeoIQ Design Process &#8211; Perfection in Simplicity</title>
		<link>http://developer.geoiq.com/blog/2011/03/31/geoiq-design-process-perfection-in-simplicity/</link>
		<comments>http://developer.geoiq.com/blog/2011/03/31/geoiq-design-process-perfection-in-simplicity/#comments</comments>
		<pubDate>Thu, 31 Mar 2011 17:39:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[design]]></category>

		<guid isPermaLink="false">http://developer.geoiq.com/?p=909</guid>
		<description><![CDATA[Here's the informal design process I've more or less evolved over the years. I've used it when I've had designers block and couldn't get past a white canvas; I've used it to bring order to complex projects with hundreds of vague and conflicting requirements and I've used it for relatively simple component designs. Sometimes I complete it on paper in a few minutes, sometimes it takes a week. Treat the process like a fractal - use it to define the high level multi-page flows or use it to define page layouts and individual components.]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s the informal design process I&#8217;ve more or less evolved over the years. I&#8217;ve used it when I&#8217;ve had designers block and couldn&#8217;t get past a white canvas; I&#8217;ve used it to bring order to complex projects with hundreds of vague and conflicting requirements and I&#8217;ve used it for relatively simple component designs. Sometimes I complete it on paper in a few minutes, sometimes it takes a week. Treat the process like a fractal &#8211; use it to define the high level multi-page flows or use it to define page layouts and individual components.
</p>
<h3>Step 1 &#8211; Roles</h3>
<p>Define who is going to use it. Understand at a high level what they are going to want to do. Instead of this &#8220;bob wants to click on &#8216;click here to map&#8217; and then wants to click &#8216;analyze my data&#8217;&#8221; do this &#8220;bob wants to make a map and analyze data&#8221;. Don&#8217;t presuppose the UI flow in your definitions. Use as much or as little detail as you need to capture the mindset of a few different kinds of people. If you can talk to actual customers in these roles, do it. If you can observe them using an existing UI then even better.
</p>
<p>If you can, try to define roles that defy the biases of you and your team. If you&#8217;re slow and methodical, imagine someone who isn&#8217;t. If you are fast and impatient, try using your product with your opposite hand or a different input device. The consumer products company OXO, renowned for their understanding of ergonomics, keeps a large collection of gloves of all shapes and sizes so their designers can better understand the roles of those they serve.
</p>
<h3>Step 2 &#8211; Requirements &#8211; What does it need to do?</h3>
<p>I use the term requirements very loosely. This is about collecting all the ideas, thoughts and hunches of everyone involved in the project. It&#8217;s about finding the specific mandates and vague notions about the design. Make a list anywhere, on paper, online, on a napkin, in a spreadsheet, wherever, of all the things people want it to be. Don&#8217;t confuse this with the massive requirement documents made by sweaty guys in dimly lit conference rooms used to enslave Java developers in the 90&#8242;s.
</p>
<h3>Step 3 &#8211; Absolute Requirements &#8211; What does it absolutely need to do now?</h3>
<p>Next, cut the list down to the absolute must-haves. It&#8217;s great to have a huge list of requirements, but be super critical about which ones are important for the current phase.
</p>
<p>Prioritize the list by looking at two items and thinking &#8220;If I could keep just one, which would it be&#8221;. Decide what on the list has to be handled in the first phase and what can iteratively follow in subsequent phases.
</p>
<p>The full list will inform your choices for later, you may decide to allow something to have a flexible height so it can accommodate future requirements when they become critical. But for now, just cut it down to the must-haves.
</p>
<h3>Step 4 &#8211; UI Inventory &#8211; A list of what needs to be designed</h3>
<p>Now, take the requirements list and turn it into an inventory of UI elements. If you&#8217;re designing a home page it might look like this: </p>
<pre>
Header
   Logo
   Tagline
   User Menu
       Login Name
       Sign Out
       Account Settings
       Thumbnail
Marketing Message
   Headline
   Slideshow
   Call To Action button
   Secondary Action
Content
   Case Studies
   Product Gallery
   ...
</pre>
</p>
<p>The idea here is to capture everything that will need to fit on the screen. List in great detail all the elements and sub-elements that you can think of. If something is vague, it&#8217;s ok, but try to make it more specific if you can. For our search results redesign we listed &#8220;quality&#8221;, maybe that can be better stated as &#8220;quality icon&#8221; or &#8220;quality gauge&#8221;.
</p>
<p>I&#8217;ve found that the more time I put into the UI inventory the easier the design goes once I jump into drawing. I&#8217;ve also found it valuable to share the inventory with the team as a sanity check. I haven&#8217;t gotten much feedback on my inventories since they can be a bit daunting, but it at least gives everyone a glimpse into the design process and they can see how their personal favorite ideas are being worked into the design.
</p>
<p>The inventory serves as  a great place to record thoughts that would be hard to illustrate. I often put notes about interactivity into the inventory:
</p>
<p>
  For Each Layer:</p>
<ul>
<li>Title  (reveals layer menu on click)</li>
<li>[menu] hint (appears on hover)</li>
<li>Attribute Icon (reflects current styles)</li>
<li>Attribute Name (truncated if necessary)</li>
</ul>
<p>These things are hard to illustrate prior to designing and going through the process of illustrating them may not add much value, so I make a note of it and move on.
</p>
<p>I consider the inventory to be one of the most helpful ways of organizing UI projects. In one particularly complex redesign, I spent almost full week in just a text editor planning out the UI inventory, no sketches or photoshop comps at all. It was worth it as it provided a lot of direction for the steps that followed.
</p>
<h3>Step 5 &#8211; Prioritize the inventory</h3>
<p>Now start removing stuff. Be ruthless as you cut and demote items. Remember that everything on the list will cost the company time and effort to build and maintain. Each item on the list will result in a series of bugs that keep you working late on a Friday.
</p>
<p>Eliminate till it breaks. Keep removing and demoting items on the list so that you have as few elements on screen as possible. The highest priority items should be critical to your entire audience, the kinds of things that the product simply won&#8217;t function without. Stop when you eliminate a feature that 20% of your users will miss and will whine endlessly about. If you&#8217;re not sure, cut it and see if anyone notices. I&#8217;ve cut out a lot of features this way that and haven&#8217;t heard a peep.
</p>
<p>Be ruthless even with your own favorite features. For example it would be cool to have a glossy sliding panel that bounces into place but that feature is going to cost time and effort. At this point it&#8217;s all about what people need to see rather than what they want to see. It will be easier to add the wants later, though more often than not I&#8217;ve found that addressing the needs counts for much more.
</p>
<p>By the end of this step, you&#8217;ll have a good idea of what needs to be addressed in the wireframes. You&#8217;ll be able to focus all of your mental capacity on layout, geometry, balancing prominence, etc. You won&#8217;t have to worry about forgetting a critical feature. I use this process because it greatly reduces the number of times that I have to work late redesigning an entire flow simply because I forgot to include a small but important element.
</p>
<h3>Step 6 &#8211; Sketch artist</h3>
<p>Start sketching, with a real pen on real paper. Steal some of those 11&#215;17 sheets from the bottom drawer of the copier. They&#8217;re free (to you), disposable and you won&#8217;t be afraid to fill them up with scribbles. Think of your inventory as a puzzle. Brainstorm out all of the possible layout solutions. Use a broad pen, don&#8217;t sweat the details, avoid writing words. The goal is to do this until you feel like you have a good idea that everything on the inventory has a sensible place.
</p>
<p>The big thing here is to figure out how much space is needed for different things. I call it the Prominence Hierarchy and for me it&#8217;s one of the most important parts. The key is to figure out, separate from the design, what needs to be most important and what can be the least. What happens if you dedicate two thirds of the space to an image versus one third? What happens if you put a lot of emphasis on the title? Or, on the navigation options? Get a good feel for the different ways pieces and parts can fit together.
</p>
<p>Consider different ways of hiding elements. What happens if you use an Accordion control vs. tabs?
</p>
<p>I&#8217;ve found that using pen and paper allows a creative flow that is much harder to initiate on a computer screen. Try getting away from your computer (and smart phone) and go somewhere where you can focus completely uninterrupted.
</p>
<h3>Step 7 &#8211; Wireframes</h3>
<p>At some point, something will click in your head and you&#8217;ll want to rush to your computer and get started. Or you might just need to place some things on screen to see how much room they really take up. Go for it.
</p>
<p>Use a program like omnigraffle, visio, axure or anything that lets you draw up some simple wireframes. Just boxes and lines. Treat it like a whiteboard to verify the direction you&#8217;re going and communicate your design to a couple people to validate the direction.
</p>
<p>I find it helpful to show my work to one or two people as I go. The earlier the design the fewer people I show it to. This eliminates the group think and design-by-committee mentality that can kill good design. It usually only takes one or two people to point out the biggest flaws in the early designs. Any more people than that and you&#8217;re just wasting time. Then as more people are brought into the loop the design has a bit more momentum and maturity resulting in less wasted time for everyone.
</p>
<h3>Step 8 &#8211; Graphical Design</h3>
<p>One advantage of this process is that it can easily be handed off to a designer at any point. Even if all you&#8217;ve done is work through the roles, that can be enormously helpful to a designer. Having a firm grasp of the requirements is even more helpful. Having a list of what needs to be designed per screen, even better. Some designers will disagree and may prefer to work out some of those steps for themselves. If so, great, that&#8217;s a mark of a good designer (my opinion). At the very least you&#8217;ve built a common vocabulary and you can weigh the designer&#8217;s solution against yours and have a deeper combined understanding.
</p>
<p>If you&#8217;re not doing the graphical design, bundle up everything that you&#8217;ve done and send it to a designer. Also send them your favorite inspiration from dribbble.com, 365psd.com and screen grabs of elements from sites you like. Avoid sending things that are not clearly related to what you&#8217;re doing. Write a few lines about what you like from each example if it isn&#8217;t already obvious. i.e. you &#8220;love the typography but not the colors&#8221;, you &#8220;love the layout but feel free to experiment with other options&#8221;.
</p>
<p>If you are responsible for the graphical design, jump into photoshop or the program of your choice and start making it real. Avoid going directly to code and css, you&#8217;ll lose a lot of flexibility that is critical at this stage.
</p>
<p>Either way, it pays to have a basic understanding of design principles. Here&#8217;s the set of principles I measure my designs against.
</p>
<p><strong>Consistency</strong></p>
<p>Use the same font and size whenever possible. I didn&#8217;t do this in my early design with Fortius and it shows. Lately I&#8217;ve standardized on 14px Helveitca Neue for everything. It&#8217;s done a lot to smooth out the UI and brought some consistency to it.
</p>
<p><strong>Repetition and Rhythm</strong>  </p>
<p>Learn about grids. In photoshop set your grid to 16px with 4 divisions. When in doubt, align it to the grid. Look at the Layers palette PSD and you&#8217;ll see how the height of the header, the spacing between lines, the padding within layers, all aligns to the grid in some way. This took a few extra hours to perfect but the results are worth it. There&#8217;s a rhythm and simplicity to it that is hard to get when you&#8217;re simply eyeballing the dimensions.
</p>
<p><strong>Alignment</strong></p>
<p>One of the big differences between novice design and expert design is the number of alignments the design contains. If you have a text on several different lines and they all start at different horizontal positions, they&#8217;re not aligned. Align them and the design will feel more cohesive. Align boxes and UI elements with each other both horizontal and vertical if you can. Align the top of the zoom bar with the top of the layers palette and the style palette.
</p>
<p><strong>Position</strong></p>
<p>Keep like things together. Don&#8217;t put logout far away from the user name. Keep attribute count near feature count. Don&#8217;t force people to scan from left to right just to match something up.
</p>
<p>Keep in mind the human fovea is small, if you put related things too far away from each other they&#8217;ll fall into the peripheral vision and people simply won&#8217;t see them. You&#8217;ll see it because you know it&#8217;s there, but others wont. Look at one point in the design, how much can you see at one time, if you&#8217;re very focused it&#8217;s probably just a few square inches. This is why designs with too much whitespace can actually hinder usability.
</p>
<p>Consistency, Repetition, Alignment, Position: CRAP for short.
</p>
<h3>Resources</h3>
<p>At any time in this process, get inspiration. </p>
<ul>
<li><a href="http://smashingmagazine.com">smashingmagazine.com</a>  &#8211; general layout, color and design inspiration.</li>
<li><a href="http://patterntap.com" title="Pattern Tap : Organized Web Design Collection of User Interfaces for Inspiration and Ideas. The CSS Gallery Alternative - Pattern Tap">patterntap.com</a> &#8211; A brilliant site where you can browse neatly categorized design examples in categories like Forms, Navigation, Signup, Layout, Introductions, etc. </li>
<li><a href="http://dribbble.com" title="Dribbble - What are you working on?">dribbble.com</a> &#8211; Like twitter for graphic designers. See what top designers are making right now. </li>
<li><a href="http://365psd.com" title="365psd ‹ Download a free PSD every day.">365psd.com</a> &#8211; Tons of downloadable photoshop examples. Lots of silky smooth buttons and UI elements. I wish I knew about this a year ago when they started.</li>
</ul>
<p>Also spend some time at sites that do things well like mint.com, delicious.com, squarespace.com, any of the 37signals products.
</p>
<p>Train your eye for what designers are doing and often more importantly, what they&#8217;re not doing. For example, back when browsers introduced repeating backgrounds, I felt compelled to add funky textures to every page I designed. Then I looked around the web at the sites made by the top designers in the field and I saw white. Lots and lots of white. No one was using funky textures and for good reason.</p>
]]></content:encoded>
			<wfw:commentRss>http://developer.geoiq.com/blog/2011/03/31/geoiq-design-process-perfection-in-simplicity/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

