quickmapr: An R package for mapping and interacting with spatial data

I do a lot of GIS. That used to mean firing up any one of the esri products, but over the course of the last couple of years I have done that less and less and instead fired up R.

When I first started using R for my spatial analysis work I often was left struggling with viewing the results of my analysis and could only do so with a clunky workflow of pushing my sp or raster objects out to shapefiles or tiffs and then pulling those into Arcmap. In short, spatial data visualization was severely lacking in R.

Fast forward to now, and that has all really started to change. Most of the work in this space has been on incorporating the slew of javascript tools (e.g. D3, leaflet, Crosslet) for visualizing spatial data. This has resulted in some really cool packages like:

These all result in great looking maps with nice interactivity; however, they all have two things in common. One, it is expected that your data are unprojected (i.e. Longitude and Latitude) and two that the data are simple text or in JSON (either GeoJSON or TopoJSON). This works for many use cases, but not for mine.

I usually start with small(ish) spatial data that are stored in GIS formats (e.g. shapefiles, esri rasters, file geodabase, etc.) and are projected. I use rgdal or raster to pull those into R and then do whatever it is I am doing to those and get sp and raster objects as output. At this point all I want to be able to do is quickly visualize the resultant data (usually less than 3 or 4 layers at a time), interact with that data by zooming, panning, and identifying values in the data interactively. I want to be able to this without having to convert to JSON or without having to un-project the data. The result of this desire is quickmapr.

With quickmapr you set up a qmap object by passing as many sp and raster objects as you’d like. There are some very basic controls on draw order and color. There are several zoom functions, a pan function, an identify function (which also returns the selected sp object or raster value), and a (currently very clunky) labeling function. This package is still a work in progress and I am hoping to keep working on quickmapr and tweaking how it works. I would love feedback so if you have thoughts, comments, complaints, etc don’t hesitate to leave some comments here, or better yet post issues on github, or fork the repo and make changes yourself. I will try and get up some contributing guidelines in the not too distant future.

Automatically Organizing Photographs on Google Drive: Why isn't this already a thing?

Over the last year or so, my wife and I have been moving most our files onto Google Drive. This has worked great as we have access across all of our devices. The last vestiges of local storage have been our photos. With the recent purchase of a Chromebook (which I’ve been impressed with but that is a different post…) and the 1TB of Google Drive storage that came with it, I decided to take the plunge and get our photos up their too.

Now, I thought that getting the photos moved and organized would be a snap because there certainly had to be a solution for keeping photos on Drive and organized. There were many options but none of them perfect. Many of them relied on Google+ Photos (I am not a fan of Google+), struggled with organizing large numbers of photos (nearly 20k), or were not able to be automated. It quickly became clear that I had to more less roll my own.

The solution I settled on in the end was to use a simple bash script set up as a cron job on an Ubuntu box that called grive and exiftool.

Update 3/13/2015: I was going to have more in this post, but didn’t get around to it. In the meantime, grive started giving me problems and wasn’t syning correctly. I think I have a solution that uses google-drive-oacmlfuse to just mount google drive directly on the linux box. I need to update my bash scripts and once I get that done, I’ll post those scripts here.

Getting a Category Feed Up and Running with Jekyll on Github

Now that I have the site up and running, I am now trying to add a few category specific RSS feeds. I will say that for someone who is new to RSS (i.e. me) the feeds on Wordpress are really easy. But, since I now fancy myself somewhat of hacker, I suppose figuring out how to get a Jekyll site hosted on Github to spit these out is something I should do.

This site is built on the Hyde theme which includes an atom.xml file. This is great and provides a feed for the entire blog but, often a category specific feed is required. For instance, my (poorly named) old blog Landscape Ecology 2.0 has been referenced by a couple of aggregators, most notably R-bloggers. Since I do blog about topics other than R, I need to be able to submit a feed that is specific to R. Wordpress does this automatically with Categories. You can also do this in Jekyll with a little work.

As it turns out many others have had this same need and there are a few options for getting it set up. Since my blog already has a site wide RSS feed built with Liquid templating all I needed was a category specifc one. So I simpl ammended the template from @snaptortoise jekyll-rss-feeds. For my blog, the template looks like:

layout: none
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<title>{{ site.title | xml_escape }} - r</title>
<description>Posts categorized as 'r'</description>
<link>{{ site.url }}</link>
<atom:link href="{{ site.url }}/feed.r.xml" rel="self" type="application/rss+xml" />
{% for post in site.categories.r limit:20 %}
<title>{{ post.title | xml_escape }}</title>
<description>{{ post.content | xml_escape }}</description>
<pubDate>{{ post.date | date: "%a, %d %b %Y %H:%M:%S %z" }}</pubDate>
<link>{{ site.url }}{{ post.url }}</link>
<guid isPermaLink="true">{{ site.url }}{{ post.url }}</guid>
{% endfor %}

I have saved this in the source of my website as feed.r.xml. One gotcha is that Jekyll appears to convert all categories to lower case. I had it set to loop on site.categories.R and it wasn’t working. Switching to site.categories.r fixed the problem.

Since feed.r.xml has the layout: null in the YAML, everytime the site builds on Github (i.e. everytime a change is made), this feed will get updated. In theory, I should be able to submit this feed to R-bloggers and everytime I have a new post with the R category, it will also get picked up by R-bloggers. Only downside to this is that a new category template will be required for each category that I want to build the RSS feed for.

NOTE: Getting the Liquid templating to be highlighted in this post also took some work as the the Liquid was getting interpreted, not highlighted. Turns out it is as easy as wrapping the code with:

{% raw %}
{% endraw %}

This answer courtesy of StackOverflow

ANOTHER NOTE: And now to get even more into the weeds, getting {% raw %} to render took another approach, raw HTML. So that looks like

<code>&#123;% raw %}</code>
<code>&#123;% endraw %}</code>

That answer provided by SLaks.Blog.

Colophon: jwhollister.com v0.2.0

Hard to believe that in less than a year I am now on the third version of my website. First one was me hacking at bootstrap. I knew next to nothing then, but was able to get a minimal site up and running. Since then I have learned quite a bit more about web design, Jekyll, hosting on github, and am a much better hacker than I was then (although still not a good one). My second site never really saw the light of day and was developed from scratch for a web design course I took.

This third site is now being built with Jekyll, hosted on Github, and uses a slightly customized version of the Hyde theme. Hyde is released under the MIT license, and the content on my website is freely available via Creatitve Commons Zero Public Domain Declaration. I would have used WTFPL v2.0, but some might take offense.

I will likely keep hacking on this site by adding some additional styling components and content (i.e. my CV). I do also plan on blogging some here when I get the time. I expect to maintain my old blog as an archive but new content will go here. Any technical changes will be added to this post.