Mapping
Google voter info gadget
Today Google launched a voter information mapplet and gadget that I built (with help from some talented people at Google).
It’s a simple little application that just looks up voter registration information for your address, and later this month will also display your voting location. They are going all out to promote it, with a link on the main Google home page, and a cool video with a few faces you may recognize:
Now go register to vote, or Leonardo will never speak with you again!
Where Do You Vote?
This is a test of the 2008 US Voter Info gadget.
Pennsylvania Primary Google Map
Another day, another primary, another Google map. This time we added a bunch of demographic information using little sparkline graphs, with help from Jim Barnes of the National Journal. I think the voter registration by age is especially interesting. Check it out:
(The map probably won’t load in an RSS feed, so click through to the article to see it.)
You can get this map for your own site!
Mapping the Votes - resources
I want to thank everyone who came to my Mapping the Votes talk at Google. The talk is available on YouTube - with apologies for the small font size in the code samples!
Here are some links and information that I referred to in the talk.
Maps and mapplets
Decision 2008 - the current election mapplet
Decision 2008 Gadget - the election map as a Google Gadget
Iowa Republican Caucus - an early API map
Iowa mapplet - an early mapplet
Twitter election map - the Super Tuesday twitter map (showing tweets from that day)
Campaign Trail - candidate calendars
New Hampshire in Google Earth - a KML file
Editors and desktop tools
The editor I used for the code samples is the one I use every day, Komodo IDE. Komodo’s debuggers for Ruby, Python, and PHP make it really easy to test my batch/script/server code. I’m especially fond of coding in the debugger. For the code that converts shapefiles and vote data into JSON output, I’d write the input part first, set a breakpoint and stop in the debugger after it reads the data, then write the conversion code with live data to look at while I code. Komodo also has a JavaScript debugger that works equally well, but most of the time I just use Firebug because of its simplicity.
Komodo IDE isn’t cheap, but I figure it paid for itself really fast. There’s also a free Komodo Edit that everyone should install even if you already have a favorite editor. Both versions have real-time syntax checking, where you get squiggly red underlines for syntax errors and squiggly green underlines for warnings, just like the spelling and grammar checkers in a word processor. This has saved me literally thousands of page reloads when testing, since Komodo catches my syntax errors before I even save the file. Komodo runs on Linux, Mac, and Windows.
One nice thing about GUI editors is that the basic editing works the same in all of them (or should), so it’s easy to switch back and forth if some other editor has a feature you want to take advantage of. Besides Komodo, I also use PSPad (free, Windows only), mostly because of its nice HTML/XML pretty-printer. It cleans up unreadable web page source code real quick.
Another expensive-but-well-worth-it tool for Windows and Mac is Araxis Merge, a terrific file compare and merge program with live editing. I use Merge as the diff/merge program for TortoiseSVN, which makes source control a dream.
A couple of free Windows tools I use every day are Zoom+ for screen zooming and my own JKLmouse for precise cursor control with the keyboard of your notebook computer. With JKLmouse, I can use the TrackPoint for fast cursor motion and then the keyboard for fine pixel-by-pixel movement, seamlessly and with no “modes”. (Sorry, I had to brag!)
Source code
The election map code is open source and is in two Google Code projects. The current code is in the primary-maps-2008 project, and the code for earliest caucuses and primaries is in the gmaps-samples project. (We moved the code to a new project to avoid filling up gmaps-samples!)
If you look at the code, go easy on me: much of it was written under severe time pressure. I asked if the elections could be delayed when I wasn’t quite ready, but even the mighty Google couldn’t seem to arrange that.
Also, if you read the code using the links provided here, there’s an awful lot of indentation, thanks to Google Code displaying my tab indentation using 8 spaces per tab. Shades of K&R! (So, why do I use tabs instead of two-space indents like everyone else? Well, one of the other benefits of Komodo is that unlike most code editors, it lets me edit in a proportional font. Two spaces in a proportional font is almost like not indenting at all.)
Shapefiles
Shapefiles are a wacky file format used for geographic data. Be thankful that other people have already written programs to pick them apart, so you and I don’t have to.
At first, I was using shp2text to convert shapefiles to an easy-to-use XML format (using the --gpx
option), but this loses some of the information in the shapefile. More recently, Zachary Forest Johnson, author of the interesting indiemaps blog, wrote shpUtils.py, which decodes shapefiles into usable Python data.
I extended shpUtils.py to calculate correct centroids, area and other information about the shapes, and to fix a few bugs. The updated version is in the primary-maps-2008 project.
Centroids
The election maps use the centroids of the state and county polygons to position markers for those states.
Centroids are one of those things that you think you understand and then find out you were completely wrong. My first guess was the same as Zachary’s, to take the arithmetic mean of all the points (X and Y separately). The Wikipedia article even seems to say this, but it’s talking about the centroid of the points, not the centroid of the polygon that those points define. If you read it carefully, the article does give the correct algorithm, but it’s better explained on this page, along with sample implementations in various languages.
Census bureau shapefiles
The state and county outlines in the election maps come from shapefiles provided by the Census Bureau. Most states report votes by county, but a few New England states report by town (County Subdivisions in the Census Bureau page), and a few other states report by congressional district.
Shapefile simplification
D’oh! I completely forgot to talk about this important topic. The Census Bureau shapefiles have too much detail to be usable in a browser-based map. If you draw polygons from them, it will be much too slow. A tile layer can handle more detail, but the graphic files will be larger than they could be, because of the excess detail.
MapShaper is a free online tool to simplify shapefiles. It is pretty neat—you can see the effect of your simplification in realtime as you try different settings. I used MapShaper for the election maps, with various levels of simplification: simpler for JavaScript and more detailed for tile layers. More recently I discovered the Map Simplification Program which looks ideal for programmed simplification.
The code that processes shapefiles for the election maps is in makepolys.py which generates JSON output, and maketiles.py which generates tiles from that JSON data using ImageMagick.
Votes and delegates
The code to convert vote data from the latest primaries is in voter.py. This processes CSV files provided by the Boston Globe and converts them to JSON data.
Twitter map
The Ruby script that gathers the Twitter updates uses the Jabber::Simple module written by Blaine Cook to create a custom Jabber client that talks to Twitter, and uses the Twittervision API to get geographic information. It parses the XML data with sweet Hpricot, then generates JSON data (but you probably saw that coming). If you like jQuery, you’ll like Hpricot.
Mapplet code
The election mapplet code is in decision2008.xml and map.js. The code for the Campaign Trail mapplet is in campaign-trail.xml and campaign-trail.js. The latter file has the latest versions of the Array.mapjoin()
, Array.index()
, Object.sort()
, S()
, and related functions that I talked about. They are at the top of the file, and not yet documented, but you can find examples of each in the code.
More to come
That’s it for now! I’ll be posting more detailed articles on some of these topics. If there is a particular area you’re interested in, please let me know in the comments.
Thanks!
Google Maps talk
Update: I posted some notes and links from the talk.
I’m giving a talk at Google tonight at 6pm about the election maps I’ve been working on. I’ll be talking about:
- How to use the same code for a mapplet, a Google Gadget, and a Maps API map
- Turn shape files into map tiles, polygons, and markers
- Collect voting results into JSON objects
- Marker madness - can we make it fast enough?
- Hosting on Google Code and Amazon S3
- A custom Twitter map using Jabber to track keywords
I’ll follow up tomorrow with links to the resources I mention in the talk, and then will post a series of articles going into some of the topics in more detail. If you are at the talk or watch the YouTube video, let me know in the comments what areas are of most interest for follow-on articles.
To register for the talk: https://sv-gtug-4.eventbrite.com/
Thanks!
My little Google map
I’ve been working on a project for Google this last month, a mapplet with primary election and caucus results. We’ve done different versions for the primaries so far. For previous states, the emphasis was on mapping the county-by-county results. The latest one is different, a bit of a Twittervision clone, but filtered for messages related to the elections instead of all Twitter messages.
Some people said it was lame and useless; others complained that they spent all day Tuesday watching it.
We report, you decide. :-)
There are plenty of stories to tell about this project, more later…