The Scoop

  • Home
  • Projects
  • About The Scoop
  • Fixing Journalism
  • Medill Links
  • Departments
    • API
    • Apple
    • Asides
    • Broadcast
    • Campaign Finance
    • Car Tools
    • Data
    • DIY
    • django
    • Fed Data
    • FOIA
    • General
    • IRE
    • Journalism
    • Local Data
    • Mapping
    • Miscellany
    • NonGov Data
    • Online
    • Paper Trail
    • Presentations
    • Public Records
    • Python
    • Rails
    • SLA
    • Social Network Analysis
    • Sports
    • State Data
    • Teaching
    • Work
    • XML
  • Subscribe via RSS

Using Geocoders with GeoDjango

January 24th, 2010  |  Published in Mapping, Python, django  |  4 Comments

Update: Simon has updated his library to make it easy to reverse the order of coordinates. Thanks!

For a “15-minute project“, Simon Willison’s geocoders library is pretty handy if you’re doing geocoding with Python. It offers a common interface to the geocoding services provided by Google, Yahoo and other sources. When we were looking at replacing the home-grown geocoding system that Andrei Scheinkman built for Represent, Simon’s project seemed a natural choice.

It was an easy drop-in, but there was one thing about it that was just slightly off. A successful geocoding result looks like this:

(u'New York, NY, USA', (40.756053999999999, -73.986951000000005))

Notice the coordinate pair is latitude, longitude. For folks using GeoDjango alongside Simon’s library, the way you build a Point object from coordinates is to pass the longitude first, like so:

>>> from django.contrib.gis.geos import Point
>>> p = Point((5, 23)) # 2D point, passed in as a tuple

So on Friday I forked Simon’s project and reversed the ordering of the coordinates in a successful result. That way you can pass that portion of the result directly to a Point constructor:

>>> from django.contrib.gis.geos import *
>>> from geocoders.google import geocoder
>>> geocode = geocoder('GOOGLE-API-KEY')
>>> results = geocode('new york')
(u'New York, NY, USA', (-73.986951000000005, 40.756053999999999))
>>> pnt = Point(results[1])

Not a huge deal, but in keeping with the spirit of library, I think.

Responses

Feed Trackback Address
  1. Simon Willison says:

    January 25th, 2010 at 8:36 am (#)

    I’m clearly not a real geo-nerd, because I’ve always found longitude/latitude ordering unintuitive. You’re right though, it’s silly not to support the format used by GeoDjango. I’ve just committed a fix for this, which changes the API to look like this:

    >>> from geocoders.google import geocoder
    >>> geocode = geocoder(‘GOOGLE-API-KEY’, lonlat=True)
    >>> results = geocode(‘new york’)
    (u’New York, NY, USA’, (-73.986951000000005, 40.756053999999999))
    >>> pnt = Point(results[1])

    As you can see, the default order remains the same (partly to ensure backwards compatibility for existing library users, but mainly because I prefer it) but you can now specify the order you want when you instantiate the geocoder – which you hopefully only do in one place in your code.

    Here’s the commit: http://github.com/simonw/geocoders/commit/46fc00bda4cff0fe222d38fe498aa9ba861e8dc1

  2. Aaron says:

    January 25th, 2010 at 8:47 am (#)

    As you say, it’s not a huge deal — and I’m not opposed to forking for minor changes — but would it be easier to just do:

    pnt = Point(results[1][::-1])

  3. Derek says:

    January 25th, 2010 at 11:02 am (#)

    Thanks, Simon! I think yours is the most flexible solution for everybody. And I’m not a real geo-nerd either; just someone who gets to look good thanks to GeoDjango.

    Aaron – yeah, you could, sure. I guess it just looked cleaner to me the other way.

  4. Chris Amico says:

    January 25th, 2010 at 11:49 am (#)

    Here’s how I’ve mostly done it (using Geopy, which has the same issue):

    def geocode(q):
    place, (lat, lng) = g.geocode(‘somewhere’)
    return Point(lng, lat)

    I do like Simon’s fix, though.

Leave a Response

Recent Comments

  • Jessica Baumgart on How APIs Help the Newsroom
  • Bookmarks van juli 7th tot juli 14th | .: zerocontent - Blog :. on How APIs Help the Newsroom
  • Reporting with Data: How the New York Times Uses APIs on How APIs Help the Newsroom
  • Brad B on Six Reasons To Look Past Caspio
  • Annelies on Big Numbers, Low Impact

Recent Posts

  • How APIs Help the Newsroom
  • Big Numbers, Low Impact
  • Using the NYT Congress API with … Excel?
  • An Even Better CAR Conference?
  • 2010 CAR Conference


©2010 The Scoop
Powered by WordPress using the Gridline Lite theme by Graph Paper Press.