Abandoned Tube Stations

(This is an auto copy over from my old blog at Joe8bit.com, some links may be broken)

An interactive data experiment with Angular, Mapbox and GeoJson

Growing up around Kentish Town there were always rumours about an old abandoned tube station. It was variously claimed people had held raves down there in the 80’s; that it was used as some kind of bizarre goth sex dungeon; or even, that it was the place ‘they’ buried that kid who just left school suddenly. While none of these were true (except we still haven’t found little Timmy, coincidence, I think not!) the truth was it self like part of a (quite literally) forgotten underground. A part of London that existed, and yet very people knew anything about, save the innuendo of bored adolescents.

Only when I grew up and Google made researching these things easy did I discover that the station did actually exist: it was South Kentish Town and that it was every bit as real as all out stupid stories had been imaginary.

1200px-South_Kentish_Town_former_tube_station_2005
South Kentish Town former tube station 2005“. Licensed under CC BY-SA 2.0 via Wikimedia Commons.

In hindsight, it was obvious: the tiling, the colour, the second exit that stands just behind where this photo was taken that leads down to nothing.

Not only are there dozens of these stations dotted around London and outside it, there are entire lines that have been closed that lead dozens of miles out of London. In my search to get more information about this subject, I came across this wonderfully 1990’s website where someone has loving indulged and curated a very good list of the stations, when this was combined with another fantastic Wikipedia resource I knew I had the beginnings of a cool data project.

Over the course of a couple weekends I put it together using AngularJS, MapBox and and some GeoJSON. However, I ran into a problem, what would I use to indicate the tube lines? I’d need a geographically accurate map of London’s Tube network. Uh oh.

Only when I found this Google map did the project come to completion. One of the issues I had, and that I found a little perplexing, was the way that MapBox rendered the default KML output from Google Maps, it never rendered the Polyline output right and never seemd to respect the styling data. What I really didn’t want to do was spend hours/days/months hand converting KML to GeoJSON, there are lots of tools for automating this process but none of them supported the conversion of the (god awful) XML based styling syntax of KML layers to the (just a little but less awful) GeoJSON styling metadata, but having tried a couple of tools I ended up using MapBox’s own toGeoJson which while it didn’t solve the styling problem it did produce very clean GeoJSON output that I would then (ugh) manually annotate with the correctly styling information.

So take a look at the project!

As with most experiments, this one is available and open sourced (under the MIT license) on Github. If you run into any issues with the little app, I’d really appreciate it if you would reach out Twitter or file a Github issue!

Advertisements

MapBox: HTML markers with GeoJson layers

(This is an auto copy over from my old blog at Joe8bit.com, some links may be broken)

Using HTML markers with rendering GeoJSON layers

I’m a big fan of MapBox, I use it wherever I can when I need maps (CartCSS + TileMill is a ray of sunshine in the otherwise crappy world of custom maps).

One of the main reasons I love their service so much is the quality of their documentation, which rarely fails to present an answer to a question I’ve had, until this instance.

So in the interest in saving a few minutes of pissing about, below is my solution to using custom HTML markers when rendering GeoJSON layers with Mapbox.js.

// Create your map is you normally would
L.mapbox.accessToken = 'YOUR_TOKEN';
var map = L.mapbox.map('map', 'YOUR_MAP').setView([YOUR_LAT, YOUR_LONG], YOUR_ZOOM);

// Add a layer with no data set as the first arg to featureLayer()// This is done to prevent the default marker icons rendering
var layer = L.mapbox.featureLayer().addTo(map);

// When the 'layeradd' event is fired (when we add the geoJSON below)layer.on('layeradd', function (e) {
var marker = e.layer;
var feature = marker.feature;

// This is where the magic happens...
marker.setIcon(L.divIcon({
    className: YOUR_ICON_CLASS, // Make sure you set an icon class here, otherwise default styles will be set by Mapbox's CSS
    html: '
<h1>Hello World</h1>
', // The content of your HTML marker, you can build a string based on the marker properties by using 'feature.properties.your_property'
    iconSize: [60,60] // The bounds for your icon
}));

// Now set your data and render the maplayer.setGeoJSON(YOUR_GEOJSON_DATA);

I can’t say for sure this is the best way to do it, but it works nicely and performantly for me.

Jekyll: generate body class

(This is an auto copy over from my old blog at Joe8bit.com, some links may be broken)

Adding a Liquid tag to generate contextual classes

In the process of moving the site you’re reading from WordPress to Jekyll (NB: lol and back again), one of the things that most appealed to me was Jekyll’s plugin API. I can now say with great pleasure, that gone are the days when I’d spend hour pouring of the (not great) WordPress plugin API docs. Not to mention that the fact there is no longer any dark corners of my life where PHP lurks, waiting to jump up and bite me in the ass.

In an attempt to get to grips with this new wonderland, I created a small plugin for Jekyll that allows you to add contextual classes to a body element. In the context of this site, it is the thing that powers the ability to have radically different styles and layouts on different pages.

The code is relativley simlple, simple add this to your _plugins directory (create it at the root of your site, if it doesn’t exist) and name it anything you like, I choose bodyClass.rb.

class BodyClassTag &lt; Liquid::Tag

    def generate_body_class(prefix, id)
        id = id.gsub(/\.\w*?$/, '').gsub(/[-\/]/, '_').gsub(/^_/, '') # Remove extension from url, replace '-' and '/' with underscore, Remove leading '_'

        case prefix
        when "class"
            prefix = ""
        else
            prefix = "#{prefix}_"
        end

        "#{prefix}#{id}"
    end

    def render(context)
        page = context.environments.first["page"]
        classes = []

        %w[class url categories tags layout].each do |prop|
            next unless page.has_key?(prop)
            if page[prop].kind_of?(Array)
                page[prop].each { |proper| classes.push generate_body_class(prop, proper) }
            else
                classes.push generate_body_class(prop, page[prop])
            end
        end

        classes.join(" ")
    end

end

Liquid::Template.register_tag('body_class', BodyClassTag)

Utilising it is then as simple as adding this Liquid tag to whichever layout you choose, for instance _layouts/default.html

<body class="{% body_class %}">;