Fire Eagle GeoJSON Oops

Update (2008-03-13)

Fixed.

Update (2008-03-12)

Problem to be solved this week, I hear.

Sharper eyes than mine noticed that the Fire Eagle "geojson" format is a bit out of date relative to the spec. I checked my location using the walkthrough app:

>>> import simplejson
>>> data = simplejson.loads(json)
>>> from pprint import pprint
>>> pprint(data['user']['location_hierarchy'][0]['geojson'])
{u'coordinates': [-105.0842514038, 40.594463348399998], u'type': u'Point'}
>>> from shapely.geometry import asShape
>>> x = asShape(data['user']['location_hierarchy'][0]['geojson'])
>>> x
<shapely.geometry.point.PointAdapter object at 0x834ce6c>
>>> x.wkt
'POINT (-105.0842514037999962 40.5944633483999979)'

Fire Eagle point representations are okay, and can be adapted into Shapely geometries. How about the polygon in the location hierarchy?

>>> pprint(data['user']['location_hierarchy'][1]['geojson'])
{u'bbox': [[-105.15278625489999, 40.480018615699997],
           [-104.9821014404, 40.639278411900001]],
 u'coordinates': [[-105.15278625489999, 40.480018615699997],
                  [-104.9821014404, 40.480018615699997],
                  [-104.9821014404, 40.639278411900001],
                  [-105.15278625489999, 40.639278411900001],
                  [-105.15278625489999, 40.480018615699997]],
 u'type': u'Polygon'}
>>> x = asShape(data['user']['location_hierarchy'][1]['geojson'])
>>> x.exterior
Traceback (most recent call last):
...
TypeError: object of type 'float' has no len()

The Fire Eagle polygon representation is wrong: it should be a list of rings, not a ring. (Memo to myself: clearly, Shapely needs to handle this situation better, providing a less ambiguous exception at the very least.)

If we insert that ring into a list, it would be fine:

>>> fe_geom = data['user']['location_hierarchy'][1]['geojson']
>>> fixed_geom = {'type': fe_geom['type'], 'coordinates': [fe_geom['coordinates']]}
>>> x = asShape(fixed_geom)
>>> x
<shapely.geometry.polygon.PolygonAdapter object at 0xb7d0746c>
>>> x.exterior.length
0.65988922139999318
>>> x.area
0.027183228771704648

We've got a problem.