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:
for row in ESRICollection(rows):
state_name = row.state_name
geom = row.shape
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):
for f in layer:
state_name = f.state_name
geom = f.geometry()
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.
Comments are closed after 13 days.