[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