[Gdal-dev] ogr.py enhancement proposal

Howard Butler hobu at iastate.edu
Wed Feb 2 11:11:26 EST 2005


Folks,

I have been making some enhancements to ogr.py to make it more pythonic and 
more convenient to program with, especially in the interactive mode which 
Python excels so well with.  Below is a short list of the enhancements I've 
already made, and a proposal for further enhancements that I would like to 
implement.  These changes are completely backward compatible (all the way 
back to 2.0), and you do not have to use them to program with ogr.py.  I'm 
interested in you feedback as to whether or not this work would be 
beneficial, keeping in line with the direction and history of ogr.py, and 
if you think they are a good idea.

The major enhancement that I made was to allow slicing and index access to 
Layer and DataSource.  Here is an example of what I mean:

#--------------------------------------------------------------
# Get the first layer on the DataSource
ds = ogr.Open(my_data_location)

# current approach
lyr = ds.GetLayer(0)

# enhanced approach
lyr = ds[0]
#--------------------------------------------------------------

The advantage of this approach is that we get slicing and looping for free 
from Python.  For example:

#--------------------------------------------------------------
# Put the first four layers into a list
layers = ds[0:4]

# Put all the layers in a list except the first one
layers = ds[1:]

# Print the names of all of the layers on the DataSource
for i in ds:
     print i.GetName()
#--------------------------------------------------------------

The same enhancement was made to the Layer object as well.  It is important 
to note, however, that you are not *guaranteed* sequential access to the 
Features in a layer.  This approach will work for the majority of cases, 
but if you have a funky DataSource/Layer, you might not always get what you 
expect.

#--------------------------------------------------------------
# Get the first 10 features of the first layer

# current approach
lyr = ds.GetLayer(0)
features = []
for i in range(lyr.GetFeatureCount()):
     if i < 11:
         features.append(lyr.GetFeature(i))

# enhanced approach
lyr = ds[0]
features = lyr[0:10]

# again, we get looping and slicing for free
for i in lyr[0:10]:
     print i.GetField(0)
#--------------------------------------------------------------

Feature Enhancement Proposal

I would like to extend Feature to support run-time attribute 
lookup.  Thanks to Frank's enhancement to allow features to clean up after 
themselves, it would now be straightforward to allow you to access field 
information as a direct attribute of the feature, rather than being forced 
to look up the field's index and then request the information.  For example:

#--------------------------------------------------------------
# Add two attribute columns together

# Table layout
#------Column1-------------Column2------------
#           3                       4
#           6                       9
#           10                     22

# current approach
lyr = ds.GetLayer(0)
features = []
values = []
for i in range(lyr.GetFeatureCount()):
     features.append(lyr.GetFeature(i))

for feat in features:
     val1 = feat.GetField(feat.GetFieldIndex('Column1'))
     val2 = feat.GetField(feat.GetFieldIndex('Column2'))
     values.append(val1+val2)

# enhanced approach
lyr = ds[0]
features = lyr[:]
values =[]
for feat in features:
     values.append(feat.Column1+feat.Column2)
#--------------------------------------------------------------

There are definitely some gotchas with this approach.  First, if the column 
name has funky characters in it, the convenience isn't that great (you 
might have to escape special python characters like quote and double quote, 
for example).  Second, does accessing things this way muddy up what a 
"Feature" is and how things are accessed?  When I request a Field, like 
feat.Column2, am I getting back the *value* of the Feature in that Field, 
or the definition of the Column2 field?

On the other hand, the convenience is quite great.  For example, in the 
interactive prompt, you would be able to go dir(feat) and see all of the 
attribute columns of the layer.  In my opinion, your code could be a bit 
more concise and clear, and things like printf-style string substitution 
would be much easier to read.

Again, I'm looking for your (and Frank's!) opinion on the proposed 
enhancement.  You would not be required to use these enhancements in your 
old or new code, but they would be there for you if you need them.  Would 
something like this make your life with ogr.py easier?  Does something like 
this break from the unified (C/C++/Python) API in too great a way?

Howard




More information about the Gdal-dev mailing list