Mike Gifford's profile picture

Mike Gifford is the founder of OpenConcept Consulting Inc, which he started in 1999. Since then, he has been particularly active in developing and extending open source content management systems to allow people to get closer to their content. Before starting OpenConcept, Mike had worked for a number of national NGOs including Oxfam Canada and Friends of the Earth.

As a techie at heart, Mike likes to get into the code when he gets the chance. Being ultimately concerned about the implementation and implications of the technology, he is able to envision how your website can become a much more powerful communications tool for your organization.

Mike has been involved with accessibility issues since the early 1990's and is a strong advocate for standards based design.

Location Aware Campaigns with HTML5

July 12, 2011

More and more our browsers know where we are and can help simplify our decisions. Many campaigns ask for your postal code as a simple means to help gain some location awareness about your visitors, however, this is rarely accurate on a smart phone and never convenient. As we've already blogged HTML5 begins to address this problem by providing a better means for dealing with location. There's a lot of new ways that sites are going begin to take advantage of this information.

One way that I've wanted to explore was with political campaigns. Most of us spend a great deal of our time in the our ridings and know which electoral district we are in even if we don't vote. However, it would be useful many times to be able to simply pick up your smart phone and figure out which riding you happen to be standing in. Say if there's a dangerous pot hole you wanted to report to a municipal councillor, but were outside of your riding. Or you wanted to tell a member of parliament where you worked that it is important to you to fund public transit. Whatever it is, if you can make it easier to put people in touch with those who are elected representatives for that region they will be more interested in your communications.

Now Vote.ca has a great system that allows you to find Canadian federal as well as some provincial & municipal electoral districts. They also have an API that allows for a machine operable way to do this, so our computers can do some work for us. I haven't spent any time verifying this data or comparing it with the postal code to riding data that we have purchased through Statistics Canada, but in my limited tests it seems to work well. It is a free rate limited service (10 requests per minute/IP address) but it should be workable for many Canadian campaigns.

I wanted to simply blend in some of the HTML5 geolocation information with this API to show quickly how powerful this framework is. I saw being able to further extend it so that we could access the name & contact information that we have on file for members of parliament through our Make the Change service (we archived this in 2014). We have a similar API that we wrote a while back to interact with riding data. I saw this all being done with the jQuery library which has a lot of great client side tools for manipulating data. Using HTML5, geodata & mashing that up with two different API's to produce politically useful information just seemed to good to pass up.

I can see extending this to hit the Sunlight Labs API for visitors from the USA & the They Work For You API for visitors from the UK. It could even be tied into services like Groups Near You (no longer available) to pull up lists of geographically tied online communities. With the Flickr API and jQuery tools like Geofetch it should be quite straight forward to do things like generate a web gallery based on images where you are right now.

Sadly it was more complicated than I thought. Partly because I'm not a Javascript developer, but also because there aren't many models of how to do this within a Drupal 7 environment. Drupal 7 is a bit more rigid about how it implements jQuery than Drupal 6 used to be. I also found that it was more difficult to share debugging information with others so that they could help resolve the problem. Fortunately, I ran into jsFiddle that allows me to create an environment to test javascript problems, share them & even fork them. I posted the code I used here so that others can play with it. I love that you can both cleanup the presentation of the javascript to make it more readable & check for errors in in the code all in the same interface. Sometimes even modern browsers like Chrome & Firefox will provide different results to the same javascript. The example below doesn't work for me with Firefox.

Please add a comment if you've mashed this up further or found other ways to make this information useful.

If you are viewing this page in Canada with a modern browser it should be able to help you determine your electoral district information.


var $message_area = jQuery('#results'); // Call this function once we have a latitude and longitude function districts_for_geocoder_result(result) { $message_area.children().remove(); // alert(theURL + "?callback=?&error=?" + latlng['lat'] + latlng['lng']); jQuery.getJSON('http://api.vote.ca/api/beta/districts?callback=?&' + jQuery.param({ 'lat': result.lat, 'lng': result.lng }), function(data) { if (data.length == 0) { $message_area.append('

No districts found. Is that address in Canada?

'); } jQuery.each(data, function() { $message_area.append('

In ' + this.electoral_group.name + ' (' + this.electoral_group.level + '), your district is ' + this.name + '.

'); }); }); } function yesclick() { $message_area.children().remove(); $message_area.html('Parsing your electoral districts...'); results.lat = lat; results.lng = lng; districts_for_geocoder_result(results); } function noclick() { $message_area.html('

Sorry, we were not able to maintain an accurate reading of where you are.

'); } jQuery(document).ready(function() { $message_area.html('Locating you... '); if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( // Find location function foundLocation(position) { $message_area.children().remove(); // To see everything available in the position.coords array: // for (key in position.coords) {alert(key)} lat = position.coords.latitude; lng = position.coords.longitude; // alt = position.coords.altitude; // acc = position.coords.accuracy; // hed = position.coords.heading; // spd = position.coords.speed; $message_area.append('Your latitude: ' + lat + ' and longitude: ' + lng + ':'); $message_area.append(''); $message_area.append('

Is this where you are: Yes or No

'); jQuery('#information-button-yes').click(function(event) { yesclick(); }); jQuery('#information-button-no').click(function(event) { noclick(); }); }, // Error callback function(error) { switch (error.code) { case error.TIMEOUT: $message_area.append('Timeout error while finding your location'); break; case error.POSITION_UNAVAILABLE: $message_area.append('Position unavailable error while finding your location'); break; case error.PERMISSION_DENIED: $message_area.append('Permission denied error while finding your location'); break; case error.UNKNOWN_ERROR: $message_area.append('Unknown error while finding your location'); break; } }); } else { $message_area.html('Your browser/OS does not seem to be compatible'); } });