Throughout my career, I’ve been able to work with a wide variety of data, on an array of project. Financial data, retail data, network data etc. Data modeling is a fun challenge. Using a standard RDMS, modeling objects can sometimes be a challenge. NoSQL has changed how data is modeled… but that’s a different topic. Fooled you.

There are two pieces of data that I have always had a harder time conceptualizing in a standard data model.
1) Time
2) Geolocation

Modeling data over time is a challenge. I’ll get back to Graphite again in the near future, but today, we’re going to talk about geolocation.

Geolocation
According to wikipedia, http://en.wikipedia.org/wiki/Geolocation, Geolocation is:
the identification of the real-world geographic location of an object, such as a radar, mobile phone or an Internet-connected computer terminal. Geolocation may refer to the practice of assessing the location, or to the actual assessed location. Geolocation is closely related to the use of positioning systems but can be distinguished from it by a greater emphasis on determining a meaningful location (e.g. a street address) rather than just a set of geographic coordinates.

I’m a huge fan and user of RunKeeper (www.runkeeper.com) and Strava (www.strava.com). I use RK for running, and Strava for cycling (mountain and road). There are reasons I like each, but again, I keep trying to digress. Back to the topic at hand.

They both provide iPhone applications to record activities. These applications use the phone’s GPS to get the location data. Then, it’s aggregated into segments/runs/etc and send to their servers. They each do some great analysis on the data for reports and status.

I wanted to know how that happens. I’ve been “around” tools like ArcGIS but never used them…. so, what could I use in my open source world.

Tools
There are two sides of this equation, one is localized sensors and second is storage and aggregation. PostgreSQL has some REALLY nice built in data structures for paths, boxes, points, etc.. more to come.

I wanted to try the web browser as the data collection point, instead of writing an iOS/Android app. That’s next step.. but for now, here’s how to get some data in the web browser.

navigator.geolocation
A new component of the HTML5 spec has browser based geolocation. According to “Can I Use”, http://caniuse.com/#feat=geolocation , all major browsers support it.

First step: Get a reference to the geolocation prototype. Tell it you want to ‘watch’ where you are, with high accuracy and some callbacks for success/error conditions.

var geo = navigator.geolocation;
if (geo){
var options = {
enableHighAccuracy: true,
timeout: 5000, maximumAge: 0
};
//Global watchID to cancel this later.
watchID = navigator.geolocation.watchPosition( where_am_i, bad_where_am_i, options);
}else{
alert("No geolocation for you!");
}

Pretty straight forward. First, I want to talk about the error callback. This is what inspired me to write. It’s a self documenting error! Having dealt with, and written, a ton of APIs/functions, etc, I am impressed with the simplicity of this callback. Just think (I know, I haven’t shown it to you yet), compared to string comparisons on error types or error messages coming out of an API call, this makes error handling EASY!

{message: "PositionUnavailable", code: 2, PERMISSION_DENIED: 1, POSITION_UNAVAILABLE: 2, TIMEOUT: 3}


bad_where_am_i = function(e_object){
console.log(e_object);
if (e_object.code == e_object.TIMEOUT){
console.log("This data point is old.");
}else if (e_object.code == e_object.POSITION_UNAVAILABLE){
console.log("Location services are temporarily unavailable.");
}else if (e_object.code == e_object.PERMISSION_DENIED){
console.log("This domain does not have permissions to access location services.");
}

}

(First off, I’m not a fan of switch statements for simple conditions like this.. personal preference).
That e_object, has a ‘code’ attribute which is an integer. It has other attributes, which are all capitalized (CONSTANTS!) to represent what the code COULD be.. plus an error message (message). This error message isn’t human readable, but, it doesn’t have to be when you have a construct like this to figure out what the error is. I can write my own internationalization messages based on the code/lookup values.

Success

Accessing geolocation data from the success callback is a breeze. Here’s the structure of a successful callback:

{
"timestamp": 1378807343723,
"coords": {
"speed": null,
"heading": null,
"altitudeAccuracy": null,
"accuracy": 24000,
"altitude": null,
"longitude": -77.649158,
"latitude": 37.505981
}
}

Accessing latitude/longitude:

var lat = position.coords.latitude;
var lon = position.coords.longitude;

Simple enough!
What to do with it, that’s the challenge. Next post, geolocation in PostgreSQL! Maybe the Google Maps API (below is a screen shot)

Screen Shot 2013-09-10 at 6.04.12 AM