Python GIS features
How do you access the attributes and geometry of features in your favorite Python and GIS environment? Let's imagine we're interested in the state_name attribute from a US States data set and compare. I'll employ the iterable adapters I introduced in a previous post to simplify the code.
ESRI:
That's not bad at all, although there's potential for name collisions.
FME:
for f in FMECollection(features): state_name = f.getAttribute('state_name') geom_type = f.getGeometryType() geom_coords = f.getCoordinates()
Evil or not, getters and setters aren't needed in Python.
OGR (earlier than 1.5):
for f in OGRCollection(layer): state_name = f.GetFieldAsString('state_name') geom = f.GetGeometryRef() # Don't forget to free the memory allocated for the feature! f.Destroy()
Destroy!
OGR (current, also known as osgeo.ogr):
Howard Butler has made osgeo.ogr much more peaceful.
QGIS:
for f in QGISCollection(provider): attribs = f.attributeMap() state_name = attribs['state_name'].toString() geom = f.geometry()
A mapping of attributes is design that I like, but it could be more user friendly.
5 different environments, 5 different ways.
Ideally, feature attributes (not to be confused with Python object attributes) are accessed through a mapping attribute to prevent collisions in the feature's own namespace, and the feature geometry is simply another attribute:
for f in features: # A dict has all kinds of nice built-in features, like attribute_items = f.properties.items() # [('state_name', 'Utah'), ...] assert 'state_name' in f.properties # True state_name = f.properties['state_name'] geom = f.geometry
Looks a bit like GeoJSON? Yes, it does.