Iterators
How do you get a GIS feature from a Python collection/layer/provider/thingy? Let's look at 4 different popular GIS scripting environments.
ESRI (ArcGIS 9.3):
FME:
self.my_collection_count = len(self.my_feature_collection) for i in range(self.my_collection_count): self.my_feature_part = self.my_feature_collection[i] # work with self.my_feature_part ...
Note: don't use instance attributes like that. Use local variables.
QGIS:
The oddball.
OGR (earlier than 1.5):
feature = layer.GetNextFeature() while feature: # work with feature ... feature.Destroy() feature = layer.GetNextFeature()
Destroy!
4 different environments, 4 different ways, and none of them the natural Python way. There's one obviously right way to do it for Python, and that's the way that it's done in ogr.py versions >= 1.5, and how it's done in WorldMill. GeoDjango, too.
where layer is among other things a generator that provides the iterator protocol just like Python strings, lists, and files do. It has a next method that yields a value, or raises a StopIteration exception when there are no more values. The advantages:
Clarity: it's agonizingly clear. More clear to a non-programmer, in my opinion, than the other alternatives. For each feature in the set: do something. And then forget about the feature and move on to the next.
Less error-prone: even a non-programmer can't screw up that one line of code any worse than to get a standard, understandable Python NameError, TypeError, or SyntaxError.
Standardization: core Python modules such as itertools and many other useful add-on packages reward you for using the iterator protocol.
Comments
Re: Iterators
Author: few people
I think ESRI has done away with the while: row = rows.next() stuff at 9.3.1: http://webhelp.esri.com/arcgisdesktop/9.3/index.cfm?TopicName=FeatureSets_and_RecordSets
Re: Iterators
Author: Mateusz Loskot
Sean, brilliant post! Finally, a voice clarity, correcness, robustness, discoverability, transparency, genericity, expressiveness, flexibility, consistency, meaning...
Quality MattersAny of the interested parties are considering it in the same manner?
I'm afraid, that's the end of story.
Re: Iterators
Author: Michael Weisman
Just a quick clarification, FME does support iterators. The following snippet will iterate over the parts of an aggregate feature and extract the coordinates for each part:
Re: Iterators
Author: Mateusz Loskot
And a bit of clarification from me, I was referring to the Open Source projects mentioned above. Unfortunately, SWIG is in the house over there.
Re: Iterators
Author: Sean
Great, Michael. I simply didn't find examples of iterators employed by FME users. I haven't seen examples of programmers using Howard Butler's neater ogr.py API either.
QGIS
Author: Martin Dobias
Thanks for the nice article. Recently I've been thinking about adding a more pythonic way of accessing features in PyQGIS... currently it's just a crude wrapper around c++ api. So thanks for the inspiration :)
Re: Iterators
Author: Howard Butler
ogr.py is not mine. ogr.py is Frank's API ;), but I think I added support for this at GDAL 1.6. I guess we haven't advertised it so well.