[gdal-dev] Fwd: NotImplementedError: Wrong number of arguments
for overloaded function 'Feature_SetField'.
Ole Nielsen
ole.moller.nielsen at gmail.com
Mon Sep 5 23:34:54 EDT 2011
Dear Even
Thank you so much for going through the trouble of reproducing this issue.
You have help a lot, but I need one more hint regarding the apparent change
in how field names get truncated (Normalized/laundered).
To summarise:
- I followed your suggestions and rebuilt from scratch.
- Your Python example worked perfectly
- However my code still produced the error in SetField
(NotImplementedError: Wrong number of arguments for overloaded function)
- It turned out the reason was that I was passing a singleton
numpy.ndarray element into it. Casting that to a float fixed the problem in
ogr 1.8
- However, I still get the following warning and associated errors of the
form
- Warning 6: Normalized/laundered field name: 'CONTENTS_LOSS_AUD' to
'CONTENTS_L'
- ERROR 1: No such field: 'CONTENTS_LOSS_AUD' (not surprisingly, if
it was truncated :-))
The warning comes from a call to lyr.CreateField(fd) and the error happens
when calling SetField with the full length string.
I have included the routine I wrote to store our layers as reference below,
but my questions are
- What are the official ogr steps required to store a vector layer
(represented as e.g. a list of x, y values and associated feature attributes
(name, value))? In particular, is CreateField perhaps obsoleted by something
else?
- Is the truncation to 10 characters hard and fast or driver dependent -
and how should one deal with this truncation? Your example (which does not
use CreateField) would suggest names can be longer than 10 characters.
- Where can i find some documentation of the OGR Python bindings?
I am sorry that my questions are so fundamental, but I am still new to this
library.
Cheers and many thanks
Ole Nielsen
------------ The code that works for version 1.6 but not 1.8
--------------------------------
def write_to_file(self, filename):
"""Save vector data to file
Input
filename: filename with extension .shp or .gml
"""
# Check file format
basename, extension = os.path.splitext(filename)
msg = ('Invalid file type for file %s. Only extensions '
'shp or gml allowed.' % filename)
assert extension == '.shp' or extension == '.gml', msg
driver = DRIVER_MAP[extension]
# FIXME (Ole): Tempory flagging of GML issue (ticket #18)
if extension == '.gml':
msg = ('OGR GML driver does not store geospatial reference.'
'This format is disabled for the time being. See '
'https://github.com/AIFDR/riab/issues/18')
raise Exception(msg)
# Derive layername from filename (excluding preceding dirs)
layername = os.path.split(basename)[-1]
# Get vector data
geometry = self.get_geometry()
data = self.get_data()
N = len(geometry)
# Clear any previous file of this name (ogr does not overwrite)
try:
os.remove(filename)
except:
pass
# Create new file with one layer
drv = ogr.GetDriverByName(driver)
if drv is None:
msg = 'OGR driver %s not available' % driver
raise Exception(msg)
ds = drv.CreateDataSource(filename)
if ds is None:
msg = 'Creation of output file %s failed' % filename
raise Exception(msg)
lyr = ds.CreateLayer(layername,
self.projection.spatial_reference,
self.geometry_type)
if lyr is None:
msg = 'Could not create layer %s' % layername
raise Exception(msg)
# Define attributes if any
store_attributes = False
if data is not None:
if len(data) > 0:
try:
fields = data[0].keys()
except:
msg = ('Input parameter "attributes" was specified '
'but it does not contain dictionaries with '
'field information as expected. The first'
'element is %s' % data[0])
raise Exception(msg)
else:
# Establish OGR types for each element
ogrtypes = {}
for name in fields:
att = data[0][name]
py_type = type(att)
msg = ('Unknown type for storing vector '
'data: %s, %s' % (name, str(py_type)[1:-1]))
assert py_type in TYPE_MAP, msg
ogrtypes[name] = TYPE_MAP[py_type]
else:
msg = ('Input parameter "data" was specified '
'but appears to be empty')
raise Exception(msg)
# Create attribute fields in layer
store_attributes = True
for name in fields:
print 'Creating', name
fd = ogr.FieldDefn(name, ogrtypes[name])
# FIXME (Ole): Trying to address issue #16
# But it doesn't work and
# somehow changes the values of MMI in test
#width = max(128, len(name))
#print name, width
#fd.SetWidth(width)
if lyr.CreateField(fd) != 0:
msg = 'Could not create field %s' % name
raise Exception(msg)
# Store geometry
geom = ogr.Geometry(self.geometry_type)
layer_def = lyr.GetLayerDefn()
for i in range(N):
# Create new feature instance
feature = ogr.Feature(layer_def)
# Store geometry and check
if self.geometry_type == ogr.wkbPoint:
x = float(geometry[i][0])
y = float(geometry[i][1])
geom.SetPoint_2D(0, x, y)
elif self.geometry_type == ogr.wkbPolygon:
wkt = array2wkt(geometry[i])
geom = ogr.CreateGeometryFromWkt(wkt)
else:
msg = 'Geometry %s not implemented' % self.geometry_type
raise Exception(msg)
feature.SetGeometry(geom)
G = feature.GetGeometryRef()
if G is None:
msg = 'Could not create GeometryRef for file %s' % filename
raise Exception(msg)
# Store attributes
if store_attributes:
for name in fields:
val = data[i][name]
if type(val) == numpy.ndarray:
# A singleton of type <type 'numpy.ndarray'> works
for gdal version 1.6
# but fails for version 1.8 in SetField with error:
# NotImplementedError: Wrong number of arguments for
overloaded function
val = float(val)
feature.SetField(name, val)
# Save this feature
if lyr.CreateFeature(feature) != 0:
msg = 'Failed to create feature %i in file %s' % (i,
filename)
raise Exception(msg)
feature.Destroy()
# Write keywords if any
write_keywords(self.keywords, basename + '.keywords')
On Sun, Sep 4, 2011 at 4:16 PM, Even Rouault
<even.rouault at mines-paris.org>wrote:
> Le dimanche 04 septembre 2011 05:54:34, Ole Nielsen a écrit :
> > Hi again and sorry for nagging, but do you have any hints as to what this
> > error means
> >
> > > return _ogr.Feature_SetField(self, *args)
> > >
> > > NotImplementedError: Wrong number of arguments for overloaded function
> > > 'Feature_SetField'.
> > >
> > > Possible C/C++ prototypes are:
> > > SetField(OGRFeatureShadow *,int,char const *)
> > > SetField(OGRFeatureShadow *,char const *,char const *)
> > > SetField(OGRFeatureShadow *,int,int)
> > > SetField(OGRFeatureShadow *,char const *,int)
> > > SetField(OGRFeatureShadow *,int,double)
> > > SetField(OGRFeatureShadow *,char const *,double)
> > > SetField(OGRFeatureShadow *,int,int,int,int,int,int,int,int)
> > > SetField(OGRFeatureShadow *,char const
> *,int,int,int,int,int,int,int)
> >
> > The input to the Python bindings is of the form
> > SetField('STRUCT_DAMAGE_fraction', 0.346734256639)
> >
> > i.e. one string argument (char*) followed by a float (double) which I
> > thought would be matched by the third last header above. It works fine on
> > version 1.6 but not version 1.8.
> >
> > Can anyone tell me what has changed, what it means and how to work around
> > it - please?
> >
> Ole,
>
> Unfortunately, I cannot explain your error, but I'm convinced it must be
> something particular with your installation. So I'd advise you to test on a
> fresh machine and/or clean a bit the packages you've installed on the one
> where you have problems.
>
> Below a test I've just done to show you that SetField(string, double)
> definitely works with GDAL 1.8.0 under normal conditions. I've installed
> Ubuntu
> 11.04 amd64 in a virtual machine, installed first python-gdal (1.6), then
> added
> ubuntugis-unstable PPA, installed qgis (1.7) :
>
> even at even-virtual-machine:~$ dpkg -l | grep gdal
> ii gdal-bin 1.8.0-2~natty2
> Geospatial Data Abstraction Library - Utility programs
> ii libgdal1-1.6.0 1.6.3-4build4
> Geospatial Data Abstraction Library
> ii libgdal1-1.8.0 1.8.0-2~natty2
> Geospatial Data Abstraction Library
> ii python-gdal 1.8.0-2~natty2
> Python bindings to the Geospatial Data Abstraction Library
>
> even at even-virtual-machine:~$ python
> Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
> [GCC 4.5.2] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
> >>> from osgeo import gdal
> >>> from osgeo import ogr
> >>> gdal.VersionInfo('')
> 'GDAL 1.8.0, released 2011/01/12'
> >>> fielddefn = ogr.FieldDefn('STRUCT_DAMAGE_fraction', ogr.OFTReal)
> >>> featuredefn = ogr.FeatureDefn()
> >>> featuredefn.AddFieldDefn(fielddefn)
> >>> feat = ogr.Feature(featuredefn)
> >>> feat.SetField('STRUCT_DAMAGE_fraction', 0.346734256639)
> >>> feat.DumpReadable()
> OGRFeature():-1
> STRUCT_DAMAGE_fraction (Real) = 0.346734256639
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.osgeo.org/pipermail/gdal-dev/attachments/20110906/9aaf248d/attachment-0001.html
More information about the gdal-dev
mailing list