If your favorite Python GIS environment doesn't provide iterators, you can easily implement adapters like these.
ESRI (ArcGIS 9.3):
class ESRICollection(object):
def __init__(self, context):
self.context = context
def __iter__(self):
row = self.context.next()
while row:
yield row
row = self.context.next()
raise StopIteration
More or less as done here. Usage:
>>> for f in ESRICollection(rows):
... # work with f
QGIS:
class QGISCollection(object):
def __init__(self, context):
self.context = context
def __iter__(self):
feat = QgsFeature()
while provider.getNextFeature(feat):
yield feat
feat = QgsFeature()
raise StopIteration
Returning new objects from the iterator rather than returning the same object with new values heads off unpleasant surprises. Usage:
>>> for f in QGISCollection(provider):
... # work with f
OGR (earlier than 1.5):
class OGRCollection(object):
def __init__(self, context):
self.context = context
def __iter__(self):
feature = layer.GetNextFeature()
while feature:
yield feature
feature = layer.GetNextFeature()
raise StopIteration
Usage:
>>> for f in OGRCollection(layer):
... # work with f
Notice a big difference between yield and return: the former gives a value, but execution continues after the statement rather than breaking as with the latter.
Comments are closed after 13 days.
1Re: Iterators, again
Eric Wolf, 2009-10-25T12:50:12Z
Thanks Sean! I've been wondering how to overload iteration in Python. Haven't bothered to find out on my own. Should make stupid ESRI cursor code a little cleaner.