Mapping Oakland’s license plate reader data


For the past few years the Oakland police department has been using license plate reader (LPR) technology to record the license plates of cars. In response to a public records requests the city released the entire data set to Ars Technica and later posted 13 of the original 20 files to their open data portal.

The released LPR data may be searched and mapped at this site, The site uses Flask and is backed by a MySQL database containing 2,738,523 LPR records. A sample search for a license plate belonging to an Oakland Police patrol car turns up 240 records.

Getting tracklogs into Mapnik

The following describes my experience generating an OpenLayers slippy map from GPS tracklogs using TileMill, TileCache, and Mapnik.

I started by exporting my run data from Garmin Training Center and converting it from Garmin Training Center format (.tcx) to GPS Exchange format (.gpx) using GPSBabel.

The resulting GPX had some improperly long, straight segments caused when I would stop and start the tracklog after taking BART underneath the Bay. I massaged the data a bit using a python script to weed out these long segments.


Run map + OpenStreetMap

I followed the instructions to add OpenStreetMap to my run map.

Larger version.

Running map

Three years of GPS track logs made into a slippy map.

This little project was a lot more difficult than I thought it would be. It took a great deal of trial and error. I’ll follow up with a post on how I got it to work.

Garmin Connect Google Maps Greasemonkey script updated

I updated my Greasemonkey script that replaces the Bing Map with a Google Map in Garmin Connect. This version is made faster by completely disabling the Bing Map and it no longer fetches the map information twice. Additionally, I’ve fixed the lap display markers and improved the quality of the track line.

Install Garmin Connect Google Maps Greasemonkey Script v0.2.

I have also posted Garmin Connect Google Maps at

Note: For some reason I had to uninstall the old script before installing the new one–Greasemonkey didn’t seem to recognize the upgrade.

Missing Google Maps on Garmin Connect

Greasemonkey logoGarmin Connect, a site I use to log my runs and bike rides, switched from Google Maps to Bing Maps back in November. Bing Maps’ coverage seems generally inferior to Google Maps and I think the maps just look better on Google. Also, Bing Maps seems to apply some overly-aggressive line smoothing, making tight corners look like wide curves.

I finally got around to writing a Greasemonkey script to restore the Google Map on the dashboard and activity pages.

Here’s the link to the script:

Install Garmin Connect Google Maps Greasemonkey script.

A Google Map compared with a Bing Map

A run I did in Kathmandu displayed on Google Maps, top, and Bing Maps, bottom.

Getting PyQt4 to work on Snow Leopard

I recently upgraded my Mac to OS 10.6 and I had to rebuild Qt and PyQt to get them working again. I installed Qt 4.5.3 from source and then installed sip 4.9.1 and PyQt4.6.1. Immediately it failed to work with the following error:

>>> from PyQt4 import QtCore
Traceback (most recent call last):
  File "", line 1, in 
ImportError: dlopen(/Library/Python/2.6/site-packages/PyQt4/, 2): Symbol not found: _sipQtConnect
  Referenced from: /Library/Python/2.6/site-packages/PyQt4/
  Expected in: flat namespace
 in /Library/Python/2.6/site-packages/PyQt4/

Some quick searching led me to this post, which implied that hacking PyQt’s file to force the architecture to be 64-bit would do the trick.
So where it says:

for a in sipcfg.arch.split():
    if a == 'i386':
    elif a == 'x86_64':
    elif a == 'ppc':

Replace qmake_archs.append('x86') with qmake_archs.append('x86_64').
Now PyQt works again.