Menu

A few days ago I created fulcrum-node, a simple JavaScript wrapper for the Fulcrum API. The library doesn’t actually do much, but it keeps you from writing a bunch of boilerplate HTTP requests and handles some error processing.

It’s packaged up nicely as an npm package but I thought it would be helpful to make it usable in the browser as well. The fuclrum-node package depends on the request package to communicate with the API. Request uses Node’s core HTTP module, which is not available in the browser. Fortunately there’s the xhr package that wraps the a browser’s XMLHttpRequest object. xhr uses the same API as request, so so we can write our code once, with the same results on the server and in the browser.

So, how do we utilize the xhr package when we’re in the browser?

Browserify

Browserify is a tool for creating node flavored modules for the browser. Running the browserify command will package up all of your dependencies and place them in a single bundle that can be easily added to easily added to a page. It turns out browserify looks for a special “browser” field in your package.json. Here you can override specific modules that set the proper file resolution for browser-specific versions of modules. In our case we set the request module to use the xhr module.

Then we just run the browserify command to create our bundle. In the example below the -s Fulcrum bit says build as a standalone and set the package contents to window.Fulcrum if no module system is found (in the browser).

browserify lib/index.js -s Fulcrum > fulcrum.js

Now we can reference the bundled script above and use the fulcrum node package in the browser just as we would on the server:

GitHub supports rendering GeoJSON files directly in their website. And with help from geojson.io you can easily create, update and edit your GeoJSON features right in the browser.

I thought it would be fun to create a spatial API that fronts and syncs your GeoJSON hosted by GitHub. So, I built GitSpatial.

How it Works

When you first visit the site, you can log in with your GitHub account. You’ll be asked to allow GitSpatial access to your public repos (maybe private ones later?). When you grant access, we’ll get a list of your repos. Since you might have many repos, and many of those won’t have any GeoJSON, you are responsible for syncing any repos that do. Syncing is a one-time process that lets our service know that we should keep track of changes in this repo. When you sync we add a post-receieve hook to your repo settings so GitSpatial is notified when changes are made.

Once your repo is synced, the final step is to sync individual feature sets (files) that you want GitSpatial to keep track of. Again, you could have many GeoJSON files in a repo that you just don’t care about syncing, so we don’t want to bother tracking updates to those. As with repo syncing, this is a one-time process, so you won’t have to worry about it again.

When your feature set is done syncing, you’ll have immediate API access to it.

What’s Next

Private Repos – For now every repo/feature set you sync is publicly available. I’d really like to add support for OAuth API access for private repos.

Attribute Searching – For GeoJSON feature properties I’m just dumbly storing the JSON as a string in a properties field. Ideally I’d like to use something like HStore to allow indexing and searching of this data.

Support non-*.geojson Files – Maybe you store your files as *.json or even *.topojson. We currently don’t look at these, but maybe soon.

A few weeks back GitHub announced rendering of geographic data in your repos via GeoJSON. It’s easier than ever to create, maintain, share and even style your geographic data. But more importantly this reduces the effort required to collaborate using geographic data.

After only a few weeks a number of interesting geo applications have surfaced using the new visualization capabilities GitHub offers. DC WiFi Social, from Ben Balter, is an effort to map locations in DC that serve alcolhol and offer WiFi – a great idea where a few residents with great local knowledge can make life much easier for visitors.

While my knowledge of Denver area bars that offer WiFi is rather limited, I thought it’d be fun to create something to gather bike routes in the Denver area based on distance and difficulty.

So, I forked DC WiFi Social which already had a great framework set up for collaborating: an informative readme, continuous integration (testing) via Travis CI, GeoJSON validation instructions, etc. With very little work of my own I was able to create a collaborative route mapping framework. You can view existing routes, filter by distance or difficulty, and add your own routes. Check it out with the links below.

More Fun Geo Things on GitHub

My wife was recently tasked with putting out signs for a consignment sale at our son’s preschool. Lots of them.

She showed me what they’d used in the past – A document with step-by-step directions from one location to the next and what kind of sign to place there. While this would have worked fine, it made it very hard to split up groups of folks to go and place specific types of signs.

So, thinking there had to be a better way, I sat down to see what I could to do make this easier for her. In just an hour or so I was able to come up with what seemed like a much better solution.

I used Google Fusion Tables to create a row for each sign location. Fusion tables is great because it will automatically geocode most things you throw at it – in my case cross streets (Pierce & Chatfield).

With just a few lines of code I could easily see all of the places where signs needed to be.

That was good, but what she really needed was a way to show only certain types of signs on the map for a specific group to place. I added a simple select element that changed the query parameters sent to the Fusion Tables API which automatically updated the overly.

Cool, now we know where the locations are and what we need to place there, but where am I? With the native geolocation capabilties now found on most mobile browsers I could easily tap in and get a very precise location and show it on the map.

Still, this could be better. Instead of using the getCurrentPosition method, I opted to use the lesser known watchPosition. This constantly polls the device for an accurate location (at the cost of battery life) so that a moving marker could be shown on the map to help the navigator.

Here at MapMyFitness we’ve been increasing our usage of the GeoJSON format over the last few months. Whether it’s displaying routes on a Google Map or processing data between subsystems, GeoJSON has proven to be a simple dialect for describing various geo features in our systems.

One thing I’ve been wanting to do for quite some time is build a GeoJSON validator. While the spec is very simple, it’s easy to get tripped up when you’re first getting started with the format.

So, I built http://geojsonlint.com. It’s a very simple django app that validates your GeoJSON and shows your feature(s) on a map if everything checks out ok. It works by POSTing your data to the /validate endpoint and returning a JSON object that signifies success or an error.

A few weeks back Brian Timoneytweeted about some recent Denver/Colorado open data efforts. OpenColorado hosts over 400 data sets from DRCOG, the City and County of Denver, Boulder and a handful of others.

I decided to see what data was available and what I could do with it. The Public Art data set seemed interesting and small enough to do create something without too much effort.

I downloaded the shapefile and uploaded to my hosted geo service of choice, CartoDB. I use CartoDB because, with the exposed SQL API, my options are almost endless.

Within a few hours (over a few days) I put together a quick “Denver Art Finder” application. It uses Leaflet for the web mapping API and Handlebars as a simple templating engine. The application works by checking your location (you can fake it if you’re not in Denver) and searching for public art within 1km of you via CartoDB’s SQL API. If we find some, we throw some pins on the map that you can click (tap) to find the title of the piece, the artist’s name, and how far away it is. Very simple stuff.

You can grab the source code or view the application at the links below:

I couldn’t help but wonder about the spatial distribution of all of the breweries attending the festival. Will there be a Colorado bias? I wonder who’s coming from my home state (North Carolina)? Anyone coming from Alaska, Hawaii? (yup)

So, being a geo geek, I headed to their website in hopes of finding a map. No luck. But there was a well-fomratted table of all 566 breweries. Nice.

I vaguely remembered some twitter chatter from a few months back about ScraperWiki, but didn’t know much about it. Within a few minutes, even with my marginal Python skills, I was able to write a recipe to scrape all of the names, cities and states for all of the breweries. The end product? A CSV.

Time to head to CartoDB. Importing my CSV was easy enough and geocoding these points through their interface was easy enough. You can even concatenate multiple columns to geocode against – in my case {city}, {state}, USA.

More exciting than the map itself is the fact that it took about 20 minutes to do all the things above. Thanks ScraperWiki and CartoDB!

Leaflet Vector Layers is Google Vector Layers’ twin brother. The API is nearly identical (new gvector.AGS({...}) vs. new lvector.AGS({...})) and the library works exactly the same — fetching features as the user pans and zooms the map, or fetching all features at once for smaller data sets.

It’s also great for use behind the firewall where the Google Maps terms or pricing can be prohibitive for some organizations.

Leaflet Vector Layers has all of the features of the Google Maps flavor like multi-provider support, popup (InfoWindow) templating, simple symbology definitions, support for dynamic data and scale dependent rendering.

So, check out the links below for an overview of the library, documentation and demos.

Links

The Main Page (Start Here) – This will link you to the source code, demos and documentation